diff options
Diffstat (limited to 'elf')
-rw-r--r-- | elf/Makefile | 14 | ||||
-rw-r--r-- | elf/dl-deps.c | 2 | ||||
-rw-r--r-- | elf/dl-load.c | 14 | ||||
-rw-r--r-- | elf/dl-object.c | 12 | ||||
-rw-r--r-- | elf/dl-open.c | 3 | ||||
-rw-r--r-- | elf/rtld.c | 5 | ||||
-rw-r--r-- | elf/tst-deep1.c | 36 | ||||
-rw-r--r-- | elf/tst-deep1mod1.c | 14 | ||||
-rw-r--r-- | elf/tst-deep1mod2.c | 16 | ||||
-rw-r--r-- | elf/tst-deep1mod3.c | 17 |
10 files changed, 116 insertions, 17 deletions
diff --git a/elf/Makefile b/elf/Makefile index ac8319bc5f..d40d3fd6a7 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -82,7 +82,8 @@ distribute := rtld-Rules \ tst-array1.exp tst-array2.exp tst-array4.exp \ tst-array2dep.c tst-piemod1.c \ tst-execstack-mod.c tst-dlmodcount.c \ - check-textrel.c dl-sysdep.h test-dlopenrpathmod.c + check-textrel.c dl-sysdep.h test-dlopenrpathmod.c \ + tst-deep1mod1.c tst-deep1mod2.c tst-deep1mod3.c CFLAGS-dl-runtime.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-dl-lookup.c = -fexceptions -fasynchronous-unwind-tables @@ -152,7 +153,8 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \ restest2 next dblload dblunload reldep5 reldep6 reldep7 reldep8 \ circleload1 tst-tls3 tst-tls4 tst-tls5 tst-tls6 tst-tls7 tst-tls8 \ tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14 tst-align \ - $(tests-execstack-$(have-z-execstack)) tst-dlmodcount tst-dlopenrpath + $(tests-execstack-$(have-z-execstack)) tst-dlmodcount \ + tst-dlopenrpath tst-deep1 # reldep9 test-srcs = tst-pathopt tests-vis-yes = vismain @@ -185,7 +187,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ reldep8mod1 reldep8mod2 reldep8mod3 \ reldep9mod1 reldep9mod2 reldep9mod3 \ tst-alignmod $(modules-execstack-$(have-z-execstack)) \ - tst-dlopenrpathmod + tst-dlopenrpathmod tst-deep1mod1 tst-deep1mod2 tst-deep1mod3 ifeq (yes,$(have-initfini-array)) modules-names += tst-array2dep endif @@ -754,3 +756,9 @@ $(objpfx)tst-dlopenrpath: $(objpfx)tst-dlopenrpathmod.so $(libdl) CFLAGS-tst-dlopenrpath.c += -DPFX=\"$(objpfx)\" LDFLAGS-tst-dlopenrpathmod.so += -Wl,-rpath,\$$ORIGIN/test-subdir $(objpfx)tst-dlopenrpath.out: $(objpfx)firstobj.so + +$(objpfx)tst-deep1mod2.so: $(objpfx)tst-deep1mod3.so +$(objpfx)tst-deep1: $(libdl) $(objpfx)tst-deep1mod1.so +$(objpfx)tst-deep1.out: $(objpfx)tst-deep1mod2.so +LDFLAGS-tst-deep1 += -rdynamic +tst-deep1mod3.so-no-z-defs = yes diff --git a/elf/dl-deps.c b/elf/dl-deps.c index b8dee8ab52..1a0fedf988 100644 --- a/elf/dl-deps.c +++ b/elf/dl-deps.c @@ -509,7 +509,7 @@ _dl_map_object_deps (struct link_map *map, runp->map->l_reserved = 0; } - if (__builtin_expect(GLRO(dl_debug_mask) & DL_DEBUG_PRELINK, 0) != 0 + if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK, 0) != 0 && map == GL(dl_loaded)) { /* If we are to compute conflicts, we have to build local scope diff --git a/elf/dl-load.c b/elf/dl-load.c index 73112bce23..15fff3c5e1 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -881,7 +881,7 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp, #endif /* Enter the new object in the list of loaded objects. */ - l = _dl_new_object (realname, name, l_type, loader); + l = _dl_new_object (realname, name, l_type, loader, mode); if (__builtin_expect (! l, 0)) { errstring = N_("cannot create shared object descriptor"); @@ -1355,15 +1355,12 @@ cannot enable executable stack as shared object requires"); /* If this object has DT_SYMBOLIC set modify now its scope. We don't have to do this for the main map. */ - if (__builtin_expect (l->l_info[DT_SYMBOLIC] != NULL, 0) + if ((mode & RTLD_DEEPBIND) == 0 + && __builtin_expect (l->l_info[DT_SYMBOLIC] != NULL, 0) && &l->l_searchlist != l->l_scope[0]) { /* Create an appropriate searchlist. It contains only this map. - - XXX This is the definition of DT_SYMBOLIC in SysVr4. The old - GNU ld.so implementation had a different interpretation which - is more reasonable. We are prepared to add this possibility - back as part of a GNU extension of the ELF format. */ + This is the definition of DT_SYMBOLIC in SysVr4. */ l->l_symbolic_searchlist.r_list = (struct link_map **) malloc (sizeof (struct link_map *)); @@ -1968,7 +1965,8 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, /* Enter the new object in the list of loaded objects. */ if ((name_copy = local_strdup (name)) == NULL - || (l = _dl_new_object (name_copy, name, type, loader)) == NULL) + || (l = _dl_new_object (name_copy, name, type, loader, + mode)) == NULL) _dl_signal_error (ENOMEM, name, NULL, N_("cannot create shared object descriptor")); /* Signal that this is a faked entry. */ diff --git a/elf/dl-object.c b/elf/dl-object.c index 52131181b3..91b1fa2187 100644 --- a/elf/dl-object.c +++ b/elf/dl-object.c @@ -32,7 +32,7 @@ struct link_map * internal_function _dl_new_object (char *realname, const char *libname, int type, - struct link_map *loader) + struct link_map *loader, int mode) { struct link_map *l; int idx; @@ -95,7 +95,15 @@ _dl_new_object (char *realname, const char *libname, int type, /* Insert the scope if it isn't the global scope we already added. */ if (idx == 0 || &loader->l_searchlist != new->l_scope[0]) - new->l_scope[idx] = &loader->l_searchlist; + { + if ((mode & RTLD_DEEPBIND) != 0 && idx != 0) + { + new->l_scope[1] = new->l_scope[0]; + idx = 0; + } + + new->l_scope[idx] = &loader->l_searchlist; + } new->l_local_scope[0] = &new->l_searchlist; diff --git a/elf/dl-open.c b/elf/dl-open.c index c352722e27..c9b4a45596 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -272,7 +272,8 @@ dl_open_worker (void *a) } /* Load that object's dependencies. */ - GLRO(dl_map_object_deps) (new, NULL, 0, 0, mode & __RTLD_DLOPEN); + GLRO(dl_map_object_deps) (new, NULL, 0, 0, + mode & (__RTLD_DLOPEN | RTLD_DEEPBIND)); /* So far, so good. Now check the versions. */ for (i = 0; i < new->l_searchlist.r_nlist; ++i) diff --git a/elf/rtld.c b/elf/rtld.c index 2daf05a6d6..1ee875a088 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -879,7 +879,7 @@ of this helper program; chances are you did not intend to run this program.\n\ { /* Create a link_map for the executable itself. This will be what dlopen on "" returns. */ - _dl_new_object ((char *) "", "", lt_executable, NULL); + _dl_new_object ((char *) "", "", lt_executable, NULL, 0); if (GL(dl_loaded) == NULL) _dl_fatal_printf ("cannot allocate memory for link map\n"); GL(dl_loaded)->l_phdr = phdr; @@ -1271,7 +1271,8 @@ ERROR: ld.so: object '%s' from %s cannot be preloaded: ignored.\n", better be, since it's read-only and so we couldn't relocate it). We just want our data structures to describe it as if we had just mapped and relocated it normally. */ - struct link_map *l = _dl_new_object ((char *) "", "", lt_library, NULL); + struct link_map *l = _dl_new_object ((char *) "", "", lt_library, NULL, + 0); if (__builtin_expect (l != NULL, 1)) { static ElfW(Dyn) dyn_temp[DL_RO_DYN_TEMP_CNT] attribute_relro; diff --git a/elf/tst-deep1.c b/elf/tst-deep1.c new file mode 100644 index 0000000000..5428d13de4 --- /dev/null +++ b/elf/tst-deep1.c @@ -0,0 +1,36 @@ +#include <dlfcn.h> +#include <stdio.h> + +int +xyzzy (void) +{ + printf ("%s:%s\n", __FILE__, __func__); + return 21; +} + +int +back (void) +{ + printf ("%s:%s\n", __FILE__, __func__); + return 1; +} + +extern int foo (void); + +static int +do_test (void) +{ + void *p = dlopen ("$ORIGIN/tst-deep1mod2.so", RTLD_LAZY|RTLD_DEEPBIND); + + int (*f) (void) = dlsym (p, "bar"); + if (f == NULL) + { + puts (dlerror ()); + return 1; + } + + return foo () + f (); +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/elf/tst-deep1mod1.c b/elf/tst-deep1mod1.c new file mode 100644 index 0000000000..cc922e6ea5 --- /dev/null +++ b/elf/tst-deep1mod1.c @@ -0,0 +1,14 @@ +#include <stdio.h> +int +foo (void) +{ + printf ("%s:%s\n", __FILE__, __func__); + return 1; +} + +int +baz (void) +{ + printf ("%s:%s\n", __FILE__, __func__); + return 20; +} diff --git a/elf/tst-deep1mod2.c b/elf/tst-deep1mod2.c new file mode 100644 index 0000000000..b99caf0328 --- /dev/null +++ b/elf/tst-deep1mod2.c @@ -0,0 +1,16 @@ +#include <stdio.h> +extern int baz (void); +extern int xyzzy (void); +int +bar (void) +{ + printf ("%s:%s\n", __FILE__, __func__); + return baz () + xyzzy ();; +} + +int +back (void) +{ + printf ("%s:%s\n", __FILE__, __func__); + return -1; +} diff --git a/elf/tst-deep1mod3.c b/elf/tst-deep1mod3.c new file mode 100644 index 0000000000..eee7d5c97b --- /dev/null +++ b/elf/tst-deep1mod3.c @@ -0,0 +1,17 @@ +#include <stdio.h> + +extern int back (void); + +int +baz (void) +{ + printf ("%s:%s\n", __FILE__, __func__); + return back (); +} + +int +xyzzy (void) +{ + printf ("%s:%s\n", __FILE__, __func__); + return 0; +} |