public inbox for glibc-cvs@sourceware.org help / color / mirror / Atom feed
From: Alan Modra <amodra@sourceware.org> To: glibc-cvs@sourceware.org Subject: [glibc] powerpc64: Set up thread register for _dl_relocate_static_pie Date: Mon, 11 Apr 2022 01:30:35 +0000 (GMT) [thread overview] Message-ID: <20220411013035.7D951385B238@sourceware.org> (raw) https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=31a9bc8c55adc2a8d6f8f795a577ba5d5eca7506 commit 31a9bc8c55adc2a8d6f8f795a577ba5d5eca7506 Author: Alan Modra <amodra@gmail.com> Date: Mon Jan 24 07:58:18 2022 +1030 powerpc64: Set up thread register for _dl_relocate_static_pie libgcc ifunc resolvers that access hwcap via a field in the tcb can't be called until the thread pointer is set up. Other ifunc resolvers might need access to at_platform. This patch sets up a fake thread pointer early to a copy of tcbhead_t. hwcapinfo.c already had local variables for hwcap and at_platform, replace them with an entire tcbhead_t. It's not that large and this way we easily ensure hwcap and at_platform are at the same relative offsets as they are in the real thread block. The patch also conditionally disables part of tst-tlsifunc-static, "bar address read from IFUNC resolver is incorrect". We can't get a proper address for a thread variable before glibc initialises tls. Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com> Diff: --- sysdeps/powerpc/hwcapinfo.c | 8 +++----- sysdeps/powerpc/hwcapinfo.h | 3 +-- sysdeps/powerpc/nptl/tls.h | 8 ++++---- sysdeps/powerpc/powerpc64/dl-machine.h | 21 +++++++++++++++++++++ sysdeps/powerpc/tst-tlsifunc-static.c | 1 + sysdeps/powerpc/tst-tlsifunc.c | 3 +++ 6 files changed, 33 insertions(+), 11 deletions(-) diff --git a/sysdeps/powerpc/hwcapinfo.c b/sysdeps/powerpc/hwcapinfo.c index e030e322bd..afde05f863 100644 --- a/sysdeps/powerpc/hwcapinfo.c +++ b/sysdeps/powerpc/hwcapinfo.c @@ -20,8 +20,7 @@ #include <shlib-compat.h> #include <dl-procinfo.h> -uint64_t __tcb_hwcap __attribute__ ((visibility ("hidden"))); -uint32_t __tcb_platform __attribute__ ((visibility ("hidden"))); +tcbhead_t __tcb __attribute__ ((visibility ("hidden"))); /* This function parses the HWCAP/HWCAP2 fields, adding the previous supported ISA bits, as well as converting the AT_PLATFORM string to a number. This @@ -34,7 +33,7 @@ __tcb_parse_hwcap_and_convert_at_platform (void) uint64_t h1, h2; /* Read AT_PLATFORM string from auxv and convert it to a number. */ - __tcb_platform = _dl_string_platform (GLRO (dl_platform)); + __tcb.at_platform = _dl_string_platform (GLRO (dl_platform)); /* Read HWCAP and HWCAP2 from auxv. */ h1 = GLRO (dl_hwcap); @@ -66,8 +65,7 @@ __tcb_parse_hwcap_and_convert_at_platform (void) /* Consolidate both HWCAP and HWCAP2 into a single doubleword so that we can read both in a single load later. */ - __tcb_hwcap = h2; - __tcb_hwcap = (h1 << 32) | __tcb_hwcap; + __tcb.hwcap = (h1 << 32) | (h2 & 0xffffffff); } #if IS_IN (rtld) diff --git a/sysdeps/powerpc/hwcapinfo.h b/sysdeps/powerpc/hwcapinfo.h index ac462835ce..1f5e0bcb51 100644 --- a/sysdeps/powerpc/hwcapinfo.h +++ b/sysdeps/powerpc/hwcapinfo.h @@ -21,8 +21,7 @@ #ifndef HWCAPINFO_H # define HWCAPINFO_H -extern uint64_t __tcb_hwcap attribute_hidden; -extern uint32_t __tcb_platform attribute_hidden; +extern tcbhead_t __tcb attribute_hidden; extern void __tcb_parse_hwcap_and_convert_at_platform (void); diff --git a/sysdeps/powerpc/nptl/tls.h b/sysdeps/powerpc/nptl/tls.h index b80d39ad41..22b0075235 100644 --- a/sysdeps/powerpc/nptl/tls.h +++ b/sysdeps/powerpc/nptl/tls.h @@ -45,8 +45,6 @@ #ifndef __ASSEMBLER__ -# include <hwcapinfo.h> - /* Get system call information. */ # include <sysdep.h> @@ -100,6 +98,8 @@ typedef struct dtv_t *dtv; } tcbhead_t; +# include <hwcapinfo.h> + /* This is the size of the initial TCB. */ # define TLS_INIT_TCB_SIZE 0 @@ -137,8 +137,8 @@ typedef struct # define TLS_INIT_TP(tcbp) \ ({ \ __thread_register = (void *) (tcbp) + TLS_TCB_OFFSET; \ - THREAD_SET_HWCAP (__tcb_hwcap); \ - THREAD_SET_AT_PLATFORM (__tcb_platform); \ + THREAD_SET_HWCAP (__tcb.hwcap); \ + THREAD_SET_AT_PLATFORM (__tcb.at_platform); \ NULL; \ }) diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h index 6fab5cbe81..bb0ccd0811 100644 --- a/sysdeps/powerpc/powerpc64/dl-machine.h +++ b/sysdeps/powerpc/powerpc64/dl-machine.h @@ -559,6 +559,27 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc, #define ARCH_LA_PLTEXIT ppc64v2_gnu_pltexit #endif +#if ENABLE_STATIC_PIE && !defined SHARED && !IS_IN (rtld) +#include <libc-diag.h> +#include <tcb-offsets.h> + +/* Set up r13 for _dl_relocate_static_pie so that libgcc ifuncs that + normally access the tcb copy of hwcap will see __tcb.hwcap. */ + +static inline void __attribute__ ((always_inline)) +ppc_init_fake_thread_pointer (void) +{ + DIAG_PUSH_NEEDS_COMMENT; + /* We are playing pointer tricks. Silence gcc warning. */ + DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Warray-bounds"); + __thread_register = (char *) &__tcb.hwcap - TCB_HWCAP; + DIAG_POP_NEEDS_COMMENT; +} + +#define ELF_MACHINE_BEFORE_RTLD_RELOC(map, dynamic_info) \ + ppc_init_fake_thread_pointer (); +#endif /* ENABLE_STATIC_PIE && !defined SHARED && !IS_IN (rtld) */ + #endif /* dl_machine_h */ #ifdef RESOLVE_MAP diff --git a/sysdeps/powerpc/tst-tlsifunc-static.c b/sysdeps/powerpc/tst-tlsifunc-static.c index c0ff8972a9..438b27c0ec 100644 --- a/sysdeps/powerpc/tst-tlsifunc-static.c +++ b/sysdeps/powerpc/tst-tlsifunc-static.c @@ -16,4 +16,5 @@ License along with the GNU C Library; if not, see <https://www.gnu.org/licenses/>. */ +#define TST_TLSIFUNC_STATIC 1 #include "tst-tlsifunc.c" diff --git a/sysdeps/powerpc/tst-tlsifunc.c b/sysdeps/powerpc/tst-tlsifunc.c index 92313e68f4..6b256c6229 100644 --- a/sysdeps/powerpc/tst-tlsifunc.c +++ b/sysdeps/powerpc/tst-tlsifunc.c @@ -101,11 +101,14 @@ do_test (void) if (&bar == bar_ptr) printf ("PASS: bar address read from IFUNC resolver is correct.\n"); +#if !defined TST_TLSIFUNC_STATIC || !defined PIC \ + || !defined PI_STATIC_AND_HIDDEN else { printf ("FAIL: bar address read from IFUNC resolver is incorrect.\n"); ret = 1; } +#endif if (tcb_test ()) printf ("PASS: tcb_test IFUNC resolver called once.\n");
reply other threads:[~2022-04-11 1:30 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20220411013035.7D951385B238@sourceware.org \ --to=amodra@sourceware.org \ --cc=glibc-cvs@sourceware.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).