gshadow: Matching sgetsgent, sgetsgent_r ERANGE handling (bug 30151)
[glibc.git] / elf / nodelete.c
blobc8d71152f2ff2f28cb967ffdb4af4d2c4abc5569
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 static int
22 do_test (void)
24 /* We are testing the two possibilities to mark an object as not deletable:
25 - marked on the linker commandline with `-z nodelete'
26 - with the RTLD_NODELETE flag at dlopen()-time.
28 The test we are performing should be safe. We are loading the objects,
29 get the address of variables in the respective object, unload the object
30 and then try to read the variable. If the object is unloaded this
31 should lead to an segmentation fault. */
32 int result = 0;
33 void *p;
34 struct sigaction sa;
36 sa.sa_handler = handler;
37 sigfillset (&sa.sa_mask);
38 sa.sa_flags = SA_RESTART;
40 if (sigaction (SIGSEGV, &sa, NULL) == -1)
41 printf ("cannot install signal handler: %m\n");
43 p = dlopen ("nodelmod1.so", RTLD_LAZY);
44 if (p == NULL)
46 printf ("failed to load \"nodelmod1.so\": %s\n", dlerror ());
47 result = 1;
49 else
51 int *varp;
53 puts ("succeeded loading \"nodelmod1.so\"");
55 varp = dlsym (p, "var1");
56 if (varp == NULL)
58 puts ("failed to get address of \"var1\" in \"nodelmod1.so\"");
59 result = 1;
61 else
63 *varp = 20000720;
65 /* Now close the object. */
66 fini_ran = 0;
67 if (dlclose (p) != 0)
69 puts ("failed to close \"nodelmod1.so\"");
70 result = 1;
72 else if (! sigsetjmp (jmpbuf, 1))
74 /* Access the variable again. */
75 if (*varp != 20000720)
77 puts ("\"var1\" value not correct");
78 result = 1;
80 else if (fini_ran != 0)
82 puts ("destructor of \"nodelmod1.so\" ran");
83 result = 1;
85 else
86 puts ("-z nodelete test succeeded");
88 else
90 /* We caught an segmentation fault. */
91 puts ("\"nodelmod1.so\" got deleted");
92 result = 1;
97 p = dlopen ("nodelmod2.so", RTLD_LAZY | RTLD_NODELETE);
98 if (p == NULL)
100 printf ("failed to load \"nodelmod2.so\": %s\n", dlerror ());
101 result = 1;
103 else
105 int *varp;
107 puts ("succeeded loading \"nodelmod2.so\"");
109 varp = dlsym (p, "var2");
110 if (varp == NULL)
112 puts ("failed to get address of \"var2\" in \"nodelmod2.so\"");
113 result = 1;
115 else
117 *varp = 42;
119 /* Now close the object. */
120 fini_ran = 0;
121 if (dlclose (p) != 0)
123 puts ("failed to close \"nodelmod2.so\"");
124 result = 1;
126 else if (! sigsetjmp (jmpbuf, 1))
128 /* Access the variable again. */
129 if (*varp != 42)
131 puts ("\"var2\" value not correct");
132 result = 1;
134 else if (fini_ran != 0)
136 puts ("destructor of \"nodelmod2.so\" ran");
137 result = 1;
139 else
140 puts ("RTLD_NODELETE test succeeded");
142 else
144 /* We caught an segmentation fault. */
145 puts ("\"nodelmod2.so\" got deleted");
146 result = 1;
151 p = dlopen ("nodelmod3.so", RTLD_LAZY);
152 if (p == NULL)
154 printf ("failed to load \"nodelmod3.so\": %s\n", dlerror ());
155 result = 1;
157 else
159 int *(*fctp) (void);
161 puts ("succeeded loading \"nodelmod3.so\"");
163 fctp = dlsym (p, "addr");
164 if (fctp == NULL)
166 puts ("failed to get address of \"addr\" in \"nodelmod3.so\"");
167 result = 1;
169 else
171 int *varp = fctp ();
173 *varp = -1;
175 /* Now close the object. */
176 fini_ran = 0;
177 if (dlclose (p) != 0)
179 puts ("failed to close \"nodelmod3.so\"");
180 result = 1;
182 else if (! sigsetjmp (jmpbuf, 1))
184 /* Access the variable again. */
185 if (*varp != -1)
187 puts ("\"var_in_mod4\" value not correct");
188 result = 1;
190 else if (fini_ran != 0)
192 puts ("destructor of \"nodelmod4.so\" ran");
193 result = 1;
195 else
196 puts ("-z nodelete in dependency succeeded");
198 else
200 /* We caught an segmentation fault. */
201 puts ("\"nodelmod4.so\" got deleted");
202 result = 1;
207 return result;
210 #include <support/test-driver.c>