1 1.16 riastrad /* $NetBSD: t_tls_extern.c,v 1.16 2024/07/23 18:11:53 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.14 kre #define ATF_REQUIRE_DL(x) ATF_REQUIRE_MSG((x) != 0, "%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.12 joerg tls_extern(const char *libdef, const char *libuse, enum order order) 45 1.4 riastrad { 46 1.4 riastrad void *def, *use; 47 1.4 riastrad int *(*fdef)(void), *(*fuse)(void); 48 1.4 riastrad int *pdef, *puse; 49 1.4 riastrad 50 1.4 riastrad (void)dlerror(); 51 1.4 riastrad 52 1.5 riastrad switch (order) { 53 1.8 riastrad case DEF_USE_EAGER: 54 1.5 riastrad ATF_REQUIRE_DL(def = dlopen(libdef, 0)); 55 1.8 riastrad ATF_REQUIRE_DL(fdef = dlsym(def, "fdef")); 56 1.8 riastrad pdef = (*fdef)(); 57 1.5 riastrad ATF_REQUIRE_DL(use = dlopen(libuse, 0)); 58 1.8 riastrad ATF_REQUIRE_DL(fuse = dlsym(use, "fuse")); 59 1.8 riastrad puse = (*fuse)(); 60 1.5 riastrad break; 61 1.8 riastrad case DEF_USE_LAZY: 62 1.8 riastrad ATF_REQUIRE_DL(def = dlopen(libdef, 0)); 63 1.8 riastrad ATF_REQUIRE_DL(use = dlopen(libuse, 0)); 64 1.8 riastrad goto lazy; 65 1.5 riastrad case USE_DEF: 66 1.5 riastrad ATF_REQUIRE_DL(use = dlopen(libuse, 0)); 67 1.5 riastrad ATF_REQUIRE_DL(def = dlopen(libdef, 0)); 68 1.8 riastrad goto lazy; 69 1.5 riastrad case USE_DEF_NOLOAD: 70 1.5 riastrad ATF_REQUIRE_DL(use = dlopen(libuse, 0)); 71 1.5 riastrad ATF_REQUIRE_DL(def = dlopen(libdef, RTLD_NOLOAD)); 72 1.8 riastrad lazy: ATF_REQUIRE_DL(fdef = dlsym(def, "fdef")); 73 1.8 riastrad ATF_REQUIRE_DL(fuse = dlsym(use, "fuse")); 74 1.8 riastrad pdef = (*fdef)(); 75 1.8 riastrad puse = (*fuse)(); 76 1.5 riastrad break; 77 1.5 riastrad } 78 1.4 riastrad 79 1.4 riastrad ATF_CHECK_EQ_MSG(pdef, puse, 80 1.4 riastrad "%p in defining library != %p in using library", 81 1.4 riastrad pdef, puse); 82 1.4 riastrad } 83 1.4 riastrad 84 1.7 riastrad ATF_TC(dynamic_abusedef); 85 1.7 riastrad ATF_TC_HEAD(dynamic_abusedef, tc) 86 1.6 riastrad { 87 1.6 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works," 88 1.6 riastrad " loading static use than dynamic def"); 89 1.6 riastrad } 90 1.7 riastrad ATF_TC_BODY(dynamic_abusedef, tc) 91 1.6 riastrad { 92 1.12 joerg tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so", USE_DEF); 93 1.6 riastrad } 94 1.6 riastrad 95 1.7 riastrad ATF_TC(dynamic_abusedefnoload); 96 1.7 riastrad ATF_TC_HEAD(dynamic_abusedefnoload, tc) 97 1.6 riastrad { 98 1.6 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works," 99 1.6 riastrad " loading static use then dynamic def with RTLD_NOLOAD"); 100 1.6 riastrad } 101 1.7 riastrad ATF_TC_BODY(dynamic_abusedefnoload, tc) 102 1.6 riastrad { 103 1.6 riastrad tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so", 104 1.12 joerg USE_DEF_NOLOAD); 105 1.6 riastrad } 106 1.6 riastrad 107 1.8 riastrad ATF_TC(dynamic_defabuse_eager); 108 1.8 riastrad ATF_TC_HEAD(dynamic_defabuse_eager, tc) 109 1.8 riastrad { 110 1.9 riastrad atf_tc_set_md_var(tc, "descr", "dlopen refuses extern __thread for TLS," 111 1.8 riastrad " loading dynamic def then static use eagerly"); 112 1.8 riastrad } 113 1.8 riastrad ATF_TC_BODY(dynamic_defabuse_eager, tc) 114 1.8 riastrad { 115 1.9 riastrad void *def; 116 1.9 riastrad int *(*fdef)(void); 117 1.9 riastrad 118 1.9 riastrad ATF_REQUIRE_DL(def = dlopen("libh_def_dynamic.so", 0)); 119 1.9 riastrad ATF_REQUIRE_DL(fdef = dlsym(def, "fdef")); 120 1.9 riastrad (void)(*fdef)(); 121 1.9 riastrad ATF_CHECK_EQ_MSG(NULL, dlopen("libh_abuse_dynamic.so", 0), 122 1.9 riastrad "dlopen failed to detect static-then-dynamic abuse"); 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.12 joerg DEF_USE_LAZY); 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.12 joerg DEF_USE_EAGER); 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.12 joerg DEF_USE_LAZY); 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.12 joerg USE_DEF); 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.12 joerg USE_DEF_NOLOAD); 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.12 joerg tls_extern("libh_def_static.so", "libh_abuse_static.so", USE_DEF); 194 1.6 riastrad } 195 1.6 riastrad 196 1.7 riastrad ATF_TC(static_abusedefnoload); 197 1.7 riastrad ATF_TC_HEAD(static_abusedefnoload, tc) 198 1.6 riastrad { 199 1.6 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works," 200 1.6 riastrad " loading dynamic use then static def with RTLD_NOLOAD"); 201 1.6 riastrad } 202 1.7 riastrad ATF_TC_BODY(static_abusedefnoload, tc) 203 1.6 riastrad { 204 1.6 riastrad tls_extern("libh_def_static.so", "libh_abuse_static.so", 205 1.12 joerg USE_DEF_NOLOAD); 206 1.6 riastrad } 207 1.6 riastrad 208 1.8 riastrad ATF_TC(static_defabuse_eager); 209 1.8 riastrad ATF_TC_HEAD(static_defabuse_eager, tc) 210 1.8 riastrad { 211 1.8 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works," 212 1.8 riastrad " loading static def then dynamic use eagerly"); 213 1.8 riastrad } 214 1.8 riastrad ATF_TC_BODY(static_defabuse_eager, tc) 215 1.8 riastrad { 216 1.8 riastrad tls_extern("libh_def_static.so", "libh_abuse_static.so", 217 1.12 joerg DEF_USE_EAGER); 218 1.8 riastrad } 219 1.8 riastrad 220 1.8 riastrad ATF_TC(static_defabuse_lazy); 221 1.8 riastrad ATF_TC_HEAD(static_defabuse_lazy, tc) 222 1.6 riastrad { 223 1.6 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works," 224 1.8 riastrad " loading static def then dynamic use lazyly"); 225 1.6 riastrad } 226 1.8 riastrad ATF_TC_BODY(static_defabuse_lazy, tc) 227 1.6 riastrad { 228 1.6 riastrad tls_extern("libh_def_static.so", "libh_abuse_static.so", 229 1.12 joerg DEF_USE_LAZY); 230 1.8 riastrad } 231 1.8 riastrad 232 1.8 riastrad ATF_TC(static_defuse_eager); 233 1.8 riastrad ATF_TC_HEAD(static_defuse_eager, tc) 234 1.8 riastrad { 235 1.8 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for static TLS works," 236 1.8 riastrad " loading def then use eagerly"); 237 1.8 riastrad } 238 1.8 riastrad ATF_TC_BODY(static_defuse_eager, tc) 239 1.8 riastrad { 240 1.8 riastrad tls_extern("libh_def_static.so", "libh_use_static.so", 241 1.12 joerg DEF_USE_EAGER); 242 1.6 riastrad } 243 1.6 riastrad 244 1.8 riastrad ATF_TC(static_defuse_lazy); 245 1.8 riastrad ATF_TC_HEAD(static_defuse_lazy, tc) 246 1.1 riastrad { 247 1.3 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for static TLS works," 248 1.8 riastrad " loading def then use lazyly"); 249 1.1 riastrad } 250 1.8 riastrad ATF_TC_BODY(static_defuse_lazy, tc) 251 1.1 riastrad { 252 1.5 riastrad tls_extern("libh_def_static.so", "libh_use_static.so", 253 1.12 joerg DEF_USE_LAZY); 254 1.3 riastrad } 255 1.3 riastrad 256 1.7 riastrad ATF_TC(static_usedef); 257 1.7 riastrad ATF_TC_HEAD(static_usedef, tc) 258 1.3 riastrad { 259 1.3 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for static TLS works," 260 1.3 riastrad " loading use then def"); 261 1.3 riastrad } 262 1.7 riastrad ATF_TC_BODY(static_usedef, tc) 263 1.3 riastrad { 264 1.5 riastrad tls_extern("libh_def_static.so", "libh_use_static.so", 265 1.12 joerg USE_DEF); 266 1.3 riastrad } 267 1.3 riastrad 268 1.7 riastrad ATF_TC(static_usedefnoload); 269 1.7 riastrad ATF_TC_HEAD(static_usedefnoload, tc) 270 1.3 riastrad { 271 1.3 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for static TLS works," 272 1.3 riastrad " loading use then def with RTLD_NOLOAD"); 273 1.3 riastrad } 274 1.7 riastrad ATF_TC_BODY(static_usedefnoload, tc) 275 1.3 riastrad { 276 1.5 riastrad tls_extern("libh_def_static.so", "libh_use_static.so", 277 1.12 joerg USE_DEF_NOLOAD); 278 1.1 riastrad } 279 1.1 riastrad 280 1.11 riastrad ATF_TC(onlydef_dynamic_static_ctor); 281 1.11 riastrad ATF_TC_HEAD(onlydef_dynamic_static_ctor, tc) 282 1.11 riastrad { 283 1.11 riastrad atf_tc_set_md_var(tc, "descr", "definition-only library," 284 1.11 riastrad " dynamic load and use in ctor, then static load fails"); 285 1.11 riastrad } 286 1.11 riastrad ATF_TC_BODY(onlydef_dynamic_static_ctor, tc) 287 1.11 riastrad { 288 1.11 riastrad 289 1.11 riastrad ATF_REQUIRE_DL(dlopen("libh_onlydef.so", 0)); 290 1.11 riastrad ATF_REQUIRE_DL(dlopen("libh_onlyctor_dynamic.so", 0)); 291 1.11 riastrad ATF_CHECK_EQ_MSG(NULL, dlopen("libh_onlyuse_static.so", 0), 292 1.11 riastrad "dlopen failed to detect dynamic-then-static abuse"); 293 1.11 riastrad } 294 1.11 riastrad 295 1.10 riastrad ATF_TC(onlydef_dynamic_static_eager); 296 1.10 riastrad ATF_TC_HEAD(onlydef_dynamic_static_eager, tc) 297 1.10 riastrad { 298 1.10 riastrad atf_tc_set_md_var(tc, "descr", "definition-only library," 299 1.10 riastrad " dynamic load and use, then static load fails"); 300 1.10 riastrad } 301 1.10 riastrad ATF_TC_BODY(onlydef_dynamic_static_eager, tc) 302 1.10 riastrad { 303 1.10 riastrad void *use_dynamic; 304 1.10 riastrad int *(*fdynamic)(void); 305 1.10 riastrad 306 1.10 riastrad ATF_REQUIRE_DL(use_dynamic = dlopen("libh_onlyuse_dynamic.so", 0)); 307 1.10 riastrad ATF_REQUIRE_DL(fdynamic = dlsym(use_dynamic, "fdynamic")); 308 1.10 riastrad (void)(*fdynamic)(); 309 1.10 riastrad ATF_CHECK_EQ_MSG(NULL, dlopen("libh_onlyuse_static.so", 0), 310 1.10 riastrad "dlopen failed to detect dynamic-then-static abuse"); 311 1.10 riastrad } 312 1.10 riastrad 313 1.10 riastrad ATF_TC(onlydef_dynamic_static_lazy); 314 1.10 riastrad ATF_TC_HEAD(onlydef_dynamic_static_lazy, tc) 315 1.10 riastrad { 316 1.10 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works," 317 1.10 riastrad " with definition-only library, dynamic and static load and use"); 318 1.10 riastrad } 319 1.10 riastrad ATF_TC_BODY(onlydef_dynamic_static_lazy, tc) 320 1.10 riastrad { 321 1.10 riastrad void *use_dynamic, *use_static; 322 1.10 riastrad int *(*fdynamic)(void), *(*fstatic)(void); 323 1.10 riastrad int *pdynamic, *pstatic; 324 1.10 riastrad 325 1.10 riastrad ATF_REQUIRE_DL(use_dynamic = dlopen("libh_onlyuse_dynamic.so", 0)); 326 1.10 riastrad ATF_REQUIRE_DL(use_static = dlopen("libh_onlyuse_static.so", 0)); 327 1.10 riastrad ATF_REQUIRE_DL(fdynamic = dlsym(use_dynamic, "fdynamic")); 328 1.10 riastrad ATF_REQUIRE_DL(fstatic = dlsym(use_static, "fstatic")); 329 1.10 riastrad pdynamic = (*fdynamic)(); 330 1.10 riastrad pstatic = (*fstatic)(); 331 1.10 riastrad ATF_CHECK_EQ_MSG(pdynamic, pstatic, 332 1.10 riastrad "%p in dynamic tls user != %p in static tls user", 333 1.10 riastrad pdynamic, pstatic); 334 1.10 riastrad } 335 1.10 riastrad 336 1.10 riastrad ATF_TC(onlydef_static_dynamic_eager); 337 1.10 riastrad ATF_TC_HEAD(onlydef_static_dynamic_eager, tc) 338 1.10 riastrad { 339 1.10 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works," 340 1.10 riastrad " with definition-only library," 341 1.10 riastrad " static load and use, then dynamic load and use"); 342 1.10 riastrad } 343 1.10 riastrad ATF_TC_BODY(onlydef_static_dynamic_eager, tc) 344 1.10 riastrad { 345 1.10 riastrad void *use_static, *use_dynamic; 346 1.10 riastrad int *(*fstatic)(void), *(*fdynamic)(void); 347 1.10 riastrad int *pstatic, *pdynamic; 348 1.10 riastrad 349 1.10 riastrad ATF_REQUIRE_DL(dlopen("libh_onlydef.so", 0)); 350 1.10 riastrad ATF_REQUIRE_DL(use_static = dlopen("libh_onlyuse_static.so", 0)); 351 1.10 riastrad ATF_REQUIRE_DL(fstatic = dlsym(use_static, "fstatic")); 352 1.10 riastrad pstatic = (*fstatic)(); 353 1.10 riastrad ATF_REQUIRE_DL(use_dynamic = dlopen("libh_onlyuse_dynamic.so", 0)); 354 1.10 riastrad ATF_REQUIRE_DL(fdynamic = dlsym(use_dynamic, "fdynamic")); 355 1.10 riastrad pdynamic = (*fdynamic)(); 356 1.10 riastrad ATF_CHECK_EQ_MSG(pstatic, pdynamic, 357 1.10 riastrad "%p in static tls user != %p in dynamic tls user", 358 1.10 riastrad pstatic, pdynamic); 359 1.10 riastrad } 360 1.10 riastrad 361 1.10 riastrad ATF_TC(onlydef_static_dynamic_lazy); 362 1.10 riastrad ATF_TC_HEAD(onlydef_static_dynamic_lazy, tc) 363 1.10 riastrad { 364 1.10 riastrad atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works," 365 1.10 riastrad " with definition-only library, static and dynamic load and use"); 366 1.10 riastrad } 367 1.10 riastrad ATF_TC_BODY(onlydef_static_dynamic_lazy, tc) 368 1.10 riastrad { 369 1.10 riastrad void *use_static, *use_dynamic; 370 1.10 riastrad int *(*fstatic)(void), *(*fdynamic)(void); 371 1.10 riastrad int *pstatic, *pdynamic; 372 1.10 riastrad 373 1.10 riastrad ATF_REQUIRE_DL(dlopen("libh_onlydef.so", 0)); 374 1.10 riastrad ATF_REQUIRE_DL(use_static = dlopen("libh_onlyuse_static.so", 0)); 375 1.10 riastrad ATF_REQUIRE_DL(use_dynamic = dlopen("libh_onlyuse_dynamic.so", 0)); 376 1.10 riastrad ATF_REQUIRE_DL(fstatic = dlsym(use_static, "fstatic")); 377 1.10 riastrad ATF_REQUIRE_DL(fdynamic = dlsym(use_dynamic, "fdynamic")); 378 1.10 riastrad pstatic = (*fstatic)(); 379 1.10 riastrad pdynamic = (*fdynamic)(); 380 1.10 riastrad ATF_CHECK_EQ_MSG(pstatic, pdynamic, 381 1.10 riastrad "%p in static tls user != %p in dynamic tls user", 382 1.10 riastrad pstatic, pdynamic); 383 1.10 riastrad } 384 1.10 riastrad 385 1.15 riastrad ATF_TC(opencloseloop_use); 386 1.15 riastrad ATF_TC_HEAD(opencloseloop_use, tc) 387 1.15 riastrad { 388 1.15 riastrad atf_tc_set_md_var(tc, "descr", "Testing opening and closing in a loop," 389 1.15 riastrad " then opening and using dynamic TLS"); 390 1.15 riastrad } 391 1.15 riastrad ATF_TC_BODY(opencloseloop_use, tc) 392 1.15 riastrad { 393 1.15 riastrad unsigned i; 394 1.15 riastrad void *def, *use; 395 1.15 riastrad int *(*fdef)(void), *(*fuse)(void); 396 1.15 riastrad int *pdef, *puse; 397 1.15 riastrad 398 1.15 riastrad /* 399 1.15 riastrad * Open and close the definition library repeatedly. This 400 1.15 riastrad * should trigger allocation of many DTV offsets, which are 401 1.15 riastrad * (currently) not recycled, so the required DTV offsets should 402 1.15 riastrad * become very long -- pages past what is actually allocated 403 1.15 riastrad * before we attempt to use it. 404 1.15 riastrad * 405 1.15 riastrad * This way, we will exercise the wrong-way-conditional fast 406 1.15 riastrad * path of PR lib/58154. 407 1.15 riastrad */ 408 1.15 riastrad for (i = sysconf(_SC_PAGESIZE); i --> 0;) { 409 1.15 riastrad ATF_REQUIRE_DL(def = dlopen("libh_def_dynamic.so", 0)); 410 1.15 riastrad ATF_REQUIRE_EQ_MSG(dlclose(def), 0, 411 1.15 riastrad "dlclose(def): %s", dlerror()); 412 1.15 riastrad } 413 1.15 riastrad 414 1.15 riastrad /* 415 1.15 riastrad * Now open the definition library and keep it open. 416 1.15 riastrad */ 417 1.15 riastrad ATF_REQUIRE_DL(def = dlopen("libh_def_dynamic.so", 0)); 418 1.15 riastrad ATF_REQUIRE_DL(fdef = dlsym(def, "fdef")); 419 1.15 riastrad 420 1.15 riastrad /* 421 1.15 riastrad * Open libraries that use the definition and verify they 422 1.15 riastrad * observe the same pointer. 423 1.15 riastrad */ 424 1.15 riastrad ATF_REQUIRE_DL(use = dlopen("libh_use_dynamic.so", 0)); 425 1.15 riastrad ATF_REQUIRE_DL(fuse = dlsym(use, "fuse")); 426 1.15 riastrad pdef = (*fdef)(); 427 1.15 riastrad puse = (*fuse)(); 428 1.15 riastrad ATF_CHECK_EQ_MSG(pdef, puse, 429 1.15 riastrad "%p in defining library != %p in using library", 430 1.15 riastrad pdef, puse); 431 1.15 riastrad 432 1.15 riastrad /* 433 1.15 riastrad * Also verify the pointer can be used. 434 1.15 riastrad */ 435 1.15 riastrad *pdef = 123; 436 1.15 riastrad *puse = 456; 437 1.15 riastrad ATF_CHECK_EQ_MSG(*pdef, *puse, 438 1.15 riastrad "%d in defining library != %d in using library", 439 1.15 riastrad *pdef, *puse); 440 1.15 riastrad } 441 1.15 riastrad 442 1.1 riastrad ATF_TP_ADD_TCS(tp) 443 1.1 riastrad { 444 1.3 riastrad 445 1.7 riastrad ATF_TP_ADD_TC(tp, dynamic_abusedef); 446 1.7 riastrad ATF_TP_ADD_TC(tp, dynamic_abusedefnoload); 447 1.8 riastrad ATF_TP_ADD_TC(tp, dynamic_defabuse_eager); 448 1.8 riastrad ATF_TP_ADD_TC(tp, dynamic_defabuse_lazy); 449 1.8 riastrad ATF_TP_ADD_TC(tp, dynamic_defuse_eager); 450 1.8 riastrad ATF_TP_ADD_TC(tp, dynamic_defuse_lazy); 451 1.7 riastrad ATF_TP_ADD_TC(tp, dynamic_usedef); 452 1.7 riastrad ATF_TP_ADD_TC(tp, dynamic_usedefnoload); 453 1.11 riastrad ATF_TP_ADD_TC(tp, onlydef_dynamic_static_ctor); 454 1.10 riastrad ATF_TP_ADD_TC(tp, onlydef_dynamic_static_eager); 455 1.10 riastrad ATF_TP_ADD_TC(tp, onlydef_dynamic_static_lazy); 456 1.10 riastrad ATF_TP_ADD_TC(tp, onlydef_static_dynamic_eager); 457 1.10 riastrad ATF_TP_ADD_TC(tp, onlydef_static_dynamic_lazy); 458 1.15 riastrad ATF_TP_ADD_TC(tp, opencloseloop_use); 459 1.7 riastrad ATF_TP_ADD_TC(tp, static_abusedef); 460 1.7 riastrad ATF_TP_ADD_TC(tp, static_abusedefnoload); 461 1.8 riastrad ATF_TP_ADD_TC(tp, static_defabuse_eager); 462 1.8 riastrad ATF_TP_ADD_TC(tp, static_defabuse_lazy); 463 1.8 riastrad ATF_TP_ADD_TC(tp, static_defuse_eager); 464 1.8 riastrad ATF_TP_ADD_TC(tp, static_defuse_lazy); 465 1.7 riastrad ATF_TP_ADD_TC(tp, static_usedef); 466 1.7 riastrad ATF_TP_ADD_TC(tp, static_usedefnoload); 467 1.1 riastrad return atf_no_error(); 468 1.1 riastrad } 469