Home | History | Annotate | Line # | Download | only in ld.elf_so
t_tls_extern.c revision 1.15
      1  1.15  riastrad /*	$NetBSD: t_tls_extern.c,v 1.15 2024/07/22 23:18:30 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.15  riastrad #include <signal.h>
     34   1.1  riastrad 
     35  1.14       kre #define	ATF_REQUIRE_DL(x) ATF_REQUIRE_MSG((x) != 0, "%s: %s", #x, dlerror())
     36   1.1  riastrad 
     37   1.5  riastrad enum order {
     38   1.8  riastrad 	DEF_USE_EAGER,
     39   1.8  riastrad 	DEF_USE_LAZY,
     40   1.5  riastrad 	USE_DEF,
     41   1.5  riastrad 	USE_DEF_NOLOAD,
     42   1.5  riastrad };
     43   1.5  riastrad 
     44   1.5  riastrad static void
     45  1.12     joerg tls_extern(const char *libdef, const char *libuse, enum order order)
     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.4  riastrad 	ATF_CHECK_EQ_MSG(pdef, puse,
     81   1.4  riastrad 	    "%p in defining library != %p in using library",
     82   1.4  riastrad 	    pdef, puse);
     83   1.4  riastrad }
     84   1.4  riastrad 
     85   1.7  riastrad ATF_TC(dynamic_abusedef);
     86   1.7  riastrad ATF_TC_HEAD(dynamic_abusedef, tc)
     87   1.6  riastrad {
     88   1.6  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
     89   1.6  riastrad 	    " loading static use than dynamic def");
     90   1.6  riastrad }
     91   1.7  riastrad ATF_TC_BODY(dynamic_abusedef, tc)
     92   1.6  riastrad {
     93  1.12     joerg 	tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so", USE_DEF);
     94   1.6  riastrad }
     95   1.6  riastrad 
     96   1.7  riastrad ATF_TC(dynamic_abusedefnoload);
     97   1.7  riastrad ATF_TC_HEAD(dynamic_abusedefnoload, tc)
     98   1.6  riastrad {
     99   1.6  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
    100   1.6  riastrad 	    " loading static use then dynamic def with RTLD_NOLOAD");
    101   1.6  riastrad }
    102   1.7  riastrad ATF_TC_BODY(dynamic_abusedefnoload, tc)
    103   1.6  riastrad {
    104   1.6  riastrad 	tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so",
    105  1.12     joerg 	    USE_DEF_NOLOAD);
    106   1.6  riastrad }
    107   1.6  riastrad 
    108   1.8  riastrad ATF_TC(dynamic_defabuse_eager);
    109   1.8  riastrad ATF_TC_HEAD(dynamic_defabuse_eager, tc)
    110   1.8  riastrad {
    111   1.9  riastrad 	atf_tc_set_md_var(tc, "descr", "dlopen refuses extern __thread for TLS,"
    112   1.8  riastrad 	    " loading dynamic def then static use eagerly");
    113   1.8  riastrad }
    114   1.8  riastrad ATF_TC_BODY(dynamic_defabuse_eager, tc)
    115   1.8  riastrad {
    116   1.9  riastrad 	void *def;
    117   1.9  riastrad 	int *(*fdef)(void);
    118   1.9  riastrad 
    119   1.9  riastrad 	ATF_REQUIRE_DL(def = dlopen("libh_def_dynamic.so", 0));
    120   1.9  riastrad 	ATF_REQUIRE_DL(fdef = dlsym(def, "fdef"));
    121   1.9  riastrad 	(void)(*fdef)();
    122   1.9  riastrad 	ATF_CHECK_EQ_MSG(NULL, dlopen("libh_abuse_dynamic.so", 0),
    123   1.9  riastrad 	    "dlopen failed to detect static-then-dynamic abuse");
    124   1.8  riastrad }
    125   1.8  riastrad 
    126   1.8  riastrad ATF_TC(dynamic_defabuse_lazy);
    127   1.8  riastrad ATF_TC_HEAD(dynamic_defabuse_lazy, tc)
    128   1.6  riastrad {
    129   1.6  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
    130   1.8  riastrad 	    " loading dynamic def then static use lazily");
    131   1.6  riastrad }
    132   1.8  riastrad ATF_TC_BODY(dynamic_defabuse_lazy, tc)
    133   1.6  riastrad {
    134   1.6  riastrad 	tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so",
    135  1.12     joerg 	    DEF_USE_LAZY);
    136   1.8  riastrad }
    137   1.8  riastrad 
    138   1.8  riastrad ATF_TC(dynamic_defuse_eager);
    139   1.8  riastrad ATF_TC_HEAD(dynamic_defuse_eager, tc)
    140   1.8  riastrad {
    141   1.8  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for dynamic TLS works,"
    142   1.8  riastrad 	    " loading def then use eagerly");
    143   1.8  riastrad }
    144   1.8  riastrad ATF_TC_BODY(dynamic_defuse_eager, tc)
    145   1.8  riastrad {
    146   1.8  riastrad 	tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so",
    147  1.12     joerg 	    DEF_USE_EAGER);
    148   1.6  riastrad }
    149   1.6  riastrad 
    150   1.8  riastrad ATF_TC(dynamic_defuse_lazy);
    151   1.8  riastrad ATF_TC_HEAD(dynamic_defuse_lazy, tc)
    152   1.5  riastrad {
    153   1.5  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for dynamic TLS works,"
    154   1.8  riastrad 	    " loading def then use lazyly");
    155   1.5  riastrad }
    156   1.8  riastrad ATF_TC_BODY(dynamic_defuse_lazy, tc)
    157   1.5  riastrad {
    158   1.5  riastrad 	tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so",
    159  1.12     joerg 	    DEF_USE_LAZY);
    160   1.5  riastrad }
    161   1.5  riastrad 
    162   1.7  riastrad ATF_TC(dynamic_usedef);
    163   1.7  riastrad ATF_TC_HEAD(dynamic_usedef, tc)
    164   1.4  riastrad {
    165   1.4  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for dynamic TLS works,"
    166   1.4  riastrad 	    " loading use then def");
    167   1.4  riastrad }
    168   1.7  riastrad ATF_TC_BODY(dynamic_usedef, tc)
    169   1.4  riastrad {
    170   1.5  riastrad 	tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so",
    171  1.12     joerg 	    USE_DEF);
    172   1.4  riastrad }
    173   1.4  riastrad 
    174   1.7  riastrad ATF_TC(dynamic_usedefnoload);
    175   1.7  riastrad ATF_TC_HEAD(dynamic_usedefnoload, tc)
    176   1.4  riastrad {
    177   1.4  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for dynamic TLS works,"
    178   1.4  riastrad 	    " loading use then def with RTLD_NOLOAD");
    179   1.4  riastrad }
    180   1.7  riastrad ATF_TC_BODY(dynamic_usedefnoload, tc)
    181   1.4  riastrad {
    182   1.5  riastrad 	tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so",
    183  1.12     joerg 	    USE_DEF_NOLOAD);
    184   1.4  riastrad }
    185   1.4  riastrad 
    186   1.7  riastrad ATF_TC(static_abusedef);
    187   1.7  riastrad ATF_TC_HEAD(static_abusedef, tc)
    188   1.6  riastrad {
    189   1.6  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
    190   1.6  riastrad 	    " loading dynamic use then static def");
    191   1.6  riastrad }
    192   1.7  riastrad ATF_TC_BODY(static_abusedef, tc)
    193   1.6  riastrad {
    194  1.12     joerg 	tls_extern("libh_def_static.so", "libh_abuse_static.so", USE_DEF);
    195   1.6  riastrad }
    196   1.6  riastrad 
    197   1.7  riastrad ATF_TC(static_abusedefnoload);
    198   1.7  riastrad ATF_TC_HEAD(static_abusedefnoload, tc)
    199   1.6  riastrad {
    200   1.6  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
    201   1.6  riastrad 	    " loading dynamic use then static def with RTLD_NOLOAD");
    202   1.6  riastrad }
    203   1.7  riastrad ATF_TC_BODY(static_abusedefnoload, tc)
    204   1.6  riastrad {
    205   1.6  riastrad 	tls_extern("libh_def_static.so", "libh_abuse_static.so",
    206  1.12     joerg 	    USE_DEF_NOLOAD);
    207   1.6  riastrad }
    208   1.6  riastrad 
    209   1.8  riastrad ATF_TC(static_defabuse_eager);
    210   1.8  riastrad ATF_TC_HEAD(static_defabuse_eager, tc)
    211   1.8  riastrad {
    212   1.8  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
    213   1.8  riastrad 	    " loading static def then dynamic use eagerly");
    214   1.8  riastrad }
    215   1.8  riastrad ATF_TC_BODY(static_defabuse_eager, tc)
    216   1.8  riastrad {
    217   1.8  riastrad 	tls_extern("libh_def_static.so", "libh_abuse_static.so",
    218  1.12     joerg 	    DEF_USE_EAGER);
    219   1.8  riastrad }
    220   1.8  riastrad 
    221   1.8  riastrad ATF_TC(static_defabuse_lazy);
    222   1.8  riastrad ATF_TC_HEAD(static_defabuse_lazy, tc)
    223   1.6  riastrad {
    224   1.6  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
    225   1.8  riastrad 	    " loading static def then dynamic use lazyly");
    226   1.6  riastrad }
    227   1.8  riastrad ATF_TC_BODY(static_defabuse_lazy, tc)
    228   1.6  riastrad {
    229   1.6  riastrad 	tls_extern("libh_def_static.so", "libh_abuse_static.so",
    230  1.12     joerg 	    DEF_USE_LAZY);
    231   1.8  riastrad }
    232   1.8  riastrad 
    233   1.8  riastrad ATF_TC(static_defuse_eager);
    234   1.8  riastrad ATF_TC_HEAD(static_defuse_eager, tc)
    235   1.8  riastrad {
    236   1.8  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for static TLS works,"
    237   1.8  riastrad 	    " loading def then use eagerly");
    238   1.8  riastrad }
    239   1.8  riastrad ATF_TC_BODY(static_defuse_eager, tc)
    240   1.8  riastrad {
    241   1.8  riastrad 	tls_extern("libh_def_static.so", "libh_use_static.so",
    242  1.12     joerg 	    DEF_USE_EAGER);
    243   1.6  riastrad }
    244   1.6  riastrad 
    245   1.8  riastrad ATF_TC(static_defuse_lazy);
    246   1.8  riastrad ATF_TC_HEAD(static_defuse_lazy, tc)
    247   1.1  riastrad {
    248   1.3  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for static TLS works,"
    249   1.8  riastrad 	    " loading def then use lazyly");
    250   1.1  riastrad }
    251   1.8  riastrad ATF_TC_BODY(static_defuse_lazy, tc)
    252   1.1  riastrad {
    253   1.5  riastrad 	tls_extern("libh_def_static.so", "libh_use_static.so",
    254  1.12     joerg 	    DEF_USE_LAZY);
    255   1.3  riastrad }
    256   1.3  riastrad 
    257   1.7  riastrad ATF_TC(static_usedef);
    258   1.7  riastrad ATF_TC_HEAD(static_usedef, tc)
    259   1.3  riastrad {
    260   1.3  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for static TLS works,"
    261   1.3  riastrad 	    " loading use then def");
    262   1.3  riastrad }
    263   1.7  riastrad ATF_TC_BODY(static_usedef, tc)
    264   1.3  riastrad {
    265   1.5  riastrad 	tls_extern("libh_def_static.so", "libh_use_static.so",
    266  1.12     joerg 	    USE_DEF);
    267   1.3  riastrad }
    268   1.3  riastrad 
    269   1.7  riastrad ATF_TC(static_usedefnoload);
    270   1.7  riastrad ATF_TC_HEAD(static_usedefnoload, tc)
    271   1.3  riastrad {
    272   1.3  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for static TLS works,"
    273   1.3  riastrad 	    " loading use then def with RTLD_NOLOAD");
    274   1.3  riastrad }
    275   1.7  riastrad ATF_TC_BODY(static_usedefnoload, tc)
    276   1.3  riastrad {
    277   1.5  riastrad 	tls_extern("libh_def_static.so", "libh_use_static.so",
    278  1.12     joerg 	    USE_DEF_NOLOAD);
    279   1.1  riastrad }
    280   1.1  riastrad 
    281  1.11  riastrad ATF_TC(onlydef_dynamic_static_ctor);
    282  1.11  riastrad ATF_TC_HEAD(onlydef_dynamic_static_ctor, tc)
    283  1.11  riastrad {
    284  1.11  riastrad 	atf_tc_set_md_var(tc, "descr", "definition-only library,"
    285  1.11  riastrad 	    " dynamic load and use in ctor, then static load fails");
    286  1.11  riastrad }
    287  1.11  riastrad ATF_TC_BODY(onlydef_dynamic_static_ctor, tc)
    288  1.11  riastrad {
    289  1.11  riastrad 
    290  1.11  riastrad 	ATF_REQUIRE_DL(dlopen("libh_onlydef.so", 0));
    291  1.11  riastrad 	ATF_REQUIRE_DL(dlopen("libh_onlyctor_dynamic.so", 0));
    292  1.11  riastrad 	ATF_CHECK_EQ_MSG(NULL, dlopen("libh_onlyuse_static.so", 0),
    293  1.11  riastrad 	    "dlopen failed to detect dynamic-then-static abuse");
    294  1.11  riastrad }
    295  1.11  riastrad 
    296  1.10  riastrad ATF_TC(onlydef_dynamic_static_eager);
    297  1.10  riastrad ATF_TC_HEAD(onlydef_dynamic_static_eager, tc)
    298  1.10  riastrad {
    299  1.10  riastrad 	atf_tc_set_md_var(tc, "descr", "definition-only library,"
    300  1.10  riastrad 	    " dynamic load and use, then static load fails");
    301  1.10  riastrad }
    302  1.10  riastrad ATF_TC_BODY(onlydef_dynamic_static_eager, tc)
    303  1.10  riastrad {
    304  1.10  riastrad 	void *use_dynamic;
    305  1.10  riastrad 	int *(*fdynamic)(void);
    306  1.10  riastrad 
    307  1.10  riastrad 	ATF_REQUIRE_DL(use_dynamic = dlopen("libh_onlyuse_dynamic.so", 0));
    308  1.10  riastrad 	ATF_REQUIRE_DL(fdynamic = dlsym(use_dynamic, "fdynamic"));
    309  1.10  riastrad 	(void)(*fdynamic)();
    310  1.10  riastrad 	ATF_CHECK_EQ_MSG(NULL, dlopen("libh_onlyuse_static.so", 0),
    311  1.10  riastrad 	    "dlopen failed to detect dynamic-then-static abuse");
    312  1.10  riastrad }
    313  1.10  riastrad 
    314  1.10  riastrad ATF_TC(onlydef_dynamic_static_lazy);
    315  1.10  riastrad ATF_TC_HEAD(onlydef_dynamic_static_lazy, tc)
    316  1.10  riastrad {
    317  1.10  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
    318  1.10  riastrad 	    " with definition-only library, dynamic and static load and use");
    319  1.10  riastrad }
    320  1.10  riastrad ATF_TC_BODY(onlydef_dynamic_static_lazy, tc)
    321  1.10  riastrad {
    322  1.10  riastrad 	void *use_dynamic, *use_static;
    323  1.10  riastrad 	int *(*fdynamic)(void), *(*fstatic)(void);
    324  1.10  riastrad 	int *pdynamic, *pstatic;
    325  1.10  riastrad 
    326  1.10  riastrad 	ATF_REQUIRE_DL(use_dynamic = dlopen("libh_onlyuse_dynamic.so", 0));
    327  1.10  riastrad 	ATF_REQUIRE_DL(use_static = dlopen("libh_onlyuse_static.so", 0));
    328  1.10  riastrad 	ATF_REQUIRE_DL(fdynamic = dlsym(use_dynamic, "fdynamic"));
    329  1.10  riastrad 	ATF_REQUIRE_DL(fstatic = dlsym(use_static, "fstatic"));
    330  1.10  riastrad 	pdynamic = (*fdynamic)();
    331  1.10  riastrad 	pstatic = (*fstatic)();
    332  1.10  riastrad 	ATF_CHECK_EQ_MSG(pdynamic, pstatic,
    333  1.10  riastrad 	    "%p in dynamic tls user != %p in static tls user",
    334  1.10  riastrad 	    pdynamic, pstatic);
    335  1.10  riastrad }
    336  1.10  riastrad 
    337  1.10  riastrad ATF_TC(onlydef_static_dynamic_eager);
    338  1.10  riastrad ATF_TC_HEAD(onlydef_static_dynamic_eager, tc)
    339  1.10  riastrad {
    340  1.10  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
    341  1.10  riastrad 	    " with definition-only library,"
    342  1.10  riastrad 	    " static load and use, then dynamic load and use");
    343  1.10  riastrad }
    344  1.10  riastrad ATF_TC_BODY(onlydef_static_dynamic_eager, tc)
    345  1.10  riastrad {
    346  1.10  riastrad 	void *use_static, *use_dynamic;
    347  1.10  riastrad 	int *(*fstatic)(void), *(*fdynamic)(void);
    348  1.10  riastrad 	int *pstatic, *pdynamic;
    349  1.10  riastrad 
    350  1.10  riastrad 	ATF_REQUIRE_DL(dlopen("libh_onlydef.so", 0));
    351  1.10  riastrad 	ATF_REQUIRE_DL(use_static = dlopen("libh_onlyuse_static.so", 0));
    352  1.10  riastrad 	ATF_REQUIRE_DL(fstatic = dlsym(use_static, "fstatic"));
    353  1.10  riastrad 	pstatic = (*fstatic)();
    354  1.10  riastrad 	ATF_REQUIRE_DL(use_dynamic = dlopen("libh_onlyuse_dynamic.so", 0));
    355  1.10  riastrad 	ATF_REQUIRE_DL(fdynamic = dlsym(use_dynamic, "fdynamic"));
    356  1.10  riastrad 	pdynamic = (*fdynamic)();
    357  1.10  riastrad 	ATF_CHECK_EQ_MSG(pstatic, pdynamic,
    358  1.10  riastrad 	    "%p in static tls user != %p in dynamic tls user",
    359  1.10  riastrad 	    pstatic, pdynamic);
    360  1.10  riastrad }
    361  1.10  riastrad 
    362  1.10  riastrad ATF_TC(onlydef_static_dynamic_lazy);
    363  1.10  riastrad ATF_TC_HEAD(onlydef_static_dynamic_lazy, tc)
    364  1.10  riastrad {
    365  1.10  riastrad 	atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
    366  1.10  riastrad 	    " with definition-only library, static and dynamic load and use");
    367  1.10  riastrad }
    368  1.10  riastrad ATF_TC_BODY(onlydef_static_dynamic_lazy, tc)
    369  1.10  riastrad {
    370  1.10  riastrad 	void *use_static, *use_dynamic;
    371  1.10  riastrad 	int *(*fstatic)(void), *(*fdynamic)(void);
    372  1.10  riastrad 	int *pstatic, *pdynamic;
    373  1.10  riastrad 
    374  1.10  riastrad 	ATF_REQUIRE_DL(dlopen("libh_onlydef.so", 0));
    375  1.10  riastrad 	ATF_REQUIRE_DL(use_static = dlopen("libh_onlyuse_static.so", 0));
    376  1.10  riastrad 	ATF_REQUIRE_DL(use_dynamic = dlopen("libh_onlyuse_dynamic.so", 0));
    377  1.10  riastrad 	ATF_REQUIRE_DL(fstatic = dlsym(use_static, "fstatic"));
    378  1.10  riastrad 	ATF_REQUIRE_DL(fdynamic = dlsym(use_dynamic, "fdynamic"));
    379  1.10  riastrad 	pstatic = (*fstatic)();
    380  1.10  riastrad 	pdynamic = (*fdynamic)();
    381  1.10  riastrad 	ATF_CHECK_EQ_MSG(pstatic, pdynamic,
    382  1.10  riastrad 	    "%p in static tls user != %p in dynamic tls user",
    383  1.10  riastrad 	    pstatic, pdynamic);
    384  1.10  riastrad }
    385  1.10  riastrad 
    386  1.15  riastrad ATF_TC(opencloseloop_use);
    387  1.15  riastrad ATF_TC_HEAD(opencloseloop_use, tc)
    388  1.15  riastrad {
    389  1.15  riastrad 	atf_tc_set_md_var(tc, "descr", "Testing opening and closing in a loop,"
    390  1.15  riastrad 	    " then opening and using dynamic TLS");
    391  1.15  riastrad }
    392  1.15  riastrad ATF_TC_BODY(opencloseloop_use, tc)
    393  1.15  riastrad {
    394  1.15  riastrad 	unsigned i;
    395  1.15  riastrad 	void *def, *use;
    396  1.15  riastrad 	int *(*fdef)(void), *(*fuse)(void);
    397  1.15  riastrad 	int *pdef, *puse;
    398  1.15  riastrad 
    399  1.15  riastrad 	/*
    400  1.15  riastrad 	 * Open and close the definition library repeatedly.  This
    401  1.15  riastrad 	 * should trigger allocation of many DTV offsets, which are
    402  1.15  riastrad 	 * (currently) not recycled, so the required DTV offsets should
    403  1.15  riastrad 	 * become very long -- pages past what is actually allocated
    404  1.15  riastrad 	 * before we attempt to use it.
    405  1.15  riastrad 	 *
    406  1.15  riastrad 	 * This way, we will exercise the wrong-way-conditional fast
    407  1.15  riastrad 	 * path of PR lib/58154.
    408  1.15  riastrad 	 */
    409  1.15  riastrad 	for (i = sysconf(_SC_PAGESIZE); i --> 0;) {
    410  1.15  riastrad 		ATF_REQUIRE_DL(def = dlopen("libh_def_dynamic.so", 0));
    411  1.15  riastrad 		ATF_REQUIRE_EQ_MSG(dlclose(def), 0,
    412  1.15  riastrad 		    "dlclose(def): %s", dlerror());
    413  1.15  riastrad 	}
    414  1.15  riastrad 
    415  1.15  riastrad 	/*
    416  1.15  riastrad 	 * Now open the definition library and keep it open.
    417  1.15  riastrad 	 */
    418  1.15  riastrad 	ATF_REQUIRE_DL(def = dlopen("libh_def_dynamic.so", 0));
    419  1.15  riastrad 	ATF_REQUIRE_DL(fdef = dlsym(def, "fdef"));
    420  1.15  riastrad 
    421  1.15  riastrad 	/*
    422  1.15  riastrad 	 * Open libraries that use the definition and verify they
    423  1.15  riastrad 	 * observe the same pointer.
    424  1.15  riastrad 	 */
    425  1.15  riastrad 	ATF_REQUIRE_DL(use = dlopen("libh_use_dynamic.so", 0));
    426  1.15  riastrad 	ATF_REQUIRE_DL(fuse = dlsym(use, "fuse"));
    427  1.15  riastrad #ifdef __aarch64__
    428  1.15  riastrad 	atf_tc_expect_signal(SIGSEGV,
    429  1.15  riastrad 	    "PR lib/58154: bad fast path test in aarch64 tls");
    430  1.15  riastrad #endif
    431  1.15  riastrad 	pdef = (*fdef)();
    432  1.15  riastrad 	puse = (*fuse)();
    433  1.15  riastrad 	ATF_CHECK_EQ_MSG(pdef, puse,
    434  1.15  riastrad 	    "%p in defining library != %p in using library",
    435  1.15  riastrad 	    pdef, puse);
    436  1.15  riastrad 
    437  1.15  riastrad 	/*
    438  1.15  riastrad 	 * Also verify the pointer can be used.
    439  1.15  riastrad 	 */
    440  1.15  riastrad 	*pdef = 123;
    441  1.15  riastrad 	*puse = 456;
    442  1.15  riastrad 	ATF_CHECK_EQ_MSG(*pdef, *puse,
    443  1.15  riastrad 	    "%d in defining library != %d in using library",
    444  1.15  riastrad 	    *pdef, *puse);
    445  1.15  riastrad }
    446  1.15  riastrad 
    447   1.1  riastrad ATF_TP_ADD_TCS(tp)
    448   1.1  riastrad {
    449   1.3  riastrad 
    450   1.7  riastrad 	ATF_TP_ADD_TC(tp, dynamic_abusedef);
    451   1.7  riastrad 	ATF_TP_ADD_TC(tp, dynamic_abusedefnoload);
    452   1.8  riastrad 	ATF_TP_ADD_TC(tp, dynamic_defabuse_eager);
    453   1.8  riastrad 	ATF_TP_ADD_TC(tp, dynamic_defabuse_lazy);
    454   1.8  riastrad 	ATF_TP_ADD_TC(tp, dynamic_defuse_eager);
    455   1.8  riastrad 	ATF_TP_ADD_TC(tp, dynamic_defuse_lazy);
    456   1.7  riastrad 	ATF_TP_ADD_TC(tp, dynamic_usedef);
    457   1.7  riastrad 	ATF_TP_ADD_TC(tp, dynamic_usedefnoload);
    458  1.11  riastrad 	ATF_TP_ADD_TC(tp, onlydef_dynamic_static_ctor);
    459  1.10  riastrad 	ATF_TP_ADD_TC(tp, onlydef_dynamic_static_eager);
    460  1.10  riastrad 	ATF_TP_ADD_TC(tp, onlydef_dynamic_static_lazy);
    461  1.10  riastrad 	ATF_TP_ADD_TC(tp, onlydef_static_dynamic_eager);
    462  1.10  riastrad 	ATF_TP_ADD_TC(tp, onlydef_static_dynamic_lazy);
    463  1.15  riastrad 	ATF_TP_ADD_TC(tp, opencloseloop_use);
    464   1.7  riastrad 	ATF_TP_ADD_TC(tp, static_abusedef);
    465   1.7  riastrad 	ATF_TP_ADD_TC(tp, static_abusedefnoload);
    466   1.8  riastrad 	ATF_TP_ADD_TC(tp, static_defabuse_eager);
    467   1.8  riastrad 	ATF_TP_ADD_TC(tp, static_defabuse_lazy);
    468   1.8  riastrad 	ATF_TP_ADD_TC(tp, static_defuse_eager);
    469   1.8  riastrad 	ATF_TP_ADD_TC(tp, static_defuse_lazy);
    470   1.7  riastrad 	ATF_TP_ADD_TC(tp, static_usedef);
    471   1.7  riastrad 	ATF_TP_ADD_TC(tp, static_usedefnoload);
    472   1.1  riastrad 	return atf_no_error();
    473   1.1  riastrad }
    474