diff options
author | marcel <marcel@FreeBSD.org> | 2002-04-27 02:48:29 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2002-04-27 02:48:29 +0000 |
commit | 1c432575fbc493d43516c111c7a0423d84028c10 (patch) | |
tree | 05a2ca1aeaedaffa75233c6a2112162962b442e2 /libexec/rtld-elf | |
parent | 300c1a11c0a8aea8ec82abdbef0f195a2091929b (diff) | |
download | FreeBSD-src-1c432575fbc493d43516c111c7a0423d84028c10.zip FreeBSD-src-1c432575fbc493d43516c111c7a0423d84028c10.tar.gz |
Don't do symbol lookups for local symbols. The symbol index in the
relocation identifies the symbol to which we need to bind. This
solves a problem seen on ia64 where the symbol hash table does not
contain local symbols and thus resulted in unresolved symbols.
Tested on: alpha, i386, ia64
Diffstat (limited to 'libexec/rtld-elf')
-rw-r--r-- | libexec/rtld-elf/rtld.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index c4cc5e8..2ddab86 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -854,20 +854,27 @@ find_symdef(unsigned long symnum, const Obj_Entry *refobj, ref = refobj->symtab + symnum; name = refobj->strtab + ref->st_name; - hash = elf_hash(name); defobj = NULL; - /* Handle STT_SECTION specially. */ - if (ELF_ST_TYPE(ref->st_info) == STT_SECTION) { - if (ELF_ST_BIND(ref->st_info) != STB_LOCAL || - ref->st_shndx != symnum) { + /* + * We don't have to do a full scale lookup if the symbol is local. + * We know it will bind to the instance in this load module; to + * which we already have a pointer (ie ref). By not doing a lookup, + * we not only improve performance, but it also avoids unresolvable + * symbols when local symbols are not in the hash table. This has + * been seen with the ia64 toolchain. + */ + if (ELF_ST_BIND(ref->st_info) != STB_LOCAL) { + if (ELF_ST_TYPE(ref->st_info) == STT_SECTION) { _rtld_error("%s: Bogus symbol table entry %lu", refobj->path, symnum); } + hash = elf_hash(name); + def = symlook_default(name, hash, refobj, &defobj, in_plt); + } else { def = ref; defobj = refobj; - } else - def = symlook_default(name, hash, refobj, &defobj, in_plt); + } /* * If we found no definition and the reference is weak, treat the |