rtld.h revision 116563
11541Srgrimes/*- 21541Srgrimes * Copyright 1996, 1997, 1998, 1999, 2000 John D. Polstra. 31541Srgrimes * All rights reserved. 41541Srgrimes * 51541Srgrimes * Redistribution and use in source and binary forms, with or without 61541Srgrimes * modification, are permitted provided that the following conditions 71541Srgrimes * are met: 81541Srgrimes * 1. Redistributions of source code must retain the above copyright 91541Srgrimes * notice, this list of conditions and the following disclaimer. 101541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111541Srgrimes * notice, this list of conditions and the following disclaimer in the 121541Srgrimes * documentation and/or other materials provided with the distribution. 131541Srgrimes * 141541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 151541Srgrimes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 161541Srgrimes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 171541Srgrimes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 181541Srgrimes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 191541Srgrimes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 201541Srgrimes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 211541Srgrimes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 221541Srgrimes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 231541Srgrimes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 241541Srgrimes * 251541Srgrimes * $FreeBSD: head/libexec/rtld-elf/rtld.h 116563 2003-06-19 03:55:38Z mdodd $ 261541Srgrimes */ 271541Srgrimes 281541Srgrimes#ifndef RTLD_H /* { */ 291541Srgrimes#define RTLD_H 1 301541Srgrimes 311541Srgrimes#include <machine/elf.h> 321541Srgrimes#include <sys/types.h> 331541Srgrimes#include <sys/queue.h> 3422521Sdyson 3550477Speter#include <elf-hints.h> 361541Srgrimes#include <link.h> 371541Srgrimes#include <stddef.h> 381541Srgrimes 391541Srgrimes#include "rtld_lock.h" 401541Srgrimes#include "rtld_machdep.h" 411541Srgrimes 421541Srgrimes#ifndef STANDARD_LIBRARY_PATH 431541Srgrimes#define STANDARD_LIBRARY_PATH "/usr/lib" 445651Sjoerg#endif 455651Sjoerg 465651Sjoerg#define NEW(type) ((type *) xmalloc(sizeof(type))) 475651Sjoerg#define CNEW(type) ((type *) xcalloc(sizeof(type))) 485651Sjoerg 491541Srgrimes/* We might as well do booleans like C++. */ 501541Srgrimestypedef unsigned char bool; 511541Srgrimes#define false 0 521541Srgrimes#define true 1 5345773Sdcs 541541Srgrimesstruct stat; 551541Srgrimesstruct Struct_Obj_Entry; 561541Srgrimes 575651Sjoerg/* Lists of shared objects */ 581541Srgrimestypedef struct Struct_Objlist_Entry { 595651Sjoerg STAILQ_ENTRY(Struct_Objlist_Entry) link; 605651Sjoerg struct Struct_Obj_Entry *obj; 611541Srgrimes} Objlist_Entry; 625651Sjoerg 635651Sjoergtypedef STAILQ_HEAD(Struct_Objlist, Struct_Objlist_Entry) Objlist; 645651Sjoerg 655651Sjoerg/* Types of init and fini functions */ 661541Srgrimestypedef void (*InitFunc)(void); 671541Srgrimes 681541Srgrimes/* Lists of shared object dependencies */ 691541Srgrimestypedef struct Struct_Needed_Entry { 701541Srgrimes struct Struct_Needed_Entry *next; 711541Srgrimes struct Struct_Obj_Entry *obj; 721541Srgrimes unsigned long name; /* Offset of name in string table */ 731541Srgrimes} Needed_Entry; 741541Srgrimes 751541Srgrimes/* Lock object */ 761541Srgrimestypedef struct Struct_LockInfo { 771541Srgrimes void *context; /* Client context for creating locks */ 781541Srgrimes void *thelock; /* The one big lock */ 791541Srgrimes /* Debugging aids. */ 801541Srgrimes volatile int rcount; /* Number of readers holding lock */ 811541Srgrimes volatile int wcount; /* Number of writers holding lock */ 821541Srgrimes /* Methods */ 831541Srgrimes void *(*lock_create)(void *context); 841541Srgrimes void (*rlock_acquire)(void *lock); 851541Srgrimes void (*wlock_acquire)(void *lock); 861541Srgrimes void (*rlock_release)(void *lock); 871541Srgrimes void (*wlock_release)(void *lock); 881541Srgrimes void (*lock_destroy)(void *lock); 891541Srgrimes void (*context_destroy)(void *context); 901541Srgrimes} LockInfo; 911541Srgrimes 921541Srgrimes/* 931541Srgrimes * Shared object descriptor. 941541Srgrimes * 951541Srgrimes * Items marked with "(%)" are dynamically allocated, and must be freed 96332955Sbenno * when the structure is destroyed. 97332955Sbenno * 981541Srgrimes * CAUTION: It appears that the JDK port peeks into these structures. 9945773Sdcs * It looks at "next" and "mapbase" at least. Don't add new members 10045773Sdcs * near the front, until this can be straightened out. 10145773Sdcs */ 10245773Sdcstypedef struct Struct_Obj_Entry { 10345773Sdcs /* 10445773Sdcs * These two items have to be set right for compatibility with the 10545773Sdcs * original ElfKit crt1.o. 10645773Sdcs */ 10745773Sdcs Elf_Word magic; /* Magic number (sanity check) */ 10845773Sdcs Elf_Word version; /* Version number of struct format */ 10945773Sdcs 11045773Sdcs struct Struct_Obj_Entry *next; 11145773Sdcs char *path; /* Pathname of underlying file (%) */ 11245773Sdcs char *origin_path; /* Directory path of origin file */ 11345773Sdcs int refcount; 11445773Sdcs int dl_refcount; /* Number of times loaded by dlopen */ 11545773Sdcs 11645773Sdcs /* These items are computed by map_object() or by digest_phdr(). */ 11745773Sdcs caddr_t mapbase; /* Base address of mapped region */ 11845773Sdcs size_t mapsize; /* Size of mapped region in bytes */ 11945773Sdcs size_t textsize; /* Size of text segment in bytes */ 12045773Sdcs Elf_Addr vaddrbase; /* Base address in shared object file */ 12145773Sdcs caddr_t relocbase; /* Relocation constant = mapbase - vaddrbase */ 12245773Sdcs const Elf_Dyn *dynamic; /* Dynamic section */ 12345773Sdcs caddr_t entry; /* Entry point */ 12445773Sdcs const Elf_Phdr *phdr; /* Program header if it is mapped, else NULL */ 12545773Sdcs size_t phsize; /* Size of program header in bytes */ 12645773Sdcs const char *interp; /* Pathname of the interpreter, if any */ 12745773Sdcs 12845773Sdcs /* Items from the dynamic section. */ 12945773Sdcs Elf_Addr *pltgot; /* PLT or GOT, depending on architecture */ 13045773Sdcs const Elf_Rel *rel; /* Relocation entries */ 13145773Sdcs unsigned long relsize; /* Size in bytes of relocation info */ 13245773Sdcs const Elf_Rela *rela; /* Relocation entries with addend */ 13345773Sdcs unsigned long relasize; /* Size in bytes of addend relocation info */ 13445773Sdcs const Elf_Rel *pltrel; /* PLT relocation entries */ 13545773Sdcs unsigned long pltrelsize; /* Size in bytes of PLT relocation info */ 13645773Sdcs const Elf_Rela *pltrela; /* PLT relocation entries with addend */ 13745773Sdcs unsigned long pltrelasize; /* Size in bytes of PLT addend reloc info */ 13845773Sdcs const Elf_Sym *symtab; /* Symbol table */ 13945773Sdcs const char *strtab; /* String table */ 1405651Sjoerg unsigned long strsize; /* Size in bytes of string table */ 1415651Sjoerg 1425651Sjoerg const Elf_Hashelt *buckets; /* Hash table buckets array */ 1435651Sjoerg unsigned long nbuckets; /* Number of buckets */ 1445651Sjoerg const Elf_Hashelt *chains; /* Hash table chain array */ 1455651Sjoerg unsigned long nchains; /* Number of chains */ 1465651Sjoerg 1475651Sjoerg const char *rpath; /* Search path specified in object */ 1485651Sjoerg Needed_Entry *needed; /* Shared objects needed by this one (%) */ 1495651Sjoerg 1505651Sjoerg Elf_Addr init; /* Initialization function to call */ 1515651Sjoerg Elf_Addr fini; /* Termination function to call */ 1525651Sjoerg 1535651Sjoerg bool mainprog; /* True if this is the main program */ 1545651Sjoerg bool rtld; /* True if this is the dynamic linker */ 1555651Sjoerg bool textrel; /* True if there are relocations to text seg */ 1565651Sjoerg bool symbolic; /* True if generated with "-Bsymbolic" */ 1575651Sjoerg bool bind_now; /* True if all relocations should be made first */ 1585651Sjoerg bool traced; /* Already printed in ldd trace output */ 1595651Sjoerg bool jmpslots_done; /* Already have relocated the jump slots */ 1605651Sjoerg bool init_done; /* Already have added object to init list */ 1615651Sjoerg 1625651Sjoerg struct link_map linkmap; /* for GDB and dlinfo() */ 1635651Sjoerg Objlist dldags; /* Object belongs to these dlopened DAGs (%) */ 1645651Sjoerg Objlist dagmembers; /* DAG has these members (%) */ 1655651Sjoerg dev_t dev; /* Object's filesystem's device */ 1665651Sjoerg ino_t ino; /* Object's inode number */ 1675651Sjoerg void *priv; /* Platform-dependant */ 1685651Sjoerg} Obj_Entry; 1695651Sjoerg 1705651Sjoerg#define RTLD_MAGIC 0xd550b87a 1715651Sjoerg#define RTLD_VERSION 1 1725651Sjoerg 1735651Sjoerg/* 1745651Sjoerg * Symbol cache entry used during relocation to avoid multiple lookups 1755651Sjoerg * of the same symbol. 1765651Sjoerg */ 1771541Srgrimestypedef struct Struct_SymCache { 1781541Srgrimes const Elf_Sym *sym; /* Symbol table entry */ 1791541Srgrimes const Obj_Entry *obj; /* Shared object which defines it */ 18022521Sdyson} SymCache; 18122521Sdyson 1821541Srgrimesextern void _rtld_error(const char *, ...) __printflike(1, 2); 1831541Srgrimesextern Obj_Entry *map_object(int, const char *, const struct stat *); 1841541Srgrimesextern void *xcalloc(size_t); 1851541Srgrimesextern void *xmalloc(size_t); 1861541Srgrimesextern char *xstrdup(const char *); 1871541Srgrimesextern Elf_Addr _GLOBAL_OFFSET_TABLE_[]; 18822521Sdyson 1891541Srgrimesextern void dump_relocations (Obj_Entry *); 1901541Srgrimesextern void dump_obj_relocations (Obj_Entry *); 1911541Srgrimesextern void dump_Elf_Rel (Obj_Entry *, const Elf_Rel *, u_long); 1921541Srgrimesextern void dump_Elf_Rela (Obj_Entry *, const Elf_Rela *, u_long); 1931541Srgrimes 1941541Srgrimes/* 19522521Sdyson * Function declarations. 19622521Sdyson */ 19722521Sdysonunsigned long elf_hash(const char *); 1981541Srgrimesconst Elf_Sym *find_symdef(unsigned long, const Obj_Entry *, 1991541Srgrimes const Obj_Entry **, bool, SymCache *); 2001541Srgrimesvoid init_pltgot(Obj_Entry *); 2011541Srgrimesvoid lockdflt_init(void); 2021541Srgrimesvoid obj_free(Obj_Entry *); 2031541SrgrimesObj_Entry *obj_new(void); 20422521Sdysonvoid _rtld_bind_start(void); 2051541Srgrimesconst Elf_Sym *symlook_obj(const char *, unsigned long, 2061541Srgrimes const Obj_Entry *, bool); 2071541Srgrimes 2081541Srgrimes/* 2091541Srgrimes * MD function declarations. 21022521Sdyson */ 2111541Srgrimesint do_copy_relocations(Obj_Entry *); 2121541Srgrimesint reloc_non_plt(Obj_Entry *, Obj_Entry *); 21355206Speterint reloc_plt(Obj_Entry *); 21425531Sjoergint reloc_jmpslots(Obj_Entry *); 2151541Srgrimes 2165651Sjoerg#endif /* } */ 21745773Sdcs