Home | History | Annotate | Line # | Download | only in ld.elf_so
t_tls_extern.c revision 1.12.6.1
      1  1.12.6.1  perseant /*	$NetBSD: t_tls_extern.c,v 1.12.6.1 2025/08/02 05:58:10 perseant 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.12.6.1  perseant #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.12.6.1  perseant ATF_TC(opencloseloop_use);
    386  1.12.6.1  perseant ATF_TC_HEAD(opencloseloop_use, tc)
    387  1.12.6.1  perseant {
    388  1.12.6.1  perseant 	atf_tc_set_md_var(tc, "descr", "Testing opening and closing in a loop,"
    389  1.12.6.1  perseant 	    " then opening and using dynamic TLS");
    390  1.12.6.1  perseant }
    391  1.12.6.1  perseant ATF_TC_BODY(opencloseloop_use, tc)
    392  1.12.6.1  perseant {
    393  1.12.6.1  perseant 	unsigned i;
    394  1.12.6.1  perseant 	void *def, *use;
    395  1.12.6.1  perseant 	int *(*fdef)(void), *(*fuse)(void);
    396  1.12.6.1  perseant 	int *pdef, *puse;
    397  1.12.6.1  perseant 
    398  1.12.6.1  perseant 	/*
    399  1.12.6.1  perseant 	 * Open and close the definition library repeatedly.  This
    400  1.12.6.1  perseant 	 * should trigger allocation of many DTV offsets, which are
    401  1.12.6.1  perseant 	 * (currently) not recycled, so the required DTV offsets should
    402  1.12.6.1  perseant 	 * become very long -- pages past what is actually allocated
    403  1.12.6.1  perseant 	 * before we attempt to use it.
    404  1.12.6.1  perseant 	 *
    405  1.12.6.1  perseant 	 * This way, we will exercise the wrong-way-conditional fast
    406  1.12.6.1  perseant 	 * path of PR lib/58154.
    407  1.12.6.1  perseant 	 */
    408  1.12.6.1  perseant 	for (i = sysconf(_SC_PAGESIZE); i --> 0;) {
    409  1.12.6.1  perseant 		ATF_REQUIRE_DL(def = dlopen("libh_def_dynamic.so", 0));
    410  1.12.6.1  perseant 		ATF_REQUIRE_EQ_MSG(dlclose(def), 0,
    411  1.12.6.1  perseant 		    "dlclose(def): %s", dlerror());
    412  1.12.6.1  perseant 	}
    413  1.12.6.1  perseant 
    414  1.12.6.1  perseant 	/*
    415  1.12.6.1  perseant 	 * Now open the definition library and keep it open.
    416  1.12.6.1  perseant 	 */
    417  1.12.6.1  perseant 	ATF_REQUIRE_DL(def = dlopen("libh_def_dynamic.so", 0));
    418  1.12.6.1  perseant 	ATF_REQUIRE_DL(fdef = dlsym(def, "fdef"));
    419  1.12.6.1  perseant 
    420  1.12.6.1  perseant 	/*
    421  1.12.6.1  perseant 	 * Open libraries that use the definition and verify they
    422  1.12.6.1  perseant 	 * observe the same pointer.
    423  1.12.6.1  perseant 	 */
    424  1.12.6.1  perseant 	ATF_REQUIRE_DL(use = dlopen("libh_use_dynamic.so", 0));
    425  1.12.6.1  perseant 	ATF_REQUIRE_DL(fuse = dlsym(use, "fuse"));
    426  1.12.6.1  perseant 	pdef = (*fdef)();
    427  1.12.6.1  perseant 	puse = (*fuse)();
    428  1.12.6.1  perseant 	ATF_CHECK_EQ_MSG(pdef, puse,
    429  1.12.6.1  perseant 	    "%p in defining library != %p in using library",
    430  1.12.6.1  perseant 	    pdef, puse);
    431  1.12.6.1  perseant 
    432  1.12.6.1  perseant 	/*
    433  1.12.6.1  perseant 	 * Also verify the pointer can be used.
    434  1.12.6.1  perseant 	 */
    435  1.12.6.1  perseant 	*pdef = 123;
    436  1.12.6.1  perseant 	*puse = 456;
    437  1.12.6.1  perseant 	ATF_CHECK_EQ_MSG(*pdef, *puse,
    438  1.12.6.1  perseant 	    "%d in defining library != %d in using library",
    439  1.12.6.1  perseant 	    *pdef, *puse);
    440  1.12.6.1  perseant }
    441  1.12.6.1  perseant 
    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.12.6.1  perseant 	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