From 48598d755cf0f6a86a7d583797f1947d19dda65c Mon Sep 17 00:00:00 2001 From: jdp Date: Mon, 30 Aug 1999 01:24:08 +0000 Subject: Simplify the logic in find_symdef(). --- libexec/rtld-elf/rtld.c | 86 +++++++++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 45 deletions(-) (limited to 'libexec/rtld-elf') 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; -- cgit v1.1