Home | History | Annotate | Line # | Download | only in ld.elf_so
t_tls_extern.c revision 1.8
      1 /*	$NetBSD: t_tls_extern.c,v 1.8 2023/06/01 23:47:24 riastradh Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2023 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     18  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     26  * POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #include <sys/types.h>
     30 
     31 #include <atf-c.h>
     32 #include <dlfcn.h>
     33 
     34 #define	ATF_REQUIRE_DL(x)	ATF_REQUIRE_MSG(x, "%s: %s", #x, dlerror())
     35 
     36 enum order {
     37 	DEF_USE_EAGER,
     38 	DEF_USE_LAZY,
     39 	USE_DEF,
     40 	USE_DEF_NOLOAD,
     41 };
     42 
     43 static void
     44 tls_extern(const char *libdef, const char *libuse, enum order order,
     45     bool xfail)
     46 {
     47 	void *def, *use;
     48 	int *(*fdef)(void), *(*fuse)(void);
     49 	int *pdef, *puse;
     50 
     51 	(void)dlerror();
     52 
     53 	switch (order) {
     54 	case DEF_USE_EAGER:
     55 		ATF_REQUIRE_DL(def = dlopen(libdef, 0));
     56 		ATF_REQUIRE_DL(fdef = dlsym(def, "fdef"));
     57 		pdef = (*fdef)();
     58 		ATF_REQUIRE_DL(use = dlopen(libuse, 0));
     59 		ATF_REQUIRE_DL(fuse = dlsym(use, "fuse"));
     60 		puse = (*fuse)();
     61 		break;
     62 	case DEF_USE_LAZY:
     63 		ATF_REQUIRE_DL(def = dlopen(libdef, 0));
     64 		ATF_REQUIRE_DL(use = dlopen(libuse, 0));
     65 		goto lazy;
     66 	case USE_DEF:
     67 		ATF_REQUIRE_DL(use = dlopen(libuse, 0));
     68 		ATF_REQUIRE_DL(def = dlopen(libdef, 0));
     69 		goto lazy;
     70 	case USE_DEF_NOLOAD:
     71 		ATF_REQUIRE_DL(use = dlopen(libuse, 0));
     72 		ATF_REQUIRE_DL(def = dlopen(libdef, RTLD_NOLOAD));
     73 lazy:		ATF_REQUIRE_DL(fdef = dlsym(def, "fdef"));
     74 		ATF_REQUIRE_DL(fuse = dlsym(use, "fuse"));
     75 		pdef = (*fdef)();
     76 		puse = (*fuse)();
     77 		break;
     78 	}
     79 
     80 	if (xfail) {
     81 		atf_tc_expect_fail("PR toolchain/50277:"
     82 		    " rtld relocation bug with thread local storage");
     83 	}
     84 	ATF_CHECK_EQ_MSG(pdef, puse,
     85 	    "%p in defining library != %p in using library",
     86 	    pdef, puse);
     87 }
     88 
     89 ATF_TC(dynamic_abusedef);
     90 ATF_TC_HEAD(dynamic_abusedef, tc)
     91 {
     92 	atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
     93 	    " loading static use than dynamic def");
     94 }
     95 ATF_TC_BODY(dynamic_abusedef, tc)
     96 {
     97 	tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so",
     98 	    USE_DEF, /*xfail*/true);
     99 }
    100 
    101 ATF_TC(dynamic_abusedefnoload);
    102 ATF_TC_HEAD(dynamic_abusedefnoload, tc)
    103 {
    104 	atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
    105 	    " loading static use then dynamic def with RTLD_NOLOAD");
    106 }
    107 ATF_TC_BODY(dynamic_abusedefnoload, tc)
    108 {
    109 	tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so",
    110 	    USE_DEF_NOLOAD, /*xfail*/true);
    111 }
    112 
    113 ATF_TC(dynamic_defabuse_eager);
    114 ATF_TC_HEAD(dynamic_defabuse_eager, tc)
    115 {
    116 	atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
    117 	    " loading dynamic def then static use eagerly");
    118 }
    119 ATF_TC_BODY(dynamic_defabuse_eager, tc)
    120 {
    121 	tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so",
    122 	    DEF_USE_EAGER, /*xfail*/true);
    123 }
    124 
    125 ATF_TC(dynamic_defabuse_lazy);
    126 ATF_TC_HEAD(dynamic_defabuse_lazy, tc)
    127 {
    128 	atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
    129 	    " loading dynamic def then static use lazily");
    130 }
    131 ATF_TC_BODY(dynamic_defabuse_lazy, tc)
    132 {
    133 	tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so",
    134 	    DEF_USE_LAZY, /*xfail*/true);
    135 }
    136 
    137 ATF_TC(dynamic_defuse_eager);
    138 ATF_TC_HEAD(dynamic_defuse_eager, tc)
    139 {
    140 	atf_tc_set_md_var(tc, "descr", "extern __thread for dynamic TLS works,"
    141 	    " loading def then use eagerly");
    142 }
    143 ATF_TC_BODY(dynamic_defuse_eager, tc)
    144 {
    145 	tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so",
    146 	    DEF_USE_EAGER, /*xfail*/false);
    147 }
    148 
    149 ATF_TC(dynamic_defuse_lazy);
    150 ATF_TC_HEAD(dynamic_defuse_lazy, tc)
    151 {
    152 	atf_tc_set_md_var(tc, "descr", "extern __thread for dynamic TLS works,"
    153 	    " loading def then use lazyly");
    154 }
    155 ATF_TC_BODY(dynamic_defuse_lazy, tc)
    156 {
    157 	tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so",
    158 	    DEF_USE_LAZY, /*xfail*/false);
    159 }
    160 
    161 ATF_TC(dynamic_usedef);
    162 ATF_TC_HEAD(dynamic_usedef, tc)
    163 {
    164 	atf_tc_set_md_var(tc, "descr", "extern __thread for dynamic TLS works,"
    165 	    " loading use then def");
    166 }
    167 ATF_TC_BODY(dynamic_usedef, tc)
    168 {
    169 	tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so",
    170 	    USE_DEF, /*xfail*/false);
    171 }
    172 
    173 ATF_TC(dynamic_usedefnoload);
    174 ATF_TC_HEAD(dynamic_usedefnoload, tc)
    175 {
    176 	atf_tc_set_md_var(tc, "descr", "extern __thread for dynamic TLS works,"
    177 	    " loading use then def with RTLD_NOLOAD");
    178 }
    179 ATF_TC_BODY(dynamic_usedefnoload, tc)
    180 {
    181 	tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so",
    182 	    USE_DEF_NOLOAD, /*xfail*/false);
    183 }
    184 
    185 ATF_TC(static_abusedef);
    186 ATF_TC_HEAD(static_abusedef, tc)
    187 {
    188 	atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
    189 	    " loading dynamic use then static def");
    190 }
    191 ATF_TC_BODY(static_abusedef, tc)
    192 {
    193 	tls_extern("libh_def_static.so", "libh_abuse_static.so",
    194 	    USE_DEF, /*xfail*/true);
    195 }
    196 
    197 ATF_TC(static_abusedefnoload);
    198 ATF_TC_HEAD(static_abusedefnoload, tc)
    199 {
    200 	atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
    201 	    " loading dynamic use then static def with RTLD_NOLOAD");
    202 }
    203 ATF_TC_BODY(static_abusedefnoload, tc)
    204 {
    205 	tls_extern("libh_def_static.so", "libh_abuse_static.so",
    206 	    USE_DEF_NOLOAD, /*xfail*/true);
    207 }
    208 
    209 ATF_TC(static_defabuse_eager);
    210 ATF_TC_HEAD(static_defabuse_eager, tc)
    211 {
    212 	atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
    213 	    " loading static def then dynamic use eagerly");
    214 }
    215 ATF_TC_BODY(static_defabuse_eager, tc)
    216 {
    217 	tls_extern("libh_def_static.so", "libh_abuse_static.so",
    218 	    DEF_USE_EAGER, /*xfail*/true);
    219 }
    220 
    221 ATF_TC(static_defabuse_lazy);
    222 ATF_TC_HEAD(static_defabuse_lazy, tc)
    223 {
    224 	atf_tc_set_md_var(tc, "descr", "extern __thread for TLS works,"
    225 	    " loading static def then dynamic use lazyly");
    226 }
    227 ATF_TC_BODY(static_defabuse_lazy, tc)
    228 {
    229 	tls_extern("libh_def_static.so", "libh_abuse_static.so",
    230 	    DEF_USE_LAZY, /*xfail*/true);
    231 }
    232 
    233 ATF_TC(static_defuse_eager);
    234 ATF_TC_HEAD(static_defuse_eager, tc)
    235 {
    236 	atf_tc_set_md_var(tc, "descr", "extern __thread for static TLS works,"
    237 	    " loading def then use eagerly");
    238 }
    239 ATF_TC_BODY(static_defuse_eager, tc)
    240 {
    241 	tls_extern("libh_def_static.so", "libh_use_static.so",
    242 	    DEF_USE_EAGER, /*xfail*/false);
    243 }
    244 
    245 ATF_TC(static_defuse_lazy);
    246 ATF_TC_HEAD(static_defuse_lazy, tc)
    247 {
    248 	atf_tc_set_md_var(tc, "descr", "extern __thread for static TLS works,"
    249 	    " loading def then use lazyly");
    250 }
    251 ATF_TC_BODY(static_defuse_lazy, tc)
    252 {
    253 	tls_extern("libh_def_static.so", "libh_use_static.so",
    254 	    DEF_USE_LAZY, /*xfail*/false);
    255 }
    256 
    257 ATF_TC(static_usedef);
    258 ATF_TC_HEAD(static_usedef, tc)
    259 {
    260 	atf_tc_set_md_var(tc, "descr", "extern __thread for static TLS works,"
    261 	    " loading use then def");
    262 }
    263 ATF_TC_BODY(static_usedef, tc)
    264 {
    265 	tls_extern("libh_def_static.so", "libh_use_static.so",
    266 	    USE_DEF, /*xfail*/true);
    267 }
    268 
    269 ATF_TC(static_usedefnoload);
    270 ATF_TC_HEAD(static_usedefnoload, tc)
    271 {
    272 	atf_tc_set_md_var(tc, "descr", "extern __thread for static TLS works,"
    273 	    " loading use then def with RTLD_NOLOAD");
    274 }
    275 ATF_TC_BODY(static_usedefnoload, tc)
    276 {
    277 	tls_extern("libh_def_static.so", "libh_use_static.so",
    278 	    USE_DEF_NOLOAD, /*xfail*/true);
    279 }
    280 
    281 ATF_TP_ADD_TCS(tp)
    282 {
    283 
    284 	ATF_TP_ADD_TC(tp, dynamic_abusedef);
    285 	ATF_TP_ADD_TC(tp, dynamic_abusedefnoload);
    286 	ATF_TP_ADD_TC(tp, dynamic_defabuse_eager);
    287 	ATF_TP_ADD_TC(tp, dynamic_defabuse_lazy);
    288 	ATF_TP_ADD_TC(tp, dynamic_defuse_eager);
    289 	ATF_TP_ADD_TC(tp, dynamic_defuse_lazy);
    290 	ATF_TP_ADD_TC(tp, dynamic_usedef);
    291 	ATF_TP_ADD_TC(tp, dynamic_usedefnoload);
    292 	ATF_TP_ADD_TC(tp, static_abusedef);
    293 	ATF_TP_ADD_TC(tp, static_abusedefnoload);
    294 	ATF_TP_ADD_TC(tp, static_defabuse_eager);
    295 	ATF_TP_ADD_TC(tp, static_defabuse_lazy);
    296 	ATF_TP_ADD_TC(tp, static_defuse_eager);
    297 	ATF_TP_ADD_TC(tp, static_defuse_lazy);
    298 	ATF_TP_ADD_TC(tp, static_usedef);
    299 	ATF_TP_ADD_TC(tp, static_usedefnoload);
    300 	return atf_no_error();
    301 }
    302