[PATCH v2 2/8] Consolidate pointer guard to use a relro variable instead of the TCB
Adhemerval Zanella
adhemerval.zanella@linaro.org
Fri Jun 12 16:10:10 GMT 2026
For the targets that still read the pointer guard from the thread
descriptor (i386, x86_64, powerpc, s390, sparc, and sh), mangle and
demangle pointers using the module-local __pointer_chk_guard_local (in
ld.so and static binaries) or the global __pointer_chk_guard provided by
the dynamic loader (in shared objects), matching the scheme already used
by aarch64, alpha, arm, csky and loongarch.
On i386 the guard is no longer reachable as a single %gs-relative memory
operand, so the assembly PTR_MANGLE/PTR_DEMANGLE PIC variants need a
register to hold the GOT pointer and the guard address.
This removes the dependency on the TCB pointer_guard slot: drop
THREAD_{GET,SET,COPY}_POINTER_GUARD and the POINTER_GUARD tcb-offset,
and point the POINTER_CHK_GUARD test macro at the relro variable. The
tcbhead_t slot is kept (renamed to an unused reserved field, except on
s390 which reused the stack guard) to preserve the ABI. s390 gains a
distinct pointer guard rather than aliasing the stack guard.
Checked on x86_64-linux-gnu, aarch64-linux-gnu, i686-linux-gnu, and
armv7a-linux-gnueabihf. I also run elf and setjmp checks on qemu
loongarch64, powerpc64, powerpc64le, and s390x systems.
Reviewed-by: DJ Delorie <dj@redhat.com>
---
sysdeps/i386/__longjmp.S | 4 +-
sysdeps/i386/bsd-_setjmp.S | 6 +-
sysdeps/i386/bsd-setjmp.S | 4 +-
sysdeps/i386/htl/tcb-offsets.sym | 1 -
sysdeps/i386/nptl/tcb-offsets.sym | 1 -
sysdeps/i386/nptl/tls.h | 10 +---
sysdeps/i386/setjmp.S | 4 +-
sysdeps/i386/stackguard-macros.h | 10 +++-
sysdeps/mach/hurd/i386/tls.h | 9 +--
sysdeps/mach/hurd/x86_64/tls.h | 8 +--
sysdeps/powerpc/nptl/tcb-offsets.sym | 1 -
sysdeps/powerpc/nptl/tls.h | 16 +-----
sysdeps/powerpc/powerpc32/stackguard-macros.h | 16 +++---
sysdeps/powerpc/powerpc64/stackguard-macros.h | 16 +++---
sysdeps/s390/__longjmp.c | 2 +-
sysdeps/s390/nptl/tls.h | 7 ---
sysdeps/s390/stackguard-macros.h | 20 +++----
sysdeps/sh/nptl/tcb-offsets.sym | 1 -
sysdeps/sh/nptl/tls.h | 15 +----
sysdeps/sh/stackguard-macros.h | 8 ++-
sysdeps/sparc/nptl/tcb-offsets.sym | 1 -
sysdeps/sparc/nptl/tls.h | 10 +---
sysdeps/sparc/sparc32/stackguard-macros.h | 9 ++-
sysdeps/sparc/sparc64/stackguard-macros.h | 9 ++-
.../unix/sysv/linux/i386/____longjmp_chk.S | 4 +-
sysdeps/unix/sysv/linux/i386/pointer_guard.h | 53 ++++++++++++++----
.../unix/sysv/linux/powerpc/pointer_guard.h | 55 ++++++++++++++-----
sysdeps/unix/sysv/linux/s390/pointer_guard.h | 33 +++++++----
sysdeps/unix/sysv/linux/sh/pointer_guard.h | 53 +++++++++++++++---
.../sysv/linux/sparc/sparc32/pointer_guard.h | 39 +++++++++++--
.../sysv/linux/sparc/sparc64/pointer_guard.h | 38 +++++++++++--
.../unix/sysv/linux/x86_64/pointer_guard.h | 18 +++---
sysdeps/x86_64/htl/tcb-offsets.sym | 1 -
sysdeps/x86_64/nptl/tcb-offsets.sym | 1 -
sysdeps/x86_64/nptl/tls.h | 10 +---
sysdeps/x86_64/stackguard-macros.h | 10 +++-
36 files changed, 303 insertions(+), 200 deletions(-)
diff --git a/sysdeps/i386/__longjmp.S b/sysdeps/i386/__longjmp.S
index f188390fb5a..c8f768d5015 100644
--- a/sysdeps/i386/__longjmp.S
+++ b/sysdeps/i386/__longjmp.S
@@ -31,8 +31,8 @@ ENTRY (__longjmp)
movl (JB_PC*4)(%eax), %edx
/* Get the stack pointer. */
movl (JB_SP*4)(%eax), %ecx
- PTR_DEMANGLE (%edx)
- PTR_DEMANGLE (%ecx)
+ PTR_DEMANGLE (%edx, bx)
+ PTR_DEMANGLE (%ecx, bx)
LIBC_PROBE (longjmp, 3, 4@%eax, -4@8(%esp), 4@%edx)
cfi_def_cfa(%eax, 0)
cfi_register(%eip, %edx)
diff --git a/sysdeps/i386/bsd-_setjmp.S b/sysdeps/i386/bsd-_setjmp.S
index cb049be42ff..8f509b7d51e 100644
--- a/sysdeps/i386/bsd-_setjmp.S
+++ b/sysdeps/i386/bsd-_setjmp.S
@@ -31,7 +31,6 @@
ENTRY (_setjmp)
- xorl %eax, %eax
movl JMPBUF(%esp), %edx
/* Save registers. */
@@ -40,17 +39,18 @@ ENTRY (_setjmp)
movl %edi, (JB_DI*4)(%edx)
leal JMPBUF(%esp), %ecx /* Save SP as it will be after we return. */
#ifdef PTR_MANGLE
- PTR_MANGLE (%ecx)
+ PTR_MANGLE (%ecx, ax)
#endif
movl %ecx, (JB_SP*4)(%edx)
movl 0(%esp), %ecx /* Save PC we are returning to now. */
LIBC_PROBE (setjmp, 3, 4@%edx, -4@$0, 4@%ecx)
#ifdef PTR_MANGLE
- PTR_MANGLE (%ecx)
+ PTR_MANGLE (%ecx, ax)
#endif
movl %ecx, (JB_PC*4)(%edx)
movl %ebp, (JB_BP*4)(%edx) /* Save caller's frame pointer. */
+ xorl %eax, %eax
movl %eax, JB_SIZE(%edx) /* No signal mask set. */
ret
END (_setjmp)
diff --git a/sysdeps/i386/bsd-setjmp.S b/sysdeps/i386/bsd-setjmp.S
index 70336a119bf..5f3a4694f39 100644
--- a/sysdeps/i386/bsd-setjmp.S
+++ b/sysdeps/i386/bsd-setjmp.S
@@ -42,13 +42,13 @@ ENTRY (setjmp)
movl %edi, (JB_DI*4)(%eax)
leal JMPBUF(%esp), %ecx /* Save SP as it will be after we return. */
#ifdef PTR_MANGLE
- PTR_MANGLE (%ecx)
+ PTR_MANGLE (%ecx, dx)
#endif
movl %ecx, (JB_SP*4)(%eax)
movl 0(%esp), %ecx /* Save PC we are returning to now. */
LIBC_PROBE (setjmp, 3, 4@%eax, -4@$1, 4@%ecx)
#ifdef PTR_MANGLE
- PTR_MANGLE (%ecx)
+ PTR_MANGLE (%ecx, dx)
#endif
movl %ecx, (JB_PC*4)(%eax)
movl %ebp, (JB_BP*4)(%eax) /* Save caller's frame pointer. */
diff --git a/sysdeps/i386/htl/tcb-offsets.sym b/sysdeps/i386/htl/tcb-offsets.sym
index 7b7c7193695..b36cfd6848a 100644
--- a/sysdeps/i386/htl/tcb-offsets.sym
+++ b/sysdeps/i386/htl/tcb-offsets.sym
@@ -4,5 +4,4 @@
MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads)
SYSINFO_OFFSET offsetof (tcbhead_t, sysinfo)
-POINTER_GUARD offsetof (tcbhead_t, pointer_guard)
SIGSTATE_OFFSET offsetof (tcbhead_t, _hurd_sigstate)
diff --git a/sysdeps/i386/nptl/tcb-offsets.sym b/sysdeps/i386/nptl/tcb-offsets.sym
index 2ec9e787c1f..48f79845129 100644
--- a/sysdeps/i386/nptl/tcb-offsets.sym
+++ b/sysdeps/i386/nptl/tcb-offsets.sym
@@ -11,6 +11,5 @@ SYSINFO_OFFSET offsetof (tcbhead_t, sysinfo)
CLEANUP offsetof (struct pthread, cleanup)
CLEANUP_PREV offsetof (struct _pthread_cleanup_buffer, __prev)
MUTEX_FUTEX offsetof (pthread_mutex_t, __data.__lock)
-POINTER_GUARD offsetof (tcbhead_t, pointer_guard)
FEATURE_1_OFFSET offsetof (tcbhead_t, feature_1)
SSP_BASE_OFFSET offsetof (tcbhead_t, ssp_base)
diff --git a/sysdeps/i386/nptl/tls.h b/sysdeps/i386/nptl/tls.h
index 87dcf5dc1f4..fb8684230fb 100644
--- a/sysdeps/i386/nptl/tls.h
+++ b/sysdeps/i386/nptl/tls.h
@@ -39,7 +39,7 @@ typedef struct
int multiple_threads;
uintptr_t sysinfo;
uintptr_t stack_guard;
- uintptr_t pointer_guard;
+ uintptr_t __unused;
int gscope_flag;
/* Bit 0: X86_FEATURE_1_IBT.
Bit 1: X86_FEATURE_1_SHSTK.
@@ -240,14 +240,6 @@ tls_fill_user_desc (union user_desc_init *desc,
= THREAD_GETMEM (THREAD_SELF, header.stack_guard))
-/* Set the pointer guard field in the TCB head. */
-#define THREAD_SET_POINTER_GUARD(value) \
- THREAD_SETMEM (THREAD_SELF, header.pointer_guard, value)
-#define THREAD_COPY_POINTER_GUARD(descr) \
- ((descr)->header.pointer_guard \
- = THREAD_GETMEM (THREAD_SELF, header.pointer_guard))
-
-
/* Get and set the global scope generation counter in the TCB head. */
#define THREAD_GSCOPE_FLAG_UNUSED 0
#define THREAD_GSCOPE_FLAG_USED 1
diff --git a/sysdeps/i386/setjmp.S b/sysdeps/i386/setjmp.S
index 1cf1796040e..8787be4edec 100644
--- a/sysdeps/i386/setjmp.S
+++ b/sysdeps/i386/setjmp.S
@@ -36,13 +36,13 @@ ENTRY (__sigsetjmp)
movl %edi, (JB_DI*4)(%eax)
leal JMPBUF(%esp), %ecx /* Save SP as it will be after we return. */
#ifdef PTR_MANGLE
- PTR_MANGLE (%ecx)
+ PTR_MANGLE (%ecx, dx)
#endif
movl %ecx, (JB_SP*4)(%eax)
movl 0(%esp), %ecx /* Save PC we are returning to now. */
LIBC_PROBE (setjmp, 3, 4@%eax, -4@SIGMSK(%esp), 4@%ecx)
#ifdef PTR_MANGLE
- PTR_MANGLE (%ecx)
+ PTR_MANGLE (%ecx, dx)
#endif
movl %ecx, (JB_PC*4)(%eax)
movl %ebp, (JB_BP*4)(%eax) /* Save caller's frame pointer. */
diff --git a/sysdeps/i386/stackguard-macros.h b/sysdeps/i386/stackguard-macros.h
index 2939934ef19..696a9777027 100644
--- a/sysdeps/i386/stackguard-macros.h
+++ b/sysdeps/i386/stackguard-macros.h
@@ -1,3 +1,11 @@
+#include <stdint.h>
+
#define STACK_CHK_GUARD (((tcbhead_t __seg_gs *)0)->stack_guard)
-#define POINTER_CHK_GUARD (((tcbhead_t __seg_gs *)0)->pointer_guard)
+#ifdef PTRGUARD_LOCAL
+extern uintptr_t __pointer_chk_guard_local;
+# define POINTER_CHK_GUARD __pointer_chk_guard_local
+#else
+extern uintptr_t __pointer_chk_guard;
+# define POINTER_CHK_GUARD __pointer_chk_guard
+#endif
diff --git a/sysdeps/mach/hurd/i386/tls.h b/sysdeps/mach/hurd/i386/tls.h
index 8cd643cdcf0..403395db9a8 100644
--- a/sysdeps/mach/hurd/i386/tls.h
+++ b/sysdeps/mach/hurd/i386/tls.h
@@ -36,7 +36,7 @@ typedef struct
int multiple_threads;
uintptr_t sysinfo;
uintptr_t stack_guard;
- uintptr_t pointer_guard;
+ uintptr_t __unused;
int gscope_flag;
unsigned int feature_1;
/* Reservation of some values for the TM ABI. */
@@ -238,13 +238,6 @@ out:
((descr)->stack_guard \
= THREAD_GETMEM (THREAD_SELF, stack_guard))
-/* Set the pointer guard field in the TCB head. */
-#define THREAD_SET_POINTER_GUARD(value) \
- THREAD_SETMEM (THREAD_SELF, pointer_guard, value)
-#define THREAD_COPY_POINTER_GUARD(descr) \
- ((descr)->pointer_guard \
- = THREAD_GETMEM (THREAD_SELF, pointer_guard))
-
# include <mach/machine/thread_status.h>
diff --git a/sysdeps/mach/hurd/x86_64/tls.h b/sysdeps/mach/hurd/x86_64/tls.h
index 85ea75b5b51..3543e9be347 100644
--- a/sysdeps/mach/hurd/x86_64/tls.h
+++ b/sysdeps/mach/hurd/x86_64/tls.h
@@ -41,7 +41,7 @@ typedef struct
int gscope_flag;
uintptr_t sysinfo;
uintptr_t stack_guard;
- uintptr_t pointer_guard;
+ uintptr_t __unused;
long __glibc_padding2[2];
int private_futex;
int __glibc_padding3;
@@ -125,12 +125,6 @@ THREAD_TCB (thread_t thread,
((descr)->stack_guard \
= THREAD_GETMEM (THREAD_SELF, stack_guard))
-/* Set the pointer guard field in the TCB head. */
-# define THREAD_SET_POINTER_GUARD(value) \
- THREAD_SETMEM (THREAD_SELF, pointer_guard, value)
-# define THREAD_COPY_POINTER_GUARD(descr) \
- ((descr)->pointer_guard \
- = THREAD_GETMEM (THREAD_SELF, pointer_guard))
/* From hurd.h, reproduced here to avoid a circular include. */
extern thread_t __hurd_thread_self (void);
diff --git a/sysdeps/powerpc/nptl/tcb-offsets.sym b/sysdeps/powerpc/nptl/tcb-offsets.sym
index 9b29fe8d1a1..bc88ecdddbf 100644
--- a/sysdeps/powerpc/nptl/tcb-offsets.sym
+++ b/sysdeps/powerpc/nptl/tcb-offsets.sym
@@ -14,7 +14,6 @@
MULTIPLE_THREADS_OFFSET thread_offsetof (header.multiple_threads)
#endif
TID thread_offsetof (tid)
-POINTER_GUARD (offsetof (tcbhead_t, pointer_guard) - TLS_TCB_OFFSET - sizeof (tcbhead_t))
TAR_SAVE (offsetof (tcbhead_t, tar_save) - TLS_TCB_OFFSET - sizeof (tcbhead_t))
DSO_SLOT1 (offsetof (tcbhead_t, dso_slot1) - TLS_TCB_OFFSET - sizeof (tcbhead_t))
DSO_SLOT2 (offsetof (tcbhead_t, dso_slot2) - TLS_TCB_OFFSET - sizeof (tcbhead_t))
diff --git a/sysdeps/powerpc/nptl/tls.h b/sysdeps/powerpc/nptl/tls.h
index 4ef6dd1a2fc..2e735c155bc 100644
--- a/sysdeps/powerpc/nptl/tls.h
+++ b/sysdeps/powerpc/nptl/tls.h
@@ -60,8 +60,7 @@
/* The stack_guard is accessed directly by GCC -fstack-protector code,
- so it is a part of public ABI. The dtv and pointer_guard fields
- are private. */
+ so it is a part of public ABI. The dtv field is private. */
typedef struct
{
/* Reservation for HWCAP3 and HWCAP4 data. To be accessed by GCC in
@@ -96,7 +95,7 @@ typedef struct
uintptr_t ebb_ctx_pointer;
uintptr_t ebb_reserved1;
uintptr_t ebb_reserved2;
- uintptr_t pointer_guard;
+ uintptr_t __unused2;
uintptr_t stack_guard;
dtv_t *dtv;
} tcbhead_t;
@@ -186,17 +185,6 @@ extern tcbhead_t __tcb attribute_hidden;
= ((tcbhead_t *) ((char *) __thread_register \
- TLS_TCB_OFFSET))[-1].stack_guard)
-/* Set the stack guard field in TCB head. */
-# define THREAD_GET_POINTER_GUARD() \
- (((tcbhead_t *) ((char *) __thread_register \
- - TLS_TCB_OFFSET))[-1].pointer_guard)
-# define THREAD_SET_POINTER_GUARD(value) \
- (THREAD_GET_POINTER_GUARD () = (value))
-# define THREAD_COPY_POINTER_GUARD(descr) \
- (((tcbhead_t *) ((char *) (descr) \
- + TLS_PRE_TCB_SIZE))[-1].pointer_guard \
- = THREAD_GET_POINTER_GUARD())
-
/* hwcap & hwcap_extn fields in TCB head. */
# define THREAD_GET_HWCAP() \
(((tcbhead_t *) ((char *) __thread_register \
diff --git a/sysdeps/powerpc/powerpc32/stackguard-macros.h b/sysdeps/powerpc/powerpc32/stackguard-macros.h
index b3d0af830f2..0c94269a731 100644
--- a/sysdeps/powerpc/powerpc32/stackguard-macros.h
+++ b/sysdeps/powerpc/powerpc32/stackguard-macros.h
@@ -3,12 +3,10 @@
#define STACK_CHK_GUARD \
({ uintptr_t x; asm ("lwz %0,-28680(2)" : "=r" (x)); x; })
-#define POINTER_CHK_GUARD \
- ({ \
- uintptr_t x; \
- asm ("lwz %0,%1(2)" \
- : "=r" (x) \
- : "i" (offsetof (tcbhead_t, pointer_guard) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) \
- ); \
- x; \
- })
+#ifdef PTRGUARD_LOCAL
+extern uintptr_t __pointer_chk_guard_local;
+# define POINTER_CHK_GUARD __pointer_chk_guard_local
+#else
+extern uintptr_t __pointer_chk_guard;
+# define POINTER_CHK_GUARD __pointer_chk_guard
+#endif
diff --git a/sysdeps/powerpc/powerpc64/stackguard-macros.h b/sysdeps/powerpc/powerpc64/stackguard-macros.h
index e80a683e64d..fec2e69f64c 100644
--- a/sysdeps/powerpc/powerpc64/stackguard-macros.h
+++ b/sysdeps/powerpc/powerpc64/stackguard-macros.h
@@ -3,12 +3,10 @@
#define STACK_CHK_GUARD \
({ uintptr_t x; asm ("ld %0,-28688(13)" : "=r" (x)); x; })
-#define POINTER_CHK_GUARD \
- ({ \
- uintptr_t x; \
- asm ("ld %0,%1(13)" \
- : "=r" (x) \
- : "i" (offsetof (tcbhead_t, pointer_guard) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) \
- ); \
- x; \
- })
+#ifdef PTRGUARD_LOCAL
+extern uintptr_t __pointer_chk_guard_local;
+# define POINTER_CHK_GUARD __pointer_chk_guard_local
+#else
+extern uintptr_t __pointer_chk_guard;
+# define POINTER_CHK_GUARD __pointer_chk_guard
+#endif
diff --git a/sysdeps/s390/__longjmp.c b/sysdeps/s390/__longjmp.c
index 7c207e44c6d..78aa70a943c 100644
--- a/sysdeps/s390/__longjmp.c
+++ b/sysdeps/s390/__longjmp.c
@@ -35,7 +35,7 @@ void
__longjmp (__jmp_buf env, int val)
{
#ifdef PTR_DEMANGLE
- uintptr_t guard = THREAD_GET_POINTER_GUARD ();
+ uintptr_t guard = PTR_GUARD_VALUE;
# ifdef CHECK_SP
CHECK_SP (env, guard);
# endif
diff --git a/sysdeps/s390/nptl/tls.h b/sysdeps/s390/nptl/tls.h
index de7e9c64828..41fd473d14a 100644
--- a/sysdeps/s390/nptl/tls.h
+++ b/sysdeps/s390/nptl/tls.h
@@ -139,13 +139,6 @@ typedef struct
((descr)->header.stack_guard \
= THREAD_GETMEM (THREAD_SELF, header.stack_guard))
-/* s390 doesn't have HP_TIMING_*, so for the time being
- use stack_guard as pointer_guard. */
-#define THREAD_GET_POINTER_GUARD() \
- THREAD_GETMEM (THREAD_SELF, header.stack_guard)
-#define THREAD_SET_POINTER_GUARD(value) ((void) (value))
-#define THREAD_COPY_POINTER_GUARD(descr)
-
/* Get and set the global scope generation counter in struct pthread. */
#define THREAD_GSCOPE_FLAG_UNUSED 0
#define THREAD_GSCOPE_FLAG_USED 1
diff --git a/sysdeps/s390/stackguard-macros.h b/sysdeps/s390/stackguard-macros.h
index 3671c7cd7a1..22e4751a73a 100644
--- a/sysdeps/s390/stackguard-macros.h
+++ b/sysdeps/s390/stackguard-macros.h
@@ -3,16 +3,10 @@
#define STACK_CHK_GUARD \
({ uintptr_t x; __asm__ ("ear %0,%%a0; sllg %0,%0,32; ear %0,%%a1; lg %0,0x28(%0)" : "=a" (x)); x; })
-/* On s390x there is no unique pointer guard, instead we use the
- same value as the stack guard. */
-#define POINTER_CHK_GUARD \
- ({ \
- uintptr_t x; \
- __asm__ ("ear %0,%%a0;" \
- "sllg %0,%0,32;" \
- "ear %0,%%a1;" \
- "lg %0,%1(%0)" \
- : "=a" (x) \
- : "i" (offsetof (tcbhead_t, stack_guard))); \
- x; \
- })
+#ifdef PTRGUARD_LOCAL
+extern uintptr_t __pointer_chk_guard_local;
+# define POINTER_CHK_GUARD __pointer_chk_guard_local
+#else
+extern uintptr_t __pointer_chk_guard;
+# define POINTER_CHK_GUARD __pointer_chk_guard
+#endif
diff --git a/sysdeps/sh/nptl/tcb-offsets.sym b/sysdeps/sh/nptl/tcb-offsets.sym
index 234207779dc..f1da9a05156 100644
--- a/sysdeps/sh/nptl/tcb-offsets.sym
+++ b/sysdeps/sh/nptl/tcb-offsets.sym
@@ -9,4 +9,3 @@ CLEANUP_JMP_BUF offsetof (struct pthread, cleanup_jmp_buf)
MULTIPLE_THREADS_OFFSET offsetof (struct pthread, header.multiple_threads)
TLS_PRE_TCB_SIZE sizeof (struct pthread)
MUTEX_FUTEX offsetof (pthread_mutex_t, __data.__lock)
-POINTER_GUARD offsetof (tcbhead_t, pointer_guard)
diff --git a/sysdeps/sh/nptl/tls.h b/sysdeps/sh/nptl/tls.h
index eac95e14c75..7008003344c 100644
--- a/sysdeps/sh/nptl/tls.h
+++ b/sysdeps/sh/nptl/tls.h
@@ -33,7 +33,7 @@
typedef struct
{
dtv_t *dtv;
- uintptr_t pointer_guard;
+ uintptr_t __unused;
} tcbhead_t;
# define TLS_MULTIPLE_THREADS_IN_TCB 1
@@ -109,19 +109,6 @@ typedef struct
# include <tcb-access.h>
-#define THREAD_GET_POINTER_GUARD() \
- ({ tcbhead_t *__tcbp; \
- __asm __volatile ("stc gbr,%0" : "=r" (__tcbp)); \
- __tcbp->pointer_guard;})
- #define THREAD_SET_POINTER_GUARD(value) \
- ({ tcbhead_t *__tcbp; \
- __asm __volatile ("stc gbr,%0" : "=r" (__tcbp)); \
- __tcbp->pointer_guard = (value);})
-#define THREAD_COPY_POINTER_GUARD(descr) \
- ({ tcbhead_t *__tcbp; \
- __asm __volatile ("stc gbr,%0" : "=r" (__tcbp)); \
- ((tcbhead_t *) (descr + 1))->pointer_guard = __tcbp->pointer_guard;})
-
/* Get and set the global scope generation counter in struct pthread. */
#define THREAD_GSCOPE_FLAG_UNUSED 0
#define THREAD_GSCOPE_FLAG_USED 1
diff --git a/sysdeps/sh/stackguard-macros.h b/sysdeps/sh/stackguard-macros.h
index 55a5771b629..b4a6b23ff87 100644
--- a/sysdeps/sh/stackguard-macros.h
+++ b/sysdeps/sh/stackguard-macros.h
@@ -3,4 +3,10 @@
extern uintptr_t __stack_chk_guard;
#define STACK_CHK_GUARD __stack_chk_guard
-#define POINTER_CHK_GUARD THREAD_GET_POINTER_GUARD()
+#ifdef PTRGUARD_LOCAL
+extern uintptr_t __pointer_chk_guard_local;
+# define POINTER_CHK_GUARD __pointer_chk_guard_local
+#else
+extern uintptr_t __pointer_chk_guard;
+# define POINTER_CHK_GUARD __pointer_chk_guard
+#endif
diff --git a/sysdeps/sparc/nptl/tcb-offsets.sym b/sysdeps/sparc/nptl/tcb-offsets.sym
index f75d02065ed..a64180da039 100644
--- a/sysdeps/sparc/nptl/tcb-offsets.sym
+++ b/sysdeps/sparc/nptl/tcb-offsets.sym
@@ -2,5 +2,4 @@
#include <tls.h>
MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads)
-POINTER_GUARD offsetof (tcbhead_t, pointer_guard)
TID offsetof (struct pthread, tid)
diff --git a/sysdeps/sparc/nptl/tls.h b/sysdeps/sparc/nptl/tls.h
index cd2112a6500..361fc11a435 100644
--- a/sysdeps/sparc/nptl/tls.h
+++ b/sysdeps/sparc/nptl/tls.h
@@ -41,7 +41,7 @@ typedef struct
#endif
uintptr_t sysinfo;
uintptr_t stack_guard;
- uintptr_t pointer_guard;
+ uintptr_t __unused;
#if __WORDSIZE != 64
int gscope_flag;
#endif
@@ -115,14 +115,6 @@ register struct pthread *__thread_self __asm__("%g7");
((descr)->header.stack_guard \
= THREAD_GETMEM (THREAD_SELF, header.stack_guard))
-/* Get/set the stack guard field in TCB head. */
-#define THREAD_GET_POINTER_GUARD() \
- THREAD_GETMEM (THREAD_SELF, header.pointer_guard)
-#define THREAD_SET_POINTER_GUARD(value) \
- THREAD_SETMEM (THREAD_SELF, header.pointer_guard, value)
-# define THREAD_COPY_POINTER_GUARD(descr) \
- ((descr)->header.pointer_guard = THREAD_GET_POINTER_GUARD ())
-
/* Get and set the global scope generation counter in struct pthread. */
#define THREAD_GSCOPE_FLAG_UNUSED 0
#define THREAD_GSCOPE_FLAG_USED 1
diff --git a/sysdeps/sparc/sparc32/stackguard-macros.h b/sysdeps/sparc/sparc32/stackguard-macros.h
index 1eef0f19f00..e8000a28991 100644
--- a/sysdeps/sparc/sparc32/stackguard-macros.h
+++ b/sysdeps/sparc/sparc32/stackguard-macros.h
@@ -3,5 +3,10 @@
#define STACK_CHK_GUARD \
({ uintptr_t x; asm ("ld [%%g7+0x14], %0" : "=r" (x)); x; })
-#define POINTER_CHK_GUARD \
- ({ uintptr_t x; asm ("ld [%%g7+0x18], %0" : "=r" (x)); x; })
+#ifdef PTRGUARD_LOCAL
+extern uintptr_t __pointer_chk_guard_local;
+# define POINTER_CHK_GUARD __pointer_chk_guard_local
+#else
+extern uintptr_t __pointer_chk_guard;
+# define POINTER_CHK_GUARD __pointer_chk_guard
+#endif
diff --git a/sysdeps/sparc/sparc64/stackguard-macros.h b/sysdeps/sparc/sparc64/stackguard-macros.h
index cc0c12c0412..99978d8beca 100644
--- a/sysdeps/sparc/sparc64/stackguard-macros.h
+++ b/sysdeps/sparc/sparc64/stackguard-macros.h
@@ -3,5 +3,10 @@
#define STACK_CHK_GUARD \
({ uintptr_t x; asm ("ldx [%%g7+0x28], %0" : "=r" (x)); x; })
-#define POINTER_CHK_GUARD \
- ({ uintptr_t x; asm ("ldx [%%g7+0x30], %0" : "=r" (x)); x; })
+#ifdef PTRGUARD_LOCAL
+extern uintptr_t __pointer_chk_guard_local;
+# define POINTER_CHK_GUARD __pointer_chk_guard_local
+#else
+extern uintptr_t __pointer_chk_guard;
+# define POINTER_CHK_GUARD __pointer_chk_guard
+#endif
diff --git a/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S b/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S
index c7573fe9276..aea4d156f76 100644
--- a/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S
+++ b/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S
@@ -52,8 +52,8 @@ ENTRY (____longjmp_chk)
/* Get the stack pointer. */
movl (JB_SP*4)(%ecx), %edi
cfi_undefined(%edi)
- PTR_DEMANGLE (%edx)
- PTR_DEMANGLE (%edi)
+ PTR_DEMANGLE (%edx, bx)
+ PTR_DEMANGLE (%edi, bx)
cmpl %edi, %esp
jbe .Lok
diff --git a/sysdeps/unix/sysv/linux/i386/pointer_guard.h b/sysdeps/unix/sysv/linux/i386/pointer_guard.h
index c8311be444b..27fa8de4656 100644
--- a/sysdeps/unix/sysv/linux/i386/pointer_guard.h
+++ b/sysdeps/unix/sysv/linux/i386/pointer_guard.h
@@ -19,26 +19,56 @@
#ifndef POINTER_GUARD_H
#define POINTER_GUARD_H
-#include <tcb-offsets.h>
-
#if IS_IN (rtld)
/* We cannot use the thread descriptor because in ld.so we use setjmp
- earlier than the descriptor is initialized. Using a global variable
- is too complicated here since we have no PC-relative addressing mode. */
+ earlier than the descriptor is initialized. */
# include <sysdeps/generic/pointer_guard.h>
#else
# ifdef __ASSEMBLER__
-# define PTR_MANGLE(reg) xorl %gs:POINTER_GUARD, reg; \
+# include <sysdep.h>
+/* The PIC variants clobber TMP, a register name suffix as expected by
+ LOAD_PIC_REG (e.g. dx for %edx), to load the guard value. */
+# ifdef SHARED
+/* The global guard is reached through the GOT. */
+# define PTR_MANGLE(reg, tmp) LOAD_PIC_REG (tmp); \
+ movl __pointer_chk_guard@GOT(%e##tmp), %e##tmp; \
+ xorl (%e##tmp), reg; \
roll $9, reg
-# define PTR_DEMANGLE(reg) rorl $9, reg; \
- xorl %gs:POINTER_GUARD, reg
+# define PTR_DEMANGLE(reg, tmp) \
+ rorl $9, reg; \
+ LOAD_PIC_REG (tmp); \
+ movl __pointer_chk_guard@GOT(%e##tmp), %e##tmp; \
+ xorl (%e##tmp), reg
+# elif defined PIC
+/* Static PIE: the module-local guard is reached via @GOTOFF. */
+# define PTR_MANGLE(reg, tmp) LOAD_PIC_REG (tmp); \
+ xorl __pointer_chk_guard_local@GOTOFF(%e##tmp), reg; \
+ roll $9, reg
+# define PTR_DEMANGLE(reg, tmp) \
+ rorl $9, reg; \
+ LOAD_PIC_REG (tmp); \
+ xorl __pointer_chk_guard_local@GOTOFF(%e##tmp), reg
+# else
+/* Position-dependent code addresses the guard directly. */
+# define PTR_MANGLE(reg, tmp) xorl __pointer_chk_guard_local, reg; \
+ roll $9, reg
+# define PTR_DEMANGLE(reg, tmp) \
+ rorl $9, reg; \
+ xorl __pointer_chk_guard_local, reg
+# endif
# else
# include <stdbit.h>
-# include <tls.h>
+# include <stdint.h>
+# ifdef SHARED
+extern uintptr_t __pointer_chk_guard attribute_relro;
+# define PTR_GUARD_VALUE __pointer_chk_guard
+# else
+extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden;
+# define PTR_GUARD_VALUE __pointer_chk_guard_local
+# endif
# define PTR_MANGLE(var) \
do { \
- (var) = (__typeof (var)) ((uintptr_t) (var) \
- ^ ((tcbhead_t __seg_gs *)0)->pointer_guard); \
+ (var) = (__typeof (var)) ((uintptr_t) (var) ^ PTR_GUARD_VALUE); \
(var) = (__typeof (var)) stdc_rotate_left ((uintptr_t) (var), \
2 * sizeof (uintptr_t) + 1); \
} while (0)
@@ -46,8 +76,7 @@
do { \
(var) = (__typeof (var)) stdc_rotate_right ((uintptr_t) (var), \
2 * sizeof (uintptr_t) + 1); \
- (var) = (__typeof (var)) ((uintptr_t) (var) \
- ^ ((tcbhead_t __seg_gs *)0)->pointer_guard); \
+ (var) = (__typeof (var)) ((uintptr_t) (var) ^ PTR_GUARD_VALUE); \
} while (0)
# endif
#endif
diff --git a/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h b/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h
index 50d177224ff..864a78ea531 100644
--- a/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h
+++ b/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h
@@ -20,34 +20,59 @@
#define POINTER_GUARD_H
#if IS_IN (rtld)
-/* We cannot use the thread descriptor because in ld.so we use setjmp
- earlier than the descriptor is initialized. */
# include <sysdeps/generic/pointer_guard.h>
#else
# ifdef __ASSEMBLER__
-# if defined(__PPC64__) || defined(__powerpc64__)
-# define LOAD ld
-# define TPREG r13
+# include <sysdep.h>
+# ifdef SHARED
+# define PTR_GUARD_SYM __pointer_chk_guard
# else
-# define LOAD lwz
-# define TPREG r2
+# define PTR_GUARD_SYM __pointer_chk_guard_local
# endif
+
+# if defined(__PPC64__) || defined(__powerpc64__)
+# define PTR_GUARD_LOAD(tmpreg) \
+ addis tmpreg,r2,PTR_GUARD_SYM@got@ha; \
+ ld tmpreg,PTR_GUARD_SYM@got@l(tmpreg); \
+ ld tmpreg,0(tmpreg)
+# elif defined PIC
+# define PTR_GUARD_LOAD(tmpreg) \
+ mflr r12; \
+ bcl 20,31,0f; \
+0: mflr tmpreg; \
+ addis tmpreg,tmpreg,_GLOBAL_OFFSET_TABLE_-0b@ha; \
+ addi tmpreg,tmpreg,_GLOBAL_OFFSET_TABLE_-0b@l; \
+ mtlr r12; \
+ lwz tmpreg,PTR_GUARD_SYM@got(tmpreg); \
+ lwz tmpreg,0(tmpreg)
+# else
+# define PTR_GUARD_LOAD(tmpreg) \
+ lis tmpreg,PTR_GUARD_SYM@ha; \
+ lwz tmpreg,PTR_GUARD_SYM@l(tmpreg)
+# endif
+
# define PTR_MANGLE(reg, tmpreg) \
- LOAD tmpreg,POINTER_GUARD(TPREG); \
- xor reg,tmpreg,reg
+ PTR_GUARD_LOAD (tmpreg); \
+ xor reg,tmpreg,reg
# define PTR_MANGLE2(reg, tmpreg) \
- xor reg,tmpreg,reg
+ xor reg,tmpreg,reg
# define PTR_MANGLE3(destreg, reg, tmpreg) \
- LOAD tmpreg,POINTER_GUARD(TPREG); \
- xor destreg,tmpreg,reg
+ PTR_GUARD_LOAD (tmpreg); \
+ xor destreg,tmpreg,reg
# define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg)
# define PTR_DEMANGLE2(reg, tmpreg) PTR_MANGLE2 (reg, tmpreg)
# define PTR_DEMANGLE3(destreg, reg, tmpreg) PTR_MANGLE3 (destreg, reg, tmpreg)
# else
# include <stdint.h>
-# include <tls.h>
-# define PTR_MANGLE(var) \
- (var) = (__typeof (var)) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ())
+# ifdef SHARED
+extern uintptr_t __pointer_chk_guard attribute_relro;
+# define PTR_MANGLE(var) \
+ (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard)
+# else
+extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden;
+# define PTR_MANGLE(var) \
+ (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local)
+# endif
# define PTR_DEMANGLE(var) PTR_MANGLE (var)
# endif
#endif
diff --git a/sysdeps/unix/sysv/linux/s390/pointer_guard.h b/sysdeps/unix/sysv/linux/s390/pointer_guard.h
index d7a574e94c6..aa75b8c42e5 100644
--- a/sysdeps/unix/sysv/linux/s390/pointer_guard.h
+++ b/sysdeps/unix/sysv/linux/s390/pointer_guard.h
@@ -20,26 +20,37 @@
#define POINTER_GUARD_H
#if IS_IN (rtld)
-/* We cannot use the thread descriptor because in ld.so we use setjmp
- earlier than the descriptor is initialized. */
# include <sysdeps/generic/pointer_guard.h>
#else
-/* For the time being just use stack_guard rather than a separate
- pointer_guard. */
# ifdef __ASSEMBLER__
+# ifdef SHARED
+# define PTR_GUARD_LOAD(tmpreg) \
+ larl tmpreg,__pointer_chk_guard@GOTENT; \
+ lg tmpreg,0(tmpreg); \
+ lg tmpreg,0(tmpreg)
+# else
+# define PTR_GUARD_LOAD(tmpreg) \
+ larl tmpreg,__pointer_chk_guard_local; \
+ lg tmpreg,0(tmpreg)
+# endif
# define PTR_MANGLE(reg, tmpreg) \
- ear tmpreg,%a0; \
- sllg tmpreg,tmpreg,32; \
- ear tmpreg,%a1; \
- xg reg,STACK_GUARD(tmpreg)
+ PTR_GUARD_LOAD (tmpreg); \
+ xgr reg,tmpreg
# define PTR_MANGLE2(reg, tmpreg) \
- xg reg,STACK_GUARD(tmpreg)
+ xgr reg,tmpreg
# define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg)
+# define PTR_DEMANGLE2(reg, tmpreg) PTR_MANGLE2 (reg, tmpreg)
# else
# include <stdint.h>
-# include <tls.h>
+# ifdef SHARED
+extern uintptr_t __pointer_chk_guard attribute_relro;
+# define PTR_GUARD_VALUE __pointer_chk_guard
+# else
+extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden;
+# define PTR_GUARD_VALUE __pointer_chk_guard_local
+# endif
# define PTR_MANGLE(var) \
- (var) = (void *) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ())
+ (var) = (void *) ((uintptr_t) (var) ^ PTR_GUARD_VALUE)
# define PTR_DEMANGLE(var) PTR_MANGLE (var)
# endif
#endif
diff --git a/sysdeps/unix/sysv/linux/sh/pointer_guard.h b/sysdeps/unix/sysv/linux/sh/pointer_guard.h
index f1ec4b41f4f..fa989573c9e 100644
--- a/sysdeps/unix/sysv/linux/sh/pointer_guard.h
+++ b/sysdeps/unix/sysv/linux/sh/pointer_guard.h
@@ -1,4 +1,4 @@
-/* Pointer obfuscation implenentation. Generic (no-op) version.
+/* Pointer obfuscation implenentation. SH version.
Copyright (C) 2005-2026 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -20,22 +20,59 @@
#define POINTER_GUARD_H
#if IS_IN (rtld)
-/* We cannot use the thread descriptor because in ld.so we use setjmp
- earlier than the descriptor is initialized. Using a global variable
- is too complicated here since we have no PC-relative addressing mode. */
# include <sysdeps/generic/pointer_guard.h>
#else
# ifdef __ASSEMBLER__
+# ifdef SHARED
+# define PTR_GUARD_SYM __pointer_chk_guard
+# else
+# define PTR_GUARD_SYM __pointer_chk_guard_local
+# endif
+# ifdef PIC
+# define PTR_GUARD_LOAD(tmp) \
+ mov r0, r3; \
+ mova .Lptrg_got, r0; \
+ mov.l .Lptrg_got, tmp; \
+ add r0, tmp; \
+ mov.l .Lptrg_sym, r0; \
+ mov.l @(r0, tmp), tmp; \
+ mov r3, r0; \
+ mov.l @tmp, tmp; \
+ bra .Lptrg_end; \
+ nop; \
+ .align 2; \
+.Lptrg_got: \
+ .long _GLOBAL_OFFSET_TABLE_; \
+.Lptrg_sym: \
+ .long PTR_GUARD_SYM@GOT; \
+.Lptrg_end:
+# else
+# define PTR_GUARD_LOAD(tmp) \
+ mov.l .Lptrg_sym, tmp; \
+ mov.l @tmp, tmp; \
+ bra .Lptrg_end; \
+ nop; \
+ .align 2; \
+.Lptrg_sym: \
+ .long PTR_GUARD_SYM; \
+.Lptrg_end:
+# endif
# define PTR_MANGLE(reg, tmp) \
- stc gbr,tmp; mov.l @(POINTER_GUARD,tmp),tmp; xor tmp,reg
+ PTR_GUARD_LOAD (tmp); xor tmp,reg
# define PTR_MANGLE2(reg, tmp) xor tmp,reg
# define PTR_DEMANGLE(reg, tmp) PTR_MANGLE (reg, tmp)
# define PTR_DEMANGLE2(reg, tmp) PTR_MANGLE2 (reg, tmp)
# else
# include <stdint.h>
-# include <tls.h>
-# define PTR_MANGLE(var) \
- (var) = (void *) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ())
+# ifdef SHARED
+extern uintptr_t __pointer_chk_guard attribute_relro;
+# define PTR_MANGLE(var) \
+ (var) = (void *) ((uintptr_t) (var) ^ __pointer_chk_guard)
+# else
+extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden;
+# define PTR_MANGLE(var) \
+ (var) = (void *) ((uintptr_t) (var) ^ __pointer_chk_guard_local)
+# endif
# define PTR_DEMANGLE(var) PTR_MANGLE (var)
# endif
#endif
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h b/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h
index 4359bf9fca6..f314f8598b4 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h
@@ -25,18 +25,45 @@
# include <sysdeps/generic/pointer_guard.h>
#else
# ifdef __ASSEMBLER__
+# include <sysdep.h>
+# ifdef SHARED
+# define PTR_GUARD_SYM __pointer_chk_guard
+# else
+# define PTR_GUARD_SYM __pointer_chk_guard_local
+# endif
+# ifdef PIC
+/* Load the guard through the GOT. SETUP_PIC_REG_LEAF computes the GOT
+ pointer in %o2 while preserving %o7 (the return address, which setjmp
+ mangles), using %o3 as a scratch register. */
+# define PTR_GUARD_LOAD(tmpreg) \
+ SETUP_PIC_REG_LEAF(o2, o3); \
+ sethi %gdop_hix22(PTR_GUARD_SYM), tmpreg; \
+ xor tmpreg, %gdop_lox10(PTR_GUARD_SYM), tmpreg; \
+ ld [%o2 + tmpreg], tmpreg, %gdop(PTR_GUARD_SYM); \
+ ld [tmpreg], tmpreg
+# else
+# define PTR_GUARD_LOAD(tmpreg) \
+ sethi %hi(PTR_GUARD_SYM), tmpreg; \
+ ld [tmpreg + %lo(PTR_GUARD_SYM)], tmpreg
+# endif
# define PTR_MANGLE(dreg, reg, tmpreg) \
- ld [%g7 + POINTER_GUARD], tmpreg; \
- xor reg, tmpreg, dreg
+ PTR_GUARD_LOAD (tmpreg); \
+ xor reg, tmpreg, dreg
# define PTR_DEMANGLE(dreg, reg, tmpreg) PTR_MANGLE (dreg, reg, tmpreg)
# define PTR_MANGLE2(dreg, reg, tmpreg) \
- xor reg, tmpreg, dreg
+ xor reg, tmpreg, dreg
# define PTR_DEMANGLE2(dreg, reg, tmpreg) PTR_MANGLE2 (dreg, reg, tmpreg)
# else
# include <stdint.h>
-# include <tls.h>
-# define PTR_MANGLE(var) \
- (var) = (__typeof (var)) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ())
+# ifdef SHARED
+extern uintptr_t __pointer_chk_guard attribute_relro;
+# define PTR_MANGLE(var) \
+ (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard)
+# else
+extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden;
+# define PTR_MANGLE(var) \
+ (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local)
+# endif
# define PTR_DEMANGLE(var) PTR_MANGLE (var)
# endif
#endif
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h b/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h
index 91bc1f4d85e..6515e0dd072 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h
@@ -25,18 +25,44 @@
# include <sysdeps/generic/pointer_guard.h>
#else
# ifdef __ASSEMBLER__
+# include <sysdep.h>
+# ifdef SHARED
+# define PTR_GUARD_SYM __pointer_chk_guard
+# else
+# define PTR_GUARD_SYM __pointer_chk_guard_local
+# endif
+# ifdef PIC
+/* Load the guard through the GOT. SETUP_PIC_REG_LEAF computes the GOT
+ pointer in %o2 while preserving %o7, using %o3 as a scratch register. */
+# define PTR_GUARD_LOAD(tmpreg) \
+ SETUP_PIC_REG_LEAF(o2, o3); \
+ sethi %gdop_hix22(PTR_GUARD_SYM), tmpreg; \
+ xor tmpreg, %gdop_lox10(PTR_GUARD_SYM), tmpreg; \
+ ldx [%o2 + tmpreg], tmpreg, %gdop(PTR_GUARD_SYM); \
+ ldx [tmpreg], tmpreg
+# else
+# define PTR_GUARD_LOAD(tmpreg) \
+ sethi %hi(PTR_GUARD_SYM), tmpreg; \
+ ldx [tmpreg + %lo(PTR_GUARD_SYM)], tmpreg
+# endif
# define PTR_MANGLE(dreg, reg, tmpreg) \
- ldx [%g7 + POINTER_GUARD], tmpreg; \
- xor reg, tmpreg, dreg
+ PTR_GUARD_LOAD (tmpreg); \
+ xor reg, tmpreg, dreg
# define PTR_DEMANGLE(dreg, reg, tmpreg) PTR_MANGLE (dreg, reg, tmpreg)
# define PTR_MANGLE2(dreg, reg, tmpreg) \
- xor reg, tmpreg, dreg
+ xor reg, tmpreg, dreg
# define PTR_DEMANGLE2(dreg, reg, tmpreg) PTR_MANGLE2 (dreg, reg, tmpreg)
# else
# include <stdint.h>
-# include <tls.h>
-# define PTR_MANGLE(var) \
- (var) = (__typeof (var)) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ())
+# ifdef SHARED
+extern uintptr_t __pointer_chk_guard attribute_relro;
+# define PTR_MANGLE(var) \
+ (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard)
+# else
+extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden;
+# define PTR_MANGLE(var) \
+ (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local)
+# endif
# define PTR_DEMANGLE(var) PTR_MANGLE (var)
# endif
#endif
diff --git a/sysdeps/unix/sysv/linux/x86_64/pointer_guard.h b/sysdeps/unix/sysv/linux/x86_64/pointer_guard.h
index 4f7abc64f49..6d09b429cd2 100644
--- a/sysdeps/unix/sysv/linux/x86_64/pointer_guard.h
+++ b/sysdeps/unix/sysv/linux/x86_64/pointer_guard.h
@@ -22,9 +22,8 @@
#include <x86-lp_size.h>
#include <tcb-offsets.h>
-#if IS_IN (rtld)
-/* We cannot use the thread descriptor because in ld.so we use setjmp
- earlier than the descriptor is initialized. */
+#if (IS_IN (rtld) \
+ || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread))))
# ifdef __ASSEMBLER__
# define PTR_MANGLE(reg) xor __pointer_chk_guard_local(%rip), reg; \
rol $2*LP_SIZE+1, reg
@@ -51,17 +50,20 @@ extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden;
# endif
#else
# ifdef __ASSEMBLER__
-# define PTR_MANGLE(reg) xor %fs:POINTER_GUARD, reg; \
+# define PTR_MANGLE(reg) mov __pointer_chk_guard@GOTPCREL(%rip), %R11_LP;\
+ xor (%R11_LP), reg; \
rol $2*LP_SIZE+1, reg
# define PTR_DEMANGLE(reg) ror $2*LP_SIZE+1, reg; \
- xor %fs:POINTER_GUARD, reg
+ mov __pointer_chk_guard@GOTPCREL(%rip), %R11_LP;\
+ xor (%R11_LP), reg
# else
# include <stdbit.h>
-# include <tls.h>
+# include <stdint.h>
+extern uintptr_t __pointer_chk_guard attribute_relro;
# define PTR_MANGLE(var) \
do { \
(var) = (__typeof (var)) ((uintptr_t) (var) \
- ^ ((tcbhead_t __seg_fs *)0)->pointer_guard); \
+ ^ __pointer_chk_guard); \
(var) = (__typeof (var)) stdc_rotate_left ((uintptr_t) (var), \
2 * sizeof (uintptr_t) + 1); \
} while (0)
@@ -70,7 +72,7 @@ extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden;
(var) = (__typeof (var)) stdc_rotate_right ((uintptr_t) (var), \
2 * sizeof (uintptr_t) + 1); \
(var) = (__typeof (var)) ((uintptr_t) (var) \
- ^ ((tcbhead_t __seg_fs *)0)->pointer_guard); \
+ ^ __pointer_chk_guard); \
} while (0)
# endif
#endif
diff --git a/sysdeps/x86_64/htl/tcb-offsets.sym b/sysdeps/x86_64/htl/tcb-offsets.sym
index 7b7c7193695..b36cfd6848a 100644
--- a/sysdeps/x86_64/htl/tcb-offsets.sym
+++ b/sysdeps/x86_64/htl/tcb-offsets.sym
@@ -4,5 +4,4 @@
MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads)
SYSINFO_OFFSET offsetof (tcbhead_t, sysinfo)
-POINTER_GUARD offsetof (tcbhead_t, pointer_guard)
SIGSTATE_OFFSET offsetof (tcbhead_t, _hurd_sigstate)
diff --git a/sysdeps/x86_64/nptl/tcb-offsets.sym b/sysdeps/x86_64/nptl/tcb-offsets.sym
index 988a4b85936..aaa1dacd0cc 100644
--- a/sysdeps/x86_64/nptl/tcb-offsets.sym
+++ b/sysdeps/x86_64/nptl/tcb-offsets.sym
@@ -10,6 +10,5 @@ CLEANUP offsetof (struct pthread, cleanup)
CLEANUP_PREV offsetof (struct _pthread_cleanup_buffer, __prev)
MUTEX_FUTEX offsetof (pthread_mutex_t, __data.__lock)
MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads)
-POINTER_GUARD offsetof (tcbhead_t, pointer_guard)
FEATURE_1_OFFSET offsetof (tcbhead_t, feature_1)
SSP_BASE_OFFSET offsetof (tcbhead_t, ssp_base)
diff --git a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h
index 836b2e22440..413ab074bf8 100644
--- a/sysdeps/x86_64/nptl/tls.h
+++ b/sysdeps/x86_64/nptl/tls.h
@@ -49,7 +49,7 @@ typedef struct
int gscope_flag;
uintptr_t sysinfo;
uintptr_t stack_guard;
- uintptr_t pointer_guard;
+ uintptr_t __unused;
unsigned long int unused_vgetcpu_cache[2];
/* Bit 0: X86_FEATURE_1_IBT.
Bit 1: X86_FEATURE_1_SHSTK.
@@ -186,14 +186,6 @@ _Static_assert (offsetof (tcbhead_t, __glibc_unused2) == 0x80,
= THREAD_GETMEM (THREAD_SELF, header.stack_guard))
-/* Set the pointer guard field in the TCB head. */
-# define THREAD_SET_POINTER_GUARD(value) \
- THREAD_SETMEM (THREAD_SELF, header.pointer_guard, value)
-# define THREAD_COPY_POINTER_GUARD(descr) \
- ((descr)->header.pointer_guard \
- = THREAD_GETMEM (THREAD_SELF, header.pointer_guard))
-
-
/* Get and set the global scope generation counter in the TCB head. */
# define THREAD_GSCOPE_FLAG_UNUSED 0
# define THREAD_GSCOPE_FLAG_USED 1
diff --git a/sysdeps/x86_64/stackguard-macros.h b/sysdeps/x86_64/stackguard-macros.h
index 77f13c986d8..3d685e0f828 100644
--- a/sysdeps/x86_64/stackguard-macros.h
+++ b/sysdeps/x86_64/stackguard-macros.h
@@ -1,3 +1,11 @@
+#include <stdint.h>
+
#define STACK_CHK_GUARD (((tcbhead_t __seg_fs *)0)->stack_guard)
-#define POINTER_CHK_GUARD (((tcbhead_t __seg_fs *)0)->pointer_guard)
+#ifdef PTRGUARD_LOCAL
+extern uintptr_t __pointer_chk_guard_local;
+# define POINTER_CHK_GUARD __pointer_chk_guard_local
+#else
+extern uintptr_t __pointer_chk_guard;
+# define POINTER_CHK_GUARD __pointer_chk_guard
+#endif
--
2.43.0
More information about the Libc-alpha
mailing list