diff options
-rw-r--r-- | test/dlopen/Makefile.in | 23 | ||||
-rw-r--r-- | test/dlopen/libA.c | 7 | ||||
-rw-r--r-- | test/dlopen/libB.c | 7 | ||||
-rw-r--r-- | test/dlopen/libC.c | 30 | ||||
-rw-r--r-- | test/dlopen/testscope.c | 29 |
5 files changed, 95 insertions, 1 deletions
diff --git a/test/dlopen/Makefile.in b/test/dlopen/Makefile.in index 22190d9f9..9b4af35e4 100644 --- a/test/dlopen/Makefile.in +++ b/test/dlopen/Makefile.in @@ -4,7 +4,8 @@ # rules need a little love to work with glibc ... export UCLIBC_ONLY := 1 -TESTS := dltest dltest2 dlstatic test1 test2 test3 dlundef dlafk dladdr +TESTS := dltest dltest2 dlstatic test1 test2 test3 dlundef dlafk dladdr \ + testscope CFLAGS_dltest := -DLIBNAME="\"./libtest.so\"" CFLAGS_dltest2 := -DLIBNAME="\"./libtest3.so\"" @@ -18,22 +19,42 @@ LDFLAGS_test1 := -ldl LDFLAGS_test2 := -ldl LDFLAGS_test3 := -ldl ./libtest1.so ./libtest2.so -Wl,-rpath,. LDFLAGS_dladdr := -ldl +LDFLAGS_testscope:= -ldl DEBUG_LIBS := X WRAPPER := env $(DEBUG_LIBS)=all LD_LIBRARY_PATH="$$PWD:.:$(LD_LIBRARY_PATH)" +# Build libC.so without -mprefergot compilation flag to force a +# R_SH_JMP_SLOT relocation instead of R_SH_GLOB_DAT for _libC_fini. This is +# needed to resolve the _libC_fini symbol when used (by libC.so destructor), +# whereas with GLOB_DAT relocation the resolution happens in the GOT entry +# when the libC is loaded, for the same reason remove also the "-z now" +# linker flag. +# These are needed to spot the issue test case want raise. + +ifeq ($(TARGET_ARCH),sh) +CFLAGS-OMIT-libC.c = -mprefergot +endif +LDFLAGS-OMIT-libC.c = -Wl,-z,now + dltest: libtest.so dltest2: libtest3.so dlstatic: libstatic.so dlundef: libundef.so dlafk: libafk.so +testscope:libA.so libafk.so: libafk-temp.so LDFLAGS_libafk.so := ./libafk-temp.so -Wl,-rpath,. test1: libtest1.so test2: libtest1.so libtest2.so test3: libtest1.so libtest2.so libtest1.so: libtest2.so +libB.so: libC.so +libA.so: libB.so LDFLAGS_libtest.so := -lpthread LDFLAGS_libtest1.so := ./libtest2.so -Wl,-rpath,. LDFLAGS_libtest2.so := -Wl,-rpath,. LDFLAGS_libtest3.so := -lpthread -Wl,-rpath,. +LDFLAGS_libC.so := -ldl +LDFLAGS_libB.so := ./libC.so -Wl,-rpath,. +LDFLAGS_libA.so := ./libB.so -Wl,-rpath,. diff --git a/test/dlopen/libA.c b/test/dlopen/libA.c new file mode 100644 index 000000000..13b83dcec --- /dev/null +++ b/test/dlopen/libA.c @@ -0,0 +1,7 @@ +extern void libB_func(void); + +void libA_func(void); +void libA_func(void) +{ + libB_func(); +} diff --git a/test/dlopen/libB.c b/test/dlopen/libB.c new file mode 100644 index 000000000..9b9fff41c --- /dev/null +++ b/test/dlopen/libB.c @@ -0,0 +1,7 @@ +extern void libC_func(void); + +void libB_func(void); +void libB_func(void) +{ + libC_func(); +} diff --git a/test/dlopen/libC.c b/test/dlopen/libC.c new file mode 100644 index 000000000..84cbbef3d --- /dev/null +++ b/test/dlopen/libC.c @@ -0,0 +1,30 @@ +#include <dlfcn.h> +#include <stdio.h> +#include <stdlib.h> + +#define LIBNAME "libB.so" +void _libC_fini(void); +void _libC_fini(void) +{ + printf("libC_fini():finish - atexit()\n"); +} + +void libC_fini(void); +void libC_fini(void) +{ + _libC_fini(); +} + +void libC_func(void); +void libC_func(void) +{ + void *libB; + + libB = dlopen(LIBNAME, RTLD_LAZY); + if (!libB) { + fprintf(stderr, "Could not open ./%s: %s\n", LIBNAME, dlerror()); + exit(1); + } + + atexit(libC_fini); +} diff --git a/test/dlopen/testscope.c b/test/dlopen/testscope.c new file mode 100644 index 000000000..90e079885 --- /dev/null +++ b/test/dlopen/testscope.c @@ -0,0 +1,29 @@ +#include <dlfcn.h> +#include <stdio.h> +#include <stdlib.h> + +#define LIBNAME "libA.so" +int main(int argc, char **argv) +{ + void *libA; + void (*libAfn)(void); + char *error; + + libA = dlopen(LIBNAME, RTLD_LAZY); + if (!libA) { + fprintf(stderr, "Could not open ./%s: %s\n", LIBNAME, dlerror()); + exit(1); + } + + libAfn = dlsym(libA, "libA_func"); + if ((error = dlerror()) != NULL) { + fprintf(stderr, "Could not locate symbol 'libA_func': %s\n", error); + exit(1); + } + + libAfn(); + + dlclose(libA); + + return EXIT_SUCCESS; +} |