1*41caf4e5Sriastradh /* $NetBSD: t_tls_extern.c,v 1.16 2024/07/23 18:11:53 riastradh Exp $ */ 212037d6aSriastradh 312037d6aSriastradh /*- 412037d6aSriastradh * Copyright (c) 2023 The NetBSD Foundation, Inc. 512037d6aSriastradh * All rights reserved. 612037d6aSriastradh * 712037d6aSriastradh * Redistribution and use in source and binary forms, with or without 812037d6aSriastradh * modification, are permitted provided that the following conditions 912037d6aSriastradh * are met: 1012037d6aSriastradh * 1. Redistributions of source code must retain the above copyright 1112037d6aSriastradh * notice, this list of conditions and the following disclaimer. 1212037d6aSriastradh * 2. Redistributions in binary form must reproduce the above copyright 1312037d6aSriastradh * notice, this list of conditions and the following disclaimer in the 1412037d6aSriastradh * documentation and/or other materials provided with the distribution. 1512037d6aSriastradh * 1612037d6aSriastradh * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 1712037d6aSriastradh * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 1812037d6aSriastradh * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 1912037d6aSriastradh * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 2012037d6aSriastradh * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2112037d6aSriastradh * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2212037d6aSriastradh * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2312037d6aSriastradh * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2412037d6aSriastradh * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2512037d6aSriastradh * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2612037d6aSriastradh * POSSIBILITY OF SUCH DAMAGE. 2712037d6aSriastradh */ 2812037d6aSriastradh 2912037d6aSriastradh #include <sys/types.h> 3012037d6aSriastradh 3112037d6aSriastradh #include <atf-c.h> 3212037d6aSriastradh #include <dlfcn.h> 3312037d6aSriastradh 342b3021f9Skre #define ATF_REQUIRE_DL(x) ATF_REQUIRE_MSG((x) != 0, "%s: %s", #x, dlerror()) 3512037d6aSriastradh 36bc9d9d11Sriastradh enum order { 3798256cacSriastradh DEF_USE_EAGER, 3898256cacSriastradh DEF_USE_LAZY, 39bc9d9d11Sriastradh USE_DEF, 40bc9d9d11Sriastradh USE_DEF_NOLOAD, 41bc9d9d11Sriastradh }; 42bc9d9d11Sriastradh 43bc9d9d11Sriastradh static void 443caa8dc7Sjoerg tls_extern(const char *libdef, const char *libuse, enum order order) 45bc9d9d11Sriastradh { 46bc9d9d11Sriastradh void *def, *use; 47bc9d9d11Sriastradh int *(*fdef)(void), *(*fuse)(void); 48bc9d9d11Sriastradh int *pdef, *puse; 49bc9d9d11Sriastradh 50bc9d9d11Sriastradh (void)dlerror(); 51bc9d9d11Sriastradh 52bc9d9d11Sriastradh switch (order) { 5398256cacSriastradh case DEF_USE_EAGER: 5498256cacSriastradh ATF_REQUIRE_DL(def = dlopen(libdef, 0)); 5598256cacSriastradh ATF_REQUIRE_DL(fdef = dlsym(def, "fdef")); 5698256cacSriastradh pdef = (*fdef)(); 5798256cacSriastradh ATF_REQUIRE_DL(use = dlopen(libuse, 0)); 5898256cacSriastradh ATF_REQUIRE_DL(fuse = dlsym(use, "fuse")); 5998256cacSriastradh puse = (*fuse)(); 6098256cacSriastradh break; 6198256cacSriastradh case DEF_USE_LAZY: 62bc9d9d11Sriastradh ATF_REQUIRE_DL(def = dlopen(libdef, 0)); 63bc9d9d11Sriastradh ATF_REQUIRE_DL(use = dlopen(libuse, 0)); 6498256cacSriastradh goto lazy; 65bc9d9d11Sriastradh case USE_DEF: 66bc9d9d11Sriastradh ATF_REQUIRE_DL(use = dlopen(libuse, 0)); 67bc9d9d11Sriastradh ATF_REQUIRE_DL(def = dlopen(libdef, 0)); 6898256cacSriastradh goto lazy; 69bc9d9d11Sriastradh case USE_DEF_NOLOAD: 70bc9d9d11Sriastradh ATF_REQUIRE_DL(use = dlopen(libuse, 0)); 71bc9d9d11Sriastradh ATF_REQUIRE_DL(def = dlopen(libdef, RTLD_NOLOAD)); 7298256cacSriastradh lazy: ATF_REQUIRE_DL(fdef = dlsym(def, "fdef")); 7398256cacSriastradh ATF_REQUIRE_DL(fuse = dlsym(use, "fuse")); 7498256cacSriastradh pdef = (*fdef)(); 7598256cacSriastradh puse = (*fuse)(); 76bc9d9d11Sriastradh break; 77bc9d9d11Sriastradh } 78bc9d9d11Sriastradh 79bc9d9d11Sriastradh ATF_CHECK_EQ_MSG(pdef, puse, 80bc9d9d11Sriastradh "%p in defining library != %p in using library", 81bc9d9d11Sriastradh pdef, puse); 82bc9d9d11Sriastradh } 83bc9d9d11Sriastradh 84e04ffa37Sriastradh ATF_TC(dynamic_abusedef); 85e04ffa37Sriastradh ATF_TC_HEAD(dynamic_abusedef, tc) 866b7ae3beSriastradh { 876b7ae3beSriastradh atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works," 886b7ae3beSriastradh " loading static use than dynamic def"); 896b7ae3beSriastradh } 90e04ffa37Sriastradh ATF_TC_BODY(dynamic_abusedef, tc) 916b7ae3beSriastradh { 923caa8dc7Sjoerg tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so", USE_DEF); 936b7ae3beSriastradh } 946b7ae3beSriastradh 95e04ffa37Sriastradh ATF_TC(dynamic_abusedefnoload); 96e04ffa37Sriastradh ATF_TC_HEAD(dynamic_abusedefnoload, tc) 976b7ae3beSriastradh { 986b7ae3beSriastradh atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works," 996b7ae3beSriastradh " loading static use then dynamic def with RTLD_NOLOAD"); 1006b7ae3beSriastradh } 101e04ffa37Sriastradh ATF_TC_BODY(dynamic_abusedefnoload, tc) 1026b7ae3beSriastradh { 1036b7ae3beSriastradh tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so", 1043caa8dc7Sjoerg USE_DEF_NOLOAD); 1056b7ae3beSriastradh } 1066b7ae3beSriastradh 10798256cacSriastradh ATF_TC(dynamic_defabuse_eager); 10898256cacSriastradh ATF_TC_HEAD(dynamic_defabuse_eager, tc) 1096b7ae3beSriastradh { 1104dedd5fcSriastradh atf_tc_set_md_var(tc, "descr", "dlopen refuses extern __thread for TLS," 11198256cacSriastradh " loading dynamic def then static use eagerly"); 1126b7ae3beSriastradh } 11398256cacSriastradh ATF_TC_BODY(dynamic_defabuse_eager, tc) 1146b7ae3beSriastradh { 1154dedd5fcSriastradh void *def; 1164dedd5fcSriastradh int *(*fdef)(void); 1174dedd5fcSriastradh 1184dedd5fcSriastradh ATF_REQUIRE_DL(def = dlopen("libh_def_dynamic.so", 0)); 1194dedd5fcSriastradh ATF_REQUIRE_DL(fdef = dlsym(def, "fdef")); 1204dedd5fcSriastradh (void)(*fdef)(); 1214dedd5fcSriastradh ATF_CHECK_EQ_MSG(NULL, dlopen("libh_abuse_dynamic.so", 0), 1224dedd5fcSriastradh "dlopen failed to detect static-then-dynamic abuse"); 1236b7ae3beSriastradh } 1246b7ae3beSriastradh 12598256cacSriastradh ATF_TC(dynamic_defabuse_lazy); 12698256cacSriastradh ATF_TC_HEAD(dynamic_defabuse_lazy, tc) 12798256cacSriastradh { 12898256cacSriastradh atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works," 12998256cacSriastradh " loading dynamic def then static use lazily"); 13098256cacSriastradh } 13198256cacSriastradh ATF_TC_BODY(dynamic_defabuse_lazy, tc) 13298256cacSriastradh { 13398256cacSriastradh tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so", 1343caa8dc7Sjoerg DEF_USE_LAZY); 13598256cacSriastradh } 13698256cacSriastradh 13798256cacSriastradh ATF_TC(dynamic_defuse_eager); 13898256cacSriastradh ATF_TC_HEAD(dynamic_defuse_eager, tc) 13905e97b5aSriastradh { 14005e97b5aSriastradh atf_tc_set_md_var(tc, "descr", "extern __thread for dynamic TLS works," 14198256cacSriastradh " loading def then use eagerly"); 14205e97b5aSriastradh } 14398256cacSriastradh ATF_TC_BODY(dynamic_defuse_eager, tc) 14405e97b5aSriastradh { 145bc9d9d11Sriastradh tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so", 1463caa8dc7Sjoerg DEF_USE_EAGER); 14798256cacSriastradh } 14898256cacSriastradh 14998256cacSriastradh ATF_TC(dynamic_defuse_lazy); 15098256cacSriastradh ATF_TC_HEAD(dynamic_defuse_lazy, tc) 15198256cacSriastradh { 15298256cacSriastradh atf_tc_set_md_var(tc, "descr", "extern __thread for dynamic TLS works," 15398256cacSriastradh " loading def then use lazyly"); 15498256cacSriastradh } 15598256cacSriastradh ATF_TC_BODY(dynamic_defuse_lazy, tc) 15698256cacSriastradh { 15798256cacSriastradh tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so", 1583caa8dc7Sjoerg DEF_USE_LAZY); 15905e97b5aSriastradh } 16005e97b5aSriastradh 161e04ffa37Sriastradh ATF_TC(dynamic_usedef); 162e04ffa37Sriastradh ATF_TC_HEAD(dynamic_usedef, tc) 16305e97b5aSriastradh { 16405e97b5aSriastradh atf_tc_set_md_var(tc, "descr", "extern __thread for dynamic TLS works," 16505e97b5aSriastradh " loading use then def"); 16605e97b5aSriastradh } 167e04ffa37Sriastradh ATF_TC_BODY(dynamic_usedef, tc) 16805e97b5aSriastradh { 169bc9d9d11Sriastradh tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so", 1703caa8dc7Sjoerg USE_DEF); 17105e97b5aSriastradh } 17205e97b5aSriastradh 173e04ffa37Sriastradh ATF_TC(dynamic_usedefnoload); 174e04ffa37Sriastradh ATF_TC_HEAD(dynamic_usedefnoload, tc) 17505e97b5aSriastradh { 17605e97b5aSriastradh atf_tc_set_md_var(tc, "descr", "extern __thread for dynamic TLS works," 17705e97b5aSriastradh " loading use then def with RTLD_NOLOAD"); 17805e97b5aSriastradh } 179e04ffa37Sriastradh ATF_TC_BODY(dynamic_usedefnoload, tc) 18005e97b5aSriastradh { 181bc9d9d11Sriastradh tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so", 1823caa8dc7Sjoerg USE_DEF_NOLOAD); 18305e97b5aSriastradh } 18405e97b5aSriastradh 185e04ffa37Sriastradh ATF_TC(static_abusedef); 186e04ffa37Sriastradh ATF_TC_HEAD(static_abusedef, tc) 1876b7ae3beSriastradh { 1886b7ae3beSriastradh atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works," 1896b7ae3beSriastradh " loading dynamic use then static def"); 1906b7ae3beSriastradh } 191e04ffa37Sriastradh ATF_TC_BODY(static_abusedef, tc) 1926b7ae3beSriastradh { 1933caa8dc7Sjoerg tls_extern("libh_def_static.so", "libh_abuse_static.so", USE_DEF); 1946b7ae3beSriastradh } 1956b7ae3beSriastradh 196e04ffa37Sriastradh ATF_TC(static_abusedefnoload); 197e04ffa37Sriastradh ATF_TC_HEAD(static_abusedefnoload, tc) 1986b7ae3beSriastradh { 1996b7ae3beSriastradh atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works," 2006b7ae3beSriastradh " loading dynamic use then static def with RTLD_NOLOAD"); 2016b7ae3beSriastradh } 202e04ffa37Sriastradh ATF_TC_BODY(static_abusedefnoload, tc) 2036b7ae3beSriastradh { 2046b7ae3beSriastradh tls_extern("libh_def_static.so", "libh_abuse_static.so", 2053caa8dc7Sjoerg USE_DEF_NOLOAD); 2066b7ae3beSriastradh } 2076b7ae3beSriastradh 20898256cacSriastradh ATF_TC(static_defabuse_eager); 20998256cacSriastradh ATF_TC_HEAD(static_defabuse_eager, tc) 2106b7ae3beSriastradh { 2116b7ae3beSriastradh atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works," 21298256cacSriastradh " loading static def then dynamic use eagerly"); 2136b7ae3beSriastradh } 21498256cacSriastradh ATF_TC_BODY(static_defabuse_eager, tc) 2156b7ae3beSriastradh { 2166b7ae3beSriastradh tls_extern("libh_def_static.so", "libh_abuse_static.so", 2173caa8dc7Sjoerg DEF_USE_EAGER); 2186b7ae3beSriastradh } 2196b7ae3beSriastradh 22098256cacSriastradh ATF_TC(static_defabuse_lazy); 22198256cacSriastradh ATF_TC_HEAD(static_defabuse_lazy, tc) 22298256cacSriastradh { 22398256cacSriastradh atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works," 22498256cacSriastradh " loading static def then dynamic use lazyly"); 22598256cacSriastradh } 22698256cacSriastradh ATF_TC_BODY(static_defabuse_lazy, tc) 22798256cacSriastradh { 22898256cacSriastradh tls_extern("libh_def_static.so", "libh_abuse_static.so", 2293caa8dc7Sjoerg DEF_USE_LAZY); 23098256cacSriastradh } 23198256cacSriastradh 23298256cacSriastradh ATF_TC(static_defuse_eager); 23398256cacSriastradh ATF_TC_HEAD(static_defuse_eager, tc) 23412037d6aSriastradh { 235f4e155a4Sriastradh atf_tc_set_md_var(tc, "descr", "extern __thread for static TLS works," 23698256cacSriastradh " loading def then use eagerly"); 23712037d6aSriastradh } 23898256cacSriastradh ATF_TC_BODY(static_defuse_eager, tc) 23912037d6aSriastradh { 240bc9d9d11Sriastradh tls_extern("libh_def_static.so", "libh_use_static.so", 2413caa8dc7Sjoerg DEF_USE_EAGER); 24298256cacSriastradh } 24398256cacSriastradh 24498256cacSriastradh ATF_TC(static_defuse_lazy); 24598256cacSriastradh ATF_TC_HEAD(static_defuse_lazy, tc) 24698256cacSriastradh { 24798256cacSriastradh atf_tc_set_md_var(tc, "descr", "extern __thread for static TLS works," 24898256cacSriastradh " loading def then use lazyly"); 24998256cacSriastradh } 25098256cacSriastradh ATF_TC_BODY(static_defuse_lazy, tc) 25198256cacSriastradh { 25298256cacSriastradh tls_extern("libh_def_static.so", "libh_use_static.so", 2533caa8dc7Sjoerg DEF_USE_LAZY); 254f4e155a4Sriastradh } 255f4e155a4Sriastradh 256e04ffa37Sriastradh ATF_TC(static_usedef); 257e04ffa37Sriastradh ATF_TC_HEAD(static_usedef, tc) 258f4e155a4Sriastradh { 259f4e155a4Sriastradh atf_tc_set_md_var(tc, "descr", "extern __thread for static TLS works," 260f4e155a4Sriastradh " loading use then def"); 261f4e155a4Sriastradh } 262e04ffa37Sriastradh ATF_TC_BODY(static_usedef, tc) 263f4e155a4Sriastradh { 264bc9d9d11Sriastradh tls_extern("libh_def_static.so", "libh_use_static.so", 2653caa8dc7Sjoerg USE_DEF); 266f4e155a4Sriastradh } 267f4e155a4Sriastradh 268e04ffa37Sriastradh ATF_TC(static_usedefnoload); 269e04ffa37Sriastradh ATF_TC_HEAD(static_usedefnoload, tc) 270f4e155a4Sriastradh { 271f4e155a4Sriastradh atf_tc_set_md_var(tc, "descr", "extern __thread for static TLS works," 272f4e155a4Sriastradh " loading use then def with RTLD_NOLOAD"); 273f4e155a4Sriastradh } 274e04ffa37Sriastradh ATF_TC_BODY(static_usedefnoload, tc) 275f4e155a4Sriastradh { 276bc9d9d11Sriastradh tls_extern("libh_def_static.so", "libh_use_static.so", 2773caa8dc7Sjoerg USE_DEF_NOLOAD); 27812037d6aSriastradh } 27912037d6aSriastradh 280067c5136Sriastradh ATF_TC(onlydef_dynamic_static_ctor); 281067c5136Sriastradh ATF_TC_HEAD(onlydef_dynamic_static_ctor, tc) 282067c5136Sriastradh { 283067c5136Sriastradh atf_tc_set_md_var(tc, "descr", "definition-only library," 284067c5136Sriastradh " dynamic load and use in ctor, then static load fails"); 285067c5136Sriastradh } 286067c5136Sriastradh ATF_TC_BODY(onlydef_dynamic_static_ctor, tc) 287067c5136Sriastradh { 288067c5136Sriastradh 289067c5136Sriastradh ATF_REQUIRE_DL(dlopen("libh_onlydef.so", 0)); 290067c5136Sriastradh ATF_REQUIRE_DL(dlopen("libh_onlyctor_dynamic.so", 0)); 291067c5136Sriastradh ATF_CHECK_EQ_MSG(NULL, dlopen("libh_onlyuse_static.so", 0), 292067c5136Sriastradh "dlopen failed to detect dynamic-then-static abuse"); 293067c5136Sriastradh } 294067c5136Sriastradh 295f4e534ddSriastradh ATF_TC(onlydef_dynamic_static_eager); 296f4e534ddSriastradh ATF_TC_HEAD(onlydef_dynamic_static_eager, tc) 297f4e534ddSriastradh { 298f4e534ddSriastradh atf_tc_set_md_var(tc, "descr", "definition-only library," 299f4e534ddSriastradh " dynamic load and use, then static load fails"); 300f4e534ddSriastradh } 301f4e534ddSriastradh ATF_TC_BODY(onlydef_dynamic_static_eager, tc) 302f4e534ddSriastradh { 303f4e534ddSriastradh void *use_dynamic; 304f4e534ddSriastradh int *(*fdynamic)(void); 305f4e534ddSriastradh 306f4e534ddSriastradh ATF_REQUIRE_DL(use_dynamic = dlopen("libh_onlyuse_dynamic.so", 0)); 307f4e534ddSriastradh ATF_REQUIRE_DL(fdynamic = dlsym(use_dynamic, "fdynamic")); 308f4e534ddSriastradh (void)(*fdynamic)(); 309f4e534ddSriastradh ATF_CHECK_EQ_MSG(NULL, dlopen("libh_onlyuse_static.so", 0), 310f4e534ddSriastradh "dlopen failed to detect dynamic-then-static abuse"); 311f4e534ddSriastradh } 312f4e534ddSriastradh 313f4e534ddSriastradh ATF_TC(onlydef_dynamic_static_lazy); 314f4e534ddSriastradh ATF_TC_HEAD(onlydef_dynamic_static_lazy, tc) 315f4e534ddSriastradh { 316f4e534ddSriastradh atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works," 317f4e534ddSriastradh " with definition-only library, dynamic and static load and use"); 318f4e534ddSriastradh } 319f4e534ddSriastradh ATF_TC_BODY(onlydef_dynamic_static_lazy, tc) 320f4e534ddSriastradh { 321f4e534ddSriastradh void *use_dynamic, *use_static; 322f4e534ddSriastradh int *(*fdynamic)(void), *(*fstatic)(void); 323f4e534ddSriastradh int *pdynamic, *pstatic; 324f4e534ddSriastradh 325f4e534ddSriastradh ATF_REQUIRE_DL(use_dynamic = dlopen("libh_onlyuse_dynamic.so", 0)); 326f4e534ddSriastradh ATF_REQUIRE_DL(use_static = dlopen("libh_onlyuse_static.so", 0)); 327f4e534ddSriastradh ATF_REQUIRE_DL(fdynamic = dlsym(use_dynamic, "fdynamic")); 328f4e534ddSriastradh ATF_REQUIRE_DL(fstatic = dlsym(use_static, "fstatic")); 329f4e534ddSriastradh pdynamic = (*fdynamic)(); 330f4e534ddSriastradh pstatic = (*fstatic)(); 331f4e534ddSriastradh ATF_CHECK_EQ_MSG(pdynamic, pstatic, 332f4e534ddSriastradh "%p in dynamic tls user != %p in static tls user", 333f4e534ddSriastradh pdynamic, pstatic); 334f4e534ddSriastradh } 335f4e534ddSriastradh 336f4e534ddSriastradh ATF_TC(onlydef_static_dynamic_eager); 337f4e534ddSriastradh ATF_TC_HEAD(onlydef_static_dynamic_eager, tc) 338f4e534ddSriastradh { 339f4e534ddSriastradh atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works," 340f4e534ddSriastradh " with definition-only library," 341f4e534ddSriastradh " static load and use, then dynamic load and use"); 342f4e534ddSriastradh } 343f4e534ddSriastradh ATF_TC_BODY(onlydef_static_dynamic_eager, tc) 344f4e534ddSriastradh { 345f4e534ddSriastradh void *use_static, *use_dynamic; 346f4e534ddSriastradh int *(*fstatic)(void), *(*fdynamic)(void); 347f4e534ddSriastradh int *pstatic, *pdynamic; 348f4e534ddSriastradh 349f4e534ddSriastradh ATF_REQUIRE_DL(dlopen("libh_onlydef.so", 0)); 350f4e534ddSriastradh ATF_REQUIRE_DL(use_static = dlopen("libh_onlyuse_static.so", 0)); 351f4e534ddSriastradh ATF_REQUIRE_DL(fstatic = dlsym(use_static, "fstatic")); 352f4e534ddSriastradh pstatic = (*fstatic)(); 353f4e534ddSriastradh ATF_REQUIRE_DL(use_dynamic = dlopen("libh_onlyuse_dynamic.so", 0)); 354f4e534ddSriastradh ATF_REQUIRE_DL(fdynamic = dlsym(use_dynamic, "fdynamic")); 355f4e534ddSriastradh pdynamic = (*fdynamic)(); 356f4e534ddSriastradh ATF_CHECK_EQ_MSG(pstatic, pdynamic, 357f4e534ddSriastradh "%p in static tls user != %p in dynamic tls user", 358f4e534ddSriastradh pstatic, pdynamic); 359f4e534ddSriastradh } 360f4e534ddSriastradh 361f4e534ddSriastradh ATF_TC(onlydef_static_dynamic_lazy); 362f4e534ddSriastradh ATF_TC_HEAD(onlydef_static_dynamic_lazy, tc) 363f4e534ddSriastradh { 364f4e534ddSriastradh atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works," 365f4e534ddSriastradh " with definition-only library, static and dynamic load and use"); 366f4e534ddSriastradh } 367f4e534ddSriastradh ATF_TC_BODY(onlydef_static_dynamic_lazy, tc) 368f4e534ddSriastradh { 369f4e534ddSriastradh void *use_static, *use_dynamic; 370f4e534ddSriastradh int *(*fstatic)(void), *(*fdynamic)(void); 371f4e534ddSriastradh int *pstatic, *pdynamic; 372f4e534ddSriastradh 373f4e534ddSriastradh ATF_REQUIRE_DL(dlopen("libh_onlydef.so", 0)); 374f4e534ddSriastradh ATF_REQUIRE_DL(use_static = dlopen("libh_onlyuse_static.so", 0)); 375f4e534ddSriastradh ATF_REQUIRE_DL(use_dynamic = dlopen("libh_onlyuse_dynamic.so", 0)); 376f4e534ddSriastradh ATF_REQUIRE_DL(fstatic = dlsym(use_static, "fstatic")); 377f4e534ddSriastradh ATF_REQUIRE_DL(fdynamic = dlsym(use_dynamic, "fdynamic")); 378f4e534ddSriastradh pstatic = (*fstatic)(); 379f4e534ddSriastradh pdynamic = (*fdynamic)(); 380f4e534ddSriastradh ATF_CHECK_EQ_MSG(pstatic, pdynamic, 381f4e534ddSriastradh "%p in static tls user != %p in dynamic tls user", 382f4e534ddSriastradh pstatic, pdynamic); 383f4e534ddSriastradh } 384f4e534ddSriastradh 3859a31d868Sriastradh ATF_TC(opencloseloop_use); 3869a31d868Sriastradh ATF_TC_HEAD(opencloseloop_use, tc) 3879a31d868Sriastradh { 3889a31d868Sriastradh atf_tc_set_md_var(tc, "descr", "Testing opening and closing in a loop," 3899a31d868Sriastradh " then opening and using dynamic TLS"); 3909a31d868Sriastradh } 3919a31d868Sriastradh ATF_TC_BODY(opencloseloop_use, tc) 3929a31d868Sriastradh { 3939a31d868Sriastradh unsigned i; 3949a31d868Sriastradh void *def, *use; 3959a31d868Sriastradh int *(*fdef)(void), *(*fuse)(void); 3969a31d868Sriastradh int *pdef, *puse; 3979a31d868Sriastradh 3989a31d868Sriastradh /* 3999a31d868Sriastradh * Open and close the definition library repeatedly. This 4009a31d868Sriastradh * should trigger allocation of many DTV offsets, which are 4019a31d868Sriastradh * (currently) not recycled, so the required DTV offsets should 4029a31d868Sriastradh * become very long -- pages past what is actually allocated 4039a31d868Sriastradh * before we attempt to use it. 4049a31d868Sriastradh * 4059a31d868Sriastradh * This way, we will exercise the wrong-way-conditional fast 4069a31d868Sriastradh * path of PR lib/58154. 4079a31d868Sriastradh */ 4089a31d868Sriastradh for (i = sysconf(_SC_PAGESIZE); i --> 0;) { 4099a31d868Sriastradh ATF_REQUIRE_DL(def = dlopen("libh_def_dynamic.so", 0)); 4109a31d868Sriastradh ATF_REQUIRE_EQ_MSG(dlclose(def), 0, 4119a31d868Sriastradh "dlclose(def): %s", dlerror()); 4129a31d868Sriastradh } 4139a31d868Sriastradh 4149a31d868Sriastradh /* 4159a31d868Sriastradh * Now open the definition library and keep it open. 4169a31d868Sriastradh */ 4179a31d868Sriastradh ATF_REQUIRE_DL(def = dlopen("libh_def_dynamic.so", 0)); 4189a31d868Sriastradh ATF_REQUIRE_DL(fdef = dlsym(def, "fdef")); 4199a31d868Sriastradh 4209a31d868Sriastradh /* 4219a31d868Sriastradh * Open libraries that use the definition and verify they 4229a31d868Sriastradh * observe the same pointer. 4239a31d868Sriastradh */ 4249a31d868Sriastradh ATF_REQUIRE_DL(use = dlopen("libh_use_dynamic.so", 0)); 4259a31d868Sriastradh ATF_REQUIRE_DL(fuse = dlsym(use, "fuse")); 4269a31d868Sriastradh pdef = (*fdef)(); 4279a31d868Sriastradh puse = (*fuse)(); 4289a31d868Sriastradh ATF_CHECK_EQ_MSG(pdef, puse, 4299a31d868Sriastradh "%p in defining library != %p in using library", 4309a31d868Sriastradh pdef, puse); 4319a31d868Sriastradh 4329a31d868Sriastradh /* 4339a31d868Sriastradh * Also verify the pointer can be used. 4349a31d868Sriastradh */ 4359a31d868Sriastradh *pdef = 123; 4369a31d868Sriastradh *puse = 456; 4379a31d868Sriastradh ATF_CHECK_EQ_MSG(*pdef, *puse, 4389a31d868Sriastradh "%d in defining library != %d in using library", 4399a31d868Sriastradh *pdef, *puse); 4409a31d868Sriastradh } 4419a31d868Sriastradh 44212037d6aSriastradh ATF_TP_ADD_TCS(tp) 44312037d6aSriastradh { 444f4e155a4Sriastradh 445e04ffa37Sriastradh ATF_TP_ADD_TC(tp, dynamic_abusedef); 446e04ffa37Sriastradh ATF_TP_ADD_TC(tp, dynamic_abusedefnoload); 44798256cacSriastradh ATF_TP_ADD_TC(tp, dynamic_defabuse_eager); 44898256cacSriastradh ATF_TP_ADD_TC(tp, dynamic_defabuse_lazy); 44998256cacSriastradh ATF_TP_ADD_TC(tp, dynamic_defuse_eager); 45098256cacSriastradh ATF_TP_ADD_TC(tp, dynamic_defuse_lazy); 451e04ffa37Sriastradh ATF_TP_ADD_TC(tp, dynamic_usedef); 452e04ffa37Sriastradh ATF_TP_ADD_TC(tp, dynamic_usedefnoload); 453067c5136Sriastradh ATF_TP_ADD_TC(tp, onlydef_dynamic_static_ctor); 454f4e534ddSriastradh ATF_TP_ADD_TC(tp, onlydef_dynamic_static_eager); 455f4e534ddSriastradh ATF_TP_ADD_TC(tp, onlydef_dynamic_static_lazy); 456f4e534ddSriastradh ATF_TP_ADD_TC(tp, onlydef_static_dynamic_eager); 457f4e534ddSriastradh ATF_TP_ADD_TC(tp, onlydef_static_dynamic_lazy); 4589a31d868Sriastradh ATF_TP_ADD_TC(tp, opencloseloop_use); 459e04ffa37Sriastradh ATF_TP_ADD_TC(tp, static_abusedef); 460e04ffa37Sriastradh ATF_TP_ADD_TC(tp, static_abusedefnoload); 46198256cacSriastradh ATF_TP_ADD_TC(tp, static_defabuse_eager); 46298256cacSriastradh ATF_TP_ADD_TC(tp, static_defabuse_lazy); 46398256cacSriastradh ATF_TP_ADD_TC(tp, static_defuse_eager); 46498256cacSriastradh ATF_TP_ADD_TC(tp, static_defuse_lazy); 465e04ffa37Sriastradh ATF_TP_ADD_TC(tp, static_usedef); 466e04ffa37Sriastradh ATF_TP_ADD_TC(tp, static_usedefnoload); 46712037d6aSriastradh return atf_no_error(); 46812037d6aSriastradh } 469