t_tls_extern.c revision 1.8 1 1.8 riastrad /* $NetBSD: t_tls_extern.c,v 1.8 2023/06/01 23:47:24 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.1 riastrad
34 1.2 riastrad #define ATF_REQUIRE_DL(x) ATF_REQUIRE_MSG(x, "%s: %s", #x, dlerror())
35 1.1 riastrad
36 1.5 riastrad enum order {
37 1.8 riastrad DEF_USE_EAGER,
38 1.8 riastrad DEF_USE_LAZY,
39 1.5 riastrad USE_DEF,
40 1.5 riastrad USE_DEF_NOLOAD,
41 1.5 riastrad };
42 1.5 riastrad
43 1.5 riastrad static void
44 1.5 riastrad tls_extern(const char *libdef, const char *libuse, enum order order,
45 1.5 riastrad bool xfail)
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.5 riastrad if (xfail) {
81 1.5 riastrad atf_tc_expect_fail("PR toolchain/50277:"
82 1.5 riastrad " rtld relocation bug with thread local storage");
83 1.5 riastrad }
84 1.4 riastrad ATF_CHECK_EQ_MSG(pdef, puse,
85 1.4 riastrad "%p in defining library != %p in using library",
86 1.4 riastrad pdef, puse);
87 1.4 riastrad }
88 1.4 riastrad
89 1.7 riastrad ATF_TC(dynamic_abusedef);
90 1.7 riastrad ATF_TC_HEAD(dynamic_abusedef, tc)
91 1.6 riastrad {
92 1.6 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
93 1.6 riastrad " loading static use than dynamic def");
94 1.6 riastrad }
95 1.7 riastrad ATF_TC_BODY(dynamic_abusedef, tc)
96 1.6 riastrad {
97 1.6 riastrad tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so",
98 1.6 riastrad USE_DEF, /*xfail*/true);
99 1.6 riastrad }
100 1.6 riastrad
101 1.7 riastrad ATF_TC(dynamic_abusedefnoload);
102 1.7 riastrad ATF_TC_HEAD(dynamic_abusedefnoload, tc)
103 1.6 riastrad {
104 1.6 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
105 1.6 riastrad " loading static use then dynamic def with RTLD_NOLOAD");
106 1.6 riastrad }
107 1.7 riastrad ATF_TC_BODY(dynamic_abusedefnoload, tc)
108 1.6 riastrad {
109 1.6 riastrad tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so",
110 1.6 riastrad USE_DEF_NOLOAD, /*xfail*/true);
111 1.6 riastrad }
112 1.6 riastrad
113 1.8 riastrad ATF_TC(dynamic_defabuse_eager);
114 1.8 riastrad ATF_TC_HEAD(dynamic_defabuse_eager, tc)
115 1.8 riastrad {
116 1.8 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
117 1.8 riastrad " loading dynamic def then static use eagerly");
118 1.8 riastrad }
119 1.8 riastrad ATF_TC_BODY(dynamic_defabuse_eager, tc)
120 1.8 riastrad {
121 1.8 riastrad tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so",
122 1.8 riastrad DEF_USE_EAGER, /*xfail*/true);
123 1.8 riastrad }
124 1.8 riastrad
125 1.8 riastrad ATF_TC(dynamic_defabuse_lazy);
126 1.8 riastrad ATF_TC_HEAD(dynamic_defabuse_lazy, tc)
127 1.6 riastrad {
128 1.6 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
129 1.8 riastrad " loading dynamic def then static use lazily");
130 1.6 riastrad }
131 1.8 riastrad ATF_TC_BODY(dynamic_defabuse_lazy, tc)
132 1.6 riastrad {
133 1.6 riastrad tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so",
134 1.8 riastrad DEF_USE_LAZY, /*xfail*/true);
135 1.8 riastrad }
136 1.8 riastrad
137 1.8 riastrad ATF_TC(dynamic_defuse_eager);
138 1.8 riastrad ATF_TC_HEAD(dynamic_defuse_eager, tc)
139 1.8 riastrad {
140 1.8 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for dynamic TLS works,"
141 1.8 riastrad " loading def then use eagerly");
142 1.8 riastrad }
143 1.8 riastrad ATF_TC_BODY(dynamic_defuse_eager, tc)
144 1.8 riastrad {
145 1.8 riastrad tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so",
146 1.8 riastrad DEF_USE_EAGER, /*xfail*/false);
147 1.6 riastrad }
148 1.6 riastrad
149 1.8 riastrad ATF_TC(dynamic_defuse_lazy);
150 1.8 riastrad ATF_TC_HEAD(dynamic_defuse_lazy, tc)
151 1.5 riastrad {
152 1.5 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for dynamic TLS works,"
153 1.8 riastrad " loading def then use lazyly");
154 1.5 riastrad }
155 1.8 riastrad ATF_TC_BODY(dynamic_defuse_lazy, tc)
156 1.5 riastrad {
157 1.5 riastrad tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so",
158 1.8 riastrad DEF_USE_LAZY, /*xfail*/false);
159 1.5 riastrad }
160 1.5 riastrad
161 1.7 riastrad ATF_TC(dynamic_usedef);
162 1.7 riastrad ATF_TC_HEAD(dynamic_usedef, tc)
163 1.4 riastrad {
164 1.4 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for dynamic TLS works,"
165 1.4 riastrad " loading use then def");
166 1.4 riastrad }
167 1.7 riastrad ATF_TC_BODY(dynamic_usedef, tc)
168 1.4 riastrad {
169 1.5 riastrad tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so",
170 1.5 riastrad USE_DEF, /*xfail*/false);
171 1.4 riastrad }
172 1.4 riastrad
173 1.7 riastrad ATF_TC(dynamic_usedefnoload);
174 1.7 riastrad ATF_TC_HEAD(dynamic_usedefnoload, tc)
175 1.4 riastrad {
176 1.4 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for dynamic TLS works,"
177 1.4 riastrad " loading use then def with RTLD_NOLOAD");
178 1.4 riastrad }
179 1.7 riastrad ATF_TC_BODY(dynamic_usedefnoload, tc)
180 1.4 riastrad {
181 1.5 riastrad tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so",
182 1.5 riastrad USE_DEF_NOLOAD, /*xfail*/false);
183 1.4 riastrad }
184 1.4 riastrad
185 1.7 riastrad ATF_TC(static_abusedef);
186 1.7 riastrad ATF_TC_HEAD(static_abusedef, tc)
187 1.6 riastrad {
188 1.6 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
189 1.6 riastrad " loading dynamic use then static def");
190 1.6 riastrad }
191 1.7 riastrad ATF_TC_BODY(static_abusedef, tc)
192 1.6 riastrad {
193 1.6 riastrad tls_extern("libh_def_static.so", "libh_abuse_static.so",
194 1.6 riastrad USE_DEF, /*xfail*/true);
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.6 riastrad USE_DEF_NOLOAD, /*xfail*/true);
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.8 riastrad DEF_USE_EAGER, /*xfail*/true);
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.8 riastrad DEF_USE_LAZY, /*xfail*/true);
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.8 riastrad DEF_USE_EAGER, /*xfail*/false);
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.8 riastrad DEF_USE_LAZY, /*xfail*/false);
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.5 riastrad USE_DEF, /*xfail*/true);
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.5 riastrad USE_DEF_NOLOAD, /*xfail*/true);
279 1.1 riastrad }
280 1.1 riastrad
281 1.1 riastrad ATF_TP_ADD_TCS(tp)
282 1.1 riastrad {
283 1.3 riastrad
284 1.7 riastrad ATF_TP_ADD_TC(tp, dynamic_abusedef);
285 1.7 riastrad ATF_TP_ADD_TC(tp, dynamic_abusedefnoload);
286 1.8 riastrad ATF_TP_ADD_TC(tp, dynamic_defabuse_eager);
287 1.8 riastrad ATF_TP_ADD_TC(tp, dynamic_defabuse_lazy);
288 1.8 riastrad ATF_TP_ADD_TC(tp, dynamic_defuse_eager);
289 1.8 riastrad ATF_TP_ADD_TC(tp, dynamic_defuse_lazy);
290 1.7 riastrad ATF_TP_ADD_TC(tp, dynamic_usedef);
291 1.7 riastrad ATF_TP_ADD_TC(tp, dynamic_usedefnoload);
292 1.7 riastrad ATF_TP_ADD_TC(tp, static_abusedef);
293 1.7 riastrad ATF_TP_ADD_TC(tp, static_abusedefnoload);
294 1.8 riastrad ATF_TP_ADD_TC(tp, static_defabuse_eager);
295 1.8 riastrad ATF_TP_ADD_TC(tp, static_defabuse_lazy);
296 1.8 riastrad ATF_TP_ADD_TC(tp, static_defuse_eager);
297 1.8 riastrad ATF_TP_ADD_TC(tp, static_defuse_lazy);
298 1.7 riastrad ATF_TP_ADD_TC(tp, static_usedef);
299 1.7 riastrad ATF_TP_ADD_TC(tp, static_usedefnoload);
300 1.1 riastrad return atf_no_error();
301 1.1 riastrad }
302