diff options
author | Kurt Miller <kurt@cvs.openbsd.org> | 2005-10-12 20:36:17 +0000 |
---|---|---|
committer | Kurt Miller <kurt@cvs.openbsd.org> | 2005-10-12 20:36:17 +0000 |
commit | cccc2cd2cda6caa1134e0a28330a80676873779a (patch) | |
tree | 378cbc744b1142098b8491e61379b5647f9d9e58 | |
parent | d85e2244b5db594ad7228c8ecf69d3807d39e4a3 (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.c | 22 | ||||
-rw-r--r-- | libexec/ld.so/library.c | 6 | ||||
-rw-r--r-- | libexec/ld.so/library_mquery.c | 6 | ||||
-rw-r--r-- | libexec/ld.so/library_subr.c | 46 | ||||
-rw-r--r-- | libexec/ld.so/loader.c | 23 | ||||
-rw-r--r-- | libexec/ld.so/resolve.c | 4 | ||||
-rw-r--r-- | libexec/ld.so/resolve.h | 6 |
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); |