summaryrefslogtreecommitdiff
path: root/libexec/ld.so
diff options
context:
space:
mode:
Diffstat (limited to 'libexec/ld.so')
-rw-r--r--libexec/ld.so/library.c29
-rw-r--r--libexec/ld.so/loader.c18
-rw-r--r--libexec/ld.so/resolve.c4
-rw-r--r--libexec/ld.so/resolve.h9
4 files changed, 52 insertions, 8 deletions
diff --git a/libexec/ld.so/library.c b/libexec/ld.so/library.c
index fd7ebe1c98b..97efb7450bd 100644
--- a/libexec/ld.so/library.c
+++ b/libexec/ld.so/library.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: library.c,v 1.24 2002/12/13 20:45:54 drahn Exp $ */
+/* $OpenBSD: library.c,v 1.25 2003/01/30 03:46:46 drahn Exp $ */
/*
* Copyright (c) 2002 Dale Rahn
@@ -57,6 +57,7 @@
(((X) & PF_X) ? PROT_EXEC : 0))
static elf_object_t *_dl_tryload_shlib(const char *libname, int type);
+static void _dl_link_sub(elf_object_t *dep, elf_object_t *p);
/*
* _dl_match_file()
@@ -246,6 +247,7 @@ _dl_load_shlib(const char *libname, elf_object_t *parent, int type)
if (_dl_strchr(libname, '/')) {
object = _dl_tryload_shlib(libname, type);
+ _dl_link_sub(object, parent);
return(object);
}
@@ -268,6 +270,7 @@ again:
sod.sod_minor, req_sod.sod_minor);
object = _dl_tryload_shlib(hint, type);
if (object != NULL) {
+ _dl_link_sub(object, parent);
_dl_free((char *)sod.sod_name);
return (object);
}
@@ -289,6 +292,7 @@ again:
sod.sod_minor, req_sod.sod_minor);
object = _dl_tryload_shlib(hint, type);
if (object != NULL) {
+ _dl_link_sub(object, parent);
_dl_free((char *)sod.sod_name);
return (object);
}
@@ -306,6 +310,7 @@ again:
sod.sod_minor, req_sod.sod_minor);
object = _dl_tryload_shlib(hint, type);
if (object != NULL) {
+ _dl_link_sub(object, parent);
_dl_free((char *)sod.sod_name);
return(object);
}
@@ -495,3 +500,25 @@ _dl_tryload_shlib(const char *libname, int type)
}
return(object);
}
+
+static void
+_dl_link_sub(elf_object_t *dep, elf_object_t *p)
+{
+ struct dep_node *n;
+
+ n = _dl_malloc(sizeof *n);
+ if (n == NULL)
+ _dl_exit(5);
+ n->data = dep;
+ n->next_sibling = NULL;
+ if (p->first_child) {
+ p->last_child->next_sibling = n;
+ p->last_child = n;
+ } else {
+ p->first_child = p->last_child = n;
+ }
+ DL_DEB(("linking dep %s as child of %s\n", dep->load_name,
+ p->load_name));
+}
+
+
diff --git a/libexec/ld.so/loader.c b/libexec/ld.so/loader.c
index 819fa60ce7e..0302039a9f6 100644
--- a/libexec/ld.so/loader.c
+++ b/libexec/ld.so/loader.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: loader.c,v 1.52 2002/11/14 15:15:54 drahn Exp $ */
+/* $OpenBSD: loader.c,v 1.53 2003/01/30 03:46:46 drahn Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -243,8 +243,10 @@ _dl_boot(const char **argv, char **envp, const long loff, long *dl_data)
* the shared libraries which follow.
* Do not run init code if run from ldd.
*/
- if ((_dl_traceld == NULL) && (_dl_objects->next != NULL))
- _dl_call_init(_dl_objects->next);
+ if ((_dl_traceld == NULL) && (_dl_objects->next != NULL)) {
+ _dl_objects->status |= STAT_INIT_DONE;
+ _dl_call_init(_dl_objects);
+ }
/*
* Schedule a routine to be run at shutdown, by using atexit.
@@ -514,8 +516,13 @@ _dl_rtld(elf_object_t *object)
void
_dl_call_init(elf_object_t *object)
{
- if (object->next)
- _dl_call_init(object->next);
+ struct dep_node *n;
+
+ for (n = object->first_child; n; n = n->next_sibling) {
+ if (n->data->status & STAT_INIT_DONE)
+ continue;
+ _dl_call_init(n->data);
+ }
if (object->status & STAT_INIT_DONE)
return;
@@ -523,6 +530,7 @@ _dl_call_init(elf_object_t *object)
if (object->dyn.init)
(*object->dyn.init)();
+ /* What about loops? */
object->status |= STAT_INIT_DONE;
}
diff --git a/libexec/ld.so/resolve.c b/libexec/ld.so/resolve.c
index c437345a661..903b4f1399b 100644
--- a/libexec/ld.so/resolve.c
+++ b/libexec/ld.so/resolve.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: resolve.c,v 1.15 2002/11/23 04:09:34 drahn Exp $ */
+/* $OpenBSD: resolve.c,v 1.16 2003/01/30 03:46:46 drahn Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -132,6 +132,8 @@ _dl_add_object(const char *objname, Elf_Dyn *dynp, const u_long *dl_data,
object->load_offs = loff;
object->load_name = _dl_strdup(objname);
object->refcount = 1;
+ object->first_child = NULL;
+ object->last_child = NULL;
return(object);
}
diff --git a/libexec/ld.so/resolve.h b/libexec/ld.so/resolve.h
index 52a99e303c9..702a296b0b9 100644
--- a/libexec/ld.so/resolve.h
+++ b/libexec/ld.so/resolve.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: resolve.h,v 1.19 2002/12/18 19:20:01 drahn Exp $ */
+/* $OpenBSD: resolve.h,v 1.20 2003/01/30 03:46:46 drahn Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -121,8 +121,15 @@ typedef struct elf_object {
u_int32_t nchains;
Elf_Dyn *dynamic;
+ struct dep_node *first_child;
+ struct dep_node *last_child;
} elf_object_t;
+struct dep_node {
+ struct dep_node *next_sibling;
+ elf_object_t *data;
+};
+
extern void _dl_rt_resolve(void);
extern elf_object_t *_dl_add_object(const char *objname, Elf_Dyn *dynp,