summaryrefslogtreecommitdiffstats
path: root/libexec/rtld-elf
diff options
context:
space:
mode:
authorjdp <jdp@FreeBSD.org>1999-08-30 01:24:08 +0000
committerjdp <jdp@FreeBSD.org>1999-08-30 01:24:08 +0000
commit48598d755cf0f6a86a7d583797f1947d19dda65c (patch)
tree49373879fc558cc11a0a77f51d50c0da738ee4a1 /libexec/rtld-elf
parent1179e4387f0eb0fdc200d5eee047178a23b19894 (diff)
downloadFreeBSD-src-48598d755cf0f6a86a7d583797f1947d19dda65c.zip
FreeBSD-src-48598d755cf0f6a86a7d583797f1947d19dda65c.tar.gz
Simplify the logic in find_symdef().
Diffstat (limited to 'libexec/rtld-elf')
-rw-r--r--libexec/rtld-elf/rtld.c86
1 files changed, 41 insertions, 45 deletions
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 58cdbef..1204243 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -685,11 +685,10 @@ find_symdef(unsigned long symnum, const Obj_Entry *refobj,
const Obj_Entry **defobj_out, bool in_plt)
{
const Elf_Sym *ref;
- const Elf_Sym *strongdef;
- const Elf_Sym *weakdef;
+ const Elf_Sym *def;
+ const Elf_Sym *symp;
const Obj_Entry *obj;
- const Obj_Entry *strongobj;
- const Obj_Entry *weakobj;
+ const Obj_Entry *defobj;
const char *name;
unsigned long hash;
@@ -698,71 +697,68 @@ find_symdef(unsigned long symnum, const Obj_Entry *refobj,
hash = elf_hash(name);
if (refobj->symbolic) { /* Look first in the referencing object */
- const Elf_Sym *def = symlook_obj(name, hash, refobj, in_plt);
- if (def != NULL) {
+ if ((symp = symlook_obj(name, hash, refobj, in_plt)) != NULL) {
*defobj_out = refobj;
- return def;
+ return symp;
}
}
/*
- * Look in all loaded objects. Skip the referencing object, if
- * we have already searched it. We keep track of the first weak
- * definition and the first strong definition we encounter. If
- * we find a strong definition we stop searching, because there
- * won't be anything better than that.
+ * Look in all loaded objects. Skip the referencing object,
+ * if we have already searched it. We remember the first weak
+ * definition we encounter, but we keep searching for a strong
+ * definition. If we find a strong definition we stop searching,
+ * because there won't be anything better than that.
*/
- strongdef = weakdef = NULL;
- strongobj = weakobj = NULL;
+ def = NULL;
+ defobj = NULL;
for (obj = obj_list; obj != NULL; obj = obj->next) {
- if (obj != refobj || !refobj->symbolic) {
- const Elf_Sym *def = symlook_obj(name, hash, obj, in_plt);
- if (def != NULL) {
- if (ELF_ST_BIND(def->st_info) == STB_WEAK) {
- if (weakdef == NULL) {
- weakdef = def;
- weakobj = obj;
- }
- } else {
- strongdef = def;
- strongobj = obj;
- break; /* We are done. */
+ if (obj == refobj && refobj->symbolic)
+ continue;
+ if ((symp = symlook_obj(name, hash, obj, in_plt)) != NULL) {
+ if (def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK) {
+ def = symp;
+ defobj = obj;
+ if (ELF_ST_BIND(def->st_info) != STB_WEAK) {
+ *defobj_out = defobj;
+ return def;
}
}
}
}
/*
- * If we still don't have a strong definition, search the dynamic
+ * We still don't have a strong definition. Search the dynamic
* linker itself, and possibly resolve the symbol from there.
* This is how the application links to dynamic linker services
* such as dlopen. Only the values listed in the "exports" array
* can be resolved from the dynamic linker.
*/
- if (strongdef == NULL) {
- const Elf_Sym *def = symlook_obj(name, hash, &obj_rtld, in_plt);
- if (def != NULL && is_exported(def)) {
- if (ELF_ST_BIND(def->st_info) == STB_WEAK) {
- if (weakdef == NULL) {
- weakdef = def;
- weakobj = &obj_rtld;
- }
- } else {
- strongdef = def;
- strongobj = &obj_rtld;
+ if ((symp = symlook_obj(name, hash, &obj_rtld, in_plt)) != NULL &&
+ is_exported(symp)) {
+ if (def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK) {
+ def = symp;
+ defobj = &obj_rtld;
+ if (ELF_ST_BIND(def->st_info) != STB_WEAK) {
+ *defobj_out = defobj;
+ return def;
}
}
}
- if (strongdef != NULL) {
- *defobj_out = strongobj;
- return strongdef;
- }
- if (weakdef != NULL) {
- *defobj_out = weakobj;
- return weakdef;
+ /*
+ * We didn't find a strong definition. Accept a weak definition
+ * if we found one.
+ */
+ if (def != NULL) {
+ *defobj_out = defobj;
+ return def;
}
+ /*
+ * We found no definition. If the reference is weak, treat the
+ * symbol as having the value zero.
+ */
if (ELF_ST_BIND(ref->st_info) == STB_WEAK) {
*defobj_out = obj_main;
return &sym_zero;
OpenPOWER on IntegriCloud