Index: map_object.c =================================================================== RCS file: /home/ncvs/src/libexec/rtld-elf/map_object.c,v retrieving revision 1.7.2.2 diff -u -r1.7.2.2 map_object.c --- map_object.c 28 Dec 2002 19:49:41 -0000 1.7.2.2 +++ map_object.c 2 Jun 2005 20:57:15 -0000 @@ -309,6 +309,7 @@ obj = CNEW(Obj_Entry); STAILQ_INIT(&obj->dldags); STAILQ_INIT(&obj->dagmembers); + STAILQ_INIT(&obj->rundeps); return obj; } Index: rtld.c =================================================================== RCS file: /home/ncvs/src/libexec/rtld-elf/rtld.c,v retrieving revision 1.43.2.19 diff -u -r1.43.2.19 rtld.c --- rtld.c 31 Mar 2005 00:32:37 -0000 1.43.2.19 +++ rtld.c 25 Jul 2005 19:09:33 -0000 @@ -458,7 +458,20 @@ (void *)target, basename(defobj->path)); reloc_jmpslot(where, target); + + if (obj == defobj || + objlist_find(&list_main, defobj) || + objlist_find(&obj->dagmembers, defobj) || + objlist_find(&obj->rundeps, defobj)) { + rlock_release(); + return target; + } + rlock_release(); + wlock_acquire(); + objlist_push_tail(&obj->rundeps, (Obj_Entry *)defobj); + ((Obj_Entry *)defobj)->refcount ++; + wlock_release(); return target; } @@ -2388,6 +2401,10 @@ /* Remove the object from all objects' DAG lists. */ STAILQ_FOREACH(elm, &root->dagmembers , link) objlist_remove(&elm->obj->dldags, root); + STAILQ_FOREACH(elm, &root->dagmembers , link) + /* Our parent has abandoned us. We need to form a DAG on our own. */ + if (STAILQ_EMPTY(&elm->obj->dldags) && elm->obj->refcount > 0) + init_dag(elm->obj); } for (needed = root->needed; needed != NULL; needed = needed->next) @@ -2399,12 +2416,16 @@ 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); + STAILQ_FOREACH(elm, &root->rundeps, link) + unref_dag(elm->obj); + } } Index: rtld.h =================================================================== RCS file: /home/ncvs/src/libexec/rtld-elf/rtld.h,v retrieving revision 1.15.2.6 diff -u -r1.15.2.6 rtld.h --- rtld.h 20 Feb 2003 20:42:46 -0000 1.15.2.6 +++ rtld.h 1 Jun 2005 19:37:13 -0000 @@ -159,6 +159,7 @@ struct link_map linkmap; /* for GDB and dlinfo() */ Objlist dldags; /* Object belongs to these dlopened DAGs (%) */ Objlist dagmembers; /* DAG has these members (%) */ + Objlist rundeps; /* DAG has these members (%) */ dev_t dev; /* Object's filesystem's device */ ino_t ino; /* Object's inode number */ } Obj_Entry;