Home | History | Annotate | Line # | Download | only in ld.elf_so
t_tls_extern.c revision 1.10
      1  1.10  riastrad /*	$NetBSD: t_tls_extern.c,v 1.10 2023/06/02 19:08:48 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.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.5  riastrad tls_extern(const char *libdef, const char *libuse, enum order order,
     45   1.5  riastrad     bool xfail)
     46   1.4  riastrad {
     47   1.4  riastrad 	void *def, *use;
     48   1.4  riastrad 	int *(*fdef)(void), *(*fuse)(void);
     49   1.4  riastrad 	int *pdef, *puse;
     50   1.4  riastrad 
     51   1.4  riastrad 	(void)dlerror();
     52   1.4  riastrad 
     53   1.5  riastrad 	switch (order) {
     54   1.8  riastrad 	case DEF_USE_EAGER:
     55   1.5  riastrad 		ATF_REQUIRE_DL(def = dlopen(libdef, 0));
     56   1.8  riastrad 		ATF_REQUIRE_DL(fdef = dlsym(def, "fdef"));
     57   1.8  riastrad 		pdef = (*fdef)();
     58   1.5  riastrad 		ATF_REQUIRE_DL(use = dlopen(libuse, 0));
     59   1.8  riastrad 		ATF_REQUIRE_DL(fuse = dlsym(use, "fuse"));
     60   1.8  riastrad 		puse = (*fuse)();
     61   1.5  riastrad 		break;
     62   1.8  riastrad 	case DEF_USE_LAZY:
     63   1.8  riastrad 		ATF_REQUIRE_DL(def = dlopen(libdef, 0));
     64   1.8  riastrad 		ATF_REQUIRE_DL(use = dlopen(libuse, 0));
     65   1.8  riastrad 		goto lazy;
     66   1.5  riastrad 	case USE_DEF:
     67   1.5  riastrad 		ATF_REQUIRE_DL(use = dlopen(libuse, 0));
     68   1.5  riastrad 		ATF_REQUIRE_DL(def = dlopen(libdef, 0));
     69   1.8  riastrad 		goto lazy;
     70   1.5  riastrad 	case USE_DEF_NOLOAD:
     71   1.5  riastrad 		ATF_REQUIRE_DL(use = dlopen(libuse, 0));
     72   1.5  riastrad 		ATF_REQUIRE_DL(def = dlopen(libdef, RTLD_NOLOAD));
     73   1.8  riastrad lazy:		ATF_REQUIRE_DL(fdef = dlsym(def, "fdef"));
     74   1.8  riastrad 		ATF_REQUIRE_DL(fuse = dlsym(use, "fuse"));
     75   1.8  riastrad 		pdef = (*fdef)();
     76   1.8  riastrad 		puse = (*fuse)();
     77   1.5  riastrad 		break;
     78   1.5  riastrad 	}
     79   1.4  riastrad 
     80   1.5  riastrad 	if (xfail) {
     81   1.5  riastrad 		atf_tc_expect_fail("PR toolchain/50277:"
     82   1.5  riastrad 		    " rtld relocation bug with thread local storage");
     83   1.5  riastrad 	}
     84   1.4  riastrad 	ATF_CHECK_EQ_MSG(pdef, puse,
     85   1.4  riastrad 	    "%p in defining library != %p in using library",
     86   1.4  riastrad 	    pdef, puse);
     87   1.4  riastrad }
     88   1.4  riastrad 
     89   1.7  riastrad ATF_TC(dynamic_abusedef);
     90   1.7  riastrad ATF_TC_HEAD(dynamic_abusedef, tc)
     91   1.6  riastrad {
     92   1.6  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
     93   1.6  riastrad 	    " loading static use than dynamic def");
     94   1.6  riastrad }
     95   1.7  riastrad ATF_TC_BODY(dynamic_abusedef, tc)
     96   1.6  riastrad {
     97   1.6  riastrad 	tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so",
     98   1.6  riastrad 	    USE_DEF, /*xfail*/true);
     99   1.6  riastrad }
    100   1.6  riastrad 
    101   1.7  riastrad ATF_TC(dynamic_abusedefnoload);
    102   1.7  riastrad ATF_TC_HEAD(dynamic_abusedefnoload, tc)
    103   1.6  riastrad {
    104   1.6  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
    105   1.6  riastrad 	    " loading static use then dynamic def with RTLD_NOLOAD");
    106   1.6  riastrad }
    107   1.7  riastrad ATF_TC_BODY(dynamic_abusedefnoload, tc)
    108   1.6  riastrad {
    109   1.6  riastrad 	tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so",
    110   1.6  riastrad 	    USE_DEF_NOLOAD, /*xfail*/true);
    111   1.6  riastrad }
    112   1.6  riastrad 
    113   1.8  riastrad ATF_TC(dynamic_defabuse_eager);
    114   1.8  riastrad ATF_TC_HEAD(dynamic_defabuse_eager, tc)
    115   1.8  riastrad {
    116   1.9  riastrad 	atf_tc_set_md_var(tc, "descr", "dlopen refuses extern __thread for TLS,"
    117   1.8  riastrad 	    " loading dynamic def then static use eagerly");
    118   1.8  riastrad }
    119   1.8  riastrad ATF_TC_BODY(dynamic_defabuse_eager, tc)
    120   1.8  riastrad {
    121   1.9  riastrad 	void *def;
    122   1.9  riastrad 	int *(*fdef)(void);
    123   1.9  riastrad 
    124   1.9  riastrad 	ATF_REQUIRE_DL(def = dlopen("libh_def_dynamic.so", 0));
    125   1.9  riastrad 	ATF_REQUIRE_DL(fdef = dlsym(def, "fdef"));
    126   1.9  riastrad 	(void)(*fdef)();
    127   1.9  riastrad 	atf_tc_expect_fail("rtld fails to detect dynamic-then-static abuse");
    128   1.9  riastrad 	ATF_CHECK_EQ_MSG(NULL, dlopen("libh_abuse_dynamic.so", 0),
    129   1.9  riastrad 	    "dlopen failed to detect static-then-dynamic abuse");
    130   1.8  riastrad }
    131   1.8  riastrad 
    132   1.8  riastrad ATF_TC(dynamic_defabuse_lazy);
    133   1.8  riastrad ATF_TC_HEAD(dynamic_defabuse_lazy, tc)
    134   1.6  riastrad {
    135   1.6  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
    136   1.8  riastrad 	    " loading dynamic def then static use lazily");
    137   1.6  riastrad }
    138   1.8  riastrad ATF_TC_BODY(dynamic_defabuse_lazy, tc)
    139   1.6  riastrad {
    140   1.6  riastrad 	tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so",
    141   1.8  riastrad 	    DEF_USE_LAZY, /*xfail*/true);
    142   1.8  riastrad }
    143   1.8  riastrad 
    144   1.8  riastrad ATF_TC(dynamic_defuse_eager);
    145   1.8  riastrad ATF_TC_HEAD(dynamic_defuse_eager, tc)
    146   1.8  riastrad {
    147   1.8  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for dynamic TLS works,"
    148   1.8  riastrad 	    " loading def then use eagerly");
    149   1.8  riastrad }
    150   1.8  riastrad ATF_TC_BODY(dynamic_defuse_eager, tc)
    151   1.8  riastrad {
    152   1.8  riastrad 	tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so",
    153   1.8  riastrad 	    DEF_USE_EAGER, /*xfail*/false);
    154   1.6  riastrad }
    155   1.6  riastrad 
    156   1.8  riastrad ATF_TC(dynamic_defuse_lazy);
    157   1.8  riastrad ATF_TC_HEAD(dynamic_defuse_lazy, tc)
    158   1.5  riastrad {
    159   1.5  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for dynamic TLS works,"
    160   1.8  riastrad 	    " loading def then use lazyly");
    161   1.5  riastrad }
    162   1.8  riastrad ATF_TC_BODY(dynamic_defuse_lazy, tc)
    163   1.5  riastrad {
    164   1.5  riastrad 	tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so",
    165   1.8  riastrad 	    DEF_USE_LAZY, /*xfail*/false);
    166   1.5  riastrad }
    167   1.5  riastrad 
    168   1.7  riastrad ATF_TC(dynamic_usedef);
    169   1.7  riastrad ATF_TC_HEAD(dynamic_usedef, tc)
    170   1.4  riastrad {
    171   1.4  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for dynamic TLS works,"
    172   1.4  riastrad 	    " loading use then def");
    173   1.4  riastrad }
    174   1.7  riastrad ATF_TC_BODY(dynamic_usedef, tc)
    175   1.4  riastrad {
    176   1.5  riastrad 	tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so",
    177   1.5  riastrad 	    USE_DEF, /*xfail*/false);
    178   1.4  riastrad }
    179   1.4  riastrad 
    180   1.7  riastrad ATF_TC(dynamic_usedefnoload);
    181   1.7  riastrad ATF_TC_HEAD(dynamic_usedefnoload, tc)
    182   1.4  riastrad {
    183   1.4  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for dynamic TLS works,"
    184   1.4  riastrad 	    " loading use then def with RTLD_NOLOAD");
    185   1.4  riastrad }
    186   1.7  riastrad ATF_TC_BODY(dynamic_usedefnoload, tc)
    187   1.4  riastrad {
    188   1.5  riastrad 	tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so",
    189   1.5  riastrad 	    USE_DEF_NOLOAD, /*xfail*/false);
    190   1.4  riastrad }
    191   1.4  riastrad 
    192   1.7  riastrad ATF_TC(static_abusedef);
    193   1.7  riastrad ATF_TC_HEAD(static_abusedef, tc)
    194   1.6  riastrad {
    195   1.6  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
    196   1.6  riastrad 	    " loading dynamic use then static def");
    197   1.6  riastrad }
    198   1.7  riastrad ATF_TC_BODY(static_abusedef, tc)
    199   1.6  riastrad {
    200   1.6  riastrad 	tls_extern("libh_def_static.so", "libh_abuse_static.so",
    201   1.6  riastrad 	    USE_DEF, /*xfail*/true);
    202   1.6  riastrad }
    203   1.6  riastrad 
    204   1.7  riastrad ATF_TC(static_abusedefnoload);
    205   1.7  riastrad ATF_TC_HEAD(static_abusedefnoload, tc)
    206   1.6  riastrad {
    207   1.6  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
    208   1.6  riastrad 	    " loading dynamic use then static def with RTLD_NOLOAD");
    209   1.6  riastrad }
    210   1.7  riastrad ATF_TC_BODY(static_abusedefnoload, tc)
    211   1.6  riastrad {
    212   1.6  riastrad 	tls_extern("libh_def_static.so", "libh_abuse_static.so",
    213   1.6  riastrad 	    USE_DEF_NOLOAD, /*xfail*/true);
    214   1.6  riastrad }
    215   1.6  riastrad 
    216   1.8  riastrad ATF_TC(static_defabuse_eager);
    217   1.8  riastrad ATF_TC_HEAD(static_defabuse_eager, tc)
    218   1.8  riastrad {
    219   1.8  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
    220   1.8  riastrad 	    " loading static def then dynamic use eagerly");
    221   1.8  riastrad }
    222   1.8  riastrad ATF_TC_BODY(static_defabuse_eager, tc)
    223   1.8  riastrad {
    224   1.8  riastrad 	tls_extern("libh_def_static.so", "libh_abuse_static.so",
    225   1.8  riastrad 	    DEF_USE_EAGER, /*xfail*/true);
    226   1.8  riastrad }
    227   1.8  riastrad 
    228   1.8  riastrad ATF_TC(static_defabuse_lazy);
    229   1.8  riastrad ATF_TC_HEAD(static_defabuse_lazy, tc)
    230   1.6  riastrad {
    231   1.6  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
    232   1.8  riastrad 	    " loading static def then dynamic use lazyly");
    233   1.6  riastrad }
    234   1.8  riastrad ATF_TC_BODY(static_defabuse_lazy, tc)
    235   1.6  riastrad {
    236   1.6  riastrad 	tls_extern("libh_def_static.so", "libh_abuse_static.so",
    237   1.8  riastrad 	    DEF_USE_LAZY, /*xfail*/true);
    238   1.8  riastrad }
    239   1.8  riastrad 
    240   1.8  riastrad ATF_TC(static_defuse_eager);
    241   1.8  riastrad ATF_TC_HEAD(static_defuse_eager, tc)
    242   1.8  riastrad {
    243   1.8  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for static TLS works,"
    244   1.8  riastrad 	    " loading def then use eagerly");
    245   1.8  riastrad }
    246   1.8  riastrad ATF_TC_BODY(static_defuse_eager, tc)
    247   1.8  riastrad {
    248   1.8  riastrad 	tls_extern("libh_def_static.so", "libh_use_static.so",
    249   1.8  riastrad 	    DEF_USE_EAGER, /*xfail*/false);
    250   1.6  riastrad }
    251   1.6  riastrad 
    252   1.8  riastrad ATF_TC(static_defuse_lazy);
    253   1.8  riastrad ATF_TC_HEAD(static_defuse_lazy, tc)
    254   1.1  riastrad {
    255   1.3  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for static TLS works,"
    256   1.8  riastrad 	    " loading def then use lazyly");
    257   1.1  riastrad }
    258   1.8  riastrad ATF_TC_BODY(static_defuse_lazy, tc)
    259   1.1  riastrad {
    260   1.5  riastrad 	tls_extern("libh_def_static.so", "libh_use_static.so",
    261   1.8  riastrad 	    DEF_USE_LAZY, /*xfail*/false);
    262   1.3  riastrad }
    263   1.3  riastrad 
    264   1.7  riastrad ATF_TC(static_usedef);
    265   1.7  riastrad ATF_TC_HEAD(static_usedef, tc)
    266   1.3  riastrad {
    267   1.3  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for static TLS works,"
    268   1.3  riastrad 	    " loading use then def");
    269   1.3  riastrad }
    270   1.7  riastrad ATF_TC_BODY(static_usedef, tc)
    271   1.3  riastrad {
    272   1.5  riastrad 	tls_extern("libh_def_static.so", "libh_use_static.so",
    273   1.5  riastrad 	    USE_DEF, /*xfail*/true);
    274   1.3  riastrad }
    275   1.3  riastrad 
    276   1.7  riastrad ATF_TC(static_usedefnoload);
    277   1.7  riastrad ATF_TC_HEAD(static_usedefnoload, tc)
    278   1.3  riastrad {
    279   1.3  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for static TLS works,"
    280   1.3  riastrad 	    " loading use then def with RTLD_NOLOAD");
    281   1.3  riastrad }
    282   1.7  riastrad ATF_TC_BODY(static_usedefnoload, tc)
    283   1.3  riastrad {
    284   1.5  riastrad 	tls_extern("libh_def_static.so", "libh_use_static.so",
    285   1.5  riastrad 	    USE_DEF_NOLOAD, /*xfail*/true);
    286   1.1  riastrad }
    287   1.1  riastrad 
    288  1.10  riastrad ATF_TC(onlydef_dynamic_static_eager);
    289  1.10  riastrad ATF_TC_HEAD(onlydef_dynamic_static_eager, tc)
    290  1.10  riastrad {
    291  1.10  riastrad 	atf_tc_set_md_var(tc, "descr", "definition-only library,"
    292  1.10  riastrad 	    " dynamic load and use, then static load fails");
    293  1.10  riastrad }
    294  1.10  riastrad ATF_TC_BODY(onlydef_dynamic_static_eager, tc)
    295  1.10  riastrad {
    296  1.10  riastrad 	void *use_dynamic;
    297  1.10  riastrad 	int *(*fdynamic)(void);
    298  1.10  riastrad 
    299  1.10  riastrad 	ATF_REQUIRE_DL(use_dynamic = dlopen("libh_onlyuse_dynamic.so", 0));
    300  1.10  riastrad 	ATF_REQUIRE_DL(fdynamic = dlsym(use_dynamic, "fdynamic"));
    301  1.10  riastrad 	(void)(*fdynamic)();
    302  1.10  riastrad 	atf_tc_expect_fail("rtld fails to detect dynamic-then-static abuse");
    303  1.10  riastrad 	ATF_CHECK_EQ_MSG(NULL, dlopen("libh_onlyuse_static.so", 0),
    304  1.10  riastrad 	    "dlopen failed to detect dynamic-then-static abuse");
    305  1.10  riastrad }
    306  1.10  riastrad 
    307  1.10  riastrad ATF_TC(onlydef_dynamic_static_lazy);
    308  1.10  riastrad ATF_TC_HEAD(onlydef_dynamic_static_lazy, tc)
    309  1.10  riastrad {
    310  1.10  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
    311  1.10  riastrad 	    " with definition-only library, dynamic and static load and use");
    312  1.10  riastrad }
    313  1.10  riastrad ATF_TC_BODY(onlydef_dynamic_static_lazy, tc)
    314  1.10  riastrad {
    315  1.10  riastrad 	void *use_dynamic, *use_static;
    316  1.10  riastrad 	int *(*fdynamic)(void), *(*fstatic)(void);
    317  1.10  riastrad 	int *pdynamic, *pstatic;
    318  1.10  riastrad 
    319  1.10  riastrad 	ATF_REQUIRE_DL(use_dynamic = dlopen("libh_onlyuse_dynamic.so", 0));
    320  1.10  riastrad 	ATF_REQUIRE_DL(use_static = dlopen("libh_onlyuse_static.so", 0));
    321  1.10  riastrad 	ATF_REQUIRE_DL(fdynamic = dlsym(use_dynamic, "fdynamic"));
    322  1.10  riastrad 	ATF_REQUIRE_DL(fstatic = dlsym(use_static, "fstatic"));
    323  1.10  riastrad 	pdynamic = (*fdynamic)();
    324  1.10  riastrad 	pstatic = (*fstatic)();
    325  1.10  riastrad 	atf_tc_expect_fail("PR toolchain/50277:"
    326  1.10  riastrad 	    " rtld relocation bug with thread local storage");
    327  1.10  riastrad 	ATF_CHECK_EQ_MSG(pdynamic, pstatic,
    328  1.10  riastrad 	    "%p in dynamic tls user != %p in static tls user",
    329  1.10  riastrad 	    pdynamic, pstatic);
    330  1.10  riastrad }
    331  1.10  riastrad 
    332  1.10  riastrad ATF_TC(onlydef_static_dynamic_eager);
    333  1.10  riastrad ATF_TC_HEAD(onlydef_static_dynamic_eager, tc)
    334  1.10  riastrad {
    335  1.10  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
    336  1.10  riastrad 	    " with definition-only library,"
    337  1.10  riastrad 	    " static load and use, then dynamic load and use");
    338  1.10  riastrad }
    339  1.10  riastrad ATF_TC_BODY(onlydef_static_dynamic_eager, tc)
    340  1.10  riastrad {
    341  1.10  riastrad 	void *use_static, *use_dynamic;
    342  1.10  riastrad 	int *(*fstatic)(void), *(*fdynamic)(void);
    343  1.10  riastrad 	int *pstatic, *pdynamic;
    344  1.10  riastrad 
    345  1.10  riastrad 	ATF_REQUIRE_DL(dlopen("libh_onlydef.so", 0));
    346  1.10  riastrad 	ATF_REQUIRE_DL(use_static = dlopen("libh_onlyuse_static.so", 0));
    347  1.10  riastrad 	ATF_REQUIRE_DL(fstatic = dlsym(use_static, "fstatic"));
    348  1.10  riastrad 	pstatic = (*fstatic)();
    349  1.10  riastrad 	ATF_REQUIRE_DL(use_dynamic = dlopen("libh_onlyuse_dynamic.so", 0));
    350  1.10  riastrad 	ATF_REQUIRE_DL(fdynamic = dlsym(use_dynamic, "fdynamic"));
    351  1.10  riastrad 	pdynamic = (*fdynamic)();
    352  1.10  riastrad 	atf_tc_expect_fail("PR toolchain/50277:"
    353  1.10  riastrad 	    " rtld relocation bug with thread local storage");
    354  1.10  riastrad 	ATF_CHECK_EQ_MSG(pstatic, pdynamic,
    355  1.10  riastrad 	    "%p in static tls user != %p in dynamic tls user",
    356  1.10  riastrad 	    pstatic, pdynamic);
    357  1.10  riastrad }
    358  1.10  riastrad 
    359  1.10  riastrad ATF_TC(onlydef_static_dynamic_lazy);
    360  1.10  riastrad ATF_TC_HEAD(onlydef_static_dynamic_lazy, tc)
    361  1.10  riastrad {
    362  1.10  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
    363  1.10  riastrad 	    " with definition-only library, static and dynamic load and use");
    364  1.10  riastrad }
    365  1.10  riastrad ATF_TC_BODY(onlydef_static_dynamic_lazy, tc)
    366  1.10  riastrad {
    367  1.10  riastrad 	void *use_static, *use_dynamic;
    368  1.10  riastrad 	int *(*fstatic)(void), *(*fdynamic)(void);
    369  1.10  riastrad 	int *pstatic, *pdynamic;
    370  1.10  riastrad 
    371  1.10  riastrad 	ATF_REQUIRE_DL(dlopen("libh_onlydef.so", 0));
    372  1.10  riastrad 	ATF_REQUIRE_DL(use_static = dlopen("libh_onlyuse_static.so", 0));
    373  1.10  riastrad 	ATF_REQUIRE_DL(use_dynamic = dlopen("libh_onlyuse_dynamic.so", 0));
    374  1.10  riastrad 	ATF_REQUIRE_DL(fstatic = dlsym(use_static, "fstatic"));
    375  1.10  riastrad 	ATF_REQUIRE_DL(fdynamic = dlsym(use_dynamic, "fdynamic"));
    376  1.10  riastrad 	pstatic = (*fstatic)();
    377  1.10  riastrad 	pdynamic = (*fdynamic)();
    378  1.10  riastrad 	atf_tc_expect_fail("PR toolchain/50277:"
    379  1.10  riastrad 	    " rtld relocation bug with thread local storage");
    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.10  riastrad 	ATF_TP_ADD_TC(tp, onlydef_dynamic_static_eager);
    397  1.10  riastrad 	ATF_TP_ADD_TC(tp, onlydef_dynamic_static_lazy);
    398  1.10  riastrad 	ATF_TP_ADD_TC(tp, onlydef_static_dynamic_eager);
    399  1.10  riastrad 	ATF_TP_ADD_TC(tp, onlydef_static_dynamic_lazy);
    400   1.7  riastrad 	ATF_TP_ADD_TC(tp, static_abusedef);
    401   1.7  riastrad 	ATF_TP_ADD_TC(tp, static_abusedefnoload);
    402   1.8  riastrad 	ATF_TP_ADD_TC(tp, static_defabuse_eager);
    403   1.8  riastrad 	ATF_TP_ADD_TC(tp, static_defabuse_lazy);
    404   1.8  riastrad 	ATF_TP_ADD_TC(tp, static_defuse_eager);
    405   1.8  riastrad 	ATF_TP_ADD_TC(tp, static_defuse_lazy);
    406   1.7  riastrad 	ATF_TP_ADD_TC(tp, static_usedef);
    407   1.7  riastrad 	ATF_TP_ADD_TC(tp, static_usedefnoload);
    408   1.1  riastrad 	return atf_no_error();
    409   1.1  riastrad }
    410