summaryrefslogtreecommitdiffstats
path: root/libexec/rtld-elf/rtld.c
diff options
context:
space:
mode:
authorkan <kan@FreeBSD.org>2003-02-10 23:15:07 +0000
committerkan <kan@FreeBSD.org>2003-02-10 23:15:07 +0000
commit76b4e9c51cf97134b8cfb2e21a8c2b92aaa542f5 (patch)
treeb5c1e46a8b57846e369d80506d67ae5c1d253aa2 /libexec/rtld-elf/rtld.c
parent4d663017dc8999384de372a2083892b9a7d0c41d (diff)
downloadFreeBSD-src-76b4e9c51cf97134b8cfb2e21a8c2b92aaa542f5.zip
FreeBSD-src-76b4e9c51cf97134b8cfb2e21a8c2b92aaa542f5.tar.gz
When unloading dependencies make sure they are removed from all the
associated lists: remove RTLD_GLOBAL objects from global objects list; remove the parent object from dldags list of its children. Previosly we were doing that only to the top-level object OF the DAG being unloaded and all its dependencies were ignored, leading to mysterious crashes later. Submitted by: peter (partially)
Diffstat (limited to 'libexec/rtld-elf/rtld.c')
-rw-r--r--libexec/rtld-elf/rtld.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 3ad6017..4408d63 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -2131,17 +2131,9 @@ unload_object(Obj_Entry *root)
{
Obj_Entry *obj;
Obj_Entry **linkp;
- Objlist_Entry *elm;
assert(root->refcount == 0);
- /* Remove the DAG from all objects' DAG lists. */
- STAILQ_FOREACH(elm, &root->dagmembers , link)
- objlist_remove(&elm->obj->dldags, root);
-
- /* Remove the DAG from the RTLD_GLOBAL list. */
- objlist_remove(&list_global, root);
-
/* Unmap all objects that are no longer referenced. */
linkp = &obj_list->next;
while ((obj = *linkp) != NULL) {
@@ -2162,14 +2154,23 @@ static void
unref_dag(Obj_Entry *root)
{
const Needed_Entry *needed;
+ Objlist_Entry *elm;
if (root->refcount == 0)
return;
root->refcount--;
- if (root->refcount == 0)
+ if (root->refcount == 0) {
for (needed = root->needed; needed != NULL; needed = needed->next)
if (needed->obj != NULL)
unref_dag(needed->obj);
+
+ /* Remove the object from the RTLD_GLOBAL list. */
+ objlist_remove(&list_global, root);
+
+ /* Remove the object from all objects' DAG lists. */
+ STAILQ_FOREACH(elm, &root->dagmembers , link)
+ objlist_remove(&elm->obj->dldags, root);
+ }
}
/*
OpenPOWER on IntegriCloud