dlsym(RTLD_NEXT) and weak symbols
Alexander Kabaev
kabaev at gmail.com
Wed Oct 8 23:55:56 UTC 2008
On Wed, 08 Oct 2008 15:33:41 -0700
Maxim Sobolev <sobomax at FreeBSD.org> wrote:
>
> The following patch fixes the issue for me:
>
<SKIP>
I do not think your patch is completely correct. How about this one
instead:
=== rtld.c
==================================================================
--- rtld.c (revision 183657)
+++ rtld.c (local)
@@ -1925,7 +1925,7 @@
{
DoneList donelist;
const Obj_Entry *obj, *defobj;
- const Elf_Sym *def;
+ const Elf_Sym *def, *symp;
unsigned long hash;
int lockstate;
@@ -1951,11 +1951,28 @@
if (handle == RTLD_NEXT)
obj = obj->next;
for (; obj != NULL; obj = obj->next) {
- if ((def = symlook_obj(name, hash, obj, ve, flags)) != NULL) {
- defobj = obj;
- break;
+ if ((symp = symlook_obj(name, hash, obj, ve, flags)) != 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)
+ break;
+ }
}
}
+ /*
+ * 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 (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) {
+ symp = symlook_obj(name, hash, &obj_rtld, ve, flags);
+ if (symp != NULL && is_exported(symp)) {
+ def = symp;
+ defobj = &obj_rtld;
+ }
+ }
} else {
assert(handle == RTLD_DEFAULT);
def = symlook_default(name, hash, obj, &defobj, ve, flags);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 187 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-current/attachments/20081008/2009f9cd/signature.pgp
More information about the freebsd-current
mailing list