aboutsummaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authorMarcel Moolenaar <marcel@FreeBSD.org>2002-04-27 02:48:29 +0000
committerMarcel Moolenaar <marcel@FreeBSD.org>2002-04-27 02:48:29 +0000
commit9d4f27148f1594b318daecf530f2cf08c691ddc8 (patch)
tree05a2ca1aeaedaffa75233c6a2112162962b442e2 /libexec
parent624abf8519406ed85bc1ef618ef72cf06f3916d5 (diff)
Notes
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 c4cc5e87b42c3..2ddab86e66a1c 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