summaryrefslogtreecommitdiff
path: root/libexec/ld.so/resolve.c
diff options
context:
space:
mode:
authorKurt Miller <kurt@cvs.openbsd.org>2005-10-06 21:53:11 +0000
committerKurt Miller <kurt@cvs.openbsd.org>2005-10-06 21:53:11 +0000
commit99b23dec2e6d2eac00cc9925a0a2615931b47b08 (patch)
tree91de14214f7f9c11ad47810d58e963df431443f8 /libexec/ld.so/resolve.c
parent28cbdbfb1a2959f448b47d2c463127d6891fe5fd (diff)
separate load group references from dep lib child/dload lists. move load
group refs to own per object ref counter (grprefcount) and list (grpref_list). corrects more complex load group ref cases and side effects from initial implementation. design ideas and ok drahn@
Diffstat (limited to 'libexec/ld.so/resolve.c')
-rw-r--r--libexec/ld.so/resolve.c42
1 files changed, 30 insertions, 12 deletions
diff --git a/libexec/ld.so/resolve.c b/libexec/ld.so/resolve.c
index afc5ede1cd9..e17ab6e315c 100644
--- a/libexec/ld.so/resolve.c
+++ b/libexec/ld.so/resolve.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: resolve.c,v 1.38 2005/10/03 19:48:24 kurt Exp $ */
+/* $OpenBSD: resolve.c,v 1.39 2005/10/06 21:53:10 kurt Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -153,18 +153,32 @@ _dl_finalize_object(const char *objname, Elf_Dyn *dynp, const long *dl_data,
}
DL_DEB(("obj %s has %s as head\n", object->load_name,
_dl_loading_object->load_name ));
- /* refcount handled in _dl_link_sub, _dl_boot & dlopen */
+ /* refcount handled in _dl_link_sub & _dl_boot */
object->refcount = 0;
TAILQ_INIT(&object->child_list);
- object->opencount = 0; /* # dlopen() */
+ object->opencount = 0; /* # dlopen() & exe */
+ object->grprefcount = 0;
/* default dev, inode for dlopen-able objects. */
object->dev = 0;
object->inode = 0;
TAILQ_INIT(&object->dload_list);
+ TAILQ_INIT(&object->grpref_list);
return(object);
}
+void
+_dl_tailq_free(struct dep_node *n)
+{
+ struct dep_node *next;
+
+ while (n != NULL) {
+ next = TAILQ_NEXT(n, next_sib);
+ _dl_free(n);
+ n = next;
+ }
+}
+
elf_object_t *free_objects;
void _dl_cleanup_objects(void);
@@ -172,20 +186,26 @@ void
_dl_cleanup_objects()
{
elf_object_t *nobj, *head;
- struct dep_node *n;
+ struct dep_node *n, *next;
-retry:
- TAILQ_FOREACH(n, &_dlopened_child_list, next_sib) {
- if (n->data->refcount == 0) {
+ n = TAILQ_FIRST(&_dlopened_child_list);
+ while (n != NULL) {
+ next = TAILQ_NEXT(n, next_sib);
+ if (n->data->opencount + n->data->grprefcount == 0) {
TAILQ_REMOVE(&_dlopened_child_list, n, next_sib);
_dl_free(n);
- goto retry;
}
+ n = next;
}
head = free_objects;
free_objects = NULL;
while (head != NULL) {
+ if (head->load_name)
+ _dl_free(head->load_name);
+ _dl_tailq_free(TAILQ_FIRST(&head->dload_list));
+ _dl_tailq_free(TAILQ_FIRST(&head->child_list));
+ _dl_tailq_free(TAILQ_FIRST(&head->grpref_list));
nobj = head->next;
_dl_free(head);
head = nobj;
@@ -204,15 +224,13 @@ _dl_remove_object(elf_object_t *object)
if (_dl_last_object == object)
_dl_last_object = object->prev;
- if (object->load_name)
- _dl_free(object->load_name);
-
while ((depobj = object->dep_next)) {
object->dep_next = object->dep_next->dep_next;
_dl_free(depobj);
}
+
object->next = free_objects;
- free_objects = object->next;
+ free_objects = object;
}