diff options
Diffstat (limited to 'elf')
-rw-r--r-- | elf/Makefile | 36 | ||||
-rw-r--r-- | elf/dl-deps.c | 27 | ||||
-rw-r--r-- | elf/dl-init.c | 2 | ||||
-rw-r--r-- | elf/dl-load.c | 133 | ||||
-rw-r--r-- | elf/dl-lookup.c | 103 | ||||
-rw-r--r-- | elf/dl-minimal.c | 17 | ||||
-rw-r--r-- | elf/dl-open.c | 45 | ||||
-rw-r--r-- | elf/dl-reloc.c | 28 | ||||
-rw-r--r-- | elf/dl-runtime.c | 24 | ||||
-rw-r--r-- | elf/dl-support.c | 51 | ||||
-rw-r--r-- | elf/dl-symbol.c | 33 | ||||
-rw-r--r-- | elf/dladdr.c | 8 | ||||
-rw-r--r-- | elf/dlclose.c | 6 | ||||
-rw-r--r-- | elf/dlsym.c | 4 | ||||
-rw-r--r-- | elf/do-rel.h | 24 | ||||
-rw-r--r-- | elf/dynamic-link.h | 6 | ||||
-rw-r--r-- | elf/elf.h | 242 | ||||
-rw-r--r-- | elf/elf_hash.c | 4 | ||||
-rw-r--r-- | elf/libelf.h | 283 | ||||
-rw-r--r-- | elf/link.h | 47 | ||||
-rw-r--r-- | elf/linux-compat.c | 4 | ||||
-rw-r--r-- | elf/rtld.c | 42 |
22 files changed, 553 insertions, 616 deletions
diff --git a/elf/Makefile b/elf/Makefile index b144e903e6..34be12e769 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -20,18 +20,25 @@ subdir := elf -headers := elf.h libelf.h link.h dlfcn.h -routines := init-first +headers = elf.h link.h dlfcn.h +routines = init-first $(dl-routines) dl-open dl-symbol dl-support + +# The core dynamic linking functions are in libc for the static and +# profiled libraries. +dl-routines = $(addprefix dl-,load lookup object reloc deps \ + runtime error init fini) +# But they are absent from the shared libc, because that code is in ld.so. +elide-routines.so = $(dl-routines) dl-support + +# ld.so uses those routines, plus some special stuff for being the program +# interpreter and operating independent of libc. +rtld-routines := rtld $(dl-routines) dl-sysdep dl-minimal +distribute = $(rtld-routines:=.c) dynamic-link.h do-rel.h dl-machine.h \ + soinit.c sofini.c ldd.sh.in linux-compat.c -extra-libs = libelf libdl -libelf-routines := elf_hash +extra-libs = libdl libdl-routines := dlopen dlclose dlsym dlerror dladdr -libdl-inhibit-o = $(filter-out .so,$(object-suffixes)) # Build only shared. -rtld-routines := rtld $(addprefix dl-,minimal load lookup object reloc \ - deps runtime sysdep error init fini) -distribute = $(rtld-routines:=.c) dynamic-link.h do-rel.h dl-machine.h \ - soinit.c sofini.c ldd.sh.in linux-compat.c all: # Make this the default target; it will be defined in Rules. @@ -43,7 +50,7 @@ generated = librtld.so dl-allobjs.so install-others = $(slibdir)/$(rtld-installed-name) install-bin = ldd -# Make sure these things is built in the `make lib' pass so it can be used +# Make sure these things are built in the `make lib' pass so they can be used # to run programs during the `make others' pass. lib-noranlib: $(objpfx)ld.so $(addprefix $(objpfx),$(extra-objs)) @@ -81,16 +88,17 @@ $(LINK.o) -nostdlib -nostartfiles -shared -o $@ \ -Wl,-rpath=$(default-rpath) $^ endef +# The dl code in the static libc needs a default library path. +CFLAGS-dl-support.c = -D'DEFAULT_RPATH="$(default-rpath)"' + # The Linux-compatible dynamic linker shared object is just the same # with one object file of compatibility initialization code added. $(objpfx)ld-linux.so.1: $(objpfx)linux-compat.so +# Specify the dependencies of libdl.so; its commands come from the generic +# rule to build a shared library. $(objpfx)libdl.so: $(objpfx)libdl_pic.a $(common-objpfx)libc.so $(objpfx)ld.so - $(patsubst %/,cd %;,$(objpfx)) \ - $(LINK.o) -shared -o $(@:$(objpfx)%=%) \ - $(LDFLAGS.so) $(LDFLAGS-dl.so) \ - -Wl,--whole-archive $(^:$(objpfx)%=%) $(no-whole-archive) $(slibdir)/$(rtld-installed-name): $(objpfx)ld.so; $(do-install-program) $(slibdir)/ld-linux.so.1: $(objpfx)ld-linux.so.1; $(do-install-program) diff --git a/elf/dl-deps.c b/elf/dl-deps.c index 92403d4110..7e3b259362 100644 --- a/elf/dl-deps.c +++ b/elf/dl-deps.c @@ -56,7 +56,7 @@ _dl_map_object_deps (struct link_map *map) { const char *strtab = ((void *) l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr); - const Elf32_Dyn *d; + const ElfW(Dyn) *d; for (d = l->l_ld; d->d_tag != DT_NULL; ++d) if (d->d_tag == DT_NEEDED) { @@ -97,28 +97,3 @@ _dl_map_object_deps (struct link_map *map) scanp->map->l_reserved = 0; } } - - -struct link_map * -_dl_open (struct link_map *parent, const char *file, int mode) -{ - struct link_map *new, *l; - Elf32_Addr init; - - /* Load the named object. */ - new = _dl_map_object (parent, file); - - /* Load that object's dependencies. */ - _dl_map_object_deps (new); - - /* Relocate the objects loaded. */ - for (l = new; l; l = l->l_next) - if (! l->l_relocated) - _dl_relocate_object (l, (mode & RTLD_BINDING_MASK) == RTLD_LAZY); - - /* Run the initializer functions of new objects. */ - while (init = _dl_init_next (new)) - (*(void (*) (void)) init) (); - - return new; -} diff --git a/elf/dl-init.c b/elf/dl-init.c index ee99ce3dec..66ef83e28b 100644 --- a/elf/dl-init.c +++ b/elf/dl-init.c @@ -24,7 +24,7 @@ Cambridge, MA 02139, USA. */ /* Run initializers for MAP and its dependencies, in inverse dependency order (that is, leaf nodes first). */ -Elf32_Addr +ElfW(Addr) _dl_init_next (struct link_map *map) { unsigned int i; diff --git a/elf/dl-load.c b/elf/dl-load.c index 8103c7af2a..c6acc8c222 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -60,6 +60,7 @@ Cambridge, MA 02139, USA. */ #define STRING(x) #x int _dl_zerofd = -1; +size_t _dl_pagesize; /* Try to open NAME in one of the directories in DIRPATH. @@ -82,31 +83,48 @@ open_path (const char *name, size_t namelen, return -1; } - buf = alloca (strlen (dirpath) + 1 + namelen); + buf = __alloca (strlen (dirpath) + 1 + namelen); do { + size_t buflen; + dirpath = p; p = strpbrk (dirpath, ":;"); if (p == NULL) p = strchr (dirpath, '\0'); if (p == dirpath) - /* Two adjacent colons, or a colon at the beginning or the end of - the path means to search the current directory. */ - (void) memcpy (buf, name, namelen); + { + /* Two adjacent colons, or a colon at the beginning or the end of + the path means to search the current directory. */ + (void) memcpy (buf, name, namelen); + buflen = namelen; + } else { /* Construct the pathname to try. */ (void) memcpy (buf, dirpath, p - dirpath); buf[p - dirpath] = '/'; (void) memcpy (&buf[(p - dirpath) + 1], name, namelen); + buflen = p - dirpath + 1 + namelen; } - fd = open (buf, O_RDONLY); + fd = __open (buf, O_RDONLY); if (fd != -1) { - *realname = strdup (buf); - return fd; + *realname = malloc (buflen); + if (*realname) + { + memcpy (*realname, buf, buflen); + return fd; + } + else + { + /* No memory for the name, we certainly won't be able + to load and link it. */ + __close (fd); + return -1; + } } if (errno != ENOENT && errno != EACCES) /* The file exists and is readable, but something went wrong. */ @@ -117,7 +135,6 @@ open_path (const char *name, size_t namelen, return -1; } - /* Map in the shared object file NAME. */ struct link_map * @@ -163,9 +180,19 @@ _dl_map_object (struct link_map *loader, const char *name) } else { - fd = open (name, O_RDONLY); + fd = __open (name, O_RDONLY); if (fd != -1) - realname = strdup (name); + { + size_t len = strlen (name) + 1; + realname = malloc (len); + if (realname) + memcpy (realname, name, len); + else + { + __close (fd); + fd = -1; + } + } } if (fd == -1) @@ -182,25 +209,24 @@ struct link_map * _dl_map_object_from_fd (const char *name, int fd, char *realname) { struct link_map *l = NULL; - const size_t pagesize = getpagesize (); void *file_mapping = NULL; size_t mapping_size = 0; #define LOSE(s) lose (0, (s)) void lose (int code, const char *msg) { - (void) close (fd); + (void) __close (fd); if (file_mapping) - munmap (file_mapping, mapping_size); + __munmap (file_mapping, mapping_size); _dl_signal_error (code, l ? l->l_name : name, msg); } - inline caddr_t map_segment (Elf32_Addr mapstart, size_t len, + inline caddr_t map_segment (ElfW(Addr) mapstart, size_t len, int prot, int fixed, off_t offset) { - caddr_t mapat = mmap ((caddr_t) mapstart, len, prot, - fixed|MAP_COPY|MAP_FILE, - fd, offset); + caddr_t mapat = __mmap ((caddr_t) mapstart, len, prot, + fixed|MAP_COPY|MAP_FILE, + fd, offset); if (mapat == (caddr_t) -1) lose (errno, "failed to map segment from shared object"); return mapat; @@ -213,11 +239,11 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname) { void *result; if (file_mapping) - munmap (file_mapping, mapping_size); - mapping_size = (location + size + 1 + pagesize - 1); - mapping_size &= ~(pagesize - 1); - result = mmap (file_mapping, mapping_size, PROT_READ, - MAP_COPY|MAP_FILE, fd, 0); + __munmap (file_mapping, mapping_size); + mapping_size = (location + size + 1 + _dl_pagesize - 1); + mapping_size &= ~(_dl_pagesize - 1); + result = __mmap (file_mapping, mapping_size, PROT_READ, + MAP_COPY|MAP_FILE, fd, 0); if (result == (void *) -1) lose (errno, "cannot map file data"); file_mapping = result; @@ -225,9 +251,9 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname) return file_mapping + location; } - const Elf32_Ehdr *header; - const Elf32_Phdr *phdr; - const Elf32_Phdr *ph; + const ElfW(Ehdr) *header; + const ElfW(Phdr) *phdr; + const ElfW(Phdr) *ph; int type; /* Look again to see if the real name matched another already loaded. */ @@ -236,12 +262,15 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname) { /* The object is already loaded. Just bump its reference count and return it. */ - close (fd); + __close (fd); free (realname); ++l->l_opencount; return l; } + if (_dl_pagesize == 0) + _dl_pagesize = __getpagesize (); + /* Map in the first page to read the header. */ header = map (0, sizeof *header); @@ -260,8 +289,10 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname) #endif ) LOSE ("invalid ELF header"); - if (header->e_ident[EI_CLASS] != ELFCLASS32) - LOSE ("ELF file class not 32-bit"); +#define ELF32_CLASS ELFCLASS32 +#define ELF64_CLASS ELFCLASS64 + if (header->e_ident[EI_CLASS] != ELFW(CLASS)) + LOSE ("ELF file class not " STRING(__ELF_WORDSIZE) "-bit"); if (header->e_ident[EI_DATA] != byteorder) LOSE ("ELF file data encoding not " byteorder_name); if (header->e_ident[EI_VERSION] != EV_CURRENT) @@ -270,7 +301,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname) LOSE ("ELF file version not " STRING(EV_CURRENT)); if (! elf_machine_matches_host (header->e_machine)) LOSE ("ELF file machine architecture not " ELF_MACHINE_NAME); - if (header->e_phentsize != sizeof (Elf32_Phdr)) + if (header->e_phentsize != sizeof (ElfW(Phdr))) LOSE ("ELF file's phentsize not the expected size"); /* Enter the new object in the list of loaded objects. */ @@ -289,13 +320,13 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname) l->l_entry = header->e_entry; type = header->e_type; l->l_phnum = header->e_phnum; - phdr = map (header->e_phoff, l->l_phnum * sizeof (Elf32_Phdr)); + phdr = map (header->e_phoff, l->l_phnum * sizeof (ElfW(Phdr))); { /* Scan the program header table, collecting its load commands. */ struct loadcmd { - Elf32_Addr mapstart, mapend, dataend, allocend; + ElfW(Addr) mapstart, mapend, dataend, allocend; off_t mapoff; int prot; } loadcmds[l->l_phnum], *c; @@ -320,15 +351,15 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname) case PT_LOAD: /* A load command tells us to map in part of the file. We record the load commands and process them all later. */ - if (ph->p_align % pagesize != 0) + if (ph->p_align % _dl_pagesize != 0) LOSE ("ELF load command alignment not page-aligned"); if ((ph->p_vaddr - ph->p_offset) % ph->p_align) LOSE ("ELF load command address/offset not properly aligned"); { struct loadcmd *c = &loadcmds[nloadcmds++]; c->mapstart = ph->p_vaddr & ~(ph->p_align - 1); - c->mapend = ((ph->p_vaddr + ph->p_filesz + pagesize - 1) - & ~(pagesize - 1)); + c->mapend = ((ph->p_vaddr + ph->p_filesz + _dl_pagesize - 1) + & ~(_dl_pagesize - 1)); c->dataend = ph->p_vaddr + ph->p_filesz; c->allocend = ph->p_vaddr + ph->p_memsz; c->mapoff = ph->p_offset & ~(ph->p_align - 1); @@ -344,7 +375,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname) } /* We are done reading the file's headers now. Unmap them. */ - munmap (file_mapping, mapping_size); + __munmap (file_mapping, mapping_size); /* Now process the load commands and map segments into memory. */ c = loadcmds; @@ -362,16 +393,16 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname) mapat = map_segment (c->mapstart, loadcmds[nloadcmds - 1].allocend - c->mapstart, c->prot, 0, c->mapoff); - l->l_addr = (Elf32_Addr) mapat - c->mapstart; + l->l_addr = (ElfW(Addr)) mapat - c->mapstart; /* Change protection on the excess portion to disallow all access; the portions we do not remap later will be inaccessible as if unallocated. Then jump into the normal segment-mapping loop to handle the portion of the segment past the end of the file mapping. */ - mprotect (mapat + c->mapend, - loadcmds[nloadcmds - 1].allocend - c->mapend, - 0); + __mprotect (mapat + c->mapend, + loadcmds[nloadcmds - 1].allocend - c->mapend, + 0); goto postmap; } @@ -387,11 +418,11 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname) { /* Extra zero pages should appear at the end of this segment, after the data mapped from the file. */ - Elf32_Addr zero, zeroend, zeropage; + ElfW(Addr) zero, zeroend, zeropage; zero = l->l_addr + c->dataend; zeroend = l->l_addr + c->allocend; - zeropage = (zero + pagesize - 1) & ~(pagesize - 1); + zeropage = (zero + _dl_pagesize - 1) & ~(_dl_pagesize - 1); if (zeroend < zeropage) /* All the extra data is in the last page of the segment. @@ -404,23 +435,23 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname) if ((c->prot & PROT_WRITE) == 0) { /* Dag nab it. */ - if (mprotect ((caddr_t) (zero & ~(pagesize - 1)), - pagesize, c->prot|PROT_WRITE) < 0) + if (__mprotect ((caddr_t) (zero & ~(_dl_pagesize - 1)), + _dl_pagesize, c->prot|PROT_WRITE) < 0) lose (errno, "cannot change memory protections"); } memset ((void *) zero, 0, zeropage - zero); if ((c->prot & PROT_WRITE) == 0) - mprotect ((caddr_t) (zero & ~(pagesize - 1)), - pagesize, c->prot); + __mprotect ((caddr_t) (zero & ~(_dl_pagesize - 1)), + _dl_pagesize, c->prot); } if (zeroend > zeropage) { /* Map the remaining zero pages in from the zero fill FD. */ caddr_t mapat; - mapat = mmap ((caddr_t) zeropage, zeroend - zeropage, c->prot, - MAP_ANON|MAP_PRIVATE|MAP_FIXED, - _dl_zerofd, 0); + mapat = __mmap ((caddr_t) zeropage, zeroend - zeropage, + c->prot, MAP_ANON|MAP_PRIVATE|MAP_FIXED, + _dl_zerofd, 0); if (mapat == (caddr_t) -1) lose (errno, "cannot map zero-fill pages"); } @@ -441,11 +472,11 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname) LOSE ("object file has no dynamic section"); } else - (Elf32_Addr) l->l_ld += l->l_addr; + (ElfW(Addr)) l->l_ld += l->l_addr; if (l->l_phdr == 0) - l->l_phdr = (void *) ((const Elf32_Ehdr *) l->l_addr)->e_phoff; - (Elf32_Addr) l->l_phdr += l->l_addr; + l->l_phdr = (void *) ((const ElfW(Ehdr) *) l->l_addr)->e_phoff; + (ElfW(Addr)) l->l_phdr += l->l_addr; elf_get_dynamic_info (l->l_ld, l->l_info); if (l->l_info[DT_HASH]) diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c index 104963987b..0674253041 100644 --- a/elf/dl-lookup.c +++ b/elf/dl-lookup.c @@ -18,27 +18,48 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <stddef.h> -#include <libelf.h> #include <link.h> #include <assert.h> + +/* This is the hashing function specified by the ELF ABI. */ +static inline unsigned +_dl_elf_hash (const char *name) +{ + unsigned long int hash = 0; + while (*name != '\0') + { + unsigned long int hi; + hash = (hash << 4) + *name++; + hi = hash & 0xf0000000; + if (hi != 0) + { + hash ^= hi >> 24; + /* The ELF ABI says `hash &= ~hi', but this is equivalent + in this case and on some machines one insn instead of two. */ + hash ^= hi; + } + } + return hash; +} + /* Search loaded objects' symbol tables for a definition of the symbol UNDEF_NAME. The chosen value can't be RELOC_ADDR. If NOPLT is nonzero, then a PLT entry cannot satisfy the reference; some different binding must be found. */ -Elf32_Addr -_dl_lookup_symbol (const char *undef_name, const Elf32_Sym **ref, +ElfW(Addr) +_dl_lookup_symbol (const char *undef_name, const ElfW(Sym) **ref, struct link_map *symbol_scope[2], const char *reference_name, - Elf32_Addr reloc_addr, + ElfW(Addr) reloc_addr, int noplt) { - unsigned long int hash = elf_hash (undef_name); + const unsigned long int hash = _dl_elf_hash (undef_name); struct { - Elf32_Addr a; - const Elf32_Sym *s; + ElfW(Addr) a; + const ElfW(Sym) *s; } weak_value = { 0, NULL }; size_t i; struct link_map **scope, *map; @@ -48,9 +69,9 @@ _dl_lookup_symbol (const char *undef_name, const Elf32_Sym **ref, if (*scope) for (i = 0; i < (*scope)->l_nsearchlist; ++i) { - const Elf32_Sym *symtab; + const ElfW(Sym) *symtab; const char *strtab; - Elf32_Word symidx; + ElfW(Word) symidx; map = (*scope)->l_searchlist[i]; @@ -63,7 +84,7 @@ _dl_lookup_symbol (const char *undef_name, const Elf32_Sym **ref, symidx != STN_UNDEF; symidx = map->l_chain[symidx]) { - const Elf32_Sym *sym = &symtab[symidx]; + const ElfW(Sym) *sym = &symtab[symidx]; if (sym->st_value == 0 || /* No value. */ /* Cannot resolve to the location being filled in. */ @@ -71,7 +92,7 @@ _dl_lookup_symbol (const char *undef_name, const Elf32_Sym **ref, (noplt && sym->st_shndx == SHN_UNDEF)) /* Reject PLT. */ continue; - switch (ELF32_ST_TYPE (sym->st_info)) + switch (ELFW(ST_TYPE) (sym->st_info)) { case STT_NOTYPE: case STT_FUNC: @@ -86,7 +107,7 @@ _dl_lookup_symbol (const char *undef_name, const Elf32_Sym **ref, /* Not the symbol we are looking for. */ continue; - switch (ELF32_ST_BIND (sym->st_info)) + switch (ELFW(ST_BIND) (sym->st_info)) { case STB_GLOBAL: /* Global definition. Just what we need. */ @@ -108,41 +129,15 @@ _dl_lookup_symbol (const char *undef_name, const Elf32_Sym **ref, } } - if (weak_value.s == NULL && ELF32_ST_BIND ((*ref)->st_info) != STB_WEAK) + if (weak_value.s == NULL && ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK) { - /* The symbol was not defined by any object in scope. To allow - access to dynamic linker functionality without using -ldl and - thereby brining the dynamic linker's symbols into scope, we - recognize a few magical symbol names and resolve them to the - addresses of functions inside the dynamic linker. */ - - struct magic - { - unsigned long int hash; - const char *name; - Elf32_Addr value; - }; - static struct magic magic[] = - { - { 0xd6a2a5e, "_GNU_libc_dl_open", (Elf32_Addr) &_dl_open }, -/* { 0x69ef845, "_GNU_libc_dl_close", (Elf32_Addr) &_dl_close },*/ - { 0xae4d63c, "_GNU_libc_dl_symbol", (Elf32_Addr) &_dl_symbol_value }, - { 0, NULL, 0 } - }; - struct magic *m; - - for (m = magic; m->hash; ++m) - if (hash == m->hash && !strcmp (undef_name, m->name)) - return m->value; - - { - const char msg[] = "undefined symbol: "; - char buf[sizeof msg + strlen (undef_name)]; - memcpy (buf, msg, sizeof msg - 1); - memcpy (&buf[sizeof msg - 1], undef_name, - sizeof buf - sizeof msg + 1); - _dl_signal_error (0, reference_name, buf); - } + /* We could find no value for a strong reference. */ + const char msg[] = "undefined symbol: "; + char buf[sizeof msg + strlen (undef_name)]; + memcpy (buf, msg, sizeof msg - 1); + memcpy (&buf[sizeof msg - 1], undef_name, + sizeof buf - sizeof msg + 1); + _dl_signal_error (0, reference_name, buf); } *ref = weak_value.s; @@ -155,23 +150,11 @@ _dl_lookup_symbol (const char *undef_name, const Elf32_Sym **ref, void _dl_setup_hash (struct link_map *map) { - Elf32_Word *hash = (void *) map->l_addr + map->l_info[DT_HASH]->d_un.d_ptr; - Elf32_Word nchain; + ElfW(Word) *hash = (void *) map->l_addr + map->l_info[DT_HASH]->d_un.d_ptr; + ElfW(Word) nchain; map->l_nbuckets = *hash++; nchain = *hash++; map->l_buckets = hash; hash += map->l_nbuckets; map->l_chain = hash; } - -/* Look up symbol NAME in MAP's scope and return its run-time address. */ - -Elf32_Addr -_dl_symbol_value (struct link_map *map, const char *name) -{ - Elf32_Addr loadbase; - const Elf32_Sym *ref = NULL; - struct link_map *scope[2] = { map, NULL }; - loadbase = _dl_lookup_symbol (name, &ref, scope, map->l_name, 0, 0); - return loadbase + ref->st_value; -} diff --git a/elf/dl-minimal.c b/elf/dl-minimal.c index c61b51532b..bf19fee6c4 100644 --- a/elf/dl-minimal.c +++ b/elf/dl-minimal.c @@ -34,10 +34,9 @@ void * malloc (size_t n) { extern int _dl_zerofd; - static size_t pagesize; - if (pagesize == 0) - pagesize = __getpagesize (); + if (_dl_pagesize == 0) + _dl_pagesize = __getpagesize (); if (_dl_zerofd == -1) _dl_zerofd = _dl_sysdep_open_zero_fill (); @@ -47,8 +46,8 @@ malloc (size_t n) /* Consume any unused space in the last page of our data segment. */ extern int _end; alloc_ptr = &_end; - alloc_end = (void *) 0 + (((alloc_ptr - (void *) 0) + pagesize - 1) - & ~(pagesize - 1)); + alloc_end = (void *) 0 + (((alloc_ptr - (void *) 0) + _dl_pagesize - 1) + & ~(_dl_pagesize - 1)); } /* Make sure the allocation pointer is ideally aligned. */ @@ -59,13 +58,13 @@ malloc (size_t n) { /* Insufficient space left; allocate another page. */ caddr_t page; - assert (n <= pagesize); - page = mmap (0, pagesize, PROT_READ|PROT_WRITE, - MAP_ANON|MAP_PRIVATE, _dl_zerofd, 0); + assert (n <= _dl_pagesize); + page = __mmap (0, _dl_pagesize, PROT_READ|PROT_WRITE, + MAP_ANON|MAP_PRIVATE, _dl_zerofd, 0); assert (page != (caddr_t) -1); if (page != alloc_end) alloc_ptr = page; - alloc_end = page + pagesize; + alloc_end = page + _dl_pagesize; } alloc_last_block = (void *) alloc_ptr; diff --git a/elf/dl-open.c b/elf/dl-open.c new file mode 100644 index 0000000000..221abbd35e --- /dev/null +++ b/elf/dl-open.c @@ -0,0 +1,45 @@ +/* Load a shared object at runtime, relocate it, and run its initializer. +Copyright (C) 1996 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <link.h> +#include <dlfcn.h> + +struct link_map * +_dl_open (struct link_map *parent, const char *file, int mode) +{ + struct link_map *new, *l; + ElfW(Addr) init; + + /* Load the named object. */ + new = _dl_map_object (parent, file); + + /* Load that object's dependencies. */ + _dl_map_object_deps (new); + + /* Relocate the objects loaded. */ + for (l = new; l; l = l->l_next) + if (! l->l_relocated) + _dl_relocate_object (l, (mode & RTLD_BINDING_MASK) == RTLD_LAZY); + + /* Run the initializer functions of new objects. */ + while (init = _dl_init_next (new)) + (*(void (*) (void)) init) (); + + return new; +} diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c index bfa0174444..5da8575da5 100644 --- a/elf/dl-reloc.c +++ b/elf/dl-reloc.c @@ -28,8 +28,6 @@ Cambridge, MA 02139, USA. */ void _dl_relocate_object (struct link_map *l, int lazy) { - const size_t pagesize = getpagesize (); - if (l->l_relocated) return; @@ -37,17 +35,17 @@ _dl_relocate_object (struct link_map *l, int lazy) { /* Bletch. We must make read-only segments writable long enough to relocate them. */ - const Elf32_Phdr *ph; + const ElfW(Phdr) *ph; for (ph = l->l_phdr; ph < &l->l_phdr[l->l_phnum]; ++ph) if (ph->p_type == PT_LOAD && (ph->p_flags & PF_W) == 0) { caddr_t mapstart = ((caddr_t) l->l_addr + - (ph->p_vaddr & ~(pagesize - 1))); + (ph->p_vaddr & ~(_dl_pagesize - 1))); caddr_t mapend = ((caddr_t) l->l_addr + - ((ph->p_vaddr + ph->p_memsz + pagesize - 1) - & ~(pagesize - 1))); - if (mprotect (mapstart, mapend - mapstart, - PROT_READ|PROT_WRITE) < 0) + ((ph->p_vaddr + ph->p_memsz + _dl_pagesize - 1) + & ~(_dl_pagesize - 1))); + if (__mprotect (mapstart, mapend - mapstart, + PROT_READ|PROT_WRITE) < 0) _dl_signal_error (errno, l->l_name, "cannot make segment writable for relocation"); } @@ -59,8 +57,8 @@ _dl_relocate_object (struct link_map *l, int lazy) const char *strtab = ((void *) l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr); - Elf32_Addr resolve (const Elf32_Sym **ref, - Elf32_Addr reloc_addr, int noplt) + ElfW(Addr) resolve (const ElfW(Sym) **ref, + ElfW(Addr) reloc_addr, int noplt) { return _dl_lookup_symbol (strtab + (*ref)->st_name, ref, scope, l->l_name, reloc_addr, noplt); @@ -97,21 +95,21 @@ _dl_relocate_object (struct link_map *l, int lazy) if (l->l_info[DT_TEXTREL]) { /* Undo the protection change we made before relocating. */ - const Elf32_Phdr *ph; + const ElfW(Phdr) *ph; for (ph = l->l_phdr; ph < &l->l_phdr[l->l_phnum]; ++ph) if (ph->p_type == PT_LOAD && (ph->p_flags & PF_W) == 0) { caddr_t mapstart = ((caddr_t) l->l_addr + - (ph->p_vaddr & ~(pagesize - 1))); + (ph->p_vaddr & ~(_dl_pagesize - 1))); caddr_t mapend = ((caddr_t) l->l_addr + - ((ph->p_vaddr + ph->p_memsz + pagesize - 1) - & ~(pagesize - 1))); + ((ph->p_vaddr + ph->p_memsz + _dl_pagesize - 1) + & ~(_dl_pagesize - 1))); int prot = 0; if (ph->p_flags & PF_R) prot |= PROT_READ; if (ph->p_flags & PF_X) prot |= PROT_EXEC; - if (mprotect (mapstart, mapend - mapstart, prot) < 0) + if (__mprotect (mapstart, mapend - mapstart, prot) < 0) _dl_signal_error (errno, l->l_name, "can't restore segment prot after reloc"); } diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c index dce34f8a89..c306543155 100644 --- a/elf/dl-runtime.c +++ b/elf/dl-runtime.c @@ -24,9 +24,9 @@ Cambridge, MA 02139, USA. */ #define elf_machine_rel 1 #define elf_machine_rela 2 #if elf_machine_relplt == elf_machine_rel -#define PLTREL Elf32_Rel +#define PLTREL ElfW(Rel) #elif elf_machine_relplt == elf_machine_rela -#define PLTREL Elf32_Rela +#define PLTREL ElfW(Rela) #else #error "dl-machine.h bug: elf_machine_relplt not rel or rela" #endif @@ -37,11 +37,11 @@ Cambridge, MA 02139, USA. */ in the trampoline code will be a local PC-relative call. Tell the compiler not to worry that the function appears not to be called. */ -static Elf32_Addr fixup ( +static ElfW(Addr) fixup ( #ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS ELF_MACHINE_RUNTIME_FIXUP_ARGS, #endif - struct link_map *l, Elf32_Word reloc_offset) + struct link_map *l, ElfW(Word) reloc_offset) __attribute__ ((unused)); /* This function is called through a special trampoline from the PLT the @@ -51,15 +51,15 @@ static Elf32_Addr fixup ( to that address. Future calls will bounce directly from the PLT to the function. */ -static Elf32_Addr +static ElfW(Addr) fixup ( #ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS ELF_MACHINE_RUNTIME_FIXUP_ARGS, #endif - struct link_map *l, Elf32_Word reloc_offset) + struct link_map *l, ElfW(Word) reloc_offset) { - const Elf32_Sym *const symtab - = (const Elf32_Sym *) (l->l_addr + l->l_info[DT_SYMTAB]->d_un.d_ptr); + const ElfW(Sym) *const symtab + = (const ElfW(Sym) *) (l->l_addr + l->l_info[DT_SYMTAB]->d_un.d_ptr); const char *strtab = (const char *) (l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr); @@ -67,8 +67,8 @@ fixup ( = (const void *) (l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr + reloc_offset); - Elf32_Addr resolve (const Elf32_Sym **ref, - Elf32_Addr reloc_addr, int noplt) + ElfW(Addr) resolve (const ElfW(Sym) **ref, + ElfW(Addr) reloc_addr, int noplt) { struct link_map *scope[2] = { _dl_loaded, NULL }; return _dl_lookup_symbol (strtab + (*ref)->st_name, ref, @@ -76,9 +76,9 @@ fixup ( } /* Perform the specified relocation. */ - elf_machine_relplt (l, reloc, &symtab[ELF32_R_SYM (reloc->r_info)], resolve); + elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)], resolve); - return *(Elf32_Addr *) (l->l_addr + reloc->r_offset); + return *(ElfW(Addr) *) (l->l_addr + reloc->r_offset); } diff --git a/elf/dl-support.c b/elf/dl-support.c new file mode 100644 index 0000000000..b85d470770 --- /dev/null +++ b/elf/dl-support.c @@ -0,0 +1,51 @@ +/* Support for dynamic linking code in static libc. +Copyright (C) 1996 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <assert.h> +#include <fcntl.h> +#include <unistd.h> + +/* This file defines some things that for the dynamic linker are defined in + rtld.c and dl-sysdep.c in ways appropriate to bootstrap dynamic linking. */ + +int _dl_secure; /* Always honor LD_LIBRARY_PATH. */ + +extern char *__progname; +char **_dl_argv = &__progname; /* This is checked for some error messages. */ + +/* This defines the default search path for libraries. + For the dynamic linker it is set by -rpath when linking. */ +const char *_dl_rpath = DEFAULT_RPATH; + +/* This is the only dl-sysdep.c function that is actually needed at run-time + by _dl_map_object. */ + +int +_dl_sysdep_open_zero_fill (void) +{ + return __open ("/dev/zero", O_RDONLY); +} + +/* This should never be called. */ +void +_dl_sysdep_fatal (void) +{ + assert (! "_dl_sysdep_fatal called"); +} + diff --git a/elf/dl-symbol.c b/elf/dl-symbol.c new file mode 100644 index 0000000000..7977e69ab6 --- /dev/null +++ b/elf/dl-symbol.c @@ -0,0 +1,33 @@ +/* Look up a symbol's run-time value in the scope of a loaded object. +Copyright (C) 1995, 1996 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <stddef.h> +#include <link.h> + +/* Look up symbol NAME in MAP's scope and return its run-time address. */ + +ElfW(Addr) +_dl_symbol_value (struct link_map *map, const char *name) +{ + ElfW(Addr) loadbase; + const ElfW(Sym) *ref = NULL; + struct link_map *scope[2] = { map, NULL }; + loadbase = _dl_lookup_symbol (name, &ref, scope, map->l_name, 0, 0); + return loadbase + ref->st_value; +} diff --git a/elf/dladdr.c b/elf/dladdr.c index 87283e2586..fa78d8fc02 100644 --- a/elf/dladdr.c +++ b/elf/dladdr.c @@ -25,9 +25,9 @@ Cambridge, MA 02139, USA. */ int dladdr (void *address, Dl_info *info) { - const Elf32_Addr addr = (Elf32_Addr) address; + const ElfW(Addr) addr = (ElfW(Addr)) address; struct link_map *l, *match; - const Elf32_Sym *symtab, *matchsym; + const ElfW(Sym) *symtab, *matchsym; const char *strtab; /* Find the highest-addressed object that ADDRESS is not below. */ @@ -64,8 +64,8 @@ dladdr (void *address, Dl_info *info) for (matchsym = NULL; (void *) symtab < (void *) strtab; ++symtab) if (addr >= match->l_addr + symtab->st_value && !matchsym || matchsym->st_value < symtab->st_value && - ELF32_ST_BIND (symtab->st_info) == STB_GLOBAL || - ELF32_ST_BIND (symtab->st_info) == STB_WEAK) + ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL || + ELFW(ST_BIND) (symtab->st_info) == STB_WEAK) matchsym = symtab; if (matchsym) diff --git a/elf/dlclose.c b/elf/dlclose.c index fbb3ca6fe2..0d2689e01c 100644 --- a/elf/dlclose.c +++ b/elf/dlclose.c @@ -65,7 +65,7 @@ dlclose (void *handle) { /* That was the last reference, and this was a dlopen-loaded object. We can unmap it. */ - const Elf32_Phdr *ph; + const ElfW(Phdr) *ph; if (map->l_info[DT_FINI]) /* Call its termination function. */ @@ -76,8 +76,8 @@ dlclose (void *handle) for (ph = map->l_phdr; ph < &map->l_phdr[map->l_phnum]; ++ph) if (ph->p_type == PT_LOAD) { - Elf32_Addr mapstart = ph->p_vaddr & ~(ph->p_align - 1); - Elf32_Addr mapend = ((ph->p_vaddr + ph->p_memsz + ElfW(Addr) mapstart = ph->p_vaddr & ~(ph->p_align - 1); + ElfW(Addr) mapend = ((ph->p_vaddr + ph->p_memsz + ph->p_align - 1) & ~(ph->p_align - 1)); munmap ((caddr_t) mapstart, mapend - mapstart); diff --git a/elf/dlsym.c b/elf/dlsym.c index f874af780a..7677f2741f 100644 --- a/elf/dlsym.c +++ b/elf/dlsym.c @@ -27,8 +27,8 @@ void * dlsym (void *handle, const char *name) { struct link_map *map = handle; - Elf32_Addr loadbase; - const Elf32_Sym *ref = NULL; + ElfW(Addr) loadbase; + const ElfW(Sym) *ref = NULL; void doit (void) { struct link_map *scope[2] = { map, NULL }; diff --git a/elf/do-rel.h b/elf/do-rel.h index 438613a32d..ebf2e84a64 100644 --- a/elf/do-rel.h +++ b/elf/do-rel.h @@ -21,9 +21,9 @@ Cambridge, MA 02139, USA. */ `elf_dynamic_do_rel' and `elf_dynamic_do_rela'. */ #ifdef DO_RELA -#define elf_dynamic_do_rel elf_dynamic_do_rela -#define Elf32_Rel Elf32_Rela -#define elf_machine_rel elf_machine_rela +#define elf_dynamic_do_rel elf_dynamic_do_rela +#define Rel Rela +#define elf_machine_rel elf_machine_rela #endif @@ -37,15 +37,15 @@ Cambridge, MA 02139, USA. */ static inline void elf_dynamic_do_rel (struct link_map *map, int reltag, int sztag, - Elf32_Addr (*resolve) (const Elf32_Sym **symbol, - Elf32_Addr reloc_addr, int noplt), + ElfW(Addr) (*resolve) (const ElfW(Sym) **symbol, + ElfW(Addr) reloc_addr, int noplt), int lazy) { - const Elf32_Sym *const symtab - = (const Elf32_Sym *) (map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr); - const Elf32_Rel *r - = (const Elf32_Rel *) (map->l_addr + map->l_info[reltag]->d_un.d_ptr); - const Elf32_Rel *end = &r[map->l_info[sztag]->d_un.d_val / sizeof *r]; + const ElfW(Sym) *const symtab + = (const ElfW(Sym) *) (map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr); + const ElfW(Rel) *r + = (const ElfW(Rel) *) (map->l_addr + map->l_info[reltag]->d_un.d_ptr); + const ElfW(Rel) *end = &r[map->l_info[sztag]->d_un.d_val / sizeof *r]; if (lazy) /* Doing lazy PLT relocations; they need very little info. */ @@ -53,9 +53,9 @@ elf_dynamic_do_rel (struct link_map *map, elf_machine_lazy_rel (map, r); else for (; r < end; ++r) - elf_machine_rel (map, r, &symtab[ELF32_R_SYM (r->r_info)], resolve); + elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], resolve); } #undef elf_dynamic_do_rel -#undef Elf32_Rel +#undef Rel #undef elf_machine_rel diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h index 38236bae2c..b69cb3fd43 100644 --- a/elf/dynamic-link.h +++ b/elf/dynamic-link.h @@ -25,7 +25,7 @@ Cambridge, MA 02139, USA. */ /* Read the dynamic section at DYN and fill in INFO with indices DT_*. */ static inline void -elf_get_dynamic_info (Elf32_Dyn *dyn, Elf32_Dyn *info[DT_NUM + DT_PROCNUM]) +elf_get_dynamic_info (ElfW(Dyn) *dyn, ElfW(Dyn) *info[DT_NUM + DT_PROCNUM]) { unsigned int i; @@ -48,9 +48,9 @@ elf_get_dynamic_info (Elf32_Dyn *dyn, Elf32_Dyn *info[DT_NUM + DT_PROCNUM]) } if (info[DT_RELA]) - assert (info[DT_RELAENT]->d_un.d_val == sizeof (Elf32_Rela)); + assert (info[DT_RELAENT]->d_un.d_val == sizeof (ElfW(Rela))); if (info[DT_REL]) - assert (info[DT_RELENT]->d_un.d_val == sizeof (Elf32_Rel)); + assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel))); if (info[DT_PLTREL]) assert (info[DT_PLTREL]->d_un.d_val == DT_REL || info[DT_PLTREL]->d_un.d_val == DT_RELA); diff --git a/elf/elf.h b/elf/elf.h index ec81f0b820..f6d023d207 100644 --- a/elf/elf.h +++ b/elf/elf.h @@ -23,16 +23,37 @@ Cambridge, MA 02139, USA. */ #define _ELF_H 1 -/* Standard ELF types. +/* Standard ELF types. Using __attribute__ mode ensures that GCC + will choose the right number of bits for these types. */ - Using __attribute__ mode ensures that gcc will choose the right for - these types. */ +/* Type for a 16-bit quantity. */ +typedef unsigned int Elf32_Half __attribute__ ((mode (HI))); +typedef unsigned int Elf64_Half __attribute__ ((mode (HI))); + +/* Types for signed and unsigned 32-bit quantities. */ +typedef unsigned int Elf32_Word __attribute__ ((mode (SI))); +typedef int Elf32_Sword __attribute__ ((mode (SI))); +typedef unsigned int Elf64_Word __attribute__ ((mode (SI))); +typedef int Elf64_Sword __attribute__ ((mode (SI))); + +/* Types for signed and unsigned 64-bit quantities. */ +typedef unsigned int Elf32_Xword __attribute__ ((mode (DI))); +typedef int Elf32_Sxword __attribute__ ((mode (DI))); +typedef unsigned int Elf64_Xword __attribute__ ((mode (DI))); +typedef int Elf64_Sxword __attribute__ ((mode (DI))); +/* Type of addresses. */ typedef unsigned int Elf32_Addr __attribute__ ((mode (SI))); -typedef unsigned int Elf32_Half __attribute__ ((mode (HI))); +typedef unsigned int Elf64_Addr __attribute__ ((mode (DI))); + +/* Type of file offsets. */ typedef unsigned int Elf32_Off __attribute__ ((mode (SI))); -typedef int Elf32_Sword __attribute__ ((mode (SI))); -typedef unsigned int Elf32_Word __attribute__ ((mode (SI))); +typedef unsigned int Elf64_Off __attribute__ ((mode (DI))); + +/* Type for section indices, which are 16-bit quantities. */ +typedef unsigned int Elf32_Section __attribute__ ((mode (HI))); +typedef unsigned int Elf64_Section __attribute__ ((mode (HI))); + /* The ELF file header. This appears at the start of every ELF file. */ @@ -56,6 +77,24 @@ typedef struct Elf32_Half e_shstrndx; /* Section header string table index */ } Elf32_Ehdr; +typedef struct +{ + unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ + Elf64_Half e_type; /* Object file type */ + Elf64_Half e_machine; /* Architecture */ + Elf64_Word e_version; /* Object file version */ + Elf64_Addr e_entry; /* Entry point virtual address */ + Elf64_Off e_phoff; /* Program header table file offset */ + Elf64_Off e_shoff; /* Section header table file offset */ + Elf64_Word e_flags; /* Processor-specific flags */ + Elf64_Half e_ehsize; /* ELF header size in bytes */ + Elf64_Half e_phentsize; /* Program header table entry size */ + Elf64_Half e_phnum; /* Program header table entry count */ + Elf64_Half e_shentsize; /* Section header table entry size */ + Elf64_Half e_shnum; /* Section header table entry count */ + Elf64_Half e_shstrndx; /* Section header string table index */ +} Elf64_Ehdr; + /* Fields in the e_ident array. The EI_* macros are indices into the array. The macros under each EI_* macro are the values the byte may have. */ @@ -125,6 +164,8 @@ typedef struct pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the chances of collision with official or non-GNU unofficial values. */ +#define EM_ALPHA 0x9026 + /* Legal values for e_version (version). */ #define EV_NONE 0 /* Invalid ELF version */ @@ -146,6 +187,20 @@ typedef struct Elf32_Word sh_entsize; /* Entry size if section holds table */ } Elf32_Shdr; +typedef struct +{ + Elf64_Word sh_name; /* Section name (string tbl index) */ + Elf64_Word sh_type; /* Section type */ + Elf64_Xword sh_flags; /* Section flags */ + Elf64_Addr sh_addr; /* Section virtual addr at execution */ + Elf64_Off sh_offset; /* Section file offset */ + Elf64_Xword sh_size; /* Section size in bytes */ + Elf64_Word sh_link; /* Link to another section */ + Elf64_Word sh_info; /* Additional section information */ + Elf64_Xword sh_addralign; /* Section alignment */ + Elf64_Xword sh_entsize; /* Entry size if section holds table */ +} Elf64_Shdr; + /* Special section indices. */ #define SHN_UNDEF 0 /* Undefined section */ @@ -192,9 +247,19 @@ typedef struct Elf32_Word st_size; /* Symbol size */ unsigned char st_info; /* Symbol type and binding */ unsigned char st_other; /* No defined meaning, 0 */ - Elf32_Half st_shndx; /* Section index */ + Elf32_Section st_shndx; /* Section index */ } Elf32_Sym; +typedef struct +{ + Elf64_Word st_name; /* Symbol name (string tbl index) */ + unsigned char st_info; /* Symbol type and binding */ + unsigned char st_other; /* No defined meaning, 0 */ + Elf64_Section st_shndx; /* Section index */ + Elf64_Addr st_value; /* Symbol value */ + Elf64_Xword st_size; /* Symbol size */ +} Elf64_Sym; + /* Special section index. */ #define SHN_UNDEF 0 /* No section, undefined symbol. */ @@ -205,6 +270,11 @@ typedef struct #define ELF32_ST_TYPE(val) ((val) & 0xf) #define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) +/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field. */ +#define ELF64_ST_BIND(val) ELF32_ST_BIND (val) +#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val) +#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type)) + /* Legal values for ST_BIND subfield of st_info (symbol binding). */ #define STB_LOCAL 0 /* Local symbol */ @@ -241,6 +311,17 @@ typedef struct Elf32_Word r_info; /* Relocation type and symbol index */ } Elf32_Rel; +/* I have seen two different definitions of the Elf64_Rel and + Elf64_Rela structures, so we'll leave them out until Novell (or + whoever) gets their act together. */ +/* The following, at least, is used on Sparc v9, MIPS, and Alpha. */ + +typedef struct +{ + Elf64_Addr r_offset; /* Address */ + Elf64_Xword r_info; /* Relocation type and symbol index */ +} Elf64_Rel; + /* Relocation table entry with addend (in section of type SHT_RELA). */ typedef struct @@ -250,6 +331,13 @@ typedef struct Elf32_Sword r_addend; /* Addend */ } Elf32_Rela; +typedef struct +{ + Elf64_Addr r_offset; /* Address */ + Elf64_Xword r_info; /* Relocation type and symbol index */ + Elf64_Sxword r_addend; /* Addend */ +} Elf64_Rela; + /* How to extract and insert information held in the r_info field. */ #define ELF32_R_SYM(val) ((val) >> 8) @@ -262,7 +350,8 @@ typedef struct /* Program segment header. */ -typedef struct { +typedef struct +{ Elf32_Word p_type; /* Segment type */ Elf32_Off p_offset; /* Segment file offset */ Elf32_Addr p_vaddr; /* Segment virtual address */ @@ -273,6 +362,18 @@ typedef struct { Elf32_Word p_align; /* Segment alignment */ } Elf32_Phdr; +typedef struct +{ + Elf64_Word p_type; /* Segment type */ + Elf64_Word p_flags; /* Segment flags */ + Elf64_Off p_offset; /* Segment file offset */ + Elf64_Addr p_vaddr; /* Segment virtual address */ + Elf64_Addr p_paddr; /* Segment physical address */ + Elf64_Xword p_filesz; /* Segment size in file */ + Elf64_Xword p_memsz; /* Segment size in memory */ + Elf64_Xword p_align; /* Segment alignment */ +} Elf64_Phdr; + /* Legal values for p_type (segment type). */ #define PT_NULL 0 /* Program header table entry unused */ @@ -316,6 +417,16 @@ typedef struct } d_un; } Elf32_Dyn; +typedef struct +{ + Elf64_Sxword d_tag; /* Dynamic entry type */ + union + { + Elf64_Xword d_val; /* Integer value */ + Elf64_Addr d_ptr; /* Address value */ + } d_un; +} Elf64_Dyn; + /* Legal values for d_tag (dynamic entry type). */ #define DT_NULL 0 /* Marks end of dynamic section */ @@ -347,76 +458,6 @@ typedef struct #define DT_HIPROC 0x7fffffff /* End of processor-specific */ #define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */ -/* Standard 64 bit ELF types. */ - -typedef unsigned int Elf64_Addr __attribute__ ((mode (DI))); -typedef unsigned int Elf64_Half __attribute__ ((mode (HI))); -typedef unsigned int Elf64_Off __attribute__ ((mode (DI))); -typedef int Elf64_Sword __attribute__ ((mode (SI))); -typedef int Elf64_Sxword __attribute__ ((mode (DI))); -typedef unsigned int Elf64_Word __attribute__ ((mode (SI))); -typedef unsigned int Elf64_Xword __attribute__ ((mode (DI))); -typedef unsigned int Elf64_Byte __attribute__ ((mode (QI))); -typedef unsigned int Elf64_Section __attribute__ ((mode (HI))); - -/* 64 bit ELF file header. */ - -typedef struct -{ - unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ - Elf64_Half e_type; /* Object file type */ - Elf64_Half e_machine; /* Architecture */ - Elf64_Word e_version; /* Object file version */ - Elf64_Addr e_entry; /* Entry point virtual address */ - Elf64_Off e_phoff; /* Program header table file offset */ - Elf64_Off e_shoff; /* Section header table file offset */ - Elf64_Word e_flags; /* Processor-specific flags */ - Elf64_Half e_ehsize; /* ELF header size in bytes */ - Elf64_Half e_phentsize; /* Program header table entry size */ - Elf64_Half e_phnum; /* Program header table entry count */ - Elf64_Half e_shentsize; /* Section header table entry size */ - Elf64_Half e_shnum; /* Section header table entry count */ - Elf64_Half e_shstrndx; /* Section header string table index */ -} Elf64_Ehdr; - -/* 64 bit section header. */ - -typedef struct -{ - Elf64_Word sh_name; /* Section name (string tbl index) */ - Elf64_Word sh_type; /* Section type */ - Elf64_Xword sh_flags; /* Section flags */ - Elf64_Addr sh_addr; /* Section virtual addr at execution */ - Elf64_Off sh_offset; /* Section file offset */ - Elf64_Xword sh_size; /* Section size in bytes */ - Elf64_Word sh_link; /* Link to another section */ - Elf64_Word sh_info; /* Additional section information */ - Elf64_Xword sh_addralign; /* Section alignment */ - Elf64_Xword sh_entsize; /* Entry size if section holds table */ -} Elf64_Shdr; - -/* 64 bit symbol table entry. */ - -typedef struct -{ - Elf64_Word st_name; /* Symbol name (string tbl index) */ - Elf64_Byte st_info; /* Symbol type and binding */ - Elf64_Byte st_other; /* No defined meaning, 0 */ - Elf64_Section st_shndx; /* Section index */ - Elf64_Addr st_value; /* Symbol value */ - Elf64_Xword st_size; /* Symbol size */ -} Elf64_Sym; - -/* The 64 bit st_info field is the same as the 32 bit one. */ - -#define ELF64_ST_BIND(val) (((unsigned char) (val)) >> 4) -#define ELF64_ST_TYPE(val) ((val) & 0xf) -#define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) - -/* I have seen two different definitions of the Elf64_Rel and - Elf64_Rela structures, so we'll leave them out until Novell (or - whoever) gets their act together. */ - /* Auxiliary vector. */ /* This vector is normally only used by the program interpreter. The @@ -437,6 +478,17 @@ typedef struct } a_un; } Elf32_auxv_t; +typedef struct +{ + long int a_type; /* Entry type */ + union + { + long int a_val; /* Integer value */ + void *a_ptr; /* Pointer value */ + void (*a_fcn) (void); /* Function pointer value */ + } a_un; +} Elf64_auxv_t; + /* Legal values for a_type (entry type). */ #define AT_NULL 0 /* End of vector */ @@ -684,4 +736,38 @@ typedef Elf32_Addr Elf32_Conflict; #define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */ +/* Alpha specific declarations. */ + +/* Alpha relocs. */ + +#define R_ALPHA_NONE 0 /* No reloc */ +#define R_ALPHA_REFLONG 1 /* Direct 32 bit */ +#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */ +#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */ +#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */ +#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */ +#define R_ALPHA_GPDISP 6 /* Add displacement to GP */ +#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */ +#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */ +#define R_ALPHA_SREL16 9 /* PC relative 16 bit */ +#define R_ALPHA_SREL32 10 /* PC relative 32 bit */ +#define R_ALPHA_SREL64 11 /* PC relative 64 bit */ +#define R_ALPHA_OP_PUSH 12 /* OP stack push */ +#define R_ALPHA_OP_STORE 13 /* OP stack pop and store */ +#define R_ALPHA_OP_PSUB 14 /* OP stack subtract */ +#define R_ALPHA_OP_PRSHIFT 15 /* OP stack right shift */ +#define R_ALPHA_GPVALUE 16 +#define R_ALPHA_GPRELHIGH 17 +#define R_ALPHA_GPRELLOW 18 +#define R_ALPHA_IMMED_GP_16 19 +#define R_ALPHA_IMMED_GP_HI32 20 +#define R_ALPHA_IMMED_SCN_HI32 21 +#define R_ALPHA_IMMED_BR_HI32 22 +#define R_ALPHA_IMMED_LO32 23 +#define R_ALPHA_COPY 24 /* Copy symbol at runtime */ +#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */ +#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */ +#define R_ALPHA_RELATIVE 27 /* Adjust by program base */ + + #endif /* elf.h */ diff --git a/elf/elf_hash.c b/elf/elf_hash.c deleted file mode 100644 index ee8358d753..0000000000 --- a/elf/elf_hash.c +++ /dev/null @@ -1,4 +0,0 @@ -/* Define the global function for the inline `elf_hash' in libelf.h. */ - -#define _EXTERN_INLINE /* Define the function globally. */ -#include "libelf.h" diff --git a/elf/libelf.h b/elf/libelf.h deleted file mode 100644 index b6575b9824..0000000000 --- a/elf/libelf.h +++ /dev/null @@ -1,283 +0,0 @@ -/* Interface for manipulating ELF object files; functions found in -lelf. -Copyright (C) 1995 Free Software Foundation, Inc. -This file is part of the GNU C Library. - -The GNU C Library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -The GNU C Library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with the GNU C Library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. */ - -#ifndef _LIBELF_H -#define _LIBELF_H 1 - -#include <sys/cdefs.h> -#include <sys/types.h> -#include <elf.h> - -__BEGIN_DECLS - -/* Commands to operate on an Elf descriptor. - The meanings are slightly different for the different functions. */ -typedef enum -{ - ELF_C_NULL = 0, - ELF_C_READ, /* Read from the file. */ - ELF_C_WRITE, /* Write the file, ignoring old contents. */ - ELF_C_CLR, /* Clear specified flag bits. */ - ELF_C_SET, /* Set specified flag bits. */ - ELF_C_FDDONE, /* Close the fd; no further io will happen. */ - ELF_C_FDREAD, /* Read the whole file, then close it. */ - ELF_C_RDWR, /* Read from and modify the file. */ - ELF_C_NUM /* Number of valid command values. */ -} Elf_Cmd; - - -/* Flag bits for `elf_flag*'. */ -#define ELF_F_DIRTY 0x1 /* Object is */ -#define ELF_F_LAYOUT 0x4 - - -/* File types. */ -typedef enum -{ - ELF_K_NONE = 0, - ELF_K_AR, - ELF_K_COFF, /* The GNU -lelf does not support COFF. */ - ELF_K_ELF, - ELF_K_NUM /* Number of valid file kinds. */ -} Elf_Kind; - - -/* Translation types. */ -typedef enum -{ - ELF_T_BYTE = 0, - ELF_T_ADDR, - ELF_T_DYN, - ELF_T_EHDR, - ELF_T_HALF, - ELF_T_OFF, - ELF_T_PHDR, - ELF_T_RELA, - ELF_T_REL, - ELF_T_SHDR, - ELF_T_SWORD, - ELF_T_SYM, - ELF_T_WORD, - ELF_T_NUM -} Elf_Type; - - -/* These types are opaque to user code; only pointers to them are used. */ -typedef struct Elf Elf; -typedef struct Elf_Scn Elf_Scn; - - -/* Archive member header. */ -typedef struct -{ - char *ar_name; - time_t ar_date; - uid_t ar_uid; - gid_t ar_gid; - mode_t ar_mode; - off_t ar_size; - char *ar_rawname; -} Elf_Arhdr; - -/* Archive symbol table. */ -typedef struct -{ - char *as_name; - size_t as_off; - unsigned long int as_hash; -} Elf_Arsym; - - -/* Data descriptor. */ -typedef struct -{ - void *d_buf; - Elf_Type d_type; - size_t d_size; - off_t d_off; /* Offset into section. */ - size_t d_align; /* Alignment in section. */ - unsigned int d_version; /* ELF version. */ -} Elf_Data; - - - -/* Open an Elf descriptor on file descriptor FD. - REF is the Elf descriptor for the containing archive (to open a member); - or the descriptor previously returned for FD (to add a user reference); - or NULL. */ -extern Elf *elf_begin __P ((int __fd, Elf_Cmd __cmd, Elf *__ref)); - -/* Finish using ELF (remove a user reference); if this is the last user - reference, its data will be freed. */ -extern int elf_end __P ((Elf *__elf)); - -/* Control the library's access to the file descriptor for ELF. - CMD is either ELF_C_FDDONE or ELF_C_FDREAD. */ -extern int elf_cntl __P ((Elf *__elf, Elf_Cmd __cmd)); - - -/* Return a string describing an ELF error number. */ -extern __const char *elf_errmsg __P ((int __errno)); - -/* Return the ELF error number for the last failed operation. */ -extern int elf_errno __P ((void)); - -/* Set the byte value used to fill sections for alignment. */ -extern void elf_fill __P ((int __fillchar)); - -/* The following functions `elf_flag*' all operate the same way: - CMD is either ELF_C_SET or ELF_C_CLR; FLAGS are `ELF_F_*' above, - which are set or cleared for the object the call relates to. */ - -/* Modify flags affecting the file as a whole (?). */ -extern unsigned int elf_flagelf __P ((Elf *__elf, Elf_Cmd __cmd, - unsigned int __flags)); -/* Modify flags affecting DATA. */ -extern unsigned int elf_flagdata __P ((Elf_Data *__data, Elf_Cmd __cmd, - unsigned int __flags)); -/* Modify flags affecting the ELF header. */ -extern unsigned int elf_flagehdr __P ((Elf *__elf, Elf_Cmd __cmd, - unsigned int __flags)); -/* Modify flags affecting the ELF program header. */ -extern unsigned int elf_flagphdr __P ((Elf *__elf, Elf_Cmd __cmd, - unsigned int __flags)); -/* Modify flags affecting the given section's data. */ -extern unsigned int elf_flagscn __P ((Elf_Scn *__scn, Elf_Cmd __cmd, - unsigned int __flags)); -/* Modify flags affecting the given section's header. */ -extern unsigned int elf_flagshdr __P ((Elf_Scn *__scn, Elf_Cmd __cmd, - unsigned int __flags)); - - -extern size_t elf32_fsize __P ((Elf_Type __type, size_t __count, - unsigned int __ver)); - -/* Return the archive header for ELF, which must describe an archive. */ -extern Elf_Arhdr *elf_getarhdr __P ((Elf *__elf)); - -/* Return the archive symbol table for ELF, and store - in *NELTSP the number of elements in the table. */ -extern Elf_Arsym *elf_getarsym __P ((Elf *__elf, size_t *__neltsp)); - -/* Return the file offset for the beginning of ELF. - If ELF describes an archive member, this points to the member header. */ -extern off_t elf_getbase __P ((Elf *__elf)); - -/* Extract the data from a section. */ -extern Elf_Data *elf_getdata __P ((Elf_Scn *__scn, Elf_Data *__data)); - -/* Extract the ELF header from the file. */ -extern Elf32_Ehdr *elf32_getehdr __P ((Elf *__elf)); - -/* Extract the initial ELF identification bytes from the file. - If PTR is nonnull, the number of identification bytes is stored there. */ -extern char *elf_getident __P((Elf *__elf, size_t *__ptr)); - -/* Extract the ELF program header from the file. */ -extern Elf32_Phdr *elf32_getphdr __P ((Elf *__elf)); - -/* Extract the indicated section from the file. */ -extern Elf_Scn *elf_getscn __P ((Elf *__elf, size_t __index)); - -/* Extract the section header from the section. */ -extern Elf32_Shdr *elf32_getshdr __P ((Elf_Scn *__scn)); - -/* Return the index of the section following SCN. */ -extern size_t elf_ndxscn __P ((Elf_Scn *__scn)); - - -/* Standard ELF symbol name hash function. */ -extern unsigned long int elf_hash __P ((__const char *__name)); - -#if defined (__OPTIMIZE__) || defined (_EXTERN_INLINE) -#ifndef _EXTERN_INLINE -#define _EXTERN_INLINE extern __inline -#endif -_EXTERN_INLINE unsigned long int -elf_hash (__const char *__name) -{ - /* This is the hashing function specified by the ELF ABI. */ - unsigned long int __hash = 0; - while (*__name != '\0') - { - unsigned long int __hi; - __hash = (__hash << 4) + *__name++; - __hi = __hash & 0xf0000000; - if (__hi != 0) - { - __hash ^= __hi >> 24; - /* The ELF ABI says `hash &= ~hi', but this is equivalent - in this case and on some machines one insn instead of two. */ - __hash ^= __hi; - } - } - return __hash; -} -#endif - -/* Return the kind of file ELF describes. */ -extern Elf_Kind elf_kind __P ((Elf *__elf)); - -extern Elf_Data *elf_newdata __P ((Elf_Scn *__scn)); - -/* Create the ELF header for ELF. */ -extern Elf32_Ehdr *elf32_newehdr __P ((Elf *__elf)); - -/* Create the program header for ELF, with COUNT segments. */ -extern Elf32_Phdr *elf32_newphdr __P ((Elf *__elf, size_t __count)); - -/* Create a new section in ELF. */ -extern Elf_Scn *elf_newscn __P ((Elf *__elf)); - -/* Return the section following SCN. */ -extern Elf_Scn *elf_nextscn __P ((Elf *__elf, Elf_Scn *__scn)); - -/* Set up ELF to read the next archive member. */ -extern Elf_Cmd elf_next __P ((Elf *__elf)); - -/* Set up ELF (which must describe an archive) to read the - archive member that starts at file position OFFSET. */ -extern size_t elf_rand __P ((Elf *__elf, size_t __offset)); - -extern Elf_Data *elf_rawdata __P ((Elf_Scn *__scn, Elf_Data *__data)); - -/* Read the entire file into memory; store its size in *PTR. */ -extern char *elf_rawfile __P ((Elf *__elf, size_t *__ptr)); - -/* Return a pointer to the string at OFFSET bytes into the string table. - SECTION is the index of the SHT_STRTAB section in ELF. */ -extern char *elf_strptr __P ((Elf *__elf, size_t __section, size_t __offset)); - -/* If CMD is ELF_C_NULL, update ELF's data structures based on any - user modifications, and set the ELF_F_DIRTY flag if anything changed. - If CMD is ELF_C_WRITE, do that and then write the changes to the file. */ -extern off_t elf_update __P ((Elf *__elf, Elf_Cmd __cmd)); - -/* Handle ELF version VER. Return the old version handled, - or EV_NONE if VER is unrecognized. */ -extern unsigned int elf_version __P ((unsigned int __ver)); - -extern Elf_Data *elf32_xlatetof __P ((Elf_Data *__dst, const Elf_Data *__src, - unsigned int __encode)); -extern Elf_Data *elf32_xlatetom __P ((Elf_Data *__dst, const Elf_Data *__src, - unsigned int __encode)); - -__END_DECLS - -#endif /* _LIBELF_H */ diff --git a/elf/link.h b/elf/link.h index a89e25846e..f7bca97e80 100644 --- a/elf/link.h +++ b/elf/link.h @@ -20,8 +20,20 @@ Cambridge, MA 02139, USA. */ #ifndef _LINK_H #define _LINK_H 1 +#define __need_size_t +#include <stddef.h> + #include <elf.h> +#define __ELF_WORDSIZE 32 /* XXX */ + +/* We use this macro to refer to ELF types independent of the native wordsize. + `ElfW(TYPE)' is used in place of `Elf32_TYPE' or `Elf64_TYPE'. */ +#define ElfW(type) _ElfW (Elf, __ELF_WORDSIZE, type) +#define ELFW(type) _ElfW (ELF, __ELF_WORDSIZE, type) +#define _ElfW(e,w,t) _ElfW_1 (e, w, _##t) +#define _ElfW_1(e,w,t) e##w##t + /* Rendezvous structure used by the run-time dynamic linker to communicate details of shared object loading to the debugger. If the executable's @@ -39,7 +51,7 @@ struct r_debug library or unmap it, and again when the mapping change is complete. The debugger can set a breakpoint at this address if it wants to notice shared object mapping changes. */ - Elf32_Addr r_brk; + ElfW(Addr) r_brk; enum { /* This state value describes the mapping change taking place when @@ -49,7 +61,7 @@ struct r_debug RT_DELETE, /* Beginning to remove an object mapping. */ } r_state; - Elf32_Addr r_ldbase; /* Base address the linker is loaded at. */ + ElfW(Addr) r_ldbase; /* Base address the linker is loaded at. */ }; /* This symbol refers to the "dynamic structure" in the `.dynamic' section @@ -59,7 +71,7 @@ struct r_debug if (dyn->d_tag == DT_DEBUG) r_debug = (struct r_debug) dyn->d_un.d_ptr; */ -extern Elf32_Dyn _DYNAMIC[]; +extern ElfW(Dyn) _DYNAMIC[]; /* Structure describing a loaded shared object. The `l_next' and `l_prev' @@ -73,9 +85,9 @@ struct link_map /* These first few members are part of the protocol with the debugger. This is the same format used in SVR4. */ - Elf32_Addr l_addr; /* Base address shared object is loaded at. */ + ElfW(Addr) l_addr; /* Base address shared object is loaded at. */ char *l_name; /* Absolute file name object was found in. */ - Elf32_Dyn *l_ld; /* Dynamic section of the shared object. */ + ElfW(Dyn) *l_ld; /* Dynamic section of the shared object. */ struct link_map *l_next, *l_prev; /* Chain of loaded objects. */ /* All following members are internal to the dynamic linker. @@ -85,10 +97,10 @@ struct link_map /* Indexed pointers to dynamic section. [0,DT_NUM) are indexed by the processor-independent tags. [DT_NUM,DT_NUM+DT_PROCNUM] are indexed by the tag minus DT_LOPROC. */ - Elf32_Dyn *l_info[DT_NUM + DT_PROCNUM]; - const Elf32_Phdr *l_phdr; /* Pointer to program header table in core. */ - Elf32_Word l_phnum; /* Number of program header entries. */ - Elf32_Addr l_entry; /* Entry point location. */ + ElfW(Dyn) *l_info[DT_NUM + DT_PROCNUM]; + const ElfW(Phdr) *l_phdr; /* Pointer to program header table in core. */ + ElfW(Addr) l_entry; /* Entry point location. */ + ElfW(Half) l_phnum; /* Number of program header entries. */ /* Array of DT_NEEDED dependencies and their dependencies, in dependency order for symbol lookup. This is null before the @@ -97,8 +109,8 @@ struct link_map unsigned int l_nsearchlist; /* Symbol hash table. */ - Elf32_Word l_nbuckets; - const Elf32_Word *l_buckets, *l_chain; + ElfW(Word) l_nbuckets; + const ElfW(Word) *l_buckets, *l_chain; unsigned int l_opencount; /* Reference count for dlopen/dlclose. */ enum /* Where this object came from. */ @@ -123,6 +135,9 @@ struct link_map user interface to run-time dynamic linking. */ +/* Cached value of `getpagesize ()'. */ +extern size_t _dl_pagesize; + /* File descriptor referring to the zero-fill device. */ extern int _dl_zerofd; @@ -209,15 +224,15 @@ extern struct link_map *_dl_open (struct link_map *loader, being fixed up and the chosen symbol cannot be one with this value. If NOPLT is nonzero, then the reference must not be resolved to a PLT entry. */ -extern Elf32_Addr _dl_lookup_symbol (const char *undef, - const Elf32_Sym **sym, +extern ElfW(Addr) _dl_lookup_symbol (const char *undef, + const ElfW(Sym) **sym, struct link_map *symbol_scope[2], const char *reference_name, - Elf32_Addr reloc_addr, + ElfW(Addr) reloc_addr, int noplt); /* Look up symbol NAME in MAP's scope and return its run-time address. */ -extern Elf32_Addr _dl_symbol_value (struct link_map *map, const char *name); +extern ElfW(Addr) _dl_symbol_value (struct link_map *map, const char *name); /* Structure describing the dynamic linker itself. */ @@ -242,7 +257,7 @@ extern void _dl_relocate_object (struct link_map *map, int lazy); its dependencies that has not yet been run. When there are no more initializers to be run, this returns zero. The functions are returned in the order they should be called. */ -extern Elf32_Addr _dl_init_next (struct link_map *map); +extern ElfW(Addr) _dl_init_next (struct link_map *map); /* Call the finalizer functions of all shared objects whose initializer functions have completed. */ diff --git a/elf/linux-compat.c b/elf/linux-compat.c index 8821a140e0..b42c78a3f7 100644 --- a/elf/linux-compat.c +++ b/elf/linux-compat.c @@ -32,9 +32,9 @@ Cambridge, MA 02139, USA. */ void _init (void) { - const Elf32_Sym *ref = NULL; + const ElfW(Sym) *ref = NULL; struct link_map *scope[2] = { _dl_loaded, NULL }; - Elf32_Addr loadbase = _dl_lookup_symbol ("atexit", &ref, scope, + ElfW(Addr) loadbase = _dl_lookup_symbol ("atexit", &ref, scope, "<ld-linux.so.1 initialization>", 0, 1); (*(__typeof (atexit) *) (loadbase + ref->st_value)) (&_dl_fini); diff --git a/elf/rtld.c b/elf/rtld.c index b34d8598bb..bc1f71bd4e 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -35,10 +35,10 @@ RTLD_START After this, file access calls and getenv must work. This is responsible for setting _dl_secure if we need to be secure (e.g. setuid), and for setting _dl_argc and _dl_argv, and then calling _dl_main. */ -extern Elf32_Addr _dl_sysdep_start (void **start_argptr, - void (*dl_main) (const Elf32_Phdr *phdr, - Elf32_Word phent, - Elf32_Addr *user_entry)); +extern ElfW(Addr) _dl_sysdep_start (void **start_argptr, + void (*dl_main) (const ElfW(Phdr) *phdr, + ElfW(Half) phent, + ElfW(Addr) *user_entry)); extern void _dl_sysdep_start_cleanup (void); int _dl_secure; @@ -46,15 +46,15 @@ int _dl_argc; char **_dl_argv; const char *_dl_rpath; -struct r_debug dl_r_debug; +struct r_debug _dl_r_debug; -static void dl_main (const Elf32_Phdr *phdr, - Elf32_Word phent, - Elf32_Addr *user_entry); +static void dl_main (const ElfW(Phdr) *phdr, + ElfW(Half) phent, + ElfW(Addr) *user_entry); struct link_map _dl_rtld_map; -Elf32_Addr +ElfW(Addr) _dl_start (void *arg) { struct link_map bootstrap_map; @@ -120,17 +120,17 @@ void _start (void); unsigned int _dl_skip_args; /* Nonzero if we were run directly. */ static void -dl_main (const Elf32_Phdr *phdr, - Elf32_Word phent, - Elf32_Addr *user_entry) +dl_main (const ElfW(Phdr) *phdr, + ElfW(Half) phent, + ElfW(Addr) *user_entry) { - const Elf32_Phdr *ph; + const ElfW(Phdr) *ph; struct link_map *l; const char *interpreter_name; int lazy; int list_only = 0; - if (*user_entry == (Elf32_Addr) &_start) + if (*user_entry == (ElfW(Addr)) &_start) { /* Ho ho. We are not the program interpreter! We are the program itself! This means someone ran ld.so as a command. Well, that @@ -240,7 +240,7 @@ of this helper program; chances are you did not intend to run this program.\n", /* There is a DT_DEBUG entry in the dynamic section. Fill it in with the run-time address of the r_debug structure, which we will set up later to communicate with the debugger. */ - l->l_info[DT_DEBUG]->d_un.d_ptr = (Elf32_Addr) &dl_r_debug; + l->l_info[DT_DEBUG]->d_un.d_ptr = (ElfW(Addr)) &_dl_r_debug; /* Put the link_map for ourselves on the chain so it can be found by name. */ @@ -292,9 +292,9 @@ of this helper program; chances are you did not intend to run this program.\n", for (i = 1; i < _dl_argc; ++i) { - const Elf32_Sym *ref = NULL; + const ElfW(Sym) *ref = NULL; struct link_map *scope[2] ={ _dl_loaded, NULL }; - Elf32_Addr loadbase + ElfW(Addr) loadbase = _dl_lookup_symbol (_dl_argv[i], &ref, scope, "argument", 0, 0); char buf[20], *bp; buf[sizeof buf - 1] = '\0'; @@ -345,10 +345,10 @@ of this helper program; chances are you did not intend to run this program.\n", _dl_relocate_object (&_dl_rtld_map, lazy); /* Tell the debugger where to find the map of loaded objects. */ - dl_r_debug.r_version = 1 /* R_DEBUG_VERSION XXX */; - dl_r_debug.r_ldbase = _dl_rtld_map.l_addr; /* Record our load address. */ - dl_r_debug.r_map = _dl_loaded; - dl_r_debug.r_brk = (Elf32_Addr) &_dl_r_debug_state; + _dl_r_debug.r_version = 1 /* R_DEBUG_VERSION XXX */; + _dl_r_debug.r_ldbase = _dl_rtld_map.l_addr; /* Record our load address. */ + _dl_r_debug.r_map = _dl_loaded; + _dl_r_debug.r_brk = (ElfW(Addr)) &_dl_r_debug_state; if (_dl_rtld_map.l_info[DT_INIT]) { |