t_tls_extern.c revision 1.15 1 1.15 riastrad /* $NetBSD: t_tls_extern.c,v 1.15 2024/07/22 23:18:30 riastradh Exp $ */
2 1.1 riastrad
3 1.1 riastrad /*-
4 1.1 riastrad * Copyright (c) 2023 The NetBSD Foundation, Inc.
5 1.1 riastrad * All rights reserved.
6 1.1 riastrad *
7 1.1 riastrad * Redistribution and use in source and binary forms, with or without
8 1.1 riastrad * modification, are permitted provided that the following conditions
9 1.1 riastrad * are met:
10 1.1 riastrad * 1. Redistributions of source code must retain the above copyright
11 1.1 riastrad * notice, this list of conditions and the following disclaimer.
12 1.1 riastrad * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 riastrad * notice, this list of conditions and the following disclaimer in the
14 1.1 riastrad * documentation and/or other materials provided with the distribution.
15 1.1 riastrad *
16 1.1 riastrad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 1.1 riastrad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 1.1 riastrad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 1.1 riastrad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 1.1 riastrad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 1.1 riastrad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 1.1 riastrad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 1.1 riastrad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 1.1 riastrad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 1.1 riastrad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 1.1 riastrad * POSSIBILITY OF SUCH DAMAGE.
27 1.1 riastrad */
28 1.1 riastrad
29 1.1 riastrad #include <sys/types.h>
30 1.1 riastrad
31 1.1 riastrad #include <atf-c.h>
32 1.1 riastrad #include <dlfcn.h>
33 1.15 riastrad #include <signal.h>
34 1.1 riastrad
35 1.14 kre #define ATF_REQUIRE_DL(x) ATF_REQUIRE_MSG((x) != 0, "%s: %s", #x, dlerror())
36 1.1 riastrad
37 1.5 riastrad enum order {
38 1.8 riastrad DEF_USE_EAGER,
39 1.8 riastrad DEF_USE_LAZY,
40 1.5 riastrad USE_DEF,
41 1.5 riastrad USE_DEF_NOLOAD,
42 1.5 riastrad };
43 1.5 riastrad
44 1.5 riastrad static void
45 1.12 joerg tls_extern(const char *libdef, const char *libuse, enum order order)
46 1.4 riastrad {
47 1.4 riastrad void *def, *use;
48 1.4 riastrad int *(*fdef)(void), *(*fuse)(void);
49 1.4 riastrad int *pdef, *puse;
50 1.4 riastrad
51 1.4 riastrad (void)dlerror();
52 1.4 riastrad
53 1.5 riastrad switch (order) {
54 1.8 riastrad case DEF_USE_EAGER:
55 1.5 riastrad ATF_REQUIRE_DL(def = dlopen(libdef, 0));
56 1.8 riastrad ATF_REQUIRE_DL(fdef = dlsym(def, "fdef"));
57 1.8 riastrad pdef = (*fdef)();
58 1.5 riastrad ATF_REQUIRE_DL(use = dlopen(libuse, 0));
59 1.8 riastrad ATF_REQUIRE_DL(fuse = dlsym(use, "fuse"));
60 1.8 riastrad puse = (*fuse)();
61 1.5 riastrad break;
62 1.8 riastrad case DEF_USE_LAZY:
63 1.8 riastrad ATF_REQUIRE_DL(def = dlopen(libdef, 0));
64 1.8 riastrad ATF_REQUIRE_DL(use = dlopen(libuse, 0));
65 1.8 riastrad goto lazy;
66 1.5 riastrad case USE_DEF:
67 1.5 riastrad ATF_REQUIRE_DL(use = dlopen(libuse, 0));
68 1.5 riastrad ATF_REQUIRE_DL(def = dlopen(libdef, 0));
69 1.8 riastrad goto lazy;
70 1.5 riastrad case USE_DEF_NOLOAD:
71 1.5 riastrad ATF_REQUIRE_DL(use = dlopen(libuse, 0));
72 1.5 riastrad ATF_REQUIRE_DL(def = dlopen(libdef, RTLD_NOLOAD));
73 1.8 riastrad lazy: ATF_REQUIRE_DL(fdef = dlsym(def, "fdef"));
74 1.8 riastrad ATF_REQUIRE_DL(fuse = dlsym(use, "fuse"));
75 1.8 riastrad pdef = (*fdef)();
76 1.8 riastrad puse = (*fuse)();
77 1.5 riastrad break;
78 1.5 riastrad }
79 1.4 riastrad
80 1.4 riastrad ATF_CHECK_EQ_MSG(pdef, puse,
81 1.4 riastrad "%p in defining library != %p in using library",
82 1.4 riastrad pdef, puse);
83 1.4 riastrad }
84 1.4 riastrad
85 1.7 riastrad ATF_TC(dynamic_abusedef);
86 1.7 riastrad ATF_TC_HEAD(dynamic_abusedef, tc)
87 1.6 riastrad {
88 1.6 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
89 1.6 riastrad " loading static use than dynamic def");
90 1.6 riastrad }
91 1.7 riastrad ATF_TC_BODY(dynamic_abusedef, tc)
92 1.6 riastrad {
93 1.12 joerg tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so", USE_DEF);
94 1.6 riastrad }
95 1.6 riastrad
96 1.7 riastrad ATF_TC(dynamic_abusedefnoload);
97 1.7 riastrad ATF_TC_HEAD(dynamic_abusedefnoload, tc)
98 1.6 riastrad {
99 1.6 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
100 1.6 riastrad " loading static use then dynamic def with RTLD_NOLOAD");
101 1.6 riastrad }
102 1.7 riastrad ATF_TC_BODY(dynamic_abusedefnoload, tc)
103 1.6 riastrad {
104 1.6 riastrad tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so",
105 1.12 joerg USE_DEF_NOLOAD);
106 1.6 riastrad }
107 1.6 riastrad
108 1.8 riastrad ATF_TC(dynamic_defabuse_eager);
109 1.8 riastrad ATF_TC_HEAD(dynamic_defabuse_eager, tc)
110 1.8 riastrad {
111 1.9 riastrad atf_tc_set_md_var(tc, "descr", "dlopen refuses extern __thread for TLS,"
112 1.8 riastrad " loading dynamic def then static use eagerly");
113 1.8 riastrad }
114 1.8 riastrad ATF_TC_BODY(dynamic_defabuse_eager, tc)
115 1.8 riastrad {
116 1.9 riastrad void *def;
117 1.9 riastrad int *(*fdef)(void);
118 1.9 riastrad
119 1.9 riastrad ATF_REQUIRE_DL(def = dlopen("libh_def_dynamic.so", 0));
120 1.9 riastrad ATF_REQUIRE_DL(fdef = dlsym(def, "fdef"));
121 1.9 riastrad (void)(*fdef)();
122 1.9 riastrad ATF_CHECK_EQ_MSG(NULL, dlopen("libh_abuse_dynamic.so", 0),
123 1.9 riastrad "dlopen failed to detect static-then-dynamic abuse");
124 1.8 riastrad }
125 1.8 riastrad
126 1.8 riastrad ATF_TC(dynamic_defabuse_lazy);
127 1.8 riastrad ATF_TC_HEAD(dynamic_defabuse_lazy, tc)
128 1.6 riastrad {
129 1.6 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
130 1.8 riastrad " loading dynamic def then static use lazily");
131 1.6 riastrad }
132 1.8 riastrad ATF_TC_BODY(dynamic_defabuse_lazy, tc)
133 1.6 riastrad {
134 1.6 riastrad tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so",
135 1.12 joerg DEF_USE_LAZY);
136 1.8 riastrad }
137 1.8 riastrad
138 1.8 riastrad ATF_TC(dynamic_defuse_eager);
139 1.8 riastrad ATF_TC_HEAD(dynamic_defuse_eager, tc)
140 1.8 riastrad {
141 1.8 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for dynamic TLS works,"
142 1.8 riastrad " loading def then use eagerly");
143 1.8 riastrad }
144 1.8 riastrad ATF_TC_BODY(dynamic_defuse_eager, tc)
145 1.8 riastrad {
146 1.8 riastrad tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so",
147 1.12 joerg DEF_USE_EAGER);
148 1.6 riastrad }
149 1.6 riastrad
150 1.8 riastrad ATF_TC(dynamic_defuse_lazy);
151 1.8 riastrad ATF_TC_HEAD(dynamic_defuse_lazy, tc)
152 1.5 riastrad {
153 1.5 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for dynamic TLS works,"
154 1.8 riastrad " loading def then use lazyly");
155 1.5 riastrad }
156 1.8 riastrad ATF_TC_BODY(dynamic_defuse_lazy, tc)
157 1.5 riastrad {
158 1.5 riastrad tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so",
159 1.12 joerg DEF_USE_LAZY);
160 1.5 riastrad }
161 1.5 riastrad
162 1.7 riastrad ATF_TC(dynamic_usedef);
163 1.7 riastrad ATF_TC_HEAD(dynamic_usedef, tc)
164 1.4 riastrad {
165 1.4 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for dynamic TLS works,"
166 1.4 riastrad " loading use then def");
167 1.4 riastrad }
168 1.7 riastrad ATF_TC_BODY(dynamic_usedef, tc)
169 1.4 riastrad {
170 1.5 riastrad tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so",
171 1.12 joerg USE_DEF);
172 1.4 riastrad }
173 1.4 riastrad
174 1.7 riastrad ATF_TC(dynamic_usedefnoload);
175 1.7 riastrad ATF_TC_HEAD(dynamic_usedefnoload, tc)
176 1.4 riastrad {
177 1.4 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for dynamic TLS works,"
178 1.4 riastrad " loading use then def with RTLD_NOLOAD");
179 1.4 riastrad }
180 1.7 riastrad ATF_TC_BODY(dynamic_usedefnoload, tc)
181 1.4 riastrad {
182 1.5 riastrad tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so",
183 1.12 joerg USE_DEF_NOLOAD);
184 1.4 riastrad }
185 1.4 riastrad
186 1.7 riastrad ATF_TC(static_abusedef);
187 1.7 riastrad ATF_TC_HEAD(static_abusedef, tc)
188 1.6 riastrad {
189 1.6 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
190 1.6 riastrad " loading dynamic use then static def");
191 1.6 riastrad }
192 1.7 riastrad ATF_TC_BODY(static_abusedef, tc)
193 1.6 riastrad {
194 1.12 joerg tls_extern("libh_def_static.so", "libh_abuse_static.so", USE_DEF);
195 1.6 riastrad }
196 1.6 riastrad
197 1.7 riastrad ATF_TC(static_abusedefnoload);
198 1.7 riastrad ATF_TC_HEAD(static_abusedefnoload, tc)
199 1.6 riastrad {
200 1.6 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
201 1.6 riastrad " loading dynamic use then static def with RTLD_NOLOAD");
202 1.6 riastrad }
203 1.7 riastrad ATF_TC_BODY(static_abusedefnoload, tc)
204 1.6 riastrad {
205 1.6 riastrad tls_extern("libh_def_static.so", "libh_abuse_static.so",
206 1.12 joerg USE_DEF_NOLOAD);
207 1.6 riastrad }
208 1.6 riastrad
209 1.8 riastrad ATF_TC(static_defabuse_eager);
210 1.8 riastrad ATF_TC_HEAD(static_defabuse_eager, tc)
211 1.8 riastrad {
212 1.8 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
213 1.8 riastrad " loading static def then dynamic use eagerly");
214 1.8 riastrad }
215 1.8 riastrad ATF_TC_BODY(static_defabuse_eager, tc)
216 1.8 riastrad {
217 1.8 riastrad tls_extern("libh_def_static.so", "libh_abuse_static.so",
218 1.12 joerg DEF_USE_EAGER);
219 1.8 riastrad }
220 1.8 riastrad
221 1.8 riastrad ATF_TC(static_defabuse_lazy);
222 1.8 riastrad ATF_TC_HEAD(static_defabuse_lazy, tc)
223 1.6 riastrad {
224 1.6 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
225 1.8 riastrad " loading static def then dynamic use lazyly");
226 1.6 riastrad }
227 1.8 riastrad ATF_TC_BODY(static_defabuse_lazy, tc)
228 1.6 riastrad {
229 1.6 riastrad tls_extern("libh_def_static.so", "libh_abuse_static.so",
230 1.12 joerg DEF_USE_LAZY);
231 1.8 riastrad }
232 1.8 riastrad
233 1.8 riastrad ATF_TC(static_defuse_eager);
234 1.8 riastrad ATF_TC_HEAD(static_defuse_eager, tc)
235 1.8 riastrad {
236 1.8 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for static TLS works,"
237 1.8 riastrad " loading def then use eagerly");
238 1.8 riastrad }
239 1.8 riastrad ATF_TC_BODY(static_defuse_eager, tc)
240 1.8 riastrad {
241 1.8 riastrad tls_extern("libh_def_static.so", "libh_use_static.so",
242 1.12 joerg DEF_USE_EAGER);
243 1.6 riastrad }
244 1.6 riastrad
245 1.8 riastrad ATF_TC(static_defuse_lazy);
246 1.8 riastrad ATF_TC_HEAD(static_defuse_lazy, tc)
247 1.1 riastrad {
248 1.3 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for static TLS works,"
249 1.8 riastrad " loading def then use lazyly");
250 1.1 riastrad }
251 1.8 riastrad ATF_TC_BODY(static_defuse_lazy, tc)
252 1.1 riastrad {
253 1.5 riastrad tls_extern("libh_def_static.so", "libh_use_static.so",
254 1.12 joerg DEF_USE_LAZY);
255 1.3 riastrad }
256 1.3 riastrad
257 1.7 riastrad ATF_TC(static_usedef);
258 1.7 riastrad ATF_TC_HEAD(static_usedef, tc)
259 1.3 riastrad {
260 1.3 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for static TLS works,"
261 1.3 riastrad " loading use then def");
262 1.3 riastrad }
263 1.7 riastrad ATF_TC_BODY(static_usedef, tc)
264 1.3 riastrad {
265 1.5 riastrad tls_extern("libh_def_static.so", "libh_use_static.so",
266 1.12 joerg USE_DEF);
267 1.3 riastrad }
268 1.3 riastrad
269 1.7 riastrad ATF_TC(static_usedefnoload);
270 1.7 riastrad ATF_TC_HEAD(static_usedefnoload, tc)
271 1.3 riastrad {
272 1.3 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for static TLS works,"
273 1.3 riastrad " loading use then def with RTLD_NOLOAD");
274 1.3 riastrad }
275 1.7 riastrad ATF_TC_BODY(static_usedefnoload, tc)
276 1.3 riastrad {
277 1.5 riastrad tls_extern("libh_def_static.so", "libh_use_static.so",
278 1.12 joerg USE_DEF_NOLOAD);
279 1.1 riastrad }
280 1.1 riastrad
281 1.11 riastrad ATF_TC(onlydef_dynamic_static_ctor);
282 1.11 riastrad ATF_TC_HEAD(onlydef_dynamic_static_ctor, tc)
283 1.11 riastrad {
284 1.11 riastrad atf_tc_set_md_var(tc, "descr", "definition-only library,"
285 1.11 riastrad " dynamic load and use in ctor, then static load fails");
286 1.11 riastrad }
287 1.11 riastrad ATF_TC_BODY(onlydef_dynamic_static_ctor, tc)
288 1.11 riastrad {
289 1.11 riastrad
290 1.11 riastrad ATF_REQUIRE_DL(dlopen("libh_onlydef.so", 0));
291 1.11 riastrad ATF_REQUIRE_DL(dlopen("libh_onlyctor_dynamic.so", 0));
292 1.11 riastrad ATF_CHECK_EQ_MSG(NULL, dlopen("libh_onlyuse_static.so", 0),
293 1.11 riastrad "dlopen failed to detect dynamic-then-static abuse");
294 1.11 riastrad }
295 1.11 riastrad
296 1.10 riastrad ATF_TC(onlydef_dynamic_static_eager);
297 1.10 riastrad ATF_TC_HEAD(onlydef_dynamic_static_eager, tc)
298 1.10 riastrad {
299 1.10 riastrad atf_tc_set_md_var(tc, "descr", "definition-only library,"
300 1.10 riastrad " dynamic load and use, then static load fails");
301 1.10 riastrad }
302 1.10 riastrad ATF_TC_BODY(onlydef_dynamic_static_eager, tc)
303 1.10 riastrad {
304 1.10 riastrad void *use_dynamic;
305 1.10 riastrad int *(*fdynamic)(void);
306 1.10 riastrad
307 1.10 riastrad ATF_REQUIRE_DL(use_dynamic = dlopen("libh_onlyuse_dynamic.so", 0));
308 1.10 riastrad ATF_REQUIRE_DL(fdynamic = dlsym(use_dynamic, "fdynamic"));
309 1.10 riastrad (void)(*fdynamic)();
310 1.10 riastrad ATF_CHECK_EQ_MSG(NULL, dlopen("libh_onlyuse_static.so", 0),
311 1.10 riastrad "dlopen failed to detect dynamic-then-static abuse");
312 1.10 riastrad }
313 1.10 riastrad
314 1.10 riastrad ATF_TC(onlydef_dynamic_static_lazy);
315 1.10 riastrad ATF_TC_HEAD(onlydef_dynamic_static_lazy, tc)
316 1.10 riastrad {
317 1.10 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
318 1.10 riastrad " with definition-only library, dynamic and static load and use");
319 1.10 riastrad }
320 1.10 riastrad ATF_TC_BODY(onlydef_dynamic_static_lazy, tc)
321 1.10 riastrad {
322 1.10 riastrad void *use_dynamic, *use_static;
323 1.10 riastrad int *(*fdynamic)(void), *(*fstatic)(void);
324 1.10 riastrad int *pdynamic, *pstatic;
325 1.10 riastrad
326 1.10 riastrad ATF_REQUIRE_DL(use_dynamic = dlopen("libh_onlyuse_dynamic.so", 0));
327 1.10 riastrad ATF_REQUIRE_DL(use_static = dlopen("libh_onlyuse_static.so", 0));
328 1.10 riastrad ATF_REQUIRE_DL(fdynamic = dlsym(use_dynamic, "fdynamic"));
329 1.10 riastrad ATF_REQUIRE_DL(fstatic = dlsym(use_static, "fstatic"));
330 1.10 riastrad pdynamic = (*fdynamic)();
331 1.10 riastrad pstatic = (*fstatic)();
332 1.10 riastrad ATF_CHECK_EQ_MSG(pdynamic, pstatic,
333 1.10 riastrad "%p in dynamic tls user != %p in static tls user",
334 1.10 riastrad pdynamic, pstatic);
335 1.10 riastrad }
336 1.10 riastrad
337 1.10 riastrad ATF_TC(onlydef_static_dynamic_eager);
338 1.10 riastrad ATF_TC_HEAD(onlydef_static_dynamic_eager, tc)
339 1.10 riastrad {
340 1.10 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
341 1.10 riastrad " with definition-only library,"
342 1.10 riastrad " static load and use, then dynamic load and use");
343 1.10 riastrad }
344 1.10 riastrad ATF_TC_BODY(onlydef_static_dynamic_eager, tc)
345 1.10 riastrad {
346 1.10 riastrad void *use_static, *use_dynamic;
347 1.10 riastrad int *(*fstatic)(void), *(*fdynamic)(void);
348 1.10 riastrad int *pstatic, *pdynamic;
349 1.10 riastrad
350 1.10 riastrad ATF_REQUIRE_DL(dlopen("libh_onlydef.so", 0));
351 1.10 riastrad ATF_REQUIRE_DL(use_static = dlopen("libh_onlyuse_static.so", 0));
352 1.10 riastrad ATF_REQUIRE_DL(fstatic = dlsym(use_static, "fstatic"));
353 1.10 riastrad pstatic = (*fstatic)();
354 1.10 riastrad ATF_REQUIRE_DL(use_dynamic = dlopen("libh_onlyuse_dynamic.so", 0));
355 1.10 riastrad ATF_REQUIRE_DL(fdynamic = dlsym(use_dynamic, "fdynamic"));
356 1.10 riastrad pdynamic = (*fdynamic)();
357 1.10 riastrad ATF_CHECK_EQ_MSG(pstatic, pdynamic,
358 1.10 riastrad "%p in static tls user != %p in dynamic tls user",
359 1.10 riastrad pstatic, pdynamic);
360 1.10 riastrad }
361 1.10 riastrad
362 1.10 riastrad ATF_TC(onlydef_static_dynamic_lazy);
363 1.10 riastrad ATF_TC_HEAD(onlydef_static_dynamic_lazy, tc)
364 1.10 riastrad {
365 1.10 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
366 1.10 riastrad " with definition-only library, static and dynamic load and use");
367 1.10 riastrad }
368 1.10 riastrad ATF_TC_BODY(onlydef_static_dynamic_lazy, tc)
369 1.10 riastrad {
370 1.10 riastrad void *use_static, *use_dynamic;
371 1.10 riastrad int *(*fstatic)(void), *(*fdynamic)(void);
372 1.10 riastrad int *pstatic, *pdynamic;
373 1.10 riastrad
374 1.10 riastrad ATF_REQUIRE_DL(dlopen("libh_onlydef.so", 0));
375 1.10 riastrad ATF_REQUIRE_DL(use_static = dlopen("libh_onlyuse_static.so", 0));
376 1.10 riastrad ATF_REQUIRE_DL(use_dynamic = dlopen("libh_onlyuse_dynamic.so", 0));
377 1.10 riastrad ATF_REQUIRE_DL(fstatic = dlsym(use_static, "fstatic"));
378 1.10 riastrad ATF_REQUIRE_DL(fdynamic = dlsym(use_dynamic, "fdynamic"));
379 1.10 riastrad pstatic = (*fstatic)();
380 1.10 riastrad pdynamic = (*fdynamic)();
381 1.10 riastrad ATF_CHECK_EQ_MSG(pstatic, pdynamic,
382 1.10 riastrad "%p in static tls user != %p in dynamic tls user",
383 1.10 riastrad pstatic, pdynamic);
384 1.10 riastrad }
385 1.10 riastrad
386 1.15 riastrad ATF_TC(opencloseloop_use);
387 1.15 riastrad ATF_TC_HEAD(opencloseloop_use, tc)
388 1.15 riastrad {
389 1.15 riastrad atf_tc_set_md_var(tc, "descr", "Testing opening and closing in a loop,"
390 1.15 riastrad " then opening and using dynamic TLS");
391 1.15 riastrad }
392 1.15 riastrad ATF_TC_BODY(opencloseloop_use, tc)
393 1.15 riastrad {
394 1.15 riastrad unsigned i;
395 1.15 riastrad void *def, *use;
396 1.15 riastrad int *(*fdef)(void), *(*fuse)(void);
397 1.15 riastrad int *pdef, *puse;
398 1.15 riastrad
399 1.15 riastrad /*
400 1.15 riastrad * Open and close the definition library repeatedly. This
401 1.15 riastrad * should trigger allocation of many DTV offsets, which are
402 1.15 riastrad * (currently) not recycled, so the required DTV offsets should
403 1.15 riastrad * become very long -- pages past what is actually allocated
404 1.15 riastrad * before we attempt to use it.
405 1.15 riastrad *
406 1.15 riastrad * This way, we will exercise the wrong-way-conditional fast
407 1.15 riastrad * path of PR lib/58154.
408 1.15 riastrad */
409 1.15 riastrad for (i = sysconf(_SC_PAGESIZE); i --> 0;) {
410 1.15 riastrad ATF_REQUIRE_DL(def = dlopen("libh_def_dynamic.so", 0));
411 1.15 riastrad ATF_REQUIRE_EQ_MSG(dlclose(def), 0,
412 1.15 riastrad "dlclose(def): %s", dlerror());
413 1.15 riastrad }
414 1.15 riastrad
415 1.15 riastrad /*
416 1.15 riastrad * Now open the definition library and keep it open.
417 1.15 riastrad */
418 1.15 riastrad ATF_REQUIRE_DL(def = dlopen("libh_def_dynamic.so", 0));
419 1.15 riastrad ATF_REQUIRE_DL(fdef = dlsym(def, "fdef"));
420 1.15 riastrad
421 1.15 riastrad /*
422 1.15 riastrad * Open libraries that use the definition and verify they
423 1.15 riastrad * observe the same pointer.
424 1.15 riastrad */
425 1.15 riastrad ATF_REQUIRE_DL(use = dlopen("libh_use_dynamic.so", 0));
426 1.15 riastrad ATF_REQUIRE_DL(fuse = dlsym(use, "fuse"));
427 1.15 riastrad #ifdef __aarch64__
428 1.15 riastrad atf_tc_expect_signal(SIGSEGV,
429 1.15 riastrad "PR lib/58154: bad fast path test in aarch64 tls");
430 1.15 riastrad #endif
431 1.15 riastrad pdef = (*fdef)();
432 1.15 riastrad puse = (*fuse)();
433 1.15 riastrad ATF_CHECK_EQ_MSG(pdef, puse,
434 1.15 riastrad "%p in defining library != %p in using library",
435 1.15 riastrad pdef, puse);
436 1.15 riastrad
437 1.15 riastrad /*
438 1.15 riastrad * Also verify the pointer can be used.
439 1.15 riastrad */
440 1.15 riastrad *pdef = 123;
441 1.15 riastrad *puse = 456;
442 1.15 riastrad ATF_CHECK_EQ_MSG(*pdef, *puse,
443 1.15 riastrad "%d in defining library != %d in using library",
444 1.15 riastrad *pdef, *puse);
445 1.15 riastrad }
446 1.15 riastrad
447 1.1 riastrad ATF_TP_ADD_TCS(tp)
448 1.1 riastrad {
449 1.3 riastrad
450 1.7 riastrad ATF_TP_ADD_TC(tp, dynamic_abusedef);
451 1.7 riastrad ATF_TP_ADD_TC(tp, dynamic_abusedefnoload);
452 1.8 riastrad ATF_TP_ADD_TC(tp, dynamic_defabuse_eager);
453 1.8 riastrad ATF_TP_ADD_TC(tp, dynamic_defabuse_lazy);
454 1.8 riastrad ATF_TP_ADD_TC(tp, dynamic_defuse_eager);
455 1.8 riastrad ATF_TP_ADD_TC(tp, dynamic_defuse_lazy);
456 1.7 riastrad ATF_TP_ADD_TC(tp, dynamic_usedef);
457 1.7 riastrad ATF_TP_ADD_TC(tp, dynamic_usedefnoload);
458 1.11 riastrad ATF_TP_ADD_TC(tp, onlydef_dynamic_static_ctor);
459 1.10 riastrad ATF_TP_ADD_TC(tp, onlydef_dynamic_static_eager);
460 1.10 riastrad ATF_TP_ADD_TC(tp, onlydef_dynamic_static_lazy);
461 1.10 riastrad ATF_TP_ADD_TC(tp, onlydef_static_dynamic_eager);
462 1.10 riastrad ATF_TP_ADD_TC(tp, onlydef_static_dynamic_lazy);
463 1.15 riastrad ATF_TP_ADD_TC(tp, opencloseloop_use);
464 1.7 riastrad ATF_TP_ADD_TC(tp, static_abusedef);
465 1.7 riastrad ATF_TP_ADD_TC(tp, static_abusedefnoload);
466 1.8 riastrad ATF_TP_ADD_TC(tp, static_defabuse_eager);
467 1.8 riastrad ATF_TP_ADD_TC(tp, static_defabuse_lazy);
468 1.8 riastrad ATF_TP_ADD_TC(tp, static_defuse_eager);
469 1.8 riastrad ATF_TP_ADD_TC(tp, static_defuse_lazy);
470 1.7 riastrad ATF_TP_ADD_TC(tp, static_usedef);
471 1.7 riastrad ATF_TP_ADD_TC(tp, static_usedefnoload);
472 1.1 riastrad return atf_no_error();
473 1.1 riastrad }
474