summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKurt Miller <kurt@cvs.openbsd.org>2005-10-12 20:36:17 +0000
committerKurt Miller <kurt@cvs.openbsd.org>2005-10-12 20:36:17 +0000
commitcccc2cd2cda6caa1134e0a28330a80676873779a (patch)
tree378cbc744b1142098b8491e61379b5647f9d9e58
parentd85e2244b5db594ad7228c8ecf69d3807d39e4a3 (diff)
Split grpsym_list creation away from child_list creation and change
grpsym_list order to match Sun's docs. Also corrects bugs where grpsym_list was either not created or partially created.
-rw-r--r--libexec/ld.so/dlfcn.c22
-rw-r--r--libexec/ld.so/library.c6
-rw-r--r--libexec/ld.so/library_mquery.c6
-rw-r--r--libexec/ld.so/library_subr.c46
-rw-r--r--libexec/ld.so/loader.c23
-rw-r--r--libexec/ld.so/resolve.c4
-rw-r--r--libexec/ld.so/resolve.h6
7 files changed, 66 insertions, 47 deletions
diff --git a/libexec/ld.so/dlfcn.c b/libexec/ld.so/dlfcn.c
index 8f8f0eca316..7f6020339e3 100644
--- a/libexec/ld.so/dlfcn.c
+++ b/libexec/ld.so/dlfcn.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dlfcn.c,v 1.67 2005/10/10 16:33:51 kurt Exp $ */
+/* $OpenBSD: dlfcn.c,v 1.68 2005/10/12 20:36:16 kurt Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -49,7 +49,6 @@ dlopen(const char *libname, int flags)
{
elf_object_t *object, *dynobj;
Elf_Dyn *dynp;
- struct dep_node *n;
int failed = 0;
const char *deplibname = NULL;
@@ -71,20 +70,21 @@ dlopen(const char *libname, int flags)
_dl_link_dlopen(object);
- if (OBJECT_REF_CNT(object) > 1)
+ if (OBJECT_REF_CNT(object) > 1) {
+ /* if opened but grpsym_list has not been created */
+ if (OBJECT_DLREF_CNT(object) == 1) {
+ /* add first object manually */
+ _dl_link_grpsym(object);
+ _dl_cache_grpsym_list(object);
+ }
goto loaded;
+ }
/* this add_object should not be here, XXX */
_dl_add_object(object);
DL_DEB(("head [%s]\n", object->load_name ));
- n = _dl_malloc(sizeof *n);
- if (n == NULL)
- _dl_exit(5);
- n->data = object;
- TAILQ_INSERT_TAIL(&object->grpsym_list, n, next_sib);
-
dynobj = object;
while (dynobj) {
for (dynp = dynobj->load_dyn; dynp->d_tag; dynp++) {
@@ -104,7 +104,7 @@ dlopen(const char *libname, int flags)
}
/* this add_object should not be here, XXX */
_dl_add_object(depobj);
- _dl_link_sub(depobj, dynobj);
+ _dl_link_child(depobj, dynobj);
}
dynobj = dynobj->next;
}
@@ -119,6 +119,8 @@ dlopen(const char *libname, int flags)
} else {
int err;
DL_DEB(("tail %s\n", object->load_name ));
+ _dl_link_grpsym(object);
+ _dl_cache_grpsym_list(object);
err = _dl_rtld(object);
if (err != 0) {
_dl_real_close(object);
diff --git a/libexec/ld.so/library.c b/libexec/ld.so/library.c
index 753f0b53617..c6afa737c6b 100644
--- a/libexec/ld.so/library.c
+++ b/libexec/ld.so/library.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: library.c,v 1.49 2005/10/09 04:29:13 kurt Exp $ */
+/* $OpenBSD: library.c,v 1.50 2005/10/12 20:36:16 kurt Exp $ */
/*
* Copyright (c) 2002 Dale Rahn
@@ -91,7 +91,7 @@ _dl_tryload_shlib(const char *libname, int type, int flags)
object = _dl_lookup_object(libname);
if (object) {
- object->load_object->obj_flags |= flags & RTLD_GLOBAL;
+ object->obj_flags |= flags & RTLD_GLOBAL;
if (_dl_loading_object == NULL)
_dl_loading_object = object;
if (object->load_object != _dl_objects &&
@@ -115,7 +115,7 @@ _dl_tryload_shlib(const char *libname, int type, int flags)
for (object = _dl_objects; object != NULL; object = object->next) {
if (object->dev == sb.st_dev &&
object->inode == sb.st_ino) {
- object->load_object->obj_flags |= flags & RTLD_GLOBAL;
+ object->obj_flags |= flags & RTLD_GLOBAL;
_dl_close(libfile);
if (_dl_loading_object == NULL)
_dl_loading_object = object;
diff --git a/libexec/ld.so/library_mquery.c b/libexec/ld.so/library_mquery.c
index b6bf72cf5de..e6615f2180b 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.30 2005/10/09 04:29:13 kurt Exp $ */
+/* $OpenBSD: library_mquery.c,v 1.31 2005/10/12 20:36:16 kurt Exp $ */
/*
* Copyright (c) 2002 Dale Rahn
@@ -98,7 +98,7 @@ _dl_tryload_shlib(const char *libname, int type, int flags)
object = _dl_lookup_object(libname);
if (object) {
- object->load_object->obj_flags |= flags & RTLD_GLOBAL;
+ object->obj_flags |= flags & RTLD_GLOBAL;
if (_dl_loading_object == NULL)
_dl_loading_object = object;
if (object->load_object != _dl_objects &&
@@ -122,7 +122,7 @@ _dl_tryload_shlib(const char *libname, int type, int flags)
for (object = _dl_objects; object != NULL; object = object->next) {
if (object->dev == sb.st_dev &&
object->inode == sb.st_ino) {
- object->load_object->obj_flags |= flags & RTLD_GLOBAL;
+ object->obj_flags |= flags & RTLD_GLOBAL;
_dl_close(libfile);
if (_dl_loading_object == NULL)
_dl_loading_object = object;
diff --git a/libexec/ld.so/library_subr.c b/libexec/ld.so/library_subr.c
index 220222ac3ca..e1c8875b9fa 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.20 2005/10/09 04:37:13 kurt Exp $ */
+/* $OpenBSD: library_subr.c,v 1.21 2005/10/12 20:36:16 kurt Exp $ */
/*
* Copyright (c) 2002 Dale Rahn
@@ -402,7 +402,7 @@ _dl_link_grpref(elf_object_t *load_group, elf_object_t *load_object)
}
void
-_dl_link_sub(elf_object_t *dep, elf_object_t *p)
+_dl_link_child(elf_object_t *dep, elf_object_t *p)
{
struct dep_node *n;
@@ -412,22 +412,44 @@ _dl_link_sub(elf_object_t *dep, elf_object_t *p)
n->data = dep;
TAILQ_INSERT_TAIL(&p->child_list, n, next_sib);
- /*
- * because two child libraries can refer to the same library
- * and we only want to deal with each one once, check for dups
- * before adding new, dup libs will have the same dep pointer.
- */
+ DL_DEB(("linking dep %s as child of %s\n", dep->load_name,
+ p->load_name));
+}
+
+void
+_dl_link_grpsym(elf_object_t *object)
+{
+ struct dep_node *n;
+
TAILQ_FOREACH(n, &_dl_loading_object->grpsym_list, next_sib)
- if (n->data == dep)
+ if (n->data == object)
return; /* found, dont bother adding */
n = _dl_malloc(sizeof *n);
if (n == NULL)
_dl_exit(8);
- n->data = dep;
+ n->data = object;
TAILQ_INSERT_TAIL(&_dl_loading_object->grpsym_list, n, next_sib);
- dep->refcount++;
- DL_DEB(("linking dep %s as child of %s\n", dep->load_name,
- p->load_name));
+ /* _dl_loading_object uses opencount & grprefcount */
+ if (object != _dl_loading_object)
+ object->refcount++;
+}
+
+void
+_dl_cache_grpsym_list(elf_object_t *object)
+{
+ struct dep_node *n;
+
+ /*
+ * grpsym_list is an ordered list of all child libs of the
+ * _dl_loading_object with no dups. The order is equalivant
+ * to a breath-first traversal of the child list without dups.
+ */
+
+ TAILQ_FOREACH(n, &object->child_list, next_sib)
+ _dl_link_grpsym(n->data);
+
+ TAILQ_FOREACH(n, &object->child_list, next_sib)
+ _dl_cache_grpsym_list(n->data);
}
diff --git a/libexec/ld.so/loader.c b/libexec/ld.so/loader.c
index 68342bf3851..c7b779a2f1f 100644
--- a/libexec/ld.so/loader.c
+++ b/libexec/ld.so/loader.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: loader.c,v 1.96 2005/10/10 16:33:51 kurt Exp $ */
+/* $OpenBSD: loader.c,v 1.97 2005/10/12 20:36:16 kurt Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -181,7 +181,7 @@ _dl_dopreload(char *paths)
_dl_exit(4);
}
_dl_add_object(shlib);
- _dl_link_sub(shlib, _dl_objects);
+ _dl_link_child(shlib, _dl_objects);
}
_dl_free(paths);
return;
@@ -318,12 +318,6 @@ _dl_boot(const char **argv, char **envp, const long loff, long *dl_data)
_dl_exit(5);
n->data = exe_obj;
TAILQ_INSERT_TAIL(&_dlopened_child_list, n, next_sib);
-
- n = _dl_malloc(sizeof *n);
- if (n == NULL)
- _dl_exit(9);
- n->data = exe_obj;
- TAILQ_INSERT_TAIL(&exe_obj->grpsym_list, n, next_sib);
exe_obj->opencount++;
if (_dl_preload != NULL)
@@ -400,27 +394,26 @@ _dl_boot(const char **argv, char **envp, const long loff, long *dl_data)
}
for (loop = 0; loop < libcnt_err; loop++) {
_dl_add_object(liblist[loop].dynobj);
- _dl_link_sub(liblist[loop].dynobj, dynobj);
+ _dl_link_child(liblist[loop].dynobj, dynobj);
}
_dl_free(liblist);
}
}
+ _dl_link_grpsym(exe_obj);
+ _dl_cache_grpsym_list(exe_obj);
+
/*
* Now add the dynamic loader itself last in the object list
* so we can use the _dl_ code when serving dl.... calls.
+ * Intentionally left off the exe child_list.
*/
dynp = (Elf_Dyn *)((void *)_DYNAMIC);
dyn_obj = _dl_finalize_object(us, dynp, 0, OBJTYPE_LDR,
dl_data[AUX_base], loff);
_dl_add_object(dyn_obj);
- n = _dl_malloc(sizeof *n);
- if (n == NULL)
- _dl_exit(5);
- n->data = dyn_obj;
- TAILQ_INSERT_TAIL(&exe_obj->grpsym_list, n, next_sib);
- dyn_obj->refcount++;
+ _dl_link_grpsym(dyn_obj);
dyn_obj->status |= STAT_RELOC_DONE;
diff --git a/libexec/ld.so/resolve.c b/libexec/ld.so/resolve.c
index b76df7997fa..a9f06d14435 100644
--- a/libexec/ld.so/resolve.c
+++ b/libexec/ld.so/resolve.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: resolve.c,v 1.42 2005/10/09 04:29:13 kurt Exp $ */
+/* $OpenBSD: resolve.c,v 1.43 2005/10/12 20:36:16 kurt Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -153,7 +153,7 @@ _dl_finalize_object(const char *objname, Elf_Dyn *dynp, const long *dl_data,
}
DL_DEB(("obj %s has %s as head\n", object->load_name,
_dl_loading_object->load_name ));
- /* refcount handled in _dl_link_sub & _dl_boot */
+ /* refcount handled in _dl_link_grpsym_list */
object->refcount = 0;
TAILQ_INIT(&object->child_list);
object->opencount = 0; /* # dlopen() & exe */
diff --git a/libexec/ld.so/resolve.h b/libexec/ld.so/resolve.h
index 173603ce38d..1fbc3eaf24e 100644
--- a/libexec/ld.so/resolve.h
+++ b/libexec/ld.so/resolve.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: resolve.h,v 1.47 2005/10/09 04:29:13 kurt Exp $ */
+/* $OpenBSD: resolve.h,v 1.48 2005/10/12 20:36:16 kurt Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -198,7 +198,9 @@ Elf_Addr _dl_find_symbol_bysym(elf_object_t *req_obj, unsigned int symidx,
int _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_child(elf_object_t *dep, elf_object_t *p);
+void _dl_link_grpsym(elf_object_t *object);
+void _dl_cache_grpsym_list(elf_object_t *object);
void _dl_link_grpref(elf_object_t *load_group, elf_object_t *load_object);
void _dl_link_dlopen(elf_object_t *dep);
void _dl_unlink_dlopen(elf_object_t *dep);