summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDale Rahn <drahn@cvs.openbsd.org>2005-10-01 19:32:23 +0000
committerDale Rahn <drahn@cvs.openbsd.org>2005-10-01 19:32:23 +0000
commit34cc8abaf39119e92cdf89258a084f4d8ccb1749 (patch)
treed0ecf55e51e19034482806c45159b67034eb408f
parent038a92308d23043d05543461cc755bf9140d5e3b (diff)
handle references to load groups caused by dlopen()ing of depenant
members of the load group. work by kurt@ and myself
-rw-r--r--libexec/ld.so/dlfcn.c17
-rw-r--r--libexec/ld.so/library.c20
-rw-r--r--libexec/ld.so/library_mquery.c19
-rw-r--r--libexec/ld.so/library_subr.c27
-rw-r--r--libexec/ld.so/resolve.c13
5 files changed, 64 insertions, 32 deletions
diff --git a/libexec/ld.so/dlfcn.c b/libexec/ld.so/dlfcn.c
index 44ee98cebf4..1efac15a4f3 100644
--- a/libexec/ld.so/dlfcn.c
+++ b/libexec/ld.so/dlfcn.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dlfcn.c,v 1.57 2005/09/28 20:35:23 drahn Exp $ */
+/* $OpenBSD: dlfcn.c,v 1.58 2005/10/01 19:32:22 drahn Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -66,6 +66,12 @@ dlopen(const char *libname, int flags)
failed = 1;
goto loaded;
}
+
+ _dl_loading_object = object;
+
+ if (object->opencount == 0)
+ _dl_link_dlopen(object);
+
if (object->refcount > 1)
goto loaded;
@@ -74,7 +80,6 @@ dlopen(const char *libname, int flags)
DL_DEB(("head [%s]\n", object->load_name ));
object->load_object = object;
- _dl_loading_object = object;
n = _dl_malloc(sizeof *n);
if (n == NULL)
@@ -120,8 +125,6 @@ dlopen(const char *libname, int flags)
dynobj = dynobj->next;
}
- _dl_loading_object = NULL;
-
if (failed == 1) {
if (deplibname != NULL) {
DL_DEB(("dlopen: failed to open %s\n", deplibname));
@@ -132,7 +135,6 @@ dlopen(const char *libname, int flags)
} else {
int err;
DL_DEB(("tail %s\n", object->load_name ));
- _dl_link_dlopen(object);
err = _dl_rtld(object);
if (err != 0) {
_dl_real_close(object);
@@ -148,6 +150,8 @@ loaded:
if (failed == 0)
object->opencount++;
+ _dl_loading_object = NULL;
+
if (_dl_debug_map->r_brk) {
_dl_debug_map->r_state = RT_ADD;
(*((void (*)(void))_dl_debug_map->r_brk))();
@@ -284,8 +288,7 @@ _dl_real_close(void *handle)
_dl_notify_unload_shlib(object);
_dl_run_all_dtors();
- if(--object->opencount == 0)
- _dl_unlink_dlopen(object);
+ object->opencount--;
_dl_unload_shlib(object);
_dl_cleanup_objects();
return (0);
diff --git a/libexec/ld.so/library.c b/libexec/ld.so/library.c
index 88ee59b3353..2c77c75f7cb 100644
--- a/libexec/ld.so/library.c
+++ b/libexec/ld.so/library.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: library.c,v 1.45 2005/09/28 21:56:24 drahn Exp $ */
+/* $OpenBSD: library.c,v 1.46 2005/10/01 19:32:22 drahn Exp $ */
/*
* Copyright (c) 2002 Dale Rahn
@@ -92,6 +92,14 @@ _dl_tryload_shlib(const char *libname, int type, int flags)
if (object) {
object->refcount++;
object->load_object->obj_flags |= flags & RTLD_GLOBAL;
+ if (object->load_object != object &&
+ object->load_object != _dl_objects &&
+ object->load_object != _dl_loading_object) {
+ object->load_object->refcount++;
+ if (_dl_loading_object == NULL)
+ _dl_loading_object = object;
+ _dl_link_sub(object->load_object, _dl_loading_object);
+ }
return(object); /* Already loaded */
}
@@ -112,6 +120,16 @@ _dl_tryload_shlib(const char *libname, int type, int flags)
object->refcount++;
object->load_object->obj_flags |= flags & RTLD_GLOBAL;
_dl_close(libfile);
+ if (object->load_object != object &&
+ object->load_object != _dl_objects &&
+ object->load_object != _dl_loading_object) {
+ object->load_object->refcount++;
+ if (_dl_loading_object == NULL)
+ _dl_loading_object = object;
+
+ _dl_link_sub(object->load_object,
+ _dl_loading_object);
+ }
return(object);
}
}
diff --git a/libexec/ld.so/library_mquery.c b/libexec/ld.so/library_mquery.c
index 49d6944ab93..a0b3532825f 100644
--- a/libexec/ld.so/library_mquery.c
+++ b/libexec/ld.so/library_mquery.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: library_mquery.c,v 1.26 2005/09/28 21:56:24 drahn Exp $ */
+/* $OpenBSD: library_mquery.c,v 1.27 2005/10/01 19:32:22 drahn Exp $ */
/*
* Copyright (c) 2002 Dale Rahn
@@ -97,6 +97,14 @@ _dl_tryload_shlib(const char *libname, int type, int flags)
if (object) {
object->refcount++;
object->load_object->obj_flags |= flags & RTLD_GLOBAL;
+ if (object->load_object != object &&
+ object->load_object != _dl_objects &&
+ object->load_object != _dl_loading_object) {
+ object->load_object->refcount++;
+ if (_dl_loading_object == NULL)
+ _dl_loading_object = object;
+ _dl_link_sub(object->load_object, _dl_loading_object);
+ }
return(object); /* Already loaded */
}
@@ -117,6 +125,15 @@ _dl_tryload_shlib(const char *libname, int type, int flags)
object->refcount++;
object->load_object->obj_flags |= flags & RTLD_GLOBAL;
_dl_close(libfile);
+ if (object->load_object != object &&
+ object->load_object != _dl_objects &&
+ object->load_object != _dl_loading_object) {
+ object->load_object->refcount++;
+ if (_dl_loading_object == NULL)
+ _dl_loading_object = object;
+ _dl_link_sub(object->load_object,
+ _dl_loading_object);
+ }
return(object);
}
}
diff --git a/libexec/ld.so/library_subr.c b/libexec/ld.so/library_subr.c
index 1fe3c55d206..2fab10ca73b 100644
--- a/libexec/ld.so/library_subr.c
+++ b/libexec/ld.so/library_subr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: library_subr.c,v 1.13 2005/09/28 20:48:00 kurt Exp $ */
+/* $OpenBSD: library_subr.c,v 1.14 2005/10/01 19:32:22 drahn Exp $ */
/*
* Copyright (c) 2002 Dale Rahn
@@ -349,31 +349,14 @@ _dl_link_dlopen(elf_object_t *dep)
}
void
-_dl_unlink_dlopen(elf_object_t *dep)
-{
-
- struct dep_node *dnode;
-
- TAILQ_FOREACH(dnode, &_dlopened_child_list, next_sib)
- if (dnode->data == dep)
- break;
-
- if (dnode == NULL) /* XXX - not found? */
- return;
-
- TAILQ_REMOVE(&_dlopened_child_list, dnode, next_sib);
-
- _dl_free(dnode);
-}
-
-void
_dl_notify_unload_shlib(elf_object_t *object)
{
struct dep_node *n;
- if (--object->refcount == 0)
- TAILQ_FOREACH(n, &object->child_list, next_sib)
- _dl_notify_unload_shlib(n->data);
+ object->refcount--;
+
+ TAILQ_FOREACH(n, &object->child_list, next_sib)
+ n->data->refcount--;
}
void
diff --git a/libexec/ld.so/resolve.c b/libexec/ld.so/resolve.c
index 2cc2c5ff160..8034492209c 100644
--- a/libexec/ld.so/resolve.c
+++ b/libexec/ld.so/resolve.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: resolve.c,v 1.36 2005/09/28 20:35:23 drahn Exp $ */
+/* $OpenBSD: resolve.c,v 1.37 2005/10/01 19:32:22 drahn Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -171,6 +171,17 @@ void
_dl_cleanup_objects()
{
elf_object_t *nobj, *head;
+ struct dep_node *n;
+
+retry:
+ TAILQ_FOREACH(n, &_dlopened_child_list, next_sib) {
+ if (n->data->refcount == 0) {
+ TAILQ_REMOVE(&_dlopened_child_list, n, next_sib);
+ _dl_free(n);
+ goto retry;
+ }
+ }
+
head = free_objects;
free_objects = NULL;
while (head != NULL) {