t_tls_extern.c revision 1.8 1 /* $NetBSD: t_tls_extern.c,v 1.8 2023/06/01 23:47:24 riastradh Exp $ */
2
3 /*-
4 * Copyright (c) 2023 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <sys/types.h>
30
31 #include <atf-c.h>
32 #include <dlfcn.h>
33
34 #define ATF_REQUIRE_DL(x) ATF_REQUIRE_MSG(x, "%s: %s", #x, dlerror())
35
36 enum order {
37 DEF_USE_EAGER,
38 DEF_USE_LAZY,
39 USE_DEF,
40 USE_DEF_NOLOAD,
41 };
42
43 static void
44 tls_extern(const char *libdef, const char *libuse, enum order order,
45 bool xfail)
46 {
47 void *def, *use;
48 int *(*fdef)(void), *(*fuse)(void);
49 int *pdef, *puse;
50
51 (void)dlerror();
52
53 switch (order) {
54 case DEF_USE_EAGER:
55 ATF_REQUIRE_DL(def = dlopen(libdef, 0));
56 ATF_REQUIRE_DL(fdef = dlsym(def, "fdef"));
57 pdef = (*fdef)();
58 ATF_REQUIRE_DL(use = dlopen(libuse, 0));
59 ATF_REQUIRE_DL(fuse = dlsym(use, "fuse"));
60 puse = (*fuse)();
61 break;
62 case DEF_USE_LAZY:
63 ATF_REQUIRE_DL(def = dlopen(libdef, 0));
64 ATF_REQUIRE_DL(use = dlopen(libuse, 0));
65 goto lazy;
66 case USE_DEF:
67 ATF_REQUIRE_DL(use = dlopen(libuse, 0));
68 ATF_REQUIRE_DL(def = dlopen(libdef, 0));
69 goto lazy;
70 case USE_DEF_NOLOAD:
71 ATF_REQUIRE_DL(use = dlopen(libuse, 0));
72 ATF_REQUIRE_DL(def = dlopen(libdef, RTLD_NOLOAD));
73 lazy: ATF_REQUIRE_DL(fdef = dlsym(def, "fdef"));
74 ATF_REQUIRE_DL(fuse = dlsym(use, "fuse"));
75 pdef = (*fdef)();
76 puse = (*fuse)();
77 break;
78 }
79
80 if (xfail) {
81 atf_tc_expect_fail("PR toolchain/50277:"
82 " rtld relocation bug with thread local storage");
83 }
84 ATF_CHECK_EQ_MSG(pdef, puse,
85 "%p in defining library != %p in using library",
86 pdef, puse);
87 }
88
89 ATF_TC(dynamic_abusedef);
90 ATF_TC_HEAD(dynamic_abusedef, tc)
91 {
92 atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
93 " loading static use than dynamic def");
94 }
95 ATF_TC_BODY(dynamic_abusedef, tc)
96 {
97 tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so",
98 USE_DEF, /*xfail*/true);
99 }
100
101 ATF_TC(dynamic_abusedefnoload);
102 ATF_TC_HEAD(dynamic_abusedefnoload, tc)
103 {
104 atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
105 " loading static use then dynamic def with RTLD_NOLOAD");
106 }
107 ATF_TC_BODY(dynamic_abusedefnoload, tc)
108 {
109 tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so",
110 USE_DEF_NOLOAD, /*xfail*/true);
111 }
112
113 ATF_TC(dynamic_defabuse_eager);
114 ATF_TC_HEAD(dynamic_defabuse_eager, tc)
115 {
116 atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
117 " loading dynamic def then static use eagerly");
118 }
119 ATF_TC_BODY(dynamic_defabuse_eager, tc)
120 {
121 tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so",
122 DEF_USE_EAGER, /*xfail*/true);
123 }
124
125 ATF_TC(dynamic_defabuse_lazy);
126 ATF_TC_HEAD(dynamic_defabuse_lazy, tc)
127 {
128 atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
129 " loading dynamic def then static use lazily");
130 }
131 ATF_TC_BODY(dynamic_defabuse_lazy, tc)
132 {
133 tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so",
134 DEF_USE_LAZY, /*xfail*/true);
135 }
136
137 ATF_TC(dynamic_defuse_eager);
138 ATF_TC_HEAD(dynamic_defuse_eager, tc)
139 {
140 atf_tc_set_md_var(tc, "descr", "extern __thread for dynamic TLS works,"
141 " loading def then use eagerly");
142 }
143 ATF_TC_BODY(dynamic_defuse_eager, tc)
144 {
145 tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so",
146 DEF_USE_EAGER, /*xfail*/false);
147 }
148
149 ATF_TC(dynamic_defuse_lazy);
150 ATF_TC_HEAD(dynamic_defuse_lazy, tc)
151 {
152 atf_tc_set_md_var(tc, "descr", "extern __thread for dynamic TLS works,"
153 " loading def then use lazyly");
154 }
155 ATF_TC_BODY(dynamic_defuse_lazy, tc)
156 {
157 tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so",
158 DEF_USE_LAZY, /*xfail*/false);
159 }
160
161 ATF_TC(dynamic_usedef);
162 ATF_TC_HEAD(dynamic_usedef, tc)
163 {
164 atf_tc_set_md_var(tc, "descr", "extern __thread for dynamic TLS works,"
165 " loading use then def");
166 }
167 ATF_TC_BODY(dynamic_usedef, tc)
168 {
169 tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so",
170 USE_DEF, /*xfail*/false);
171 }
172
173 ATF_TC(dynamic_usedefnoload);
174 ATF_TC_HEAD(dynamic_usedefnoload, tc)
175 {
176 atf_tc_set_md_var(tc, "descr", "extern __thread for dynamic TLS works,"
177 " loading use then def with RTLD_NOLOAD");
178 }
179 ATF_TC_BODY(dynamic_usedefnoload, tc)
180 {
181 tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so",
182 USE_DEF_NOLOAD, /*xfail*/false);
183 }
184
185 ATF_TC(static_abusedef);
186 ATF_TC_HEAD(static_abusedef, tc)
187 {
188 atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
189 " loading dynamic use then static def");
190 }
191 ATF_TC_BODY(static_abusedef, tc)
192 {
193 tls_extern("libh_def_static.so", "libh_abuse_static.so",
194 USE_DEF, /*xfail*/true);
195 }
196
197 ATF_TC(static_abusedefnoload);
198 ATF_TC_HEAD(static_abusedefnoload, tc)
199 {
200 atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
201 " loading dynamic use then static def with RTLD_NOLOAD");
202 }
203 ATF_TC_BODY(static_abusedefnoload, tc)
204 {
205 tls_extern("libh_def_static.so", "libh_abuse_static.so",
206 USE_DEF_NOLOAD, /*xfail*/true);
207 }
208
209 ATF_TC(static_defabuse_eager);
210 ATF_TC_HEAD(static_defabuse_eager, tc)
211 {
212 atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
213 " loading static def then dynamic use eagerly");
214 }
215 ATF_TC_BODY(static_defabuse_eager, tc)
216 {
217 tls_extern("libh_def_static.so", "libh_abuse_static.so",
218 DEF_USE_EAGER, /*xfail*/true);
219 }
220
221 ATF_TC(static_defabuse_lazy);
222 ATF_TC_HEAD(static_defabuse_lazy, tc)
223 {
224 atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
225 " loading static def then dynamic use lazyly");
226 }
227 ATF_TC_BODY(static_defabuse_lazy, tc)
228 {
229 tls_extern("libh_def_static.so", "libh_abuse_static.so",
230 DEF_USE_LAZY, /*xfail*/true);
231 }
232
233 ATF_TC(static_defuse_eager);
234 ATF_TC_HEAD(static_defuse_eager, tc)
235 {
236 atf_tc_set_md_var(tc, "descr", "extern __thread for static TLS works,"
237 " loading def then use eagerly");
238 }
239 ATF_TC_BODY(static_defuse_eager, tc)
240 {
241 tls_extern("libh_def_static.so", "libh_use_static.so",
242 DEF_USE_EAGER, /*xfail*/false);
243 }
244
245 ATF_TC(static_defuse_lazy);
246 ATF_TC_HEAD(static_defuse_lazy, tc)
247 {
248 atf_tc_set_md_var(tc, "descr", "extern __thread for static TLS works,"
249 " loading def then use lazyly");
250 }
251 ATF_TC_BODY(static_defuse_lazy, tc)
252 {
253 tls_extern("libh_def_static.so", "libh_use_static.so",
254 DEF_USE_LAZY, /*xfail*/false);
255 }
256
257 ATF_TC(static_usedef);
258 ATF_TC_HEAD(static_usedef, tc)
259 {
260 atf_tc_set_md_var(tc, "descr", "extern __thread for static TLS works,"
261 " loading use then def");
262 }
263 ATF_TC_BODY(static_usedef, tc)
264 {
265 tls_extern("libh_def_static.so", "libh_use_static.so",
266 USE_DEF, /*xfail*/true);
267 }
268
269 ATF_TC(static_usedefnoload);
270 ATF_TC_HEAD(static_usedefnoload, tc)
271 {
272 atf_tc_set_md_var(tc, "descr", "extern __thread for static TLS works,"
273 " loading use then def with RTLD_NOLOAD");
274 }
275 ATF_TC_BODY(static_usedefnoload, tc)
276 {
277 tls_extern("libh_def_static.so", "libh_use_static.so",
278 USE_DEF_NOLOAD, /*xfail*/true);
279 }
280
281 ATF_TP_ADD_TCS(tp)
282 {
283
284 ATF_TP_ADD_TC(tp, dynamic_abusedef);
285 ATF_TP_ADD_TC(tp, dynamic_abusedefnoload);
286 ATF_TP_ADD_TC(tp, dynamic_defabuse_eager);
287 ATF_TP_ADD_TC(tp, dynamic_defabuse_lazy);
288 ATF_TP_ADD_TC(tp, dynamic_defuse_eager);
289 ATF_TP_ADD_TC(tp, dynamic_defuse_lazy);
290 ATF_TP_ADD_TC(tp, dynamic_usedef);
291 ATF_TP_ADD_TC(tp, dynamic_usedefnoload);
292 ATF_TP_ADD_TC(tp, static_abusedef);
293 ATF_TP_ADD_TC(tp, static_abusedefnoload);
294 ATF_TP_ADD_TC(tp, static_defabuse_eager);
295 ATF_TP_ADD_TC(tp, static_defabuse_lazy);
296 ATF_TP_ADD_TC(tp, static_defuse_eager);
297 ATF_TP_ADD_TC(tp, static_defuse_lazy);
298 ATF_TP_ADD_TC(tp, static_usedef);
299 ATF_TP_ADD_TC(tp, static_usedefnoload);
300 return atf_no_error();
301 }
302