Index: elf/dl-addr.c =================================================================== RCS file: /cvs/glibc/libc/elf/dl-addr.c,v retrieving revision 1.17 diff -u -r1.17 dl-addr.c --- elf/dl-addr.c 4 Aug 2002 09:05:47 -0000 1.17 +++ elf/dl-addr.c 27 Sep 2002 02:53:53 -0000 @@ -28,7 +28,7 @@ { 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 @@ 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 @@ && (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) { Index: elf/dl-lookup.c =================================================================== RCS file: /cvs/glibc/libc/elf/dl-lookup.c,v retrieving revision 1.104 diff -u -r1.104 dl-lookup.c --- elf/dl-lookup.c 18 Sep 2002 01:17:54 -0000 1.104 +++ elf/dl-lookup.c 27 Sep 2002 02:54:11 -0000 @@ -587,7 +587,7 @@ 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++; Index: elf/dynamic-link.h =================================================================== RCS file: /cvs/glibc/libc/elf/dynamic-link.h,v retrieving revision 1.44 diff -u -r1.44 dynamic-link.h --- elf/dynamic-link.h 31 Aug 2002 04:09:05 -0000 1.44 +++ elf/dynamic-link.h 27 Sep 2002 02:54:11 -0000 @@ -67,6 +67,8 @@ { ElfW(Addr) l_addr = l->l_addr; + if (info[DT_HASH] != NULL) + info[DT_HASH]->d_un.d_ptr += l_addr; if (info[DT_PLTGOT] != NULL) info[DT_PLTGOT]->d_un.d_ptr += l_addr; if (info[DT_STRTAB] != NULL)