summaryrefslogtreecommitdiffstats
path: root/libexec
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2002-04-27 02:48:29 +0000
committermarcel <marcel@FreeBSD.org>2002-04-27 02:48:29 +0000
commit1c432575fbc493d43516c111c7a0423d84028c10 (patch)
tree05a2ca1aeaedaffa75233c6a2112162962b442e2 /libexec
parent300c1a11c0a8aea8ec82abdbef0f195a2091929b (diff)
downloadFreeBSD-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')
-rw-r--r--libexec/rtld-elf/rtld.c21
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
OpenPOWER on IntegriCloud