diff options
Diffstat (limited to 'libexec')
-rw-r--r-- | libexec/ld.so/dlfcn.c | 24 | ||||
-rw-r--r-- | libexec/ld.so/library.c | 10 | ||||
-rw-r--r-- | libexec/ld.so/library_mquery.c | 21 | ||||
-rw-r--r-- | libexec/ld.so/library_subr.c | 85 | ||||
-rw-r--r-- | libexec/ld.so/loader.c | 103 | ||||
-rw-r--r-- | libexec/ld.so/resolve.c | 13 | ||||
-rw-r--r-- | libexec/ld.so/resolve.h | 21 |
7 files changed, 41 insertions, 236 deletions
diff --git a/libexec/ld.so/dlfcn.c b/libexec/ld.so/dlfcn.c index 2826cdf8cf4..cfa466ee718 100644 --- a/libexec/ld.so/dlfcn.c +++ b/libexec/ld.so/dlfcn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dlfcn.c,v 1.45 2005/04/05 19:29:09 drahn Exp $ */ +/* $OpenBSD: dlfcn.c,v 1.46 2005/04/06 00:16:53 deraadt Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -40,10 +40,12 @@ int _dl_errno; -int _dl_real_close(void *handle); -void _dl_unload_deps(elf_object_t *object); -void (*_dl_thread_fnc)(int) = NULL; -elf_object_t *obj_from_addr(const void *addr); +static int _dl_real_close(void *handle); +static void _dl_unload_deps(elf_object_t *object); +static void _dl_thread_kern_stop(void); +static void _dl_thread_kern_go(void); +static void (*_dl_thread_fnc)(int) = NULL; +static elf_object_t *obj_from_addr(const void *addr); void * dlopen(const char *libname, int flags) @@ -111,9 +113,6 @@ dlopen(const char *libname, int flags) _dl_rtld(object); _dl_call_init(object); - _dl_link_dlopen(object); - - if (_dl_debug_map->r_brk) { _dl_debug_map->r_state = RT_ADD; (*((void (*)(void))_dl_debug_map->r_brk))(); @@ -230,7 +229,7 @@ dlclose(void *handle) return (retval); } -int +static int _dl_real_close(void *handle) { elf_object_t *object; @@ -251,7 +250,6 @@ _dl_real_close(void *handle) _dl_unload_deps(dynobj); } - _dl_unlink_dlopen(object); _dl_unload_shlib(object); return (0); } @@ -260,7 +258,7 @@ _dl_real_close(void *handle) * Scan through the shadow dep list and 'unload' every library * we depend upon. Shadow objects are removed when removing ourself. */ -void +static void _dl_unload_deps(elf_object_t *object) { elf_object_t *depobj; @@ -381,14 +379,14 @@ _dl_show_objects(void) _dl_symcachestat_lookups)); } -void +static void _dl_thread_kern_stop(void) { if (_dl_thread_fnc != NULL) (*_dl_thread_fnc)(0); } -void +static void _dl_thread_kern_go(void) { if (_dl_thread_fnc != NULL) diff --git a/libexec/ld.so/library.c b/libexec/ld.so/library.c index d144978b9c9..87fd7144c56 100644 --- a/libexec/ld.so/library.c +++ b/libexec/ld.so/library.c @@ -1,4 +1,4 @@ -/* $OpenBSD: library.c,v 1.37 2005/04/05 19:29:09 drahn Exp $ */ +/* $OpenBSD: library.c,v 1.38 2005/04/06 00:16:53 deraadt Exp $ */ /* * Copyright (c) 2002 Dale Rahn @@ -55,16 +55,10 @@ _dl_load_list_free(struct load_list *load_list) } void -_dl_notify_unload_shlib(elf_object_t *object) +_dl_unload_shlib(elf_object_t *object) { if (--object->refcount == 0) { _dl_run_dtors(object); - } -} -void -_dl_unload_shlib(elf_object_t *object) -{ - if (object->refcount == 0) { _dl_load_list_free(object->load_list); _dl_munmap((void *)object->load_addr, object->load_size); _dl_remove_object(object); diff --git a/libexec/ld.so/library_mquery.c b/libexec/ld.so/library_mquery.c index 61807f55fa0..86345c02457 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.17 2005/04/05 19:29:09 drahn Exp $ */ +/* $OpenBSD: library_mquery.c,v 1.18 2005/04/06 00:16:53 deraadt Exp $ */ /* * Copyright (c) 2002 Dale Rahn @@ -59,27 +59,12 @@ _dl_load_list_free(struct load_list *load_list) } void -_dl_notify_unload_shlib(elf_object_t *object) -{ - struct dep_node *n; - - if (--object->refcount == 0) - for (n = object->first_child; n; n = n->next_sibling) - _dl_notify_unload_shlib(n->data); -} - -void _dl_unload_shlib(elf_object_t *object) { - struct dep_node *n; - - if (object->refcount == 0) { + if (--object->refcount == 0) { + _dl_run_dtors(object); _dl_load_list_free(object->load_list); _dl_remove_object(object); - - for (n = object->first_child; n; n = n->next_sibling) { - _dl_unload_shlib(n->data); - } } } diff --git a/libexec/ld.so/library_subr.c b/libexec/ld.so/library_subr.c index bd1b2bb85d3..c3e3fef80aa 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.2 2005/04/05 19:29:09 drahn Exp $ */ +/* $OpenBSD: library_subr.c,v 1.3 2005/04/06 00:16:53 deraadt Exp $ */ /* * Copyright (c) 2002 Dale Rahn @@ -41,12 +41,6 @@ #define DEFAULT_PATH "/usr/lib" -static void _dl_unload_dlopen_recurse(struct dep_node *node); - -/* STATIC DATA */ -static struct dep_node *_dlopened_first_child; -static struct dep_node *_dlopened_last_child; - /* * _dl_match_file() * @@ -335,83 +329,6 @@ again: void -_dl_link_dlopen(elf_object_t *dep) -{ - struct dep_node *n; - - n = _dl_malloc(sizeof *n); - if (n == NULL) - _dl_exit(5); - - n->data = dep; - n->next_sibling = NULL; - if (_dlopened_first_child) { - _dlopened_last_child->next_sibling = n; - _dlopened_last_child = n; - } else - _dlopened_first_child = _dlopened_last_child = n; - - DL_DEB(("linking %s as dlopen()ed\n", dep->load_name)); -} - -void -_dl_unlink_dlopen(elf_object_t *dep) -{ - struct dep_node **dnode; - struct dep_node *pnode; - struct dep_node *next; - - dnode = &_dlopened_first_child; - - if (_dlopened_first_child == NULL) - return; - - if (_dlopened_first_child->data == dep) { - next = _dlopened_first_child->next_sibling; - _dl_free(_dlopened_first_child); - _dlopened_first_child = next; - return; - } - pnode = _dlopened_first_child; - - while (pnode->next_sibling != NULL) { - if (pnode->next_sibling->data == dep) { - next = pnode->next_sibling->next_sibling; - if (pnode->next_sibling == _dlopened_last_child) - _dlopened_last_child = pnode; - _dl_free(pnode->next_sibling); - pnode->next_sibling = next; - break; - } - pnode = pnode->next_sibling; - } -} - -void -_dl_unload_dlopen(void) -{ - if (_dlopened_first_child != NULL) - _dl_unload_dlopen_recurse(_dlopened_first_child); -} - -/* - * is recursion here a good thing? - */ -void -_dl_unload_dlopen_recurse(struct dep_node *node) -{ - if (node->next_sibling != NULL) { - _dl_unload_dlopen_recurse(node->next_sibling); - } - _dl_notify_unload_shlib(node->data); - _dl_run_all_dtors(); - if (_dl_exiting == 0) - _dl_unload_shlib(node->data); - _dl_free(node); -} - - -void _dl_link_sub(elf_object_t *dep, elf_object_t *p) { struct dep_node *n; diff --git a/libexec/ld.so/loader.c b/libexec/ld.so/loader.c index 88552a04de0..1ed5097e327 100644 --- a/libexec/ld.so/loader.c +++ b/libexec/ld.so/loader.c @@ -1,4 +1,4 @@ -/* $OpenBSD: loader.c,v 1.84 2005/04/05 19:29:09 drahn Exp $ */ +/* $OpenBSD: loader.c,v 1.85 2005/04/06 00:16:53 deraadt Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -71,8 +71,6 @@ struct r_debug *_dl_debug_map; void _dl_dopreload(char *paths); -int _dl_exiting; - void _dl_debug_state(void) { @@ -80,102 +78,27 @@ _dl_debug_state(void) } /* - * Run dtors for the current object, then notify all of the DT_NEEDED - * libraries that it can be unloaded (or ref count lowered). + * Routine to walk through all of the objects except the first + * (main executable). */ - -void -_dl_run_all_dtors() -{ - elf_object_t *node; - int fini_complete; - struct dep_node *dnode; - - fini_complete = 0; - - while (fini_complete == 0) { - fini_complete = 1; - for (node = _dl_objects->next; - node != NULL; - node = node->next) { - if ((node->dyn.fini) && - (node->refcount == 0) && - (node->status & STAT_INIT_DONE) && - ((node->status & STAT_FINI_DONE) == 0)) { - node->status |= STAT_FINI_READY; - } - } - for (node = _dl_objects->next; - node != NULL; - node = node->next ) { - if ((node->dyn.fini) && - (node->refcount == 0) && - (node->status & STAT_INIT_DONE) && - ((node->status & STAT_FINI_DONE) == 0)) - for (dnode = node->first_child; - dnode != NULL; - dnode = dnode->next_sibling) - dnode->data->status &= ~STAT_FINI_READY; - } - - - for (node = _dl_objects->next; - node != NULL; - node = node->next ) { - if (node->status & STAT_FINI_READY) { - DL_DEB(("doing dtors obj %p @%p: [%s]\n", - node, node->dyn.fini, - node->load_name)); - - fini_complete = 0; - node->status |= STAT_FINI_DONE; - node->status &= ~STAT_FINI_READY; - (*node->dyn.fini)(); - } - } - } -} - void _dl_run_dtors(elf_object_t *object) { - struct dep_node *n; - - for (n = object->first_child; n; n = n->next_sibling) { - _dl_notify_unload_shlib(n->data); + if (object->dyn.fini) { + DL_DEB(("doing dtors @%p: [%s]\n", + object->dyn.fini, object->load_name)); + (*object->dyn.fini)(); } - - _dl_run_all_dtors(); - - - if (_dl_exiting == 0) - for (n = object->first_child; n; n = n->next_sibling) - _dl_unload_shlib(n->data); + if (object->next) + _dl_run_dtors(object->next); } -/* - * Routine to walk through all of the objects except the first - * (main executable). - * - * Big question, should dlopen()ed objects be unloaded before or after - * the destructor for the main application runs? - */ void _dl_dtors(void) { - _dl_thread_kern_stop(); - _dl_exiting = 1; - - /* ORDER? */ - _dl_unload_dlopen(); - DL_DEB(("doing dtors\n")); - - /* main program runs its dtors itself - * but we want to run dtors on all it's children); - */ - _dl_objects->status |= STAT_FINI_DONE; - _dl_run_dtors(_dl_objects); + if (_dl_objects->next) + _dl_run_dtors(_dl_objects->next); } void @@ -753,8 +676,8 @@ _dl_call_init(elf_object_t *object) return; if (object->dyn.init) { - DL_DEB(("doing ctors obj %p @%p: [%s]\n", - object, object->dyn.init, object->load_name)); + DL_DEB(("doing ctors @%p: [%s]\n", + object->dyn.init, object->load_name)); (*object->dyn.init)(); } diff --git a/libexec/ld.so/resolve.c b/libexec/ld.so/resolve.c index 8dfcbac48b0..26a9f46b68c 100644 --- a/libexec/ld.so/resolve.c +++ b/libexec/ld.so/resolve.c @@ -1,4 +1,4 @@ -/* $OpenBSD: resolve.c,v 1.25 2005/04/05 19:29:09 drahn Exp $ */ +/* $OpenBSD: resolve.c,v 1.26 2005/04/06 00:16:53 deraadt Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -187,9 +187,8 @@ _dl_lookup_object(const char *name) return(0); } -int _dl_find_symbol_obj(elf_object_t *object, const char *name, - unsigned long hash, int flags, const Elf_Sym **ref, - const Elf_Sym **weak_sym, +int find_symbol_obj(elf_object_t *object, const char *name, unsigned long hash, + int flags, const Elf_Sym **ref, const Elf_Sym **weak_sym, elf_object_t **weak_object); sym_cache *_dl_symcache; @@ -262,7 +261,7 @@ _dl_find_symbol(const char *name, elf_object_t *startlook, } if (req_obj->dyn.symbolic) - if (_dl_find_symbol_obj(req_obj, name, h, flags, ref, &weak_sym, + if (find_symbol_obj(req_obj, name, h, flags, ref, &weak_sym, &weak_object)) { object = req_obj; found = 1; @@ -279,7 +278,7 @@ retry_nonglobal_dlo: (object != req_obj)) continue; - if (_dl_find_symbol_obj(object, name, h, flags, ref, &weak_sym, + if (find_symbol_obj(object, name, h, flags, ref, &weak_sym, &weak_object)) { found = 1; break; @@ -319,7 +318,7 @@ found: } int -_dl_find_symbol_obj(elf_object_t *object, const char *name, unsigned long hash, +find_symbol_obj(elf_object_t *object, const char *name, unsigned long hash, int flags, const Elf_Sym **ref, const Elf_Sym **weak_sym, elf_object_t **weak_object) { diff --git a/libexec/ld.so/resolve.h b/libexec/ld.so/resolve.h index af303fae8d9..64009996094 100644 --- a/libexec/ld.so/resolve.h +++ b/libexec/ld.so/resolve.h @@ -1,4 +1,4 @@ -/* $OpenBSD: resolve.h,v 1.34 2005/04/05 19:29:09 drahn Exp $ */ +/* $OpenBSD: resolve.h,v 1.35 2005/04/06 00:16:53 deraadt Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -99,11 +99,9 @@ typedef struct elf_object { struct elf_object *dep_next; /* Shadow objects for resolve search */ int status; -#define STAT_RELOC_DONE 0x01 -#define STAT_GOT_DONE 0x02 -#define STAT_INIT_DONE 0x04 -#define STAT_FINI_DONE 0x08 -#define STAT_FINI_READY 0x10 +#define STAT_RELOC_DONE 1 +#define STAT_GOT_DONE 2 +#define STAT_INIT_DONE 4 Elf_Phdr *phdrp; int phdrc; @@ -120,7 +118,7 @@ typedef struct elf_object { u_int32_t nbuckets; Elf_Word *chains; u_int32_t nchains; - Elf_Dyn *dynamic; + Elf_Dyn *dynamic; struct dep_node *first_child; struct dep_node *last_child; @@ -182,13 +180,8 @@ Elf_Addr _dl_find_symbol_bysym(elf_object_t *req_obj, unsigned int symidx, void _dl_rtld(elf_object_t *object); void _dl_call_init(elf_object_t *object); void _dl_link_sub(elf_object_t *dep, elf_object_t *p); -void _dl_link_dlopen(elf_object_t *dep); -void _dl_unlink_dlopen(elf_object_t *dep); -void _dl_notify_unload_shlib(elf_object_t *object); -void _dl_unload_dlopen(void); void _dl_run_dtors(elf_object_t *object); -void _dl_run_all_dtors(void); Elf_Addr _dl_bind(elf_object_t *object, int index); @@ -196,9 +189,6 @@ int _dl_match_file(struct sod *sodp, char *name, int namelen); char *_dl_find_shlib(struct sod *sodp, const char *searchpath, int nohints); void _dl_load_list_free(struct load_list *load_list); -void _dl_thread_kern_go(void); -void _dl_thread_kern_stop(void); - extern elf_object_t *_dl_objects; extern elf_object_t *_dl_last_object; @@ -207,7 +197,6 @@ extern struct r_debug *_dl_debug_map; extern int _dl_pagesz; extern int _dl_errno; -extern int _dl_exiting; extern char *_dl_libpath; extern char *_dl_preload; |