Home | History | Annotate | Line # | Download | only in ld.elf_so
t_tls_extern.c revision 1.12
      1  1.12     joerg /*	$NetBSD: t_tls_extern.c,v 1.12 2023/06/04 01:24:58 joerg 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.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.1  riastrad ATF_TP_ADD_TCS(tp)
    386   1.1  riastrad {
    387   1.3  riastrad 
    388   1.7  riastrad 	ATF_TP_ADD_TC(tp, dynamic_abusedef);
    389   1.7  riastrad 	ATF_TP_ADD_TC(tp, dynamic_abusedefnoload);
    390   1.8  riastrad 	ATF_TP_ADD_TC(tp, dynamic_defabuse_eager);
    391   1.8  riastrad 	ATF_TP_ADD_TC(tp, dynamic_defabuse_lazy);
    392   1.8  riastrad 	ATF_TP_ADD_TC(tp, dynamic_defuse_eager);
    393   1.8  riastrad 	ATF_TP_ADD_TC(tp, dynamic_defuse_lazy);
    394   1.7  riastrad 	ATF_TP_ADD_TC(tp, dynamic_usedef);
    395   1.7  riastrad 	ATF_TP_ADD_TC(tp, dynamic_usedefnoload);
    396  1.11  riastrad 	ATF_TP_ADD_TC(tp, onlydef_dynamic_static_ctor);
    397  1.10  riastrad 	ATF_TP_ADD_TC(tp, onlydef_dynamic_static_eager);
    398  1.10  riastrad 	ATF_TP_ADD_TC(tp, onlydef_dynamic_static_lazy);
    399  1.10  riastrad 	ATF_TP_ADD_TC(tp, onlydef_static_dynamic_eager);
    400  1.10  riastrad 	ATF_TP_ADD_TC(tp, onlydef_static_dynamic_lazy);
    401   1.7  riastrad 	ATF_TP_ADD_TC(tp, static_abusedef);
    402   1.7  riastrad 	ATF_TP_ADD_TC(tp, static_abusedefnoload);
    403   1.8  riastrad 	ATF_TP_ADD_TC(tp, static_defabuse_eager);
    404   1.8  riastrad 	ATF_TP_ADD_TC(tp, static_defabuse_lazy);
    405   1.8  riastrad 	ATF_TP_ADD_TC(tp, static_defuse_eager);
    406   1.8  riastrad 	ATF_TP_ADD_TC(tp, static_defuse_lazy);
    407   1.7  riastrad 	ATF_TP_ADD_TC(tp, static_usedef);
    408   1.7  riastrad 	ATF_TP_ADD_TC(tp, static_usedefnoload);
    409   1.1  riastrad 	return atf_no_error();
    410   1.1  riastrad }
    411