summaryrefslogtreecommitdiff
path: root/elf/nodelete.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2000-07-21 00:15:14 +0000
committerUlrich Drepper <drepper@redhat.com>2000-07-21 00:15:14 +0000
commit0fb7851fce038b80be60eae2d66d60f337a60e14 (patch)
treeab7595811bd0e5b1d1c7160629dad013f4f23f8a /elf/nodelete.c
parentbf8b3e74bfdc50935445c324f8dc03025a6f2419 (diff)
Update.
* elf/Makefile (tests): Add $(tests-nodelete-$(have-z-nodelete)). (tests-nodelete-yes): Define. (modules-names): Add $(modules-nodelete-$(have-z-nodelete)). Add rules to build nodelete and modules. * elf/nodelete.c: New file. * elf/nodelmod1.c: New file. * elf/nodelmod2.c: New file. * configure.in: Add test for -z nodelete option. * config.make.in: Define have-z-nodelete with libc_cv_z_nodelete.
Diffstat (limited to 'elf/nodelete.c')
-rw-r--r--elf/nodelete.c140
1 files changed, 140 insertions, 0 deletions
diff --git a/elf/nodelete.c b/elf/nodelete.c
new file mode 100644
index 0000000000..317a2a03e1
--- /dev/null
+++ b/elf/nodelete.c
@@ -0,0 +1,140 @@
+#include <dlfcn.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+
+
+static sigjmp_buf jmpbuf;
+
+
+static void
+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. */
+ int result = 0;
+ void *p;
+ struct sigaction sa;
+
+ sa.sa_handler = handler;
+ sigfillset (&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+ sa.sa_restorer = NULL;
+
+ if (sigaction (SIGSEGV, &sa, NULL) == -1)
+ printf ("cannot install signal handler: %m\n");
+
+ p = dlopen ("nodelmod1.so", RTLD_LAZY);
+ if (p == NULL)
+ {
+ puts ("failed to load \"nodelmod1.so\"");
+ result = 1;
+ }
+ else
+ {
+ int *varp;
+
+ puts ("succeeded loading \"nodelmod1.so\"");
+
+ varp = dlsym (p, "var1");
+ if (varp == NULL)
+ {
+ puts ("failed to get address of \"var1\" in \"nodelmod1.so\"");
+ result = 1;
+ }
+ else
+ {
+ *varp = 20000720;
+
+ /* Now close the object. */
+ if (dlclose (p) != 0)
+ {
+ puts ("failed to close \"nodelmod1.so\"");
+ result = 1;
+ }
+ else if (! sigsetjmp (jmpbuf, 1))
+ {
+ /* Access the variable again. */
+ if (*varp != 20000720)
+ {
+ puts ("\"var1\" value not correct");
+ result = 1;
+ }
+ else
+ puts ("-z nodelete test succeeded");
+ }
+ else
+ {
+ /* We caught an segmentation fault. */
+ puts ("\"nodelmod1.so\" got deleted");
+ result = 1;
+ }
+ }
+ }
+
+ p = dlopen ("nodelmod2.so", RTLD_LAZY | RTLD_NODELETE);
+ if (p == NULL)
+ {
+ puts ("failed to load \"nodelmod2.so\"");
+ result = 1;
+ }
+ else
+ {
+ int *varp;
+
+ puts ("succeeded loading \"nodelmod2.so\"");
+
+ varp = dlsym (p, "var2");
+ if (varp == NULL)
+ {
+ puts ("failed to get address of \"var2\" in \"nodelmod2.so\"");
+ result = 1;
+ }
+ else
+ {
+ *varp = 42;
+
+ /* Now close the object. */
+ if (dlclose (p) != 0)
+ {
+ puts ("failed to close \"nodelmod2.so\"");
+ result = 1;
+ }
+ else if (! sigsetjmp (jmpbuf, 1))
+ {
+ /* Access the variable again. */
+ if (*varp != 42)
+ {
+ puts ("\"var2\" value not correct");
+ result = 1;
+ }
+ else
+ puts ("RTLD_NODELETE test succeeded");
+ }
+ else
+ {
+ /* We caught an segmentation fault. */
+ puts ("\"nodelmod2.so\" got deleted");
+ result = 1;
+ }
+ }
+ }
+
+ return result;
+}
+
+#include "../test-skeleton.c"