2004-12-07 Roland McGrath <roland@redhat.com>
[glibc.git] / elf / nodelete.c
blob78364a278a688a49f5fd0b5ce58854bfc8cb19d1
1 #include <dlfcn.h>
2 #include <setjmp.h>
3 #include <signal.h>
4 #include <stdio.h>
7 static sigjmp_buf jmpbuf;
10 int fini_ran;
13 static void
14 __attribute__ ((noreturn))
15 handler (int sig)
17 siglongjmp (jmpbuf, 1);
21 #define TEST_FUNCTION do_test ()
22 static int
23 do_test (void)
25 /* We are testing the two possibilities to mark an object as not deletable:
26 - marked on the linker commandline with `-z nodelete'
27 - with the RTLD_NODELETE flag at dlopen()-time.
29 The test we are performing should be safe. We are loading the objects,
30 get the address of variables in the respective object, unload the object
31 and then try to read the variable. If the object is unloaded this
32 should lead to an segmentation fault. */
33 int result = 0;
34 void *p;
35 struct sigaction sa;
37 sa.sa_handler = handler;
38 sigfillset (&sa.sa_mask);
39 sa.sa_flags = SA_RESTART;
41 if (sigaction (SIGSEGV, &sa, NULL) == -1)
42 printf ("cannot install signal handler: %m\n");
44 p = dlopen ("nodelmod1.so", RTLD_LAZY);
45 if (p == NULL)
47 printf ("failed to load \"nodelmod1.so\": %s\n", dlerror ());
48 result = 1;
50 else
52 int *varp;
54 puts ("succeeded loading \"nodelmod1.so\"");
56 varp = dlsym (p, "var1");
57 if (varp == NULL)
59 puts ("failed to get address of \"var1\" in \"nodelmod1.so\"");
60 result = 1;
62 else
64 *varp = 20000720;
66 /* Now close the object. */
67 fini_ran = 0;
68 if (dlclose (p) != 0)
70 puts ("failed to close \"nodelmod1.so\"");
71 result = 1;
73 else if (! sigsetjmp (jmpbuf, 1))
75 /* Access the variable again. */
76 if (*varp != 20000720)
78 puts ("\"var1\" value not correct");
79 result = 1;
81 else if (fini_ran != 0)
83 puts ("destructor of \"nodelmod1.so\" ran");
84 result = 1;
86 else
87 puts ("-z nodelete test succeeded");
89 else
91 /* We caught an segmentation fault. */
92 puts ("\"nodelmod1.so\" got deleted");
93 result = 1;
98 p = dlopen ("nodelmod2.so", RTLD_LAZY | RTLD_NODELETE);
99 if (p == NULL)
101 printf ("failed to load \"nodelmod2.so\": %s\n", dlerror ());
102 result = 1;
104 else
106 int *varp;
108 puts ("succeeded loading \"nodelmod2.so\"");
110 varp = dlsym (p, "var2");
111 if (varp == NULL)
113 puts ("failed to get address of \"var2\" in \"nodelmod2.so\"");
114 result = 1;
116 else
118 *varp = 42;
120 /* Now close the object. */
121 fini_ran = 0;
122 if (dlclose (p) != 0)
124 puts ("failed to close \"nodelmod2.so\"");
125 result = 1;
127 else if (! sigsetjmp (jmpbuf, 1))
129 /* Access the variable again. */
130 if (*varp != 42)
132 puts ("\"var2\" value not correct");
133 result = 1;
135 else if (fini_ran != 0)
137 puts ("destructor of \"nodelmod2.so\" ran");
138 result = 1;
140 else
141 puts ("RTLD_NODELETE test succeeded");
143 else
145 /* We caught an segmentation fault. */
146 puts ("\"nodelmod2.so\" got deleted");
147 result = 1;
152 p = dlopen ("nodelmod3.so", RTLD_LAZY);
153 if (p == NULL)
155 printf ("failed to load \"nodelmod3.so\": %s\n", dlerror ());
156 result = 1;
158 else
160 int *(*fctp) (void);
162 puts ("succeeded loading \"nodelmod3.so\"");
164 fctp = dlsym (p, "addr");
165 if (fctp == NULL)
167 puts ("failed to get address of \"addr\" in \"nodelmod3.so\"");
168 result = 1;
170 else
172 int *varp = fctp ();
174 *varp = -1;
176 /* Now close the object. */
177 fini_ran = 0;
178 if (dlclose (p) != 0)
180 puts ("failed to close \"nodelmod3.so\"");
181 result = 1;
183 else if (! sigsetjmp (jmpbuf, 1))
185 /* Access the variable again. */
186 if (*varp != -1)
188 puts ("\"var_in_mod4\" value not correct");
189 result = 1;
191 else if (fini_ran != 0)
193 puts ("destructor of \"nodelmod4.so\" ran");
194 result = 1;
196 else
197 puts ("-z nodelete in dependency succeeded");
199 else
201 /* We caught an segmentation fault. */
202 puts ("\"nodelmod4.so\" got deleted");
203 result = 1;
208 return result;
211 #include "../test-skeleton.c"