| Summary: | dlopen(..,RTLD_GLOBAL) doesn't work for shared libraries linked to the loaded one | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Base System | Reporter: | nikip <nikip> | ||||
| Component: | bin | Assignee: | Dag-Erling Smørgrav <des> | ||||
| Status: | Closed FIXED | ||||||
| Severity: | Affects Only Me | ||||||
| Priority: | Normal | ||||||
| Version: | 4.2-STABLE | ||||||
| Hardware: | Any | ||||||
| OS: | Any | ||||||
| Attachments: |
|
||||||
|
Description
nikip
2001-02-13 09:20:00 UTC
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
Responsible Changed From-To: freebsd-bugs->des I have a patch for this. I'm a little bit wary of Dag-Erling's patch because it changes the
semantics of symlook_list(), which is supposed to be a utility
function that does a particular thing. I would prefer to change
symlook_default() to search the RTLD_GLOBAL DAGs explicitly, as in the
patch below. This patch makes Nikolay Pelov's test case work OK.
Dag-Erling, if this patch looks OK to you and it solves your problem,
please feel free to commit it for me. I am leaving on holiday, and
won't be able to do it myself for a couple weeks.
John
Index: rtld.c
===================================================================
RCS file: /home/ncvs/src/libexec/rtld-elf/rtld.c,v
retrieving revision 1.59
diff -U9 -r1.59 rtld.c
--- rtld.c 4 Feb 2002 10:44:15 -0000 1.59
+++ rtld.c 26 Feb 2002 18:49:47 -0000
@@ -1909,21 +1909,24 @@
symp = symlook_list(name, hash, &elm->obj->dagmembers, &obj, in_plt,
&donelist);
if (symp != NULL &&
(def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
def = symp;
defobj = obj;
}
}
- /* Search all RTLD_GLOBAL objects. */
- if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) {
- symp = symlook_list(name, hash, &list_global, &obj, in_plt, &donelist);
+ /* Search all DAGs whose roots are RTLD_GLOBAL objects. */
+ STAILQ_FOREACH(elm, &list_global, link) {
+ if (def != NULL && ELF_ST_BIND(def->st_info) != STB_WEAK)
+ break;
+ symp = symlook_list(name, hash, &elm->obj->dagmembers, &obj, in_plt,
+ &donelist);
if (symp != NULL &&
(def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
def = symp;
defobj = obj;
}
}
/*
* Search the dynamic linker itself, and possibly resolve the
State Changed From-To: open->feedback Fixed in -CURRENT, awaiting MFC. State Changed From-To: feedback->closed MFCed, thanks! |