diff options
author | Waldemar Brodkorb <wbx@uclibc-ng.org> | 2016-10-24 20:22:12 +0200 |
---|---|---|
committer | Waldemar Brodkorb <wbx@uclibc-ng.org> | 2016-10-24 20:22:12 +0200 |
commit | 7988979a722b4cdf287b2093956a76a3f19b9897 (patch) | |
tree | d35e251d0472ceca55a2eef61cff261c8ee68fab /test/dlopen |
add uClibc-ng test directory
Diffstat (limited to 'test/dlopen')
30 files changed, 872 insertions, 0 deletions
diff --git a/test/dlopen/Makefile b/test/dlopen/Makefile new file mode 100644 index 0000000..d5be53c --- /dev/null +++ b/test/dlopen/Makefile @@ -0,0 +1,8 @@ +# uClibc dlopen tests +# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + +top_builddir=../../ +top_srcdir=../../ +include ../Rules.mak +-include Makefile.in +include ../Test.mak diff --git a/test/dlopen/Makefile.in b/test/dlopen/Makefile.in new file mode 100644 index 0000000..740453a --- /dev/null +++ b/test/dlopen/Makefile.in @@ -0,0 +1,84 @@ +# uClibc dlopen tests +# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + +# rules need a little love to work with glibc ... +export UCLIBC_ONLY := 1 + +TESTS := dltest dltest2 dlstatic test1 test2 test3 dlundef dlafk dladdr \ + testscope nodelete nodelete1 tst-origin + +ifneq ($(HAVE_SHARED),y) +TESTS_DISABLED := test3 +LDFLAGS_libtest.so := -lpthread +endif + +CFLAGS_dltest := -DLIBNAME="\"./libtest.so\"" +CFLAGS_dltest2 := -DLIBNAME="\"./libtest3.so\"" + +LDFLAGS_dlstatic := -ldl +LDFLAGS_dltest := -ldl +LDFLAGS_dltest2 := -ldl +LDFLAGS_dlundef := -ldl +LDFLAGS_dlafk := -ldl ./libafk.so -Wl,-rpath,. +LDFLAGS_test1 := -ldl +LDFLAGS_test2 := -ldl +LDFLAGS_test3 := -ldl ./libtest1.so ./libtest2.so -Wl,-rpath,. +LDFLAGS_dladdr := -ldl +LDFLAGS_testscope:= -ldl +LDFLAGS_tst-origin:= -ldl -Wl,-rpath,\$$ORIGIN/testlib + +DEBUG_LIBS := X +WRAPPER := env $(DEBUG_LIBS)=all LD_LIBRARY_PATH="$$PWD:.:$(LD_LIBRARY_PATH)" + +testlib: + @mkdir $@ + +testlib/libtest31.so: libtest3.so | testlib + @cp $^ $@ + +EXTRA_DIRS := testlib + +# 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 +tst-origin: testlib/libtest31.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,. + +nodelete: nodelmod1.so nodelmod2.so nodelmod3.so +nodelmod3.so: nodelmod4.so +LDFLAGS_nodelete := -rdynamic -ldl +LDFLAGS_nodelmod1.so := -Wl,-z,nodelete +LDFLAGS_nodelmod3.so := ./nodelmod4.so +LDFLAGS_nodelmod4.so := -Wl,-z,nodelete +nodelete1: nodelmod1.so nodelmod2.so +LDFLAGS_nodelete1 := -rdynamic -ldl diff --git a/test/dlopen/dladdr.c b/test/dlopen/dladdr.c new file mode 100644 index 0000000..b64c000 --- /dev/null +++ b/test/dlopen/dladdr.c @@ -0,0 +1,25 @@ +#include <dlfcn.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +int main(int argc, char **argv) +{ + Dl_info info; + int res = 0; + + memset(&info, '\0', sizeof(Dl_info)); + res = dladdr((void *)1, &info); + if (res != 0) { + fprintf(stderr, "dladdr() should fail\n"); + fprintf(stderr, "dli_fname = %s\n", info.dli_fname); + fprintf(stderr, "dli_fbase = 0x%08x\n", (unsigned int)info.dli_fbase); + fprintf(stderr, "dli_sname = %s\n", info.dli_sname); + fprintf(stderr, "dli_saddr = 0x%08x\n", (unsigned int)info.dli_saddr); + exit(1); + } + + fprintf(stderr, "dladdr() failed as expected\n"); + return EXIT_SUCCESS; +} + diff --git a/test/dlopen/dlafk.c b/test/dlopen/dlafk.c new file mode 100644 index 0000000..2eac4af --- /dev/null +++ b/test/dlopen/dlafk.c @@ -0,0 +1,36 @@ +#include <fcntl.h> +#include <stdlib.h> +#include <stdio.h> +#include <dlfcn.h> +#include <stdint.h> +#include <unistd.h> +#include <errno.h> +#include <string.h> + +#define LIBNAME "libafk.so" + +#define LIBAFK "libafk-temp.so" +#define LIBAFK_BAK ".libafk-temp.so.temp" + +int main(int argc, char **argv) +{ + void *handle; + + if (rename(LIBAFK, LIBAFK_BAK)) { + fprintf(stderr, "Unable to rename %s: %s\n", LIBAFK, strerror(errno)); + return EXIT_FAILURE; + } + + handle = dlopen(LIBNAME, RTLD_NOW); + if (!handle) { + fprintf(stderr, "Could not open ./%s: %s\n", LIBNAME, dlerror()); + return EXIT_FAILURE; + } + + if (rename(LIBAFK_BAK, LIBAFK)) { + fprintf(stderr, "Unable to rename %s: %s\n", LIBAFK_BAK, strerror(errno)); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/test/dlopen/dlstatic.c b/test/dlopen/dlstatic.c new file mode 100644 index 0000000..57c8c5d --- /dev/null +++ b/test/dlopen/dlstatic.c @@ -0,0 +1,43 @@ +#include <fcntl.h> +#include <stdlib.h> +#include <stdio.h> +#include <dlfcn.h> +#include <stdint.h> + +#define LIBNAME "libstatic.so" + +int load_and_test(void) +{ + void *handle; + int (*mystatic)(void); + + handle = dlopen(LIBNAME, RTLD_LAZY); + if (!handle) { + fprintf(stderr, "Could not open ./%s: %s\n", LIBNAME, dlerror()); + return 1; + } + + mystatic = dlsym(handle, "static_test"); + if (mystatic == NULL) { + fprintf(stderr, "Could not locate symbol 'static_test': %s\n", dlerror()); + return 1; + } + + if (!mystatic()) { + fprintf(stderr, "mystatic() failed: static vars were not setup properly\n"); + return 1; + } + + dlclose(handle); + + return 0; +} + +int main(int argc, char **argv) +{ + int count = 5; + while (count-- > 0) + if (load_and_test()) + return EXIT_FAILURE; + return EXIT_SUCCESS; +} diff --git a/test/dlopen/dltest.c b/test/dlopen/dltest.c new file mode 100644 index 0000000..a0fac90 --- /dev/null +++ b/test/dlopen/dltest.c @@ -0,0 +1,41 @@ +#include <fcntl.h> +#include <stdlib.h> +#include <stdio.h> +#include <dlfcn.h> +#include <stdint.h> + +int main(int argc, char **argv) +{ + int ret = EXIT_SUCCESS; + void *handle; + void (*mydltest)(void *value1, void *value2); + char *error; + uint32_t *value1, *value2; + + handle = dlopen (LIBNAME, RTLD_LAZY); + if (!handle) { + fprintf(stderr, "Could not open ./%s: %s\n", LIBNAME, dlerror()); + exit(1); + } + + mydltest = dlsym(handle, "dltest"); + if ((error = dlerror()) != NULL) { + fprintf(stderr, "Could not locate symbol 'dltest': %s\n", error); + exit(1); + } + + mydltest(&value1, &value2); + printf("dltest: pthread_once=%p\n", value1); + printf("dltest: pthread_self=%p\n", value2); + if (value1 == value2) { + ret = EXIT_FAILURE; + printf("dltest: values should NOT be equal Weak values resolved incorrectly!\n"); + } else { + printf("dltest: weak symbols resolved correctly.\n"); + } + + dlclose(handle); + + return ret; +} + diff --git a/test/dlopen/dltest2.c b/test/dlopen/dltest2.c new file mode 100644 index 0000000..127b3b5 --- /dev/null +++ b/test/dlopen/dltest2.c @@ -0,0 +1 @@ +#include "dltest.c" diff --git a/test/dlopen/dlundef.c b/test/dlopen/dlundef.c new file mode 100644 index 0000000..cefd933 --- /dev/null +++ b/test/dlopen/dlundef.c @@ -0,0 +1,29 @@ +#include <fcntl.h> +#include <stdlib.h> +#include <stdio.h> +#include <dlfcn.h> +#include <stdint.h> + +#define LIBNAME "libundef.so" + +int main(int argc, char **argv) +{ + void *handle; + int (*myundefined)(void); + + handle = dlopen(LIBNAME, RTLD_LAZY); + if (!handle) { + fprintf(stderr, "Could not open ./%s: %s\n", LIBNAME, dlerror()); + return EXIT_FAILURE; + } + + myundefined = dlsym(handle, "__booga_booga_you_cant_touch_this__"); + if (myundefined != NULL) { + fprintf(stderr, "dlsym() found a symbol that does not exist!\n"); + return EXIT_FAILURE; + } + + dlclose(handle); + + return EXIT_SUCCESS; +} diff --git a/test/dlopen/libA.c b/test/dlopen/libA.c new file mode 100644 index 0000000..13b83dc --- /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 0000000..9b9fff4 --- /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 0000000..84cbbef --- /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/libafk-temp.c b/test/dlopen/libafk-temp.c new file mode 100644 index 0000000..39b58df --- /dev/null +++ b/test/dlopen/libafk-temp.c @@ -0,0 +1 @@ +/* the actual contents doesnt matter */ diff --git a/test/dlopen/libafk.c b/test/dlopen/libafk.c new file mode 100644 index 0000000..39b58df --- /dev/null +++ b/test/dlopen/libafk.c @@ -0,0 +1 @@ +/* the actual contents doesnt matter */ diff --git a/test/dlopen/libstatic.c b/test/dlopen/libstatic.c new file mode 100644 index 0000000..bf44c3c --- /dev/null +++ b/test/dlopen/libstatic.c @@ -0,0 +1,15 @@ +#include <stdio.h> + +static int global_static = -1; + +int static_test(void) +{ + static int local_static = -2; + + if (global_static != -1) + printf("FAIL: global_static is not -1\n"); + if (local_static != -2) + printf("FAIL: local_static is not -2\n"); + + return (global_static == -1 && local_static == -2); +} diff --git a/test/dlopen/libtest.c b/test/dlopen/libtest.c new file mode 100644 index 0000000..3fd137f --- /dev/null +++ b/test/dlopen/libtest.c @@ -0,0 +1,11 @@ +#include <stdio.h> +#include <pthread.h> +#include <stdint.h> + +void dltest(uint32_t **value1, uint32_t **value2); +void dltest(uint32_t **value1, uint32_t **value2) +{ + *value1 = (uint32_t *) pthread_once; + *value2 = (uint32_t *) pthread_self; +} + diff --git a/test/dlopen/libtest1.c b/test/dlopen/libtest1.c new file mode 100644 index 0000000..a2f7dcd --- /dev/null +++ b/test/dlopen/libtest1.c @@ -0,0 +1,40 @@ +#include <stdio.h> + +extern int libtest2_func(const char *s); + +void __attribute__((constructor)) libtest1_ctor(void); +void libtest1_ctor(void) +{ + printf("libtest1: constructor!\n"); +} + +void __attribute__((destructor)) libtest1_dtor(void); +void libtest1_dtor(void) +{ + printf("libtest1: destructor!\n"); +} + +void __attribute__((weak)) function1(void); +void function1(void) +{ + printf("libtest1: I am weak function1!\n"); +} + +void function2(void); +void function2(void) +{ + printf("libtest1: I am function2!\n"); +} + +int dltest(const char *s); +int dltest(const char *s) +{ + printf( "libtest1: function1 = %p\n" + "libtest1: function2 = %p\n", + function1, function2); + function1(); + function2(); + return(libtest2_func(s)); +} + + diff --git a/test/dlopen/libtest2.c b/test/dlopen/libtest2.c new file mode 100644 index 0000000..5261506 --- /dev/null +++ b/test/dlopen/libtest2.c @@ -0,0 +1,38 @@ +#include <stdio.h> +#include <pthread.h> + +void __attribute__((constructor)) libtest2_ctor(void); +void libtest2_ctor(void) +{ + printf("libtest2: constructor!\n"); +} + +void __attribute__((destructor)) libtest2_dtor(void); +void libtest2_dtor(void) +{ + printf("libtest2: destructor!\n"); +} + +void function1(void); +void function1(void) +{ + printf("libtest2: I am function1!\n"); +} + +void __attribute__((weak)) function2(void); +void function2(void) +{ + printf("libtest2: I am weak function2!\n"); +} + + +int libtest2_func(const char *s); +int libtest2_func(const char *s) +{ + printf( "libtest2: function1 = %p\n" + "libtest2: function2 = %p\n", + function1, function2); + function1(); + function2(); + return 0; +} diff --git a/test/dlopen/libtest3.c b/test/dlopen/libtest3.c new file mode 100644 index 0000000..1d4bd7e --- /dev/null +++ b/test/dlopen/libtest3.c @@ -0,0 +1 @@ +#include "libtest.c" diff --git a/test/dlopen/libundef.c b/test/dlopen/libundef.c new file mode 100644 index 0000000..39b58df --- /dev/null +++ b/test/dlopen/libundef.c @@ -0,0 +1 @@ +/* the actual contents doesnt matter */ diff --git a/test/dlopen/nodelete.c b/test/dlopen/nodelete.c new file mode 100644 index 0000000..07ff961 --- /dev/null +++ b/test/dlopen/nodelete.c @@ -0,0 +1,205 @@ +#include <dlfcn.h> +#include <setjmp.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> + + +static sigjmp_buf jmpbuf; + + +int fini_ran; + + +static void +__attribute__ ((noreturn)) +handler (int sig) +{ + siglongjmp (jmpbuf, 1); +} + + +#define TEST_FUNCTION do_test () +static int +do_test (void) +{ + /* We are testing the two possibilities to mark an object as not deletable: + - marked on the linker commandline with `-z nodelete' + - with the RTLD_NODELETE flag at dlopen()-time. + + The test we are performing should be safe. We are loading the objects, + get the address of variables in the respective object, unload the object + and then try to read the variable. If the object is unloaded this + should lead to an segmentation fault. */ + void *p; + struct sigaction sa; + + sa.sa_handler = handler; + sigfillset (&sa.sa_mask); + sa.sa_flags = SA_RESTART; + + if (sigaction (SIGSEGV, &sa, NULL) == -1) + puts ("cannot install signal handler: %m"); + + p = dlopen ("nodelmod1.so", RTLD_LAZY); + if (p == NULL) + { + printf ("failed to load \"nodelmod1.so\": %s\n", dlerror ()); + exit (1); + } + else + { + int *varp; + + varp = dlsym (p, "var1"); + if (varp == NULL) + { + puts ("failed to get address of \"var1\" in \"nodelmod1.so\""); + exit (1); + } + else + { + *varp = 20000720; + + /* Now close the object. */ + fini_ran = 0; + if (dlclose (p) != 0) + { + puts ("failed to close \"nodelmod1.so\""); + exit (1); + } + else if (! sigsetjmp (jmpbuf, 1)) + { + /* Access the variable again. */ + if (*varp != 20000720) + { + puts ("\"var1\" value not correct"); + exit (1); + } + else if (fini_ran != 0) + { + puts ("destructor of \"nodelmod1.so\" ran"); + exit (1); + } + else + puts ("-z nodelete test succeeded"); + } + else + { + /* We caught an segmentation fault. */ + puts ("\"nodelmod1.so\" got deleted!"); + exit (1); + } + } + } + + p = dlopen ("nodelmod2.so", RTLD_LAZY | RTLD_NODELETE); + if (p == NULL) + { + printf ("failed to load \"nodelmod2.so\": %s\n", dlerror ()); + exit (1); + } + else + { + int *varp; + + varp = dlsym (p, "var2"); + if (varp == NULL) + { + puts ("failed to get address of \"var2\" in \"nodelmod2.so\""); + exit (1); + } + else + { + *varp = 42; + + /* Now close the object. */ + fini_ran = 0; + if (dlclose (p) != 0) + { + puts ("failed to close \"nodelmod2.so\""); + exit (1); + } + else if (! sigsetjmp (jmpbuf, 1)) + { + /* Access the variable again. */ + if (*varp != 42) + { + puts ("\"var2\" value not correct"); + exit (1); + } + else if (fini_ran != 0) + { + puts ("destructor of \"nodelmod2.so\" ran"); + exit (1); + } + else + puts ("RTLD_NODELETE test succeeded"); + } + else + { + /* We caught an segmentation fault. */ + puts ("\"nodelmod2.so\" got deleted!"); + exit (1); + } + } + } + + p = dlopen ("nodelmod3.so", RTLD_LAZY); + if (p == NULL) + { + printf ("failed to load \"nodelmod3.so\": %s\n", dlerror ()); + exit (1); + } + else + { + int *(*fctp) (void); + + fctp = dlsym (p, "addr"); + if (fctp == NULL) + { + puts ("failed to get address of \"addr\" in \"nodelmod3.so\""); + exit (1); + } + else + { + int *varp = fctp (); + + *varp = -1; + + /* Now close the object. */ + fini_ran = 0; + if (dlclose (p) != 0) + { + puts ("failed to close \"nodelmod3.so\""); + exit (1); + } + else if (! sigsetjmp (jmpbuf, 1)) + { + /* Access the variable again. */ + if (*varp != -1) + { + puts ("\"var_in_mod4\" value not correct"); + exit (1); + } + else if (fini_ran != 0) + { + puts ("destructor of \"nodelmod4.so\" ran"); + exit (1); + } + else + puts ("-z nodelete in dependency succeeded"); + } + else + { + /* We caught an segmentation fault. */ + puts ("\"nodelmod4.so\" got deleted!"); + exit (1); + } + } + } + + return 0; +} + +#include "../test-skeleton.c" diff --git a/test/dlopen/nodelete1.c b/test/dlopen/nodelete1.c new file mode 100644 index 0000000..720e37f --- /dev/null +++ b/test/dlopen/nodelete1.c @@ -0,0 +1,59 @@ +#include <dlfcn.h> +#include <stdio.h> +#include <stdlib.h> + + +int fini_ran; + +#define LIBNAME1 "nodelmod1.so" + +static int +do_test (void) +{ + /* Verify ability to reload RTLD_NODELETE libraries. + */ + void *p; + + p = dlopen (LIBNAME1, RTLD_NOW); + if (p == NULL) + { + printf ("failed to load "LIBNAME1": %s\n", dlerror ()); + exit (1); + } + + if (dlclose (p) != 0) + { + puts ("failed to close "LIBNAME1""); + exit (1); + } + + p = dlopen (LIBNAME1, RTLD_LAZY); + if (p == NULL) + { + printf ("failed to load "LIBNAME1": %s\n", dlerror ()); + exit (1); + } + + if (dlclose (p) != 0) + { + puts ("failed to close "LIBNAME1""); + exit (1); + } + + p = dlopen ("nodelmod2.so", RTLD_LAZY); + if (p == NULL) + { + printf ("failed to load \"nodelmod2.so\": %s\n", dlerror ()); + exit (1); + } + if (dlclose (p) != 0) + { + puts ("failed to close \"nodelmod2.so\""); + exit (1); + } + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/test/dlopen/nodelmod1.c b/test/dlopen/nodelmod1.c new file mode 100644 index 0000000..51be080 --- /dev/null +++ b/test/dlopen/nodelmod1.c @@ -0,0 +1,10 @@ +extern int fini_ran; + +int var1 = 42; + +static void +__attribute__ ((__destructor__)) +destr (void) +{ + fini_ran = 1; +} diff --git a/test/dlopen/nodelmod2.c b/test/dlopen/nodelmod2.c new file mode 100644 index 0000000..ff2ffc2 --- /dev/null +++ b/test/dlopen/nodelmod2.c @@ -0,0 +1,10 @@ +extern int fini_ran; + +int var2 = 100; + +static void +__attribute__ ((__destructor__)) +destr (void) +{ + fini_ran = 1; +} diff --git a/test/dlopen/nodelmod3.c b/test/dlopen/nodelmod3.c new file mode 100644 index 0000000..817c94d --- /dev/null +++ b/test/dlopen/nodelmod3.c @@ -0,0 +1,8 @@ +extern int var_in_mod4; +extern int *addr (void); + +int * +addr (void) +{ + return &var_in_mod4; +} diff --git a/test/dlopen/nodelmod4.c b/test/dlopen/nodelmod4.c new file mode 100644 index 0000000..d7fa893 --- /dev/null +++ b/test/dlopen/nodelmod4.c @@ -0,0 +1,10 @@ +extern int fini_ran; + +int var_in_mod4 = 99; + +static void +__attribute__ ((__destructor__)) +destr (void) +{ + fini_ran = 1; +} diff --git a/test/dlopen/test1.c b/test/dlopen/test1.c new file mode 100644 index 0000000..c13eb30 --- /dev/null +++ b/test/dlopen/test1.c @@ -0,0 +1,33 @@ +#include <fcntl.h> +#include <stdlib.h> +#include <stdio.h> +#include <dlfcn.h> + +#ifdef __UCLIBC__ +extern void _dlinfo(void); +#endif + +int main(int argc, char **argv) { + void *handle; + int (*mydltest)(const char *s); + char *error; + + handle = dlopen ("./libtest1.so", RTLD_LAZY); + if (!handle) { + fprintf(stderr, "Could not open ./libtest1.so: %s\n", dlerror()); + exit(1); + } + + mydltest = dlsym(handle, "dltest"); + if ((error = dlerror()) != NULL) { + fprintf(stderr, "Could not locate symbol 'dltest': %s\n", error); + exit(1); + } + + mydltest("hello world!"); + + dlclose(handle); + + return EXIT_SUCCESS; +} + diff --git a/test/dlopen/test2.c b/test/dlopen/test2.c new file mode 100644 index 0000000..d8428f7 --- /dev/null +++ b/test/dlopen/test2.c @@ -0,0 +1,39 @@ +#include <fcntl.h> +#include <stdlib.h> +#include <stdio.h> +#include <dlfcn.h> + +#ifdef __UCLIBC__ +extern void _dlinfo(void); +#endif + +int main(int argc, char **argv) { + void *handle; + int (*mydltest)(const char *s); + char *error; + + handle = dlopen ("./libtest2.so", RTLD_LAZY); + if (!handle) { + fprintf(stderr, "Could not open ./libtest2.so: %s\n", dlerror()); + exit(1); + } + + handle = dlopen ("./libtest1.so", RTLD_LAZY); + if (!handle) { + fprintf(stderr, "Could not open ./libtest1.so: %s\n", dlerror()); + exit(1); + } + + mydltest = dlsym(handle, "dltest"); + if ((error = dlerror()) != NULL) { + fprintf(stderr, "Could not locate symbol 'dltest': %s\n", error); + exit(1); + } + + mydltest("hello world!"); + + dlclose(handle); + + return EXIT_SUCCESS; +} + diff --git a/test/dlopen/test3.c b/test/dlopen/test3.c new file mode 100644 index 0000000..2f2dfc6 --- /dev/null +++ b/test/dlopen/test3.c @@ -0,0 +1,13 @@ +#include <fcntl.h> +#include <stdlib.h> +#include <stdio.h> +#include <dlfcn.h> + +extern int dltest(const char *s); + +int main(int argc, char **argv) +{ + dltest("hello world!"); + return EXIT_SUCCESS; +} + diff --git a/test/dlopen/testscope.c b/test/dlopen/testscope.c new file mode 100644 index 0000000..90e0798 --- /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; +} diff --git a/test/dlopen/tst-origin.c b/test/dlopen/tst-origin.c new file mode 100644 index 0000000..60fcd3f --- /dev/null +++ b/test/dlopen/tst-origin.c @@ -0,0 +1,37 @@ +#include <fcntl.h> +#include <stdlib.h> +#include <stdio.h> +#include <dlfcn.h> + +#ifdef __UCLIBC__ +extern void _dlinfo(void); +#endif + +int main(int argc, char **argv) { + void *h1, *h2; + int __attribute__((unused))(*mydltest)(const char *s); + char *error; + + h1 = dlopen ("libtest31.so", RTLD_LAZY); + if (!h1) { + fprintf(stderr, "Could not open libtest31.so: %s\n", dlerror()); + exit(1); + } + + h2 = dlopen ("libtest31.so", RTLD_NOLOAD); + if (!h2) { + fprintf(stderr, "Could not open libtest31.so(RTLD_NOLOAD): %s\n", dlerror()); + exit(1); + } + + mydltest = dlsym(h1, "dltest"); + if ((error = dlerror()) != NULL) { + fprintf(stderr, "Could not locate symbol 'dltest': %s\n", error); + exit(1); + } + + dlclose(h2); + dlclose(h1); + + return EXIT_SUCCESS; +} |