]> git.ipfire.org Git - thirdparty/glibc.git/blame - elf/nodelete.c
install.texi: Build was tested with binutils 2.41 (just released)
[thirdparty/glibc.git] / elf / nodelete.c
CommitLineData
0fb7851f
UD
1#include <dlfcn.h>
2#include <setjmp.h>
3#include <signal.h>
4#include <stdio.h>
5
6
7static sigjmp_buf jmpbuf;
8
9
ad7534c8
UD
10int fini_ran;
11
12
0fb7851f 13static void
a850e77f 14__attribute__ ((noreturn))
0fb7851f
UD
15handler (int sig)
16{
17 siglongjmp (jmpbuf, 1);
18}
19
20
0fb7851f
UD
21static int
22do_test (void)
23{
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.
27
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;
35
36 sa.sa_handler = handler;
37 sigfillset (&sa.sa_mask);
38 sa.sa_flags = SA_RESTART;
0fb7851f
UD
39
40 if (sigaction (SIGSEGV, &sa, NULL) == -1)
41 printf ("cannot install signal handler: %m\n");
42
43 p = dlopen ("nodelmod1.so", RTLD_LAZY);
44 if (p == NULL)
45 {
2cb8cefb 46 printf ("failed to load \"nodelmod1.so\": %s\n", dlerror ());
0fb7851f
UD
47 result = 1;
48 }
49 else
50 {
51 int *varp;
52
53 puts ("succeeded loading \"nodelmod1.so\"");
54
55 varp = dlsym (p, "var1");
56 if (varp == NULL)
57 {
58 puts ("failed to get address of \"var1\" in \"nodelmod1.so\"");
59 result = 1;
60 }
61 else
62 {
63 *varp = 20000720;
64
65 /* Now close the object. */
ad7534c8 66 fini_ran = 0;
0fb7851f
UD
67 if (dlclose (p) != 0)
68 {
69 puts ("failed to close \"nodelmod1.so\"");
70 result = 1;
71 }
72 else if (! sigsetjmp (jmpbuf, 1))
73 {
74 /* Access the variable again. */
75 if (*varp != 20000720)
76 {
77 puts ("\"var1\" value not correct");
78 result = 1;
79 }
ad7534c8
UD
80 else if (fini_ran != 0)
81 {
82 puts ("destructor of \"nodelmod1.so\" ran");
83 result = 1;
84 }
0fb7851f
UD
85 else
86 puts ("-z nodelete test succeeded");
87 }
88 else
89 {
90 /* We caught an segmentation fault. */
91 puts ("\"nodelmod1.so\" got deleted");
92 result = 1;
93 }
94 }
95 }
96
97 p = dlopen ("nodelmod2.so", RTLD_LAZY | RTLD_NODELETE);
98 if (p == NULL)
99 {
2cb8cefb 100 printf ("failed to load \"nodelmod2.so\": %s\n", dlerror ());
0fb7851f
UD
101 result = 1;
102 }
103 else
104 {
105 int *varp;
106
107 puts ("succeeded loading \"nodelmod2.so\"");
108
109 varp = dlsym (p, "var2");
110 if (varp == NULL)
111 {
112 puts ("failed to get address of \"var2\" in \"nodelmod2.so\"");
113 result = 1;
114 }
115 else
116 {
117 *varp = 42;
118
119 /* Now close the object. */
ad7534c8 120 fini_ran = 0;
0fb7851f
UD
121 if (dlclose (p) != 0)
122 {
123 puts ("failed to close \"nodelmod2.so\"");
124 result = 1;
125 }
126 else if (! sigsetjmp (jmpbuf, 1))
127 {
128 /* Access the variable again. */
129 if (*varp != 42)
130 {
131 puts ("\"var2\" value not correct");
132 result = 1;
133 }
ad7534c8
UD
134 else if (fini_ran != 0)
135 {
136 puts ("destructor of \"nodelmod2.so\" ran");
137 result = 1;
138 }
0fb7851f
UD
139 else
140 puts ("RTLD_NODELETE test succeeded");
141 }
142 else
143 {
144 /* We caught an segmentation fault. */
145 puts ("\"nodelmod2.so\" got deleted");
146 result = 1;
147 }
148 }
149 }
150
2cb8cefb
UD
151 p = dlopen ("nodelmod3.so", RTLD_LAZY);
152 if (p == NULL)
153 {
154 printf ("failed to load \"nodelmod3.so\": %s\n", dlerror ());
155 result = 1;
156 }
157 else
158 {
159 int *(*fctp) (void);
160
161 puts ("succeeded loading \"nodelmod3.so\"");
162
163 fctp = dlsym (p, "addr");
164 if (fctp == NULL)
165 {
166 puts ("failed to get address of \"addr\" in \"nodelmod3.so\"");
167 result = 1;
168 }
169 else
170 {
171 int *varp = fctp ();
172
173 *varp = -1;
174
175 /* Now close the object. */
ad7534c8 176 fini_ran = 0;
2cb8cefb
UD
177 if (dlclose (p) != 0)
178 {
179 puts ("failed to close \"nodelmod3.so\"");
180 result = 1;
181 }
182 else if (! sigsetjmp (jmpbuf, 1))
183 {
184 /* Access the variable again. */
185 if (*varp != -1)
186 {
187 puts ("\"var_in_mod4\" value not correct");
188 result = 1;
189 }
ad7534c8
UD
190 else if (fini_ran != 0)
191 {
192 puts ("destructor of \"nodelmod4.so\" ran");
193 result = 1;
194 }
2cb8cefb
UD
195 else
196 puts ("-z nodelete in dependency succeeded");
197 }
198 else
199 {
200 /* We caught an segmentation fault. */
201 puts ("\"nodelmod4.so\" got deleted");
202 result = 1;
203 }
204 }
205 }
206
0fb7851f
UD
207 return result;
208}
209
36fe25fd 210#include <support/test-driver.c>