tst-tls16 tst-tls17 tst-tls18 tst-tls19 tst-tls-dlinfo \
tst-align tst-align2 $(tests-execstack-$(have-z-execstack)) \
tst-dlmodcount tst-dlopenrpath tst-deep1 \
+ tst-dlopen-offset \
tst-dlmopen1 tst-dlmopen3 \
unload3 unload4 unload5 unload6 unload7 unload8 tst-global1 order2 \
tst-audit1 tst-audit2 tst-audit8 tst-audit9 \
tst-audit12mod1 tst-audit12mod2 tst-audit12mod3 tst-auditmod12 \
tst-latepthreadmod $(tst-tls-many-dynamic-modules) \
tst-nodelete-dlclose-dso tst-nodelete-dlclose-plugin \
+ tst-dlopen-offset-mod1 tst-dlopen-offset-mod2 tst-dlopen-offset-mod3 \
tst-main1mod tst-libc_dlvsym-dso
ifeq (yes,$(have-mtls-dialect-gnu2))
tests += tst-gnu2-tls1
tst-libc_dlvsym-static-ENV = \
LD_LIBRARY_PATH=$(objpfx):$(common-objpfx):$(common-objpfx)dlfcn
$(objpfx)tst-libc_dlvsym-static.out: $(objpfx)tst-libc_dlvsym-dso.so
+
+$(objpfx)tst-dlopen-offset: $(libdl)
+$(objpfx)tst-dlopen-offset.out: $(objpfx)tst-dlopen-offset-comb.so
+$(objpfx)tst-dlopen-offset-comb.so: $(objpfx)tst-dlopen-offset-mod1.so $(objpfx)tst-dlopen-offset-mod2.so $(objpfx)tst-dlopen-offset-mod3.so
+ dd if=$(objpfx)tst-dlopen-offset-mod1.so of=$(objpfx)tst-dlopen-offset-comb.so bs=1024 seek=64
+ dd if=$(objpfx)tst-dlopen-offset-mod2.so of=$(objpfx)tst-dlopen-offset-comb.so bs=1024 seek=128
+ dd if=$(objpfx)tst-dlopen-offset-mod3.so of=$(objpfx)tst-dlopen-offset-comb.so bs=1024 seek=192
--- /dev/null
+#include <dlfcn.h>
+#include <stdio.h>
+
+/* These numbers need to be coordinated with the offsets passed to make the combined .so. */
+int offa = 64;
+int offb = 128;
+int offc = 192;
+
+int
+do_test (void)
+{
+ void *p1 = __google_dlopen_with_offset ("$ORIGIN/tst-dlopen-offset-comb.so", offa * 1024, RTLD_LAZY);
+
+ if (!p1)
+ {
+ puts (dlerror ());
+ return 1;
+ }
+
+ int (*f) (void) = dlsym (p1, "foo");
+ if (f)
+ {
+ (*f)();
+ }
+ else
+ {
+ puts (dlerror ());
+ return 1;
+ }
+
+ void *p2 = __google_dlopen_with_offset ("$ORIGIN/tst-dlopen-offset-comb.so", offb * 1024, RTLD_LAZY);
+
+ int (*bar) (void) = dlsym (p2, "bar");
+ if (bar)
+ {
+ (*bar)();
+ }
+ else
+ {
+ puts (dlerror ());
+ return 1;
+ }
+
+ void *p3 = __google_dlopen_with_offset ("$ORIGIN/tst-dlopen-offset-comb.so", offc * 1024, RTLD_LAZY);
+
+ int (*xyzzy) (void) = dlsym (p3, "xyzzy");
+ if (xyzzy)
+ {
+ (*xyzzy)();
+ }
+ else
+ {
+ puts (dlerror ());
+ return 1;
+ }
+
+ if (p1)
+ dlclose (p1);
+
+ p1 = __google_dlopen_with_offset ("$ORIGIN/tst-dlopen-offset-comb.so", offa * 1024, RTLD_LAZY);
+
+ f = dlsym (p1, "someothersym");
+ if (!f)
+ {
+ puts (dlerror ());
+ puts (" (expected)");
+ }
+ else
+ {
+ puts ("Symbol found unexpectedly");
+ return 1;
+ }
+
+ f = dlsym (p1, "xyzzy");
+ if (!f)
+ {
+ puts (dlerror ());
+ puts (" (expected)");
+ }
+ else
+ {
+ puts ("Symbol found unexpectedly");
+ return 1;
+ }
+
+ p1 = __google_dlopen_with_offset ("$ORIGIN/tst-dlopen-offset-comb.so", offa * 1024, RTLD_LAZY);
+
+ f = dlsym (p1, "foo");
+ if (f)
+ {
+ (*f)();
+ }
+ else
+ {
+ puts (dlerror ());
+ return 1;
+ }
+
+ void *px = __google_dlopen_with_offset ("$ORIGIN/tst-dlopen-offset-comb.so", 0, RTLD_LAZY);
+
+ if (!px)
+ {
+ puts (dlerror ());
+ puts (" (expected)");
+ }
+ else
+ {
+ puts ("dlopen_with_offset succeeded unexpectedly");
+ return 1;
+ }
+
+ px = __google_dlopen_with_offset ("$ORIGIN/tst-dlopen-offset-mod1.so", 0, RTLD_LAZY);
+
+ f = dlsym (px, "foo");
+ if (f)
+ {
+ (*f)();
+ }
+ else
+ {
+ puts (dlerror ());
+ return 1;
+ }
+
+ px = __google_dlopen_with_offset ("$ORIGIN/nonexistent.so", 0, RTLD_LAZY);
+
+ if (!px)
+ {
+ puts (dlerror ());
+ puts (" (expected)");
+ }
+ else
+ {
+ puts ("dlopen_with_offset succeeded unexpectedly");
+ return 1;
+ }
+
+ return 0;
+}
+
+#define TIMEOUT 100
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"