diff options
author | Dale Rahn <drahn@cvs.openbsd.org> | 2003-01-30 03:46:47 +0000 |
---|---|---|
committer | Dale Rahn <drahn@cvs.openbsd.org> | 2003-01-30 03:46:47 +0000 |
commit | 0dfe583a33cbd584479c6b978a64a644d2d3d050 (patch) | |
tree | 64c7cade67e79d561fd70a293ea2f7e99a108f7c /libexec | |
parent | d74de5d15a88f9431648dc890c93ad307a74392f (diff) |
Change the constructor execution order to initialize dependant libraries
first. This mirrors the commit espie put in a.out ld.so recently.
Diffstat (limited to 'libexec')
-rw-r--r-- | libexec/ld.so/library.c | 29 | ||||
-rw-r--r-- | libexec/ld.so/loader.c | 18 | ||||
-rw-r--r-- | libexec/ld.so/resolve.c | 4 | ||||
-rw-r--r-- | libexec/ld.so/resolve.h | 9 |
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, |