Date: 24 Feb 2002 00:21:49 +0100 From: Dag-Erling Smorgrav <des@ofug.org> To: arch@freebsd.org Subject: bin/25059 (rtld bug) Message-ID: <xzpu1s7n5rm.fsf@flood.ping.uio.no>
next in thread | raw e-mail | index | archive | help
--=-=-= Our dlopen(3) man page states: RTLD_GLOBAL Symbols from this shared object and its directed acyclic graph (DAG) of needed objects will be available for resolv ing undefined references from all other shared objects. but this is a lie - only the object itself is searched, not its DAG. The attached patch fixes this by adding a flag to the Obj_Entry structure that marks an object as global, and changing symlook_list() to search each global object's DAG if the object itself doesn't have the requested symbol. With this patch applied, the test program referenced in the PR works. (some might argue that symlook_obj() should be changed instead - but changing symlook_list() was simpler, and the only difference it makes is, in the worst case, a slightly longer search) DES -- Dag-Erling Smorgrav - des@ofug.org --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=rtld.diff Index: rtld.c =================================================================== RCS file: /home/ncvs/src/libexec/rtld-elf/rtld.c,v retrieving revision 1.60 diff -u -r1.60 rtld.c --- rtld.c 17 Feb 2002 07:00:25 -0000 1.60 +++ rtld.c 23 Feb 2002 23:21:28 -0000 @@ -1329,6 +1329,7 @@ elm = NEW(Objlist_Entry); elm->obj = obj; STAILQ_INSERT_TAIL(list, elm, link); + obj->global = true; } static void @@ -1581,7 +1582,7 @@ if (obj) { obj->dl_refcount++; - if (mode & RTLD_GLOBAL && objlist_find(&list_global, obj) == NULL) + if (mode & RTLD_GLOBAL && !obj->global) objlist_push_tail(&list_global, obj); mode &= RTLD_MODEMASK; if (*old_obj_tail != NULL) { /* We loaded something new. */ @@ -1915,7 +1916,7 @@ } } - /* Search all RTLD_GLOBAL objects. */ + /* Search all RTLD_GLOBAL objects and their DAGs. */ if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) { symp = symlook_list(name, hash, &list_global, &obj, in_plt, &donelist); if (symp != NULL && @@ -1965,6 +1966,12 @@ if (ELF_ST_BIND(def->st_info) != STB_WEAK) break; } + } else if (elm->obj->global) { + /* search the DAGs of global objects */ + symp = symlook_list(name, hash, &elm->obj->dagmembers, + defobj_out, in_plt, dlp); + if (symp != NULL) + return symp; } } if (def != NULL) Index: rtld.h =================================================================== RCS file: /home/ncvs/src/libexec/rtld-elf/rtld.h,v retrieving revision 1.24 diff -u -r1.24 rtld.h --- rtld.h 29 Oct 2001 10:10:02 -0000 1.24 +++ rtld.h 23 Feb 2002 23:02:18 -0000 @@ -155,6 +155,7 @@ bool traced; /* Already printed in ldd trace output */ bool jmpslots_done; /* Already have relocated the jump slots */ bool init_done; /* Already have added object to init list */ + bool global; /* This object is on the global list */ struct link_map linkmap; /* for GDB */ Objlist dldags; /* Object belongs to these dlopened DAGs (%) */ --=-=-=-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-arch" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?xzpu1s7n5rm.fsf>