diff options
author | Ulrich Drepper <drepper@redhat.com> | 2002-09-27 03:17:20 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2002-09-27 03:17:20 +0000 |
commit | 9a88a2d7b35b7f08c07a9a189a176e7ca49d82b4 (patch) | |
tree | 67af4eeb0d14730788cbd9a2b3dd0d095db8aee2 /elf | |
parent | 58c9f058a240339cbbb6476d804d80f02a59595f (diff) | |
download | glibc-9a88a2d7b35b7f08c07a9a189a176e7ca49d82b4.zip glibc-9a88a2d7b35b7f08c07a9a189a176e7ca49d82b4.tar.gz glibc-9a88a2d7b35b7f08c07a9a189a176e7ca49d82b4.tar.bz2 |
Update.
2002-09-26 Ulrich Drepper <drepper@redhat.com>
* elf/dynamic-link.h (elf_get_dynamic_info): Relocate DT_HASH entry
if necessary.
* elf/dl-lookup.c (_dl_setup_hash): DT_HASH entry is already relocated.
* elf/dl-addr.c (_dl_addr): Use .hash[1] entry to determine end of the
symbol table if necessary.
Diffstat (limited to 'elf')
-rw-r--r-- | elf/dl-addr.c | 16 | ||||
-rw-r--r-- | elf/dl-lookup.c | 2 |
2 files changed, 14 insertions, 4 deletions
diff --git a/elf/dl-addr.c b/elf/dl-addr.c index 11f8311..66cec39 100644 --- a/elf/dl-addr.c +++ b/elf/dl-addr.c @@ -28,7 +28,7 @@ _dl_addr (const void *address, Dl_info *info) { const ElfW(Addr) addr = DL_LOOKUP_ADDRESS (address); struct link_map *l, *match; - const ElfW(Sym) *symtab, *matchsym; + const ElfW(Sym) *symtab, *matchsym, *symtabend; const char *strtab; ElfW(Word) strtabsize; @@ -71,11 +71,21 @@ _dl_addr (const void *address, Dl_info *info) symtab = (const void *) D_PTR (match, l_info[DT_SYMTAB]); strtab = (const void *) D_PTR (match, l_info[DT_STRTAB]); + strtabsize = match->l_info[DT_STRSZ]->d_un.d_val; + if (match->l_info[DT_HASH] != NULL) + symtabend = symtab + ((Elf_Symndx *) D_PTR (match, l_info[DT_HASH]))[1]; + else + /* There is no direct way to determine the number of symbols in the + dynamic symbol table and no hash table is present. The ELF + binary is ill-formed but what shall we do? Use the beginning of + the string table which generally follows the symbol table. */ + symtabend = strtab; + /* We assume that the string table follows the symbol table, because there is no way in ELF to know the size of the dynamic symbol table!! */ - for (matchsym = NULL; (void *) symtab < (void *) strtab; ++symtab) + for (matchsym = NULL; (void *) symtab < (void *) symtabend; ++symtab) if (addr >= match->l_addr + symtab->st_value && ((symtab->st_size == 0 && addr == match->l_addr + symtab->st_value) || addr < match->l_addr + symtab->st_value + symtab->st_size) @@ -83,7 +93,7 @@ _dl_addr (const void *address, Dl_info *info) && (matchsym == NULL || matchsym->st_value < symtab->st_value) && (ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL || ELFW(ST_BIND) (symtab->st_info) == STB_WEAK)) - matchsym = symtab; + matchsym = (ElfW(Sym) *) symtab; if (matchsym) { diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c index e2f5506..1c3d9b5 100644 --- a/elf/dl-lookup.c +++ b/elf/dl-lookup.c @@ -587,7 +587,7 @@ _dl_setup_hash (struct link_map *map) if (!map->l_info[DT_HASH]) return; - hash = (void *)(map->l_addr + map->l_info[DT_HASH]->d_un.d_ptr); + hash = (void *) D_PTR (map, l_info[DT_HASH]); map->l_nbuckets = *hash++; nchain = *hash++; |