summaryrefslogtreecommitdiff
path: root/libexec/ld.so
diff options
context:
space:
mode:
authorDale Rahn <drahn@cvs.openbsd.org>2005-09-28 15:41:07 +0000
committerDale Rahn <drahn@cvs.openbsd.org>2005-09-28 15:41:07 +0000
commit533868b989d82a44d3c5e1688d5635d60f71f04c (patch)
treefb39e76ef4b4865627e8d70805d63a6fa597ffb4 /libexec/ld.so
parentb1bb0e421389e910c2bdbed4619cf53056269631 (diff)
keep track of opencounts for dlopened objects, so that they
get unloaded the right number of times on exit.
Diffstat (limited to 'libexec/ld.so')
-rw-r--r--libexec/ld.so/dlfcn.c9
-rw-r--r--libexec/ld.so/library_subr.c12
-rw-r--r--libexec/ld.so/resolve.c3
-rw-r--r--libexec/ld.so/resolve.h4
4 files changed, 18 insertions, 10 deletions
diff --git a/libexec/ld.so/dlfcn.c b/libexec/ld.so/dlfcn.c
index 81f44af0b0b..e700b516088 100644
--- a/libexec/ld.so/dlfcn.c
+++ b/libexec/ld.so/dlfcn.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dlfcn.c,v 1.55 2005/09/28 15:24:22 kurt Exp $ */
+/* $OpenBSD: dlfcn.c,v 1.56 2005/09/28 15:41:06 drahn Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -145,6 +145,9 @@ dlopen(const char *libname, int flags)
}
loaded:
+ if (failed == 0)
+ object->opencount++;
+
if (_dl_debug_map->r_brk) {
_dl_debug_map->r_state = RT_ADD;
(*((void (*)(void))_dl_debug_map->r_brk))();
@@ -279,10 +282,10 @@ _dl_real_close(void *handle)
return (1);
}
-
_dl_notify_unload_shlib(object);
_dl_run_all_dtors();
- _dl_unlink_dlopen(object);
+ if(--object->opencount == 0)
+ _dl_unlink_dlopen(object);
_dl_unload_shlib(object);
return (0);
}
diff --git a/libexec/ld.so/library_subr.c b/libexec/ld.so/library_subr.c
index 28843ba6765..7f76eba742c 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.10 2005/09/22 04:07:10 deraadt Exp $ */
+/* $OpenBSD: library_subr.c,v 1.11 2005/09/28 15:41:06 drahn Exp $ */
/*
* Copyright (c) 2002 Dale Rahn
@@ -386,10 +386,12 @@ _dl_unload_dlopen(void)
if (node->data == _dl_objects)
continue;
- _dl_notify_unload_shlib(node->data);
- _dl_run_all_dtors();
- if (_dl_exiting == 0)
- _dl_unload_shlib(node->data);
+ while(node->data->opencount-- != 0) {
+ _dl_notify_unload_shlib(node->data);
+ _dl_run_all_dtors();
+ if (_dl_exiting == 0)
+ _dl_unload_shlib(node->data);
+ }
TAILQ_REMOVE(&_dlopened_child_list, node, next_sib);
_dl_free(node);
diff --git a/libexec/ld.so/resolve.c b/libexec/ld.so/resolve.c
index 16b20ef2d23..f3973e5039f 100644
--- a/libexec/ld.so/resolve.c
+++ b/libexec/ld.so/resolve.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: resolve.c,v 1.34 2005/09/22 04:07:11 deraadt Exp $ */
+/* $OpenBSD: resolve.c,v 1.35 2005/09/28 15:41:06 drahn Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -155,6 +155,7 @@ _dl_finalize_object(const char *objname, Elf_Dyn *dynp, const long *dl_data,
_dl_loading_object->load_name ));
object->refcount = 1;
TAILQ_INIT(&object->child_list);
+ object->opencount = 0; /* # dlopen() */
/* default dev, inode for dlopen-able objects. */
object->dev = 0;
object->inode = 0;
diff --git a/libexec/ld.so/resolve.h b/libexec/ld.so/resolve.h
index b44dfb991a7..7254159bcee 100644
--- a/libexec/ld.so/resolve.h
+++ b/libexec/ld.so/resolve.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: resolve.h,v 1.40 2005/09/22 22:33:40 drahn Exp $ */
+/* $OpenBSD: resolve.h,v 1.41 2005/09/28 15:41:06 drahn Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -127,6 +127,8 @@ struct elf_object {
TAILQ_HEAD(,dep_node) child_list;
TAILQ_HEAD(,dep_node) dload_list;
+ int opencount; /* # dlopen() */
+
/* object that caused this module to be loaded, used in symbol lookup */
elf_object_t *load_object;