|
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
02111-1307 USA. */ | 02111-1307 USA. */ |
| |
|
# define SUSEIDX(sym) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM + \ |
|
DT_EXTRANUM + DT_VALNUM + DT_ADDRNUM + DT_SUSE_TAGIDX (sym)) |
|
|
/* Inner part of the lookup functions. We return a value > 0 if we | /* Inner part of the lookup functions. We return a value > 0 if we |
found the symbol, the value 0 if nothing is found and < 0 if | found the symbol, the value 0 if nothing is found and < 0 if |
something bad happened. */ | something bad happened. */ |
|
|
do | do |
{ | { |
const ElfW(Sym) *symtab; | const ElfW(Sym) *symtab; |
|
const Elf_Symndx *hashvals; |
const char *strtab; | const char *strtab; |
const ElfW(Half) *verstab; | const ElfW(Half) *verstab; |
Elf_Symndx symidx; | Elf_Symndx symidx; |
|
|
undef_name, | undef_name, |
map->l_name[0] ? map->l_name : rtld_progname); | map->l_name[0] ? map->l_name : rtld_progname); |
| |
symtab = (const void *) D_PTR (map, l_info[DT_SYMTAB]); |
if (__builtin_expect (map->l_info[SUSEIDX(DT_SUSE_HASHVALS)] != NULL, 1)) |
strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]); |
hashvals = (const void *) D_PTR (map, l_info[SUSEIDX(DT_SUSE_HASHVALS)]); |
verstab = map->l_versyms; |
else |
|
hashvals = NULL; |
| |
/* Search the appropriate hash bucket in this object's symbol table | /* Search the appropriate hash bucket in this object's symbol table |
for a definition for the same symbol name. */ | for a definition for the same symbol name. */ |
|
|
symidx != STN_UNDEF; | symidx != STN_UNDEF; |
symidx = map->l_chain[symidx]) | symidx = map->l_chain[symidx]) |
{ | { |
|
if (__builtin_expect (hashvals != NULL, 1) && |
|
__builtin_expect ((ElfW(Addr))hashvals < map->l_map_end, 1) && |
|
__builtin_expect ((ElfW(Addr))hashvals > map->l_map_start, 1)) |
|
{ |
|
if (__builtin_expect (hashvals[symidx] != hash, 1)) |
|
continue; |
|
} |
|
/* If hashvals is present 99.9% of the loop is done: what follows |
|
is the very un-common / direct-hit case */ |
|
|
|
symtab = (const void *) D_PTR (map, l_info[DT_SYMTAB]); |
|
strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]); |
|
verstab = map->l_versyms; |
|
|
sym = &symtab[symidx]; | sym = &symtab[symidx]; |
| |
assert (ELF_RTYPE_CLASS_PLT == 1); | assert (ELF_RTYPE_CLASS_PLT == 1); |