diff options
author | Dale Rahn <drahn@cvs.openbsd.org> | 2005-10-01 19:32:23 +0000 |
---|---|---|
committer | Dale Rahn <drahn@cvs.openbsd.org> | 2005-10-01 19:32:23 +0000 |
commit | 34cc8abaf39119e92cdf89258a084f4d8ccb1749 (patch) | |
tree | d0ecf55e51e19034482806c45159b67034eb408f /libexec | |
parent | 038a92308d23043d05543461cc755bf9140d5e3b (diff) |
handle references to load groups caused by dlopen()ing of depenant
members of the load group. work by kurt@ and myself
Diffstat (limited to 'libexec')
-rw-r--r-- | libexec/ld.so/dlfcn.c | 17 | ||||
-rw-r--r-- | libexec/ld.so/library.c | 20 | ||||
-rw-r--r-- | libexec/ld.so/library_mquery.c | 19 | ||||
-rw-r--r-- | libexec/ld.so/library_subr.c | 27 | ||||
-rw-r--r-- | libexec/ld.so/resolve.c | 13 |
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) { |