diff options
author | Kurt Miller <kurt@cvs.openbsd.org> | 2005-10-16 04:14:23 +0000 |
---|---|---|
committer | Kurt Miller <kurt@cvs.openbsd.org> | 2005-10-16 04:14:23 +0000 |
commit | d79d5e6d0731e9db4b1d547095536e7206722850 (patch) | |
tree | fc4f9f06f3eb584d88740c1a1e8d2c8a78992683 /libexec/ld.so | |
parent | d29b1ec6711c01f2e3af05cb2420d7f93a2ad1d3 (diff) |
Consolidate dl_boot and dlopen dep lib loading into new function
_dl_load_dep_libs. Now both dl_boot and dlopen will randomize dep lib
loading, where previously only dl_boot did.
Diffstat (limited to 'libexec/ld.so')
-rw-r--r-- | libexec/ld.so/dlfcn.c | 37 | ||||
-rw-r--r-- | libexec/ld.so/loader.c | 186 | ||||
-rw-r--r-- | libexec/ld.so/resolve.h | 3 |
3 files changed, 105 insertions, 121 deletions
diff --git a/libexec/ld.so/dlfcn.c b/libexec/ld.so/dlfcn.c index 7f6020339e3..25fa5dd8e6f 100644 --- a/libexec/ld.so/dlfcn.c +++ b/libexec/ld.so/dlfcn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dlfcn.c,v 1.68 2005/10/12 20:36:16 kurt Exp $ */ +/* $OpenBSD: dlfcn.c,v 1.69 2005/10/16 04:14:22 kurt Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -47,10 +47,8 @@ static elf_object_t *obj_from_addr(const void *addr); void * dlopen(const char *libname, int flags) { - elf_object_t *object, *dynobj; - Elf_Dyn *dynp; + elf_object_t *object; int failed = 0; - const char *deplibname = NULL; if (libname == NULL) return _dl_objects; @@ -85,42 +83,13 @@ dlopen(const char *libname, int flags) DL_DEB(("head [%s]\n", object->load_name )); - dynobj = object; - while (dynobj) { - for (dynp = dynobj->load_dyn; dynp->d_tag; dynp++) { - elf_object_t *depobj; - - if (dynp->d_tag != DT_NEEDED) - continue; - - deplibname = dynobj->dyn.strtab + dynp->d_un.d_val; - DL_DEB(("dlopen: loading: %s required by %s\n", - deplibname, libname)); - depobj = _dl_load_shlib(deplibname, dynobj, OBJTYPE_LIB, - flags); - if (!depobj) { - failed = 1; - break; - } - /* this add_object should not be here, XXX */ - _dl_add_object(depobj); - _dl_link_child(depobj, dynobj); - } - dynobj = dynobj->next; - } - - if (failed == 1) { - if (deplibname != NULL) { - DL_DEB(("dlopen: failed to open %s\n", deplibname)); - } + if ((failed = _dl_load_dep_libs(object, flags, 0)) == 1) { _dl_real_close(object); object = NULL; _dl_errno = DL_CANT_LOAD_OBJ; } 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/loader.c b/libexec/ld.so/loader.c index c7b779a2f1f..84942ce4221 100644 --- a/libexec/ld.so/loader.c +++ b/libexec/ld.so/loader.c @@ -1,4 +1,4 @@ -/* $OpenBSD: loader.c,v 1.97 2005/10/12 20:36:16 kurt Exp $ */ +/* $OpenBSD: loader.c,v 1.98 2005/10/16 04:14:22 kurt Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -234,6 +234,99 @@ _dl_setup_env(char **envp) _dl_so_envp = envp; } +int +_dl_load_dep_libs(elf_object_t *object, int flags, int booting) +{ + elf_object_t *dynobj; + Elf_Dyn *dynp; + unsigned int loop; + int libcount; + + dynobj = object; + while(dynobj) { + DL_DEB(("examining: '%s'\n", dynobj->load_name)); + libcount = 0; + for (dynp = dynobj->load_dyn; dynp->d_tag; dynp++) { + if (dynp->d_tag == DT_NEEDED) { + libcount++; + } + } + + if ( libcount != 0) { + struct listent { + Elf_Dyn *dynp; + elf_object_t *depobj; + } *liblist; + int *randomlist; + + liblist = _dl_malloc(libcount * sizeof(struct listent)); + randomlist = _dl_malloc(libcount * sizeof(int)); + + if (liblist == NULL) + _dl_exit(5); + + for (dynp = dynobj->load_dyn, loop = 0; dynp->d_tag; + dynp++) + if (dynp->d_tag == DT_NEEDED) + liblist[loop++].dynp = dynp; + + /* Randomize these */ + for (loop = 0; loop < libcount; loop++) + randomlist[loop] = loop; + + if (!_dl_norandom) + for (loop = 1; loop < libcount; loop++) { + unsigned int rnd; + int cur; + rnd = _dl_random(); + rnd = rnd % (loop+1); + cur = randomlist[rnd]; + randomlist[rnd] = randomlist[loop]; + randomlist[loop] = cur; + } + + for (loop = 0; loop < libcount; loop++) { + elf_object_t *depobj; + const char *libname; + libname = dynobj->dyn.strtab; + libname += + liblist[randomlist[loop]].dynp->d_un.d_val; + DL_DEB(("loading: %s required by %s\n", libname, + dynobj->load_name)); + depobj = _dl_load_shlib(libname, dynobj, + OBJTYPE_LIB, flags); + if (depobj == 0) { + if (booting) { + _dl_printf( + "%s: can't load library '%s'\n", + _dl_progname, libname); + _dl_exit(4); + } else { + DL_DEB(("dlopen: failed to open %s\n", + libname)); + _dl_free(liblist); + return (1); + } + } + liblist[randomlist[loop]].depobj = depobj; + } + + for (loop = 0; loop < libcount; loop++) { + _dl_add_object(liblist[loop].depobj); + _dl_link_child(liblist[loop].depobj, dynobj); + } + _dl_free(liblist); + } + dynobj = dynobj->next; + } + + /* add first object manually */ + _dl_link_grpsym(object); + _dl_cache_grpsym_list(object); + + return(0); +} + /* * This is the dynamic loader entrypoint. When entering here, depending * on architecture type, the stack and registers are set up according @@ -248,11 +341,10 @@ _dl_boot(const char **argv, char **envp, const long loff, long *dl_data) struct r_debug **map_link; /* Where to put pointer for gdb */ struct r_debug *debug_map; Elf_Dyn *dynp; - elf_object_t *dynobj; Elf_Phdr *phdp; char *us = ""; unsigned int loop; - int libcnt_err = 0; + int failed; struct dep_node *n; _dl_setup_env(envp); @@ -323,85 +415,7 @@ _dl_boot(const char **argv, char **envp, const long loff, long *dl_data) if (_dl_preload != NULL) _dl_dopreload(_dl_preload); - /* - * Now, pick up and 'load' all libraries required. Start - * with the first on the list and then do whatever gets - * added along the tour. - */ - dynobj = _dl_objects; - for (dynobj = _dl_objects; dynobj != NULL; dynobj = dynobj->next) { - DL_DEB(("examining: '%s'\n", dynobj->load_name)); - libcnt_err = 0; - for (dynp = dynobj->load_dyn; dynp->d_tag; dynp++) { - if (dynp->d_tag == DT_NEEDED) { - libcnt_err++; - } - } - if ( libcnt_err != 0) { - struct listent { - Elf_Dyn *dynp; - elf_object_t *dynobj; - } *liblist; - int *randomlist; - - liblist = _dl_malloc(libcnt_err * - sizeof(struct listent)); - randomlist = _dl_malloc(libcnt_err * sizeof(int)); - if (liblist == NULL) - _dl_exit(5); - - for (dynp = dynobj->load_dyn, loop = 0; - dynp->d_tag; - dynp++) - if (dynp->d_tag == DT_NEEDED) - liblist[loop++].dynp = dynp; - - /* Randomize these */ - for (loop = 0; loop < libcnt_err; loop++) - randomlist[loop] = loop; - - if (!_dl_norandom) - for (loop = 1; loop < libcnt_err; loop++) { - unsigned int rnd; - int cur; - - rnd = _dl_random(); - - rnd = rnd % (loop+1); - - cur = randomlist[rnd]; - randomlist[rnd] = randomlist[loop]; - randomlist[loop] = cur; - } - - for (loop = 0; loop < libcnt_err; loop++) { - elf_object_t *depobj; - const char *libname; - - libname = dynobj->dyn.strtab; - libname += - liblist[randomlist[loop]].dynp->d_un.d_val; - DL_DEB(("needs: '%s'\n", libname)); - depobj = _dl_load_shlib(libname, dynobj, - OBJTYPE_LIB, DL_LAZY|RTLD_GLOBAL); - if (depobj == 0) { - _dl_printf( - "%s: can't load library '%s'\n", - _dl_progname, libname); - _dl_exit(4); - } - liblist[randomlist[loop]].dynobj = depobj; - } - for (loop = 0; loop < libcnt_err; loop++) { - _dl_add_object(liblist[loop].dynobj); - _dl_link_child(liblist[loop].dynobj, dynobj); - } - _dl_free(liblist); - } - } - - _dl_link_grpsym(exe_obj); - _dl_cache_grpsym_list(exe_obj); + _dl_load_dep_libs(exe_obj, DL_LAZY|RTLD_GLOBAL, 1); /* * Now add the dynamic loader itself last in the object list @@ -421,17 +435,17 @@ _dl_boot(const char **argv, char **envp, const long loff, long *dl_data) * Everything should be in place now for doing the relocation * and binding. Call _dl_rtld to do the job. Fingers crossed. */ - libcnt_err = 0; + failed = 0; if (_dl_traceld == NULL) - libcnt_err = _dl_rtld(_dl_objects); + failed = _dl_rtld(_dl_objects); if (_dl_debug || _dl_traceld) _dl_show_objects(); DL_DEB(("dynamic loading done, %s.\n", - (libcnt_err == 0) ? "success":"failed")); + (failed == 0) ? "success":"failed")); - if (libcnt_err != 0) + if (failed != 0) _dl_exit(1); if (_dl_traceld) diff --git a/libexec/ld.so/resolve.h b/libexec/ld.so/resolve.h index 1fbc3eaf24e..c58fe64ba19 100644 --- a/libexec/ld.so/resolve.h +++ b/libexec/ld.so/resolve.h @@ -1,4 +1,4 @@ -/* $OpenBSD: resolve.h,v 1.48 2005/10/12 20:36:16 kurt Exp $ */ +/* $OpenBSD: resolve.h,v 1.49 2005/10/16 04:14:22 kurt Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -196,6 +196,7 @@ Elf_Addr _dl_find_symbol_bysym(elf_object_t *req_obj, unsigned int symidx, #define SYM_DLSYM 0x40 +int _dl_load_dep_libs(elf_object_t *object, int flags, int booting); int _dl_rtld(elf_object_t *object); void _dl_call_init(elf_object_t *object); void _dl_link_child(elf_object_t *dep, elf_object_t *p); |