summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libexec/ld.so/dlfcn.c3
-rw-r--r--libexec/ld.so/library.c5
-rw-r--r--libexec/ld.so/resolve.c21
-rw-r--r--libexec/ld.so/resolve.h4
4 files changed, 27 insertions, 6 deletions
diff --git a/libexec/ld.so/dlfcn.c b/libexec/ld.so/dlfcn.c
index e700b516088..44ee98cebf4 100644
--- a/libexec/ld.so/dlfcn.c
+++ b/libexec/ld.so/dlfcn.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dlfcn.c,v 1.56 2005/09/28 15:41:06 drahn Exp $ */
+/* $OpenBSD: dlfcn.c,v 1.57 2005/09/28 20:35:23 drahn Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -287,6 +287,7 @@ _dl_real_close(void *handle)
if(--object->opencount == 0)
_dl_unlink_dlopen(object);
_dl_unload_shlib(object);
+ _dl_cleanup_objects();
return (0);
}
diff --git a/libexec/ld.so/library.c b/libexec/ld.so/library.c
index a708784c66d..a08d5d3f410 100644
--- a/libexec/ld.so/library.c
+++ b/libexec/ld.so/library.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: library.c,v 1.43 2005/09/27 14:47:00 kurt Exp $ */
+/* $OpenBSD: library.c,v 1.44 2005/09/28 20:35:23 drahn Exp $ */
/*
* Copyright (c) 2002 Dale Rahn
@@ -59,7 +59,8 @@ _dl_unload_shlib(elf_object_t *object)
{
struct dep_node *n;
DL_DEB(("unload_shlib called on %s\n", object->load_name));
- if (object->refcount == 0) {
+ if (object->refcount == 0 && (object->status & STATUS_UNLOADED) == 0) {
+ object->status |= STATUS_UNLOADED;
TAILQ_FOREACH(n, &object->child_list, next_sib)
_dl_unload_shlib(n->data);
DL_DEB(("unload_shlib unloading on %s\n", object->load_name));
diff --git a/libexec/ld.so/resolve.c b/libexec/ld.so/resolve.c
index f3973e5039f..2cc2c5ff160 100644
--- a/libexec/ld.so/resolve.c
+++ b/libexec/ld.so/resolve.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: resolve.c,v 1.35 2005/09/28 15:41:06 drahn Exp $ */
+/* $OpenBSD: resolve.c,v 1.36 2005/09/28 20:35:23 drahn Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -164,6 +164,22 @@ _dl_finalize_object(const char *objname, Elf_Dyn *dynp, const long *dl_data,
return(object);
}
+elf_object_t *free_objects;
+
+void _dl_cleanup_objects(void);
+void
+_dl_cleanup_objects()
+{
+ elf_object_t *nobj, *head;
+ head = free_objects;
+ free_objects = NULL;
+ while (head != NULL) {
+ nobj = head->next;
+ _dl_free(head);
+ head = nobj;
+ }
+}
+
void
_dl_remove_object(elf_object_t *object)
{
@@ -183,7 +199,8 @@ _dl_remove_object(elf_object_t *object)
object->dep_next = object->dep_next->dep_next;
_dl_free(depobj);
}
- _dl_free(object);
+ object->next = free_objects;
+ free_objects = object->next;
}
diff --git a/libexec/ld.so/resolve.h b/libexec/ld.so/resolve.h
index b698d837206..f2cceaad8cd 100644
--- a/libexec/ld.so/resolve.h
+++ b/libexec/ld.so/resolve.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: resolve.h,v 1.42 2005/09/28 18:17:42 kurt Exp $ */
+/* $OpenBSD: resolve.h,v 1.43 2005/09/28 20:35:23 drahn Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -106,6 +106,7 @@ struct elf_object {
#define STAT_INIT_DONE 0x04
#define STAT_FINI_DONE 0x08
#define STAT_FINI_READY 0x10
+#define STAT_UNLOADED 0x20
Elf_Phdr *phdrp;
int phdrc;
@@ -148,6 +149,7 @@ void _dl_add_object(elf_object_t *object);
elf_object_t *_dl_finalize_object(const char *objname, Elf_Dyn *dynp,
const long *, const int objtype, const long laddr, const long loff);
void _dl_remove_object(elf_object_t *object);
+void _dl_cleanup_objects(void);
elf_object_t *_dl_lookup_object(const char *objname);
elf_object_t *_dl_load_shlib(const char *, elf_object_t *, int, int);