summaryrefslogtreecommitdiff
path: root/libexec/ld.so
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2005-04-06 00:16:54 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2005-04-06 00:16:54 +0000
commit97b5dbcee340f2c57bc7189ecfe7c93337e29007 (patch)
tree221b9c2493747769edb7397bf5c666ea4a8962de /libexec/ld.so
parent6119f0701e2a8cb66ce05c15007eb7c8185c117b (diff)
backout -- breaks at least amd64; spotted by marc
Diffstat (limited to 'libexec/ld.so')
-rw-r--r--libexec/ld.so/dlfcn.c24
-rw-r--r--libexec/ld.so/library.c10
-rw-r--r--libexec/ld.so/library_mquery.c21
-rw-r--r--libexec/ld.so/library_subr.c85
-rw-r--r--libexec/ld.so/loader.c103
-rw-r--r--libexec/ld.so/resolve.c13
-rw-r--r--libexec/ld.so/resolve.h21
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;