diff options
Diffstat (limited to 'libexec/ld.elf_so')
| -rw-r--r-- | libexec/ld.elf_so/h_r_rel.c | 147 | ||||
| -rw-r--r-- | libexec/ld.elf_so/t_dladdr.c | 171 | ||||
| -rw-r--r-- | libexec/ld.elf_so/t_dlclose_thread.c | 98 | ||||
| -rw-r--r-- | libexec/ld.elf_so/t_r_rel.sh | 113 | ||||
| -rw-r--r-- | libexec/ld.elf_so/t_tls_alignment.c | 70 |
5 files changed, 599 insertions, 0 deletions
diff --git a/libexec/ld.elf_so/h_r_rel.c b/libexec/ld.elf_so/h_r_rel.c new file mode 100644 index 000000000000..17cece208ebe --- /dev/null +++ b/libexec/ld.elf_so/h_r_rel.c @@ -0,0 +1,147 @@ +/* $NetBSD: h_r_rel.c,v 1.2 2025/12/21 19:08:09 riastradh Exp $ */ + +/*- + * Copyright (c) 2025 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: h_r_rel.c,v 1.2 2025/12/21 19:08:09 riastradh Exp $"); + +#include <stddef.h> +#include <stdio.h> + +/* + * When built as position-independent executable, the value of foop and + * foopp should be computed either via R_*_RELATIVE or R_*_REL32 or + * similar, which -- ports that support it -- may be compressed into a + * SHT_RELR section. + * + * One pointer indirection is enough to produce this effect, but we use + * two pointer indirections to increase the probability of a crash in + * case the relocations are done wrong. + */ +static int foo = 0x5f4d7635; +static int *volatile foop = &foo; +static int *volatile *volatile foopp = &foop; + +/* + * The RELR section compresses relocations for adjacent addresses into + * bitmaps of 31 or 63 bits apiece. Create a bunch of consecutive + * addresses to relocate, punctuated by the occasional non-relocated + * address (null), to check for fencepost errors in the bitmap + * iteration. + */ +static int bar[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, +}; + +static int *volatile barp[] = { + &bar[0x00], &bar[0x01], &bar[0x02], &bar[0x03], + &bar[0x04], &bar[0x05], &bar[0x06], &bar[0x07], + &bar[0x08], &bar[0x09], &bar[0x0a], &bar[0x0b], + &bar[0x0c], &bar[0x0d], &bar[0x0e], &bar[0x0f], + &bar[0x10], &bar[0x11], &bar[0x12], &bar[0x13], + &bar[0x14], &bar[0x15], &bar[0x16], &bar[0x17], + &bar[0x18], &bar[0x19], &bar[0x1a], &bar[0x1b], + &bar[0x1c], &bar[0x1d], &bar[0x1e], &bar[0x1f], + &bar[0x20], &bar[0x21], &bar[0x22], &bar[0x23], + &bar[0x24], &bar[0x25], &bar[0x26], &bar[0x27], + &bar[0x28], &bar[0x29], &bar[0x2a], &bar[0x2b], + &bar[0x2c], &bar[0x2d], &bar[0x2e], &bar[0x2f], + &bar[0x30], &bar[0x31], &bar[0x32], &bar[0x33], + &bar[0x34], &bar[0x35], &bar[0x36], &bar[0x37], + &bar[0x38], &bar[0x39], &bar[0x3a], &bar[0x3b], + &bar[0x3c], &bar[0x3d], &bar[0x3e], &bar[0x3f], + NULL, &bar[0x41], &bar[0x42], &bar[0x43], /* test a clear bit */ + &bar[0x44], &bar[0x45], &bar[0x46], &bar[0x47], + &bar[0x48], &bar[0x49], &bar[0x4a], &bar[0x4b], + &bar[0x4c], &bar[0x4d], &bar[0x4e], &bar[0x4f], + &bar[0x50], &bar[0x51], &bar[0x52], &bar[0x53], + &bar[0x54], &bar[0x55], &bar[0x56], &bar[0x57], + &bar[0x58], &bar[0x59], &bar[0x5a], &bar[0x5b], + &bar[0x5c], &bar[0x5d], &bar[0x5e], &bar[0x5f], + &bar[0x60], &bar[0x61], &bar[0x62], &bar[0x63], + &bar[0x64], &bar[0x65], &bar[0x66], &bar[0x67], + &bar[0x68], &bar[0x69], &bar[0x6a], &bar[0x6b], + &bar[0x6c], &bar[0x6d], &bar[0x6e], &bar[0x6f], + &bar[0x70], &bar[0x71], &bar[0x72], &bar[0x73], + &bar[0x74], &bar[0x75], &bar[0x76], &bar[0x77], + &bar[0x78], &bar[0x79], &bar[0x7a], &bar[0x7b], + &bar[0x7c], &bar[0x7d], &bar[0x7e], &bar[0x7f], + NULL, /* confirm we stop at the end */ +}; + +static int baz = -0x1adbd477; +static int *volatile bazp = &baz; + +int +main(void) +{ + int i, result = 0; + + if (**foopp != 0x5f4d7635) { + fprintf(stderr, "foo @ %p, foop = %p, *foop = %p," + " **foopp = 0x%x\n", + &foo, foop, *foopp, **foopp); + result |= 1; + } + for (i = 0; i < (int)__arraycount(barp); i++) { + if (i == 0x40 || i == 0x80) { + if (barp[i] != NULL) { + fprintf(stderr, "barp[%u] = %p\n", + i, barp[i]); + } + } else { + if (*barp[i] != i) { + fprintf(stderr, "bar[%u] @ %p, barp[%u] = %p," + " *barp[%u] = %u\n", + i, &bar[i], i, barp[i], i, *barp[i]); + result |= 1; + } + } + } + if (*bazp != -0x1adbd477) { + fprintf(stderr, "baz @ %p, bazp = %p, *bazp = 0x%x\n", + &baz, bazp, *bazp); + result |= 1; + } + + return result; +} diff --git a/libexec/ld.elf_so/t_dladdr.c b/libexec/ld.elf_so/t_dladdr.c new file mode 100644 index 000000000000..5cdb0148fecf --- /dev/null +++ b/libexec/ld.elf_so/t_dladdr.c @@ -0,0 +1,171 @@ +/* $NetBSD: t_dladdr.c,v 1.2 2025/12/15 02:36:47 riastradh Exp $ */ + +/*- + * Copyright (c) 2025 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_dladdr.c,v 1.2 2025/12/15 02:36:47 riastradh Exp $"); + +#include <sys/mman.h> + +#include <atf-c.h> +#include <dlfcn.h> +#include <unistd.h> + +#include "h_macros.h" + +#define SELF "t_dladdr" + +/* + * Note: the symbols foo, bar, and baz must be exposed to dlfcn(3) by + * linking this with -export-dynamic. + */ +int foo; /* something in this ELF object */ +int bar; /* something in this ELF object */ +int baz; /* something in this ELF object */ + +extern char _end[]; /* one past last byte of this ELF object */ + +ATF_TC(dladdr_self); +ATF_TC_HEAD(dladdr_self, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify dladdr of data in this object returns self"); +} +ATF_TC_BODY(dladdr_self, tc) +{ + Dl_info info; + const char *ptr = (char *)&bar + 1; + const char *p; + + /* + * If we're statically linked, dladdr just fails (XXX is that + * right?). But we're not statically linked because these are + * the ld.elf_so tests (XXX should migrate this to + * tests/lib/libc/dlfcn/ and handle it there). + * + * If we're dynamically linked, then foo, bar, and baz should + * live in self. + */ + ATF_CHECK_MSG(dladdr(ptr, &info) != 0, + "[bar @ %p + [0,%zu)] dladdr(%p) failed: %s", + &bar, sizeof(bar), ptr, dlerror()); + p = strrchr(info.dli_fname, '/'); + if (p == NULL) + p = info.dli_fname; + else + p++; + ATF_CHECK_MSG(strcmp(p, SELF) == 0, + "[bar @ %p + [0,%zu)] dladdr found %p in %s, not self=%s", + &bar, sizeof(bar), ptr, info.dli_fname, SELF); + ATF_CHECK_MSG(strcmp(info.dli_sname, "bar") == 0, + "[bar @ %p + [0,%zu)] dladdr found %p in %s at %p, not bar", + &bar, sizeof(bar), ptr, info.dli_sname, info.dli_saddr); +} + +ATF_TC(dladdr_errno); +ATF_TC_HEAD(dladdr_errno, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify dladdr(errno) returns libc.so (or self if static)"); +} +ATF_TC_BODY(dladdr_errno, tc) +{ + Dl_info info; + const char *p; + + /* + * If we're statically linked, dladdr just fails (XXX is that + * right?). But we're not statically linked because these are + * the ld.elf_so tests (XXX should migrate this to + * tests/lib/libc/dlfcn/ and handle it there). + * + * If we're dynamically linked and single-threaded (no + * libpthread.so), &errno will be in libc. + * + * If we're dynamically linked and multi-threaded, &errno would + * be in a pthread_t object -- but we're not multithreaded, so + * it's not. Hence only two cases: static vs dynamic. + */ + ATF_CHECK_MSG(dladdr(&errno, &info) != 0, + "[errno @ %p] dladdr failed: %s", &errno, dlerror()); + p = strrchr(info.dli_fname, '/'); + if (p == NULL) + p = info.dli_fname; + else + p++; + ATF_CHECK_MSG(strcmp(p, SELF) != 0, + "[errno @ %p] dladdr found errno in self=%s, not in libc.so", + &errno, info.dli_fname); +} + +ATF_TC(dladdr_after__end); +ATF_TC_HEAD(dladdr_after__end, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify dladdr doesn't claim pages past _end for self"); +} +ATF_TC_BODY(dladdr_after__end, tc) +{ + const size_t pagesize = sysconf(_SC_PAGESIZE); + uintptr_t endp, nextp; + void *page; + Dl_info info; + + /* + * Round up to a page start. + */ + endp = (uintptr_t)(void *)_end; + nextp = pagesize*((endp + pagesize - 1)/pagesize); + + /* + * Map the next page, or something after it. It just has to be + * not mapped by an existing object, but for the sake of + * testing for past bugs, we would like to make it as close to + * a real object as we can. + */ + REQUIRE_LIBC(page = mmap((void *)nextp, pagesize, PROT_NONE, MAP_ANON, + /*fd*/-1, /*off*/0), + MAP_FAILED); + + /* + * Verify dladdr doesn't return anything for this page. + */ + ATF_CHECK_MSG(dladdr(page, &info) == 0, + "dladdr returned %s @ %p (symbol %s @ %p) for bogus address %p", + info.dli_fname, info.dli_fbase, + info.dli_sname, info.dli_saddr, + page); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, dladdr_after__end); + ATF_TP_ADD_TC(tp, dladdr_errno); + ATF_TP_ADD_TC(tp, dladdr_self); + return atf_no_error(); +} diff --git a/libexec/ld.elf_so/t_dlclose_thread.c b/libexec/ld.elf_so/t_dlclose_thread.c new file mode 100644 index 000000000000..3b80990c1fec --- /dev/null +++ b/libexec/ld.elf_so/t_dlclose_thread.c @@ -0,0 +1,98 @@ +/* $NetBSD: t_dlclose_thread.c,v 1.1 2025/11/23 22:01:13 riastradh Exp $ */ + +/*- + * Copyright (c) 2025 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_dlclose_thread.c,v 1.1 2025/11/23 22:01:13 riastradh Exp $"); + +#include <atf-c.h> +#include <dlfcn.h> +#include <pthread.h> +#include <stdatomic.h> +#include <unistd.h> + +#include "h_macros.h" + +pthread_barrier_t bar; +atomic_bool stop = false; + +int sleep_init; +int sleep_fini; +int dlopen_cookie; +int dlclose_cookie; + +static const char *const libh_helper_dso[] = { + "libh_helper_dso1.so", + "libh_helper_dso2.so", + "libh_helper_dso3.so", +}; + +static void * +dlclose_thread(void *cookie) +{ + const unsigned i = (uintptr_t)cookie % __arraycount(libh_helper_dso); + void *handle; + + (void)pthread_barrier_wait(&bar); + while (!atomic_load_explicit(&stop, memory_order_relaxed)) { + handle = dlopen(libh_helper_dso[i], RTLD_LAZY | RTLD_LOCAL); + ATF_REQUIRE(handle != NULL); + dlclose(handle); + } + return NULL; +} + +ATF_TC(dlclose_thread); +ATF_TC_HEAD(dlclose_thread, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test concurrent dlopen and dlclose with destructors"); +} +ATF_TC_BODY(dlclose_thread, tc) +{ + pthread_t t[2*__arraycount(libh_helper_dso)]; + unsigned i; + + RZ(pthread_barrier_init(&bar, NULL, 1 + __arraycount(t))); + for (i = 0; i < __arraycount(t); i++) { + RZ(pthread_create(&t[i], NULL, &dlclose_thread, + (void *)(uintptr_t)i)); + } + atf_tc_expect_signal(-1, "PR lib/59751:" + " dlclose is not MT-safe depending on the libraries unloaded"); + (void)pthread_barrier_wait(&bar); + (void)sleep(1); + atomic_store_explicit(&stop, true, memory_order_relaxed); + for (i = 0; i < __arraycount(t); i++) + RZ(pthread_join(t[i], NULL)); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, dlclose_thread); + return atf_no_error(); +} diff --git a/libexec/ld.elf_so/t_r_rel.sh b/libexec/ld.elf_so/t_r_rel.sh new file mode 100644 index 000000000000..2bc1059a32ca --- /dev/null +++ b/libexec/ld.elf_so/t_r_rel.sh @@ -0,0 +1,113 @@ +# $NetBSD: t_r_rel.sh,v 1.3 2025/12/21 19:08:09 riastradh Exp $ +# +# Copyright (c) 2025 The NetBSD Foundation, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +cleanup_core() +{ + local prog + + prog=$1 + test -f "${prog}.core" || return 0 + readelf -rs "$(atf_get_srcdir)/${prog}" + gdb -batch -ex bt -ex 'info registers' -ex disas \ + "$(atf_get_srcdir)/${prog}" "${prog}.core" +} + +atf_test_case readelf_relative_nopack +readelf_relative_nopack_head() +{ + atf_set "descr" "readelf R_*_RELATIVE with -z nopack-relative-relocs" + atf_set "require.progs" "readelf" +} +readelf_relative_nopack_body() +{ + atf_check -o match:'R_.*_REL' \ + readelf -r "$(atf_get_srcdir)"/h_r_rel_nopack +} + +atf_test_case readelf_relative_pack +readelf_relative_pack_head() +{ + atf_set "descr" "readelf R_*_RELATIVE with -z pack-relative-relocs" + atf_set "require.progs" "readelf" +} +readelf_relative_pack_body() +{ + case `uname -p` in + i386|powerpc64*|x86_64) + ;; + *) # Actually missing GNU binutils ld(1) support. + atf_expect_fail "PR bin/59360: ld.elf_so(8):" \ + " missing RELR support" + ;; + esac + atf_check -o not-match:'R_.*_REL' \ + readelf -r "$(atf_get_srcdir)"/h_r_rel_pack +} + +atf_test_case run_relative_nopack cleanup +run_relative_nopack_head() +{ + atf_set "descr" "run R_*_RELATIVE with -z nopack-relative-relocs" +} +run_relative_nopack_body() +{ + atf_check "$(atf_get_srcdir)"/h_r_rel_nopack +} +run_relative_nopack_cleanup() +{ + cleanup_core h_r_rel_nopack +} + +atf_test_case run_relative_pack cleanup +run_relative_pack_head() +{ + atf_set "descr" "run R_*_RELATIVE with -z pack-relative-relocs" +} +run_relative_pack_body() +{ + case `uname -p` in + i386|powerpc64*|x86_64) + ;; + *) # Missing GNU binutils ld(1) support to generate RELR + # sections, so the program should run just fine because + # it just uses traditional REL/RELA instead. + ;; + esac + atf_check "$(atf_get_srcdir)"/h_r_rel_pack +} +run_relative_pack_cleanup() +{ + cleanup_core h_r_rel_pack +} + +atf_init_test_cases() +{ + atf_add_test_case readelf_relative_nopack + atf_add_test_case readelf_relative_pack + atf_add_test_case run_relative_nopack + atf_add_test_case run_relative_pack +} diff --git a/libexec/ld.elf_so/t_tls_alignment.c b/libexec/ld.elf_so/t_tls_alignment.c new file mode 100644 index 000000000000..13d2a5cf4536 --- /dev/null +++ b/libexec/ld.elf_so/t_tls_alignment.c @@ -0,0 +1,70 @@ +/* $NetBSD: t_tls_alignment.c,v 1.2 2026/01/17 10:48:31 skrll Exp $ */ + +/* + * Copyright (c) 2025 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND + * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/types.h> + +#include <atf-c.h> + +#define ALIGNMENT 64 + +#define MAGIC1 0xaa55aa55aa55aa55 +#define MAGIC2 0xc0ffeeeeeeeeeeee +#define MAGIC3 0xff00ff00ff00ff00 + +__thread +struct { + uint64_t magic1; + uint64_t magic2 __attribute__((aligned(ALIGNMENT))); + uint64_t magic3; +} tls_data = { + .magic1 = MAGIC1, + .magic2 = MAGIC2, + .magic3 = MAGIC3, +}; + +ATF_TC(tls_alignment); +ATF_TC_HEAD(tls_alignment, tc) +{ + atf_tc_set_md_var(tc, "descr", + "TLS alignment requirements met"); +} + +ATF_TC_BODY(tls_alignment, tc) +{ + ATF_CHECK(tls_data.magic1 == MAGIC1); + ATF_CHECK(tls_data.magic2 == MAGIC2); + ATF_CHECK(tls_data.magic3 == MAGIC3); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, tls_alignment); + + return atf_no_error(); +} |
