[glibc] Consolidate the C pointer guard and align the assembly implementations

Adhemerval Zanella via Glibc-cvs <[email protected]> Tue, 16 Jun 2026 18:16:01 +0000 (GMT)
Newsgroups gmane.comp.lib.glibc.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=78f1f0e39cd41d28ae771eb3498bc33780c85cfd

commit 78f1f0e39cd41d28ae771eb3498bc33780c85cfd
Author: Adhemerval Zanella <[email protected]>
Date:   Fri Jun 12 13:10:14 2026 -0300

    Consolidate the C pointer guard and align the assembly implementations
    
    The per-architecture pointer_guard.h files all implemented some variant
    of C PTR_MANGLE/PTR_DEMANGLE: the i386 and x86_64 versions did an
    exclusive-or by the guard followed by a rotate left by
    2 * sizeof (uintptr_t) + 1 bits (9 on 32-bit, 17 on 64-bit), while the
    other targets did the exclusive-or only.  The assembly macros likewise
    rotated on i386 and x86_64 but not on the other targets.
    
    Consolidate everything to use XOR + rotate uniformly: collapse the
    per-architecture C headers into a single generic implementation, and
    add the matching rotate to the assembly implementations that lacked it.
    
    Targets with an assembly rotate instruction (aarch64, arm, loongarch,
    powerpc, s390, csky) just add it.  Those without one (alpha, sparc, sh)
    synthesize the rotation: alpha and sparc with a shift/shift/or sequence,
    which needs an extra scratch register added to the PTR_MANGLE/PTR_DEMANGLE
    macros, sh with single-bit rotates, which needs no scratch.  The s390
    __longjmp and ____longjmp_chk demangle the return address and stack
    pointer in C, so update those too.
    
    Checked with setjmp, ptrguard and longjmp_chk tests for all supported
    ABIs that can run under qemu (all but csky), and with builds for all
    supported ABIs.
    
    Reviewed-by: DJ Delorie <[email protected]>

Diff:
---
 sysdeps/alpha/__longjmp.S                          |  6 +-
 sysdeps/alpha/setjmp.S                             |  8 +--
 sysdeps/arm/pointer_guard-asm.h                    | 31 ++++-------
 sysdeps/arm/pointer_guard.h                        | 40 --------------
 sysdeps/generic/pointer_guard.h                    | 28 +++++++++-
 .../{unix/sysv/linux => }/i386/pointer_guard-asm.h |  0
 sysdeps/mach/hurd/i386/____longjmp_chk.S           |  4 +-
 sysdeps/mach/hurd/i386/__longjmp.S                 |  4 +-
 sysdeps/s390/__longjmp.c                           |  2 +
 sysdeps/sparc/sparc32/__longjmp.S                  | 10 ++--
 sysdeps/sparc/sparc32/setjmp.S                     |  6 +-
 .../unix/sysv/linux/aarch64/pointer_guard-asm.h    | 20 ++++---
 sysdeps/unix/sysv/linux/aarch64/pointer_guard.h    | 41 --------------
 sysdeps/unix/sysv/linux/alpha/____longjmp_chk.S    |  6 +-
 sysdeps/unix/sysv/linux/alpha/pointer_guard-asm.h  | 37 ++++++++-----
 sysdeps/unix/sysv/linux/alpha/pointer_guard.h      | 40 --------------
 sysdeps/unix/sysv/linux/csky/pointer_guard-asm.h   | 42 +++++++-------
 sysdeps/unix/sysv/linux/csky/pointer_guard.h       | 40 --------------
 sysdeps/unix/sysv/linux/i386/pointer_guard.h       | 48 ----------------
 .../unix/sysv/linux/loongarch/pointer_guard-asm.h  | 35 +++++-------
 sysdeps/unix/sysv/linux/loongarch/pointer_guard.h  | 41 --------------
 .../unix/sysv/linux/powerpc/pointer_guard-asm.h    | 31 +++++++++--
 sysdeps/unix/sysv/linux/powerpc/pointer_guard.h    | 38 -------------
 sysdeps/unix/sysv/linux/s390/____longjmp_chk.c     |  4 +-
 sysdeps/unix/sysv/linux/s390/pointer_guard-asm.h   | 13 ++++-
 sysdeps/unix/sysv/linux/s390/pointer_guard.h       | 38 -------------
 sysdeps/unix/sysv/linux/sh/pointer_guard-asm.h     | 14 +++--
 sysdeps/unix/sysv/linux/sh/pointer_guard.h         | 38 -------------
 .../sysv/linux/sparc/sparc32/____longjmp_chk.S     |  6 +-
 .../sysv/linux/sparc/sparc32/pointer_guard-asm.h   | 21 +++++--
 .../unix/sysv/linux/sparc/sparc32/pointer_guard.h  | 38 -------------
 .../sysv/linux/sparc/sparc64/pointer_guard-asm.h   | 21 +++++--
 .../unix/sysv/linux/sparc/sparc64/pointer_guard.h  | 38 -------------
 sysdeps/unix/sysv/linux/x86_64/pointer_guard.h     | 64 ----------------------
 .../sysv/linux => }/x86_64/pointer_guard-asm.h     |  0
 35 files changed, 213 insertions(+), 640 deletions(-)

diff --git a/sysdeps/alpha/__longjmp.S b/sysdeps/alpha/__longjmp.S
index 0a18a37789..f516e9ba61 100644
--- a/sysdeps/alpha/__longjmp.S
+++ b/sysdeps/alpha/__longjmp.S
@@ -53,9 +53,9 @@ ENTRY(__longjmp)
 	ldt     $f8, JB_F8*8(a0)
 	ldt     $f9, JB_F9*8(a0)
 #ifdef PTR_DEMANGLE
-	PTR_DEMANGLE(ra, t1)
-	PTR_DEMANGLE2(t0, t1)
-	PTR_DEMANGLE2(fp, t1)
+	PTR_DEMANGLE(ra, t1, t2)
+	PTR_DEMANGLE2(t0, t1, t2)
+	PTR_DEMANGLE2(fp, t1, t2)
 #endif
 	cmoveq  v0, 1, v0
 	mov     t0, sp
diff --git a/sysdeps/alpha/setjmp.S b/sysdeps/alpha/setjmp.S
index 8dc3dacab4..bf228991da 100644
--- a/sysdeps/alpha/setjmp.S
+++ b/sysdeps/alpha/setjmp.S
@@ -52,22 +52,22 @@ $sigsetjmp_local:
 	stq	s4, JB_S4*8(a0)
 	stq	s5, JB_S5*8(a0)
 #ifdef PTR_MANGLE
-	PTR_MANGLE(t1, ra, t0)
+	PTR_MANGLE(t1, ra, t0, t2)
 	stq	t1, JB_PC*8(a0)
 #else
 	stq	ra, JB_PC*8(a0)
 #endif
 #if defined(PTR_MANGLE) && FRAME == 0
-	PTR_MANGLE2(t1, sp, t0)
+	PTR_MANGLE2(t1, sp, t0, t2)
 #else
 	addq	sp, FRAME, t1
 # ifdef PTR_MANGLE
-	PTR_MANGLE2(t1, t1, t0)
+	PTR_MANGLE2(t1, t1, t0, t2)
 # endif
 #endif
 	stq	t1, JB_SP*8(a0)
 #ifdef PTR_MANGLE
-	PTR_MANGLE2(t1, fp, t0)
+	PTR_MANGLE2(t1, fp, t0, t2)
 	stq	t1, JB_FP*8(a0)
 #else
 	stq	fp, JB_FP*8(a0)
diff --git a/sysdeps/arm/pointer_guard-asm.h b/sysdeps/arm/pointer_guard-asm.h
index 86a9055b61..e34faa40ca 100644
--- a/sysdeps/arm/pointer_guard-asm.h
+++ b/sysdeps/arm/pointer_guard-asm.h
@@ -24,30 +24,23 @@
       || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread))))
 #  define PTR_MANGLE_LOAD(guard, tmp)                                   \
   LDR_HIDDEN (guard, tmp, C_SYMBOL_NAME(__pointer_chk_guard_local), 0)
-#  define PTR_MANGLE(dst, src, guard, tmp)                              \
-  PTR_MANGLE_LOAD(guard, tmp);                                          \
-  PTR_MANGLE2(dst, src, guard)
-/* Use PTR_MANGLE2 for efficiency if guard is already loaded.  */
-#  define PTR_MANGLE2(dst, src, guard)          \
-  eor dst, src, guard
-#  define PTR_DEMANGLE(dst, src, guard, tmp)    \
-  PTR_MANGLE (dst, src, guard, tmp)
-#  define PTR_DEMANGLE2(dst, src, guard)        \
-  PTR_MANGLE2 (dst, src, guard)
 # else
 #  define PTR_MANGLE_LOAD(guard, tmp)                                   \
-  LDR_GLOBAL (guard, tmp, C_SYMBOL_NAME(__pointer_chk_guard), 0);
-#  define PTR_MANGLE(dst, src, guard, tmp)                              \
+  LDR_GLOBAL (guard, tmp, C_SYMBOL_NAME(__pointer_chk_guard), 0)
+# endif
+# define PTR_MANGLE(dst, src, guard, tmp)                              \
   PTR_MANGLE_LOAD(guard, tmp);                                          \
   PTR_MANGLE2(dst, src, guard)
 /* Use PTR_MANGLE2 for efficiency if guard is already loaded.  */
-#  define PTR_MANGLE2(dst, src, guard)          \
-  eor dst, src, guard
-#  define PTR_DEMANGLE(dst, src, guard, tmp)    \
-  PTR_MANGLE (dst, src, guard, tmp)
-#  define PTR_DEMANGLE2(dst, src, guard)        \
-  PTR_MANGLE2 (dst, src, guard)
-# endif
+# define PTR_MANGLE2(dst, src, guard)          \
+  eor dst, src, guard;                         \
+  ror dst, dst, #23
+# define PTR_DEMANGLE(dst, src, guard, tmp)    \
+  PTR_MANGLE_LOAD(guard, tmp);                  \
+  PTR_DEMANGLE2(dst, src, guard)
+# define PTR_DEMANGLE2(dst, src, guard)        \
+  ror dst, src, #9;                            \
+  eor dst, dst, guard
 #endif
 
 #endif /* POINTER_GUARD_ASM_H */
diff --git a/sysdeps/arm/pointer_guard.h b/sysdeps/arm/pointer_guard.h
deleted file mode 100644
index 9fa25c708a..0000000000
--- a/sysdeps/arm/pointer_guard.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Pointer guard implementation.  Arm version.
-   Copyright (C) 2013-2026 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library.  If not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#ifndef POINTER_GUARD_H
-#define POINTER_GUARD_H
-
-#include <pointer_guard-asm.h>
-
-#ifndef __ASSEMBLER__
-# if (IS_IN (rtld) \
-      || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread))))
-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)
-#  define PTR_DEMANGLE(var)     PTR_MANGLE (var)
-# else
-#  include <stdint.h>
-extern uintptr_t __pointer_chk_guard attribute_relro;
-#  define PTR_MANGLE(var) \
-  (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard)
-#  define PTR_DEMANGLE(var)     PTR_MANGLE (var)
-# endif
-#endif
-
-#endif /* POINTER_GUARD_H */
diff --git a/sysdeps/generic/pointer_guard.h b/sysdeps/generic/pointer_guard.h
index 49eb5ca4ba..aee84c1fa4 100644
--- a/sysdeps/generic/pointer_guard.h
+++ b/sysdeps/generic/pointer_guard.h
@@ -1,4 +1,4 @@
-/* Pointer obfuscation implenentation.  Generic (no-op) version.
+/* Pointer obfuscation implenentation.  Generic version.
    Copyright (C) 2022-2026 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -22,8 +22,30 @@
 #include <pointer_guard-asm.h>
 
 #ifndef __ASSEMBLER__
-# define PTR_MANGLE(x) (void) (x)
-# define PTR_DEMANGLE(x) (void) (x)
+# include <stdbit.h>
+# include <stdint.h>
+
+# if (IS_IN (rtld) \
+      || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread))))
+extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden;
+#  define PTR_GUARD_VALUE	__pointer_chk_guard_local
+# else
+extern uintptr_t __pointer_chk_guard attribute_relro;
+#  define PTR_GUARD_VALUE	__pointer_chk_guard
+# endif
+
+# define PTR_MANGLE(var)						      \
+    do {								      \
+      (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)
+# define PTR_DEMANGLE(var)						      \
+    do {								      \
+      (var) = (__typeof (var)) stdc_rotate_right ((uintptr_t) (var),	      \
+						  2 * sizeof (uintptr_t) + 1); \
+      (var) = (__typeof (var)) ((uintptr_t) (var) ^ PTR_GUARD_VALUE);	      \
+    } while (0)
 #endif
 
 #endif /* POINTER_GUARD_H */
diff --git a/sysdeps/unix/sysv/linux/i386/pointer_guard-asm.h b/sysdeps/i386/pointer_guard-asm.h
similarity index 100%
rename from sysdeps/unix/sysv/linux/i386/pointer_guard-asm.h
rename to sysdeps/i386/pointer_guard-asm.h
diff --git a/sysdeps/mach/hurd/i386/____longjmp_chk.S b/sysdeps/mach/hurd/i386/____longjmp_chk.S
index 135282f9e4..d7b6c4d4b1 100644
--- a/sysdeps/mach/hurd/i386/____longjmp_chk.S
+++ b/sysdeps/mach/hurd/i386/____longjmp_chk.S
@@ -57,8 +57,8 @@ ENTRY (____longjmp_chk)
 	movl	(JB_SP*4)(%eax), %ecx
 	cfi_undefined(%ecx)
 #ifdef PTR_DEMANGLE
-	PTR_DEMANGLE (%edx)
-	PTR_DEMANGLE (%ecx)
+	PTR_DEMANGLE (%edx, bx)
+	PTR_DEMANGLE (%ecx, bx)
 #endif
 
 	movw	%ds, %si
diff --git a/sysdeps/mach/hurd/i386/__longjmp.S b/sysdeps/mach/hurd/i386/__longjmp.S
index 7718d3469a..8431a7f362 100644
--- a/sysdeps/mach/hurd/i386/__longjmp.S
+++ b/sysdeps/mach/hurd/i386/__longjmp.S
@@ -35,8 +35,8 @@ ENTRY (__longjmp)
 	movl (JB_SP*4)(%eax), %ecx
 	cfi_undefined(%ecx)
 #ifdef PTR_DEMANGLE
-	PTR_DEMANGLE (%edx)
-	PTR_DEMANGLE (%ecx)
+	PTR_DEMANGLE (%edx, bx)
+	PTR_DEMANGLE (%ecx, bx)
 #endif
 
 	movw	%ds, %si
diff --git a/sysdeps/s390/__longjmp.c b/sysdeps/s390/__longjmp.c
index 50d67bf42c..cf59686579 100644
--- a/sysdeps/s390/__longjmp.c
+++ b/sysdeps/s390/__longjmp.c
@@ -48,7 +48,9 @@ __longjmp (__jmp_buf env, int val)
 			   argument and target address.  */
 #ifdef PTR_DEMANGLE
 			"lmg  %%r4,%%r5,64(%1)\n\t"
+			"rllg %%r4,%%r4,47\n\t"
 			"xgr  %%r4,%2\n\t"
+			"rllg %%r5,%%r5,47\n\t"
 			"xgr  %%r5,%2\n\t"
 			LIBC_PROBE_ASM (longjmp, 8@%1 -4@%0 8@%%r4)
 #else
diff --git a/sysdeps/sparc/sparc32/__longjmp.S b/sysdeps/sparc/sparc32/__longjmp.S
index 732a250e4d..c443011996 100644
--- a/sysdeps/sparc/sparc32/__longjmp.S
+++ b/sysdeps/sparc/sparc32/__longjmp.S
@@ -28,7 +28,7 @@ ENTRY(__longjmp)
 
 	ld ENV(o0,JB_FP), %g3	/* Cache target FP in register %g3.  */
 #ifdef PTR_DEMANGLE
-	PTR_DEMANGLE (%g3, %g3, %g4)
+	PTR_DEMANGLE (%g3, %g3, %g4, %g5)
 #endif
 	mov %o0, %g1		/* ENV in %g1 */
 	orcc %o1, %g0, %g2	/* VAL in %g2 */
@@ -66,8 +66,8 @@ LOC(thread):
 #ifdef PTR_DEMANGLE
 	ld	ENV(g1,JB_PC), %g5 /* Set return PC. */
 	ld	ENV(g1,JB_SP), %g1 /* Set saved SP on restore below. */
-	PTR_DEMANGLE2 (%i7, %g5, %g4)
-	PTR_DEMANGLE2 (%fp, %g1, %g4)
+	PTR_DEMANGLE2 (%i7, %g5, %g4, %g3)
+	PTR_DEMANGLE2 (%fp, %g1, %g4, %g3)
 #else
 	ld	ENV(g1,JB_PC), %i7 /* Set return PC. */
 	ld	ENV(g1,JB_SP), %fp /* Set saved SP on restore below. */
@@ -78,7 +78,7 @@ LOC(thread):
 LOC(found):
 	/* We have unwound register windows so %fp matches the target.  */
 #ifdef PTR_DEMANGLE
-	PTR_DEMANGLE2 (%sp, %o0, %g4)
+	PTR_DEMANGLE2 (%sp, %o0, %g4, %g3)
 #else
 	mov %o0, %sp		/* OK, install new SP.  */
 #endif
@@ -86,7 +86,7 @@ LOC(found):
 LOC(sp_ok):
 	ld ENV(g1,JB_PC), %o0	/* Extract target return PC.  */
 #ifdef PTR_DEMANGLE
-	PTR_DEMANGLE2 (%o0, %o0, %g4)
+	PTR_DEMANGLE2 (%o0, %o0, %g4, %g3)
 #endif
 	jmp %o0 + 8		/* Return there.  */
 	 mov %g2, %o0		/* Delay slot: set return value.  */
diff --git a/sysdeps/sparc/sparc32/setjmp.S b/sysdeps/sparc/sparc32/setjmp.S
index 5f2aec113a..e389c5077e 100644
--- a/sysdeps/sparc/sparc32/setjmp.S
+++ b/sysdeps/sparc/sparc32/setjmp.S
@@ -38,9 +38,9 @@ ENTRY (__sigsetjmp)
 	ta	ST_FLUSH_WINDOWS
 
 #ifdef PTR_MANGLE
-	PTR_MANGLE (%g1, %o7, %g4)
-	PTR_MANGLE2 (%g2, %sp, %g4)
-	PTR_MANGLE2 (%g3, %fp, %g4)
+	PTR_MANGLE (%g1, %o7, %g4, %g5)
+	PTR_MANGLE2 (%g2, %sp, %g4, %g5)
+	PTR_MANGLE2 (%g3, %fp, %g4, %g5)
 	st	%g1, [%o0 + (JB_PC * 4)]
 	st	%g2, [%o0 + (JB_SP * 4)]
 	st	%g3, [%o0 + (JB_FP * 4)]
diff --git a/sysdeps/unix/sysv/linux/aarch64/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/aarch64/pointer_guard-asm.h
index ed483a806a..0fd2697341 100644
--- a/sysdeps/unix/sysv/linux/aarch64/pointer_guard-asm.h
+++ b/sysdeps/unix/sysv/linux/aarch64/pointer_guard-asm.h
@@ -23,19 +23,23 @@
 # if (IS_IN (rtld) \
       || (!defined SHARED && (IS_IN (libc) \
                               || IS_IN (libpthread))))
-#  define PTR_MANGLE(dst, src, tmp)					    \
+#  define PTR_GUARD_LOAD(tmp)						    \
 	adrp    tmp, C_SYMBOL_NAME(__pointer_chk_guard_local);		    \
-	ldr	tmp, [tmp, :lo12:C_SYMBOL_NAME(__pointer_chk_guard_local)]; \
-	eor	dst, src, tmp
-#  define PTR_DEMANGLE(dst, src, tmp) PTR_MANGLE (dst, src, tmp)
+	ldr	tmp, [tmp, :lo12:C_SYMBOL_NAME(__pointer_chk_guard_local)]
 # else
-#  define PTR_MANGLE(dst, src, tmp)					  \
+#  define PTR_GUARD_LOAD(tmp)						  \
 	adrp	tmp, :got:C_SYMBOL_NAME(__pointer_chk_guard);		  \
 	ldr	tmp, [tmp, :got_lo12:C_SYMBOL_NAME(__pointer_chk_guard)]; \
-	ldr	tmp, [tmp];						  \
-	eor	dst, src, tmp;
-#  define PTR_DEMANGLE(dst, src, tmp) PTR_MANGLE (dst, src, tmp)
+	ldr	tmp, [tmp]
 # endif
+#  define PTR_MANGLE(dst, src, tmp)					    \
+	PTR_GUARD_LOAD (tmp);						    \
+	eor	dst, src, tmp;						    \
+	ror	dst, dst, #(64 - 17)
+#  define PTR_DEMANGLE(dst, src, tmp)					    \
+	PTR_GUARD_LOAD (tmp);						    \
+	ror	dst, src, #17;						    \
+	eor	dst, dst, tmp
 #endif
 
 #endif /* POINTER_GUARD_ASM_H */
diff --git a/sysdeps/unix/sysv/linux/aarch64/pointer_guard.h b/sysdeps/unix/sysv/linux/aarch64/pointer_guard.h
deleted file mode 100644
index 7b7d8b0b71..0000000000
--- a/sysdeps/unix/sysv/linux/aarch64/pointer_guard.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Pointer guard implementation.  AArch64 version.
-   Copyright (C) 2014-2026 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library.  If not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#ifndef POINTER_GUARD_H
-#define POINTER_GUARD_H
-
-#include <pointer_guard-asm.h>
-
-#ifndef __ASSEMBLER__
-# if (IS_IN (rtld) \
-      || (!defined SHARED && (IS_IN (libc) \
-                              || IS_IN (libpthread))))
-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)
-#  define PTR_DEMANGLE(var)     PTR_MANGLE (var)
-# else
-#  include <stdint.h>
-extern uintptr_t __pointer_chk_guard attribute_relro;
-#  define PTR_MANGLE(var) \
-  (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard)
-#  define PTR_DEMANGLE(var) PTR_MANGLE (var)
-# endif
-#endif
-
-#endif /* POINTER_GUARD_H */
diff --git a/sysdeps/unix/sysv/linux/alpha/____longjmp_chk.S b/sysdeps/unix/sysv/linux/alpha/____longjmp_chk.S
index 6661db76c9..135eb10faa 100644
--- a/sysdeps/unix/sysv/linux/alpha/____longjmp_chk.S
+++ b/sysdeps/unix/sysv/linux/alpha/____longjmp_chk.S
@@ -54,9 +54,9 @@ ____longjmp_chk:
 	cmoveq  s1, 1, s1
 
 #ifdef PTR_DEMANGLE
-	PTR_DEMANGLE(s2, t1)
-	PTR_DEMANGLE2(s3, t1)
-	PTR_DEMANGLE2(fp, t1)
+	PTR_DEMANGLE(s2, t1, t2)
+	PTR_DEMANGLE2(s3, t1, t2)
+	PTR_DEMANGLE2(fp, t1, t2)
 #endif
 	/* ??? While this is a proper test for detecting a longjmp to an
 	   invalid frame within any given stack, the main thread stack is
diff --git a/sysdeps/unix/sysv/linux/alpha/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/alpha/pointer_guard-asm.h
index 15f9e6cace..3ca56dd7aa 100644
--- a/sysdeps/unix/sysv/linux/alpha/pointer_guard-asm.h
+++ b/sysdeps/unix/sysv/linux/alpha/pointer_guard-asm.h
@@ -21,25 +21,32 @@
 
 #ifdef __ASSEMBLER__
 # if IS_IN (rtld)
-#  define PTR_MANGLE(dst, src, tmp)                             \
+#  define PTR_GUARD_LOAD(tmp)                                   \
         ldah    tmp, __pointer_chk_guard_local($29) !gprelhigh; \
-        ldq     tmp, __pointer_chk_guard_local(tmp) !gprellow;  \
-        xor     src, tmp, dst
-#  define PTR_MANGLE2(dst, src, tmp)                            \
-        xor     src, tmp, dst
+        ldq     tmp, __pointer_chk_guard_local(tmp) !gprellow
 # elif defined SHARED
-#  define PTR_MANGLE(dst, src, tmp)             \
-        ldq     tmp, __pointer_chk_guard;       \
-        xor     src, tmp, dst
+#  define PTR_GUARD_LOAD(tmp)                   \
+        ldq     tmp, __pointer_chk_guard
 # else
-#  define PTR_MANGLE(dst, src, tmp)             \
-        ldq     tmp, __pointer_chk_guard_local; \
-        xor     src, tmp, dst
+#  define PTR_GUARD_LOAD(tmp)                   \
+        ldq     tmp, __pointer_chk_guard_local
 # endif
-# define PTR_MANGLE2(dst, src, tmp)             \
-        xor     src, tmp, dst
-# define PTR_DEMANGLE(dst, tmp)   PTR_MANGLE(dst, dst, tmp)
-# define PTR_DEMANGLE2(dst, tmp)  PTR_MANGLE2(dst, dst, tmp)
+# define PTR_MANGLE(dst, src, tmp, tmp2)        \
+        PTR_GUARD_LOAD (tmp);                   \
+        PTR_MANGLE2 (dst, src, tmp, tmp2)
+# define PTR_MANGLE2(dst, src, tmp, tmp2)       \
+        xor     src, tmp, dst;                  \
+        sll     dst, 17, tmp2;                  \
+        srl     dst, 47, dst;                   \
+        bis     dst, tmp2, dst
+# define PTR_DEMANGLE(dst, tmp, tmp2)           \
+        PTR_GUARD_LOAD (tmp);                   \
+        PTR_DEMANGLE2 (dst, tmp, tmp2)
+# define PTR_DEMANGLE2(dst, tmp, tmp2)          \
+        sll     dst, 47, tmp2;                  \
+        srl     dst, 17, dst;                   \
+        bis     dst, tmp2, dst;                 \
+        xor     dst, tmp, dst
 #endif
 
 #endif /* POINTER_GUARD_ASM_H */
diff --git a/sysdeps/unix/sysv/linux/alpha/pointer_guard.h b/sysdeps/unix/sysv/linux/alpha/pointer_guard.h
deleted file mode 100644
index 0741bf7a18..0000000000
--- a/sysdeps/unix/sysv/linux/alpha/pointer_guard.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Pointer guard implementation.  Alpha version.
-   Copyright (C) 2006-2026 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library.  If not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#ifndef POINTER_GUARD_H
-#define POINTER_GUARD_H
-
-#include <pointer_guard-asm.h>
-
-#ifndef __ASSEMBLER__
-# include <stdint.h>
-# if (IS_IN (rtld) \
-      || (!defined SHARED && (IS_IN (libc) \
-                              || IS_IN (libpthread))))
-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)
-# else
-extern uintptr_t __pointer_chk_guard attribute_relro;
-#  define PTR_MANGLE(var) \
-        (var) = (__typeof(var)) ((uintptr_t) (var) ^ __pointer_chk_guard)
-# endif
-# define PTR_DEMANGLE(var)  PTR_MANGLE(var)
-#endif /* ASSEMBLER */
-
-#endif /* POINTER_GUARD_H */
diff --git a/sysdeps/unix/sysv/linux/csky/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/csky/pointer_guard-asm.h
index 8eb6d2c1d4..074251cbdf 100644
--- a/sysdeps/unix/sysv/linux/csky/pointer_guard-asm.h
+++ b/sysdeps/unix/sysv/linux/csky/pointer_guard-asm.h
@@ -22,34 +22,36 @@
 #ifdef __ASSEMBLER__
 # if (IS_IN (rtld) \
       || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread))))
-#  define PTR_MANGLE(dst, src, guard)                   \
+#  define PTR_MANGLE_LOAD(guard)                        \
         grs     t0, 1f;                                 \
 1:                                                      \
         lrw     guard, 1b@GOTPC;                        \
         addu    t0, guard;                              \
         lrw     guard, __pointer_chk_guard_local@GOT;   \
         ldr.w   guard, (t0, guard << 0);                \
-        ldw     guard, (guard, 0);                      \
-        xor     dst, src, guard;
-#  define PTR_DEMANGLE(dst, src, guard) PTR_MANGLE (dst, src, guard)
-#  define PTR_MANGLE2(dst, src, guard) \
-        xor     dst, src, guard
-#  define PTR_DEMANGLE2(dst, src, guard) PTR_MANGLE2 (dst, src, guard)
+        ldw     guard, (guard, 0);
 # else
-#  define PTR_MANGLE(dst, src, guard)           \
-        grs     t0, 1f;                         \
-1:                                              \
-        lrw     guard, 1b@GOTPC;                \
-        addu    t0, guard;                      \
-        lrw     guard, __pointer_chk_guard@GOT; \
-        ldr.w   guard, (t0, guard << 0);        \
-        ldw     guard, (guard, 0);              \
-        xor     dst, src, guard;
-#  define PTR_DEMANGLE(dst, src, guard) PTR_MANGLE (dst, src, guard)
-#  define PTR_MANGLE2(dst, src, guard) \
-        xor     dst, src, guard
-#  define PTR_DEMANGLE2(dst, src, guard) PTR_MANGLE2 (dst, src, guard)
+#  define PTR_MANGLE_LOAD(guard)                        \
+        grs     t0, 1f;                                 \
+1:                                                      \
+        lrw     guard, 1b@GOTPC;                        \
+        addu    t0, guard;                              \
+        lrw     guard, __pointer_chk_guard@GOT;         \
+        ldr.w   guard, (t0, guard << 0);                \
+        ldw     guard, (guard, 0);
 # endif
+# define PTR_MANGLE(dst, src, guard)                    \
+        PTR_MANGLE_LOAD (guard);                        \
+        PTR_MANGLE2 (dst, src, guard)
+# define PTR_MANGLE2(dst, src, guard)                   \
+        xor     dst, src, guard;                        \
+        rotli   dst, dst, 9
+# define PTR_DEMANGLE(dst, src, guard)                  \
+        PTR_MANGLE_LOAD (guard);                        \
+        PTR_DEMANGLE2 (dst, src, guard)
+# define PTR_DEMANGLE2(dst, src, guard)                 \
+        rotli   dst, src, 23;                           \
+        xor     dst, dst, guard
 #endif
 
 #endif /* POINTER_GUARD_ASM_H */
diff --git a/sysdeps/unix/sysv/linux/csky/pointer_guard.h b/sysdeps/unix/sysv/linux/csky/pointer_guard.h
deleted file mode 100644
index 2aa044bdc4..0000000000
--- a/sysdeps/unix/sysv/linux/csky/pointer_guard.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Pointer obfuscation implenentation.  C-SKY version.
-   Copyright (C) 2022-2026 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#ifndef POINTER_GUARD_H
-#define POINTER_GUARD_H
-
-#include <pointer_guard-asm.h>
-
-#ifndef __ASSEMBLER__
-# if (IS_IN (rtld) \
-      || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread))))
-extern uintptr_t __pointer_chk_guard_local;
-#  define PTR_MANGLE(var) \
-  (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local)
-#  define PTR_DEMANGLE(var) PTR_MANGLE (var)
-# else
-# include <stdint.h>
-extern uintptr_t __pointer_chk_guard;
-#  define PTR_MANGLE(var) \
-  (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard)
-#  define PTR_DEMANGLE(var) PTR_MANGLE (var)
-# endif
-#endif
-
-#endif /* POINTER_GUARD_H */
diff --git a/sysdeps/unix/sysv/linux/i386/pointer_guard.h b/sysdeps/unix/sysv/linux/i386/pointer_guard.h
deleted file mode 100644
index 7776c282d8..0000000000
--- a/sysdeps/unix/sysv/linux/i386/pointer_guard.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Pointer obfuscation implenentation.  i386 version.
-   Copyright (C) 2005-2026 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#ifndef POINTER_GUARD_H
-#define POINTER_GUARD_H
-
-#include <pointer_guard-asm.h>
-
-#ifndef __ASSEMBLER__
-# include <stdbit.h>
-# include <stdint.h>
-# if IS_IN (rtld) || !defined SHARED
-extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden;
-#  define PTR_GUARD_VALUE	__pointer_chk_guard_local
-# else
-extern uintptr_t __pointer_chk_guard attribute_relro;
-#  define PTR_GUARD_VALUE	__pointer_chk_guard
-# endif
-# define PTR_MANGLE(var)						      \
-    do {								      \
-      (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)
-# define PTR_DEMANGLE(var)						      \
-    do {								      \
-      (var) = (__typeof (var)) stdc_rotate_right ((uintptr_t) (var),	      \
-						  2 * sizeof (uintptr_t) + 1); \
-      (var) = (__typeof (var)) ((uintptr_t) (var) ^ PTR_GUARD_VALUE);	      \
-    } while (0)
-#endif
-
-#endif /* POINTER_GUARD_H */
diff --git a/sysdeps/unix/sysv/linux/loongarch/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/loongarch/pointer_guard-asm.h
index ac55dd8c95..75498545cb 100644
--- a/sysdeps/unix/sysv/linux/loongarch/pointer_guard-asm.h
+++ b/sysdeps/unix/sysv/linux/loongarch/pointer_guard-asm.h
@@ -23,30 +23,25 @@
 # if (IS_IN (rtld) \
       || (!defined SHARED && (IS_IN (libc) \
       || IS_IN (libpthread))))
-#  define PTR_MANGLE(dst, src, guard) \
-  LOAD_LOCAL (guard, __pointer_chk_guard_local); \
-  PTR_MANGLE2 (dst, src, guard);
-#  define PTR_DEMANGLE(dst, src, guard) \
-  LOAD_LOCAL (guard, __pointer_chk_guard_local); \
-  PTR_DEMANGLE2 (dst, src, guard);
-/* Use PTR_MANGLE2 for efficiency if guard is already loaded.  */
-#  define PTR_MANGLE2(dst, src, guard) \
-  xor  dst, src, guard;
-#  define PTR_DEMANGLE2(dst, src, guard) \
-  PTR_MANGLE2 (dst, src, guard);
+#  define PTR_MANGLE_LOAD(guard) \
+  LOAD_LOCAL (guard, __pointer_chk_guard_local);
 # else
-#  define PTR_MANGLE(dst, src, guard) \
-  LOAD_GLOBAL (guard, __pointer_chk_guard); \
+#  define PTR_MANGLE_LOAD(guard) \
+  LOAD_GLOBAL (guard, __pointer_chk_guard);
+# endif
+# define PTR_MANGLE(dst, src, guard) \
+  PTR_MANGLE_LOAD (guard); \
   PTR_MANGLE2 (dst, src, guard);
-#  define PTR_DEMANGLE(dst, src, guard) \
-  LOAD_GLOBAL (guard, __pointer_chk_guard); \
+# define PTR_DEMANGLE(dst, src, guard) \
+  PTR_MANGLE_LOAD (guard); \
   PTR_DEMANGLE2 (dst, src, guard);
 /* Use PTR_MANGLE2 for efficiency if guard is already loaded.  */
-#  define PTR_MANGLE2(dst, src, guard) \
-  xor dst, src, guard;
-#  define PTR_DEMANGLE2(dst, src, guard) \
-  PTR_MANGLE2 (dst, src, guard);
-# endif
+# define PTR_MANGLE2(dst, src, guard) \
+  xor  dst, src, guard; \
+  rotri.d  dst, dst, 47;
+# define PTR_DEMANGLE2(dst, src, guard) \
+  rotri.d  dst, src, 17; \
+  xor  dst, dst, guard;
 #endif
 
 #endif /* POINTER_GUARD_ASM_H */
diff --git a/sysdeps/unix/sysv/linux/loongarch/pointer_guard.h b/sysdeps/unix/sysv/linux/loongarch/pointer_guard.h
deleted file mode 100644
index c080bdd0a9..0000000000
--- a/sysdeps/unix/sysv/linux/loongarch/pointer_guard.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Pointer obfuscation implenentation.  LoongArch version.
-   Copyright (C) 2022-2026 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#ifndef POINTER_GUARD_H
-#define POINTER_GUARD_H
-
-#include <pointer_guard-asm.h>
-
-#ifndef __ASSEMBLER__
-# include <stdint.h>
-# if (IS_IN (rtld) \
-      || (!defined SHARED && (IS_IN (libc) \
-      || IS_IN (libpthread))))
-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)
-#  define PTR_DEMANGLE(var) PTR_MANGLE (var)
-# else
-extern uintptr_t __pointer_chk_guard attribute_relro;
-#  define PTR_MANGLE(var) \
-  (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard)
-#  define PTR_DEMANGLE(var) PTR_MANGLE (var)
-# endif
-#endif
-
-#endif /* POINTER_GUARD_H */
diff --git a/sysdeps/unix/sysv/linux/powerpc/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/powerpc/pointer_guard-asm.h
index ca4278cc00..962ad10e59 100644
--- a/sysdeps/unix/sysv/linux/powerpc/pointer_guard-asm.h
+++ b/sysdeps/unix/sysv/linux/powerpc/pointer_guard-asm.h
@@ -50,17 +50,36 @@
 	lwz	tmpreg,PTR_GUARD_SYM@l(tmpreg)
 # endif
 
+# if defined(__PPC64__) || defined(__powerpc64__)
+#  define PTR_ROT_MANGLE(dst, src)	rotldi	dst,src,17
+#  define PTR_ROT_DEMANGLE(dst, src)	rotldi	dst,src,47
+# else
+#  define PTR_ROT_MANGLE(dst, src)	rotlwi	dst,src,9
+#  define PTR_ROT_DEMANGLE(dst, src)	rotlwi	dst,src,23
+# endif
+
 # define PTR_MANGLE(reg, tmpreg) \
 	PTR_GUARD_LOAD (tmpreg); \
-	xor	reg,tmpreg,reg
+	xor	reg,tmpreg,reg; \
+	PTR_ROT_MANGLE (reg, reg)
 # define PTR_MANGLE2(reg, tmpreg) \
-	xor	reg,tmpreg,reg
+	xor	reg,tmpreg,reg; \
+	PTR_ROT_MANGLE (reg, reg)
 # define PTR_MANGLE3(destreg, reg, tmpreg) \
 	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)
+	xor	destreg,tmpreg,reg; \
+	PTR_ROT_MANGLE (destreg, destreg)
+# define PTR_DEMANGLE(reg, tmpreg) \
+	PTR_GUARD_LOAD (tmpreg); \
+	PTR_ROT_DEMANGLE (reg, reg); \
+	xor	reg,tmpreg,reg
+# define PTR_DEMANGLE2(reg, tmpreg) \
+	PTR_ROT_DEMANGLE (reg, reg); \
+	xor	reg,tmpreg,reg
+# define PTR_DEMANGLE3(destreg, reg, tmpreg) \
+	PTR_GUARD_LOAD (tmpreg); \
+	PTR_ROT_DEMANGLE (destreg, reg); \
+	xor	destreg,tmpreg,destreg
 #endif
 
 #endif /* POINTER_GUARD_ASM_H */
diff --git a/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h b/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h
deleted file mode 100644
index 621784ac88..0000000000
--- a/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Pointer obfuscation implenentation.  PowerpC version.
-   Copyright (C) 2005-2026 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#ifndef POINTER_GUARD_H
-#define POINTER_GUARD_H
-
-#include <pointer_guard-asm.h>
-
-#ifndef __ASSEMBLER__
-# include <stdint.h>
-# if IS_IN (rtld) || !defined SHARED
-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)
-# else
-extern uintptr_t __pointer_chk_guard attribute_relro;
-#  define PTR_MANGLE(var) \
-  (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard)
-# endif
-# define PTR_DEMANGLE(var)     PTR_MANGLE (var)
-#endif
-
-#endif /* POINTER_GUARD_H */
diff --git a/sysdeps/unix/sysv/linux/s390/____longjmp_chk.c b/sysdeps/unix/sysv/linux/s390/____longjmp_chk.c
index 4186114844..7ee7bf71cf 100644
--- a/sysdeps/unix/sysv/linux/s390/____longjmp_chk.c
+++ b/sysdeps/unix/sysv/linux/s390/____longjmp_chk.c
@@ -23,6 +23,7 @@
 #include <unistd.h>
 #include <stdio.h>
 #include <stdint.h>
+#include <stdbit.h>
 #include <signal.h>
 #include <sys/syscall.h>
 
@@ -34,7 +35,8 @@
       uintptr_t cur_sp;							\
       uintptr_t new_sp = env->__gregs[9];				\
       __asm__ ("lgr %0, %%r15" : "=r" (cur_sp));			\
-      new_sp ^= guard;							\
+      new_sp = stdc_rotate_right (new_sp, 2 * sizeof (uintptr_t) + 1)	\
+	       ^ guard;							\
       if (new_sp < cur_sp)						\
 	{								\
 	  stack_t oss;							\
diff --git a/sysdeps/unix/sysv/linux/s390/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/s390/pointer_guard-asm.h
index 71cc0465d1..44c9a2a156 100644
--- a/sysdeps/unix/sysv/linux/s390/pointer_guard-asm.h
+++ b/sysdeps/unix/sysv/linux/s390/pointer_guard-asm.h
@@ -32,11 +32,18 @@
 # endif
 # define PTR_MANGLE(reg, tmpreg) \
 	PTR_GUARD_LOAD (tmpreg);					\
-	xgr	reg,tmpreg
+	xgr	reg,tmpreg;						\
+	rllg	reg,reg,17
 # define PTR_MANGLE2(reg, tmpreg) \
+	xgr	reg,tmpreg;						\
+	rllg	reg,reg,17
+# define PTR_DEMANGLE(reg, tmpreg) \
+	PTR_GUARD_LOAD (tmpreg);					\
+	rllg	reg,reg,47;						\
+	xgr	reg,tmpreg
+# define PTR_DEMANGLE2(reg, tmpreg) \
+	rllg	reg,reg,47;						\
 	xgr	reg,tmpreg
-# define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg)
-# define PTR_DEMANGLE2(reg, tmpreg) PTR_MANGLE2 (reg, tmpreg)
 #endif
 
 #endif /* POINTER_GUARD_ASM_H */
diff --git a/sysdeps/unix/sysv/linux/s390/pointer_guard.h b/sysdeps/unix/sysv/linux/s390/pointer_guard.h
deleted file mode 100644
index 403eff6328..0000000000
--- a/sysdeps/unix/sysv/linux/s390/pointer_guard.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Pointer obfuscation implenentation.  s390x version.
-   Copyright (C) 2005-2026 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#ifndef POINTER_GUARD_H
-#define POINTER_GUARD_H
-
-#include <pointer_guard-asm.h>
-
-#ifndef __ASSEMBLER__
-# include <stdint.h>
-# if IS_IN (rtld) || !defined SHARED
-extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden;
-#  define PTR_GUARD_VALUE	__pointer_chk_guard_local
-# else
-extern uintptr_t __pointer_chk_guard attribute_relro;
-#  define PTR_GUARD_VALUE	__pointer_chk_guard
-# endif
-# define PTR_MANGLE(var) \
-  (var) = (void *) ((uintptr_t) (var) ^ PTR_GUARD_VALUE)
-# define PTR_DEMANGLE(var)	PTR_MANGLE (var)
-#endif
-
-#endif /* POINTER_GUARD_H */
diff --git a/sysdeps/unix/sysv/linux/sh/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/sh/pointer_guard-asm.h
index 64e6f6153e..f6002efdea 100644
--- a/sysdeps/unix/sysv/linux/sh/pointer_guard-asm.h
+++ b/sysdeps/unix/sysv/linux/sh/pointer_guard-asm.h
@@ -55,10 +55,16 @@
 .Lptrg_end:
 # endif
 # define PTR_MANGLE(reg, tmp) \
-     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)
+     PTR_GUARD_LOAD (tmp); PTR_MANGLE2 (reg, tmp)
+# define PTR_MANGLE2(reg, tmp) \
+     xor tmp,reg;							\
+     rotl reg; rotl reg; rotl reg; rotl reg; rotl reg;			\
+     rotl reg; rotl reg; rotl reg; rotl reg
+# define PTR_DEMANGLE(reg, tmp)        PTR_GUARD_LOAD (tmp); PTR_DEMANGLE2 (reg, tmp)
+# define PTR_DEMANGLE2(reg, tmp) \
+     rotr reg; rotr reg; rotr reg; rotr reg; rotr reg;			\
+     rotr reg; rotr reg; rotr reg; rotr reg;				\
+     xor tmp,reg
 #endif
 
 #endif /* POINTER_GUARD_ASM_H */
diff --git a/sysdeps/unix/sysv/linux/sh/pointer_guard.h b/sysdeps/unix/sysv/linux/sh/pointer_guard.h
deleted file mode 100644
index 42340faca8..0000000000
--- a/sysdeps/unix/sysv/linux/sh/pointer_guard.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Pointer obfuscation implenentation.  SH version.
-   Copyright (C) 2005-2026 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#ifndef POINTER_GUARD_H
-#define POINTER_GUARD_H
-
-#include <pointer_guard-asm.h>
-
-#ifndef __ASSEMBLER__
-# include <stdint.h>
-# if IS_IN (rtld) || !defined SHARED
-extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden;
-#  define PTR_MANGLE(var) \
-     (var) = (void *) ((uintptr_t) (var) ^ __pointer_chk_guard_local)
-# else
-extern uintptr_t __pointer_chk_guard attribute_relro;
-#  define PTR_MANGLE(var) \
-     (var) = (void *) ((uintptr_t) (var) ^ __pointer_chk_guard)
-# endif
-# define PTR_DEMANGLE(var)     PTR_MANGLE (var)
-#endif
-
-#endif /* POINTER_GUARD_H */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/____longjmp_chk.S b/sysdeps/unix/sysv/linux/sparc/sparc32/____longjmp_chk.S
index b0c6160bd2..07baa0c9ed 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/____longjmp_chk.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/____longjmp_chk.S
@@ -32,7 +32,7 @@ longjmp_msg:
 ENTRY (____longjmp_chk)
 	ld	ENV(o0,JB_SP), %g5
 #ifdef PTR_DEMANGLE
-	PTR_DEMANGLE (%g5, %g5, %g4)
+	PTR_DEMANGLE (%g5, %g5, %g4, %g3)
 #endif
 
 	cmp	%sp, %g5
@@ -82,7 +82,7 @@ ENTRY (____longjmp_chk)
 .Lok_norestore:
 	ld	ENV(o0,JB_FP), %g3	/* Cache target FP in register %g3.  */
 #ifdef PTR_DEMANGLE
-	PTR_DEMANGLE2 (%g3, %g3, %g4)
+	PTR_DEMANGLE2 (%g3, %g3, %g4, %g1)
 #endif
 
 	mov %o0, %g1		/* ENV in %g1 */
@@ -103,7 +103,7 @@ ENTRY (____longjmp_chk)
 	ta	ST_FLUSH_WINDOWS
 #ifdef PTR_DEMANGLE
 	ld	ENV(g1,JB_PC), %g1 /* Set return PC. */
-	PTR_DEMANGLE2 (%i7, %g1, %g4)
+	PTR_DEMANGLE2 (%i7, %g1, %g4, %g3)
 #else
 	ld	ENV(g1,JB_PC), %i7 /* Set return PC. */
 #endif
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard-asm.h
index e1e42f8087..aa2b7609c9 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard-asm.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard-asm.h
@@ -39,13 +39,22 @@
 	sethi	%hi(PTR_GUARD_SYM), tmpreg;				\
 	ld	[tmpreg + %lo(PTR_GUARD_SYM)], tmpreg
 # endif
-# define PTR_MANGLE(dreg, reg, tmpreg) \
+# define PTR_MANGLE(dreg, reg, tmpreg, tmp2) \
 	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
-# define PTR_DEMANGLE2(dreg, reg, tmpreg) PTR_MANGLE2 (dreg, reg, tmpreg)
+	PTR_MANGLE2 (dreg, reg, tmpreg, tmp2)
+# define PTR_MANGLE2(dreg, reg, tmpreg, tmp2) \
+	xor	reg, tmpreg, dreg;					\
+	sll	dreg, 9, tmp2;						\
+	srl	dreg, 23, dreg;						\
+	or	dreg, tmp2, dreg
+# define PTR_DEMANGLE(dreg, reg, tmpreg, tmp2) \
+	PTR_GUARD_LOAD (tmpreg);					\
+	PTR_DEMANGLE2 (dreg, reg, tmpreg, tmp2)
+# define PTR_DEMANGLE2(dreg, reg, tmpreg, tmp2) \
+	srl	reg, 9, tmp2;						\
+	sll	reg, 23, dreg;						\
+	or	dreg, tmp2, dreg;					\
+	xor	dreg, tmpreg, dreg
 #endif
 
 #endif /* POINTER_GUARD_ASM_H */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h b/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h
deleted file mode 100644
index 86d3fbb7d2..0000000000
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Pointer obfuscation implenentation.  32-bit SPARC version.
-   Copyright (C) 2006-2026 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#ifndef POINTER_GUARD_H
-#define POINTER_GUARD_H
-
-#include <pointer_guard-asm.h>
-
-#ifndef __ASSEMBLER__
-# include <stdint.h>
-# if IS_IN (rtld) || !defined SHARED
-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)
-# else
-extern uintptr_t __pointer_chk_guard attribute_relro;
-#  define PTR_MANGLE(var) \
-  (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard)
-# endif
-# define PTR_DEMANGLE(var)     PTR_MANGLE (var)
-#endif
-
-#endif /* POINTER_GUARD_H */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard-asm.h
index f378c88e58..ef5b38f541 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard-asm.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard-asm.h
@@ -39,13 +39,22 @@
 	sethi	%hi(PTR_GUARD_SYM), tmpreg;				\
 	ldx	[tmpreg + %lo(PTR_GUARD_SYM)], tmpreg
 # endif
-# define PTR_MANGLE(dreg, reg, tmpreg) \
+# define PTR_MANGLE(dreg, reg, tmpreg, tmp2) \
 	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
-# define PTR_DEMANGLE2(dreg, reg, tmpreg) PTR_MANGLE2 (dreg, reg, tmpreg)
+	PTR_MANGLE2 (dreg, reg, tmpreg, tmp2)
+# define PTR_MANGLE2(dreg, reg, tmpreg, tmp2) \
+	xor	reg, tmpreg, dreg;					\
+	sllx	dreg, 17, tmp2;						\
+	srlx	dreg, 47, dreg;						\
+	or	dreg, tmp2, dreg
+# define PTR_DEMANGLE(dreg, reg, tmpreg, tmp2) \
+	PTR_GUARD_LOAD (tmpreg);					\
+	PTR_DEMANGLE2 (dreg, reg, tmpreg, tmp2)
+# define PTR_DEMANGLE2(dreg, reg, tmpreg, tmp2) \
+	srlx	reg, 17, tmp2;						\
+	sllx	reg, 47, dreg;						\
+	or	dreg, tmp2, dreg;					\
+	xor	dreg, tmpreg, dreg
 #endif
 
 #endif /* POINTER_GUARD_ASM_H */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h b/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h
deleted file mode 100644
index fc0a723905..0000000000
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Pointer obfuscation implenentation.  64-bit SPARC version.
-   Copyright (C) 2006-2026 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#ifndef POINTER_GUARD_H
-#define POINTER_GUARD_H
-
-#include <pointer_guard-asm.h>
-
-#ifndef __ASSEMBLER__
-# include <stdint.h>
-# if IS_IN (rtld) || !defined SHARED
-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)
-# else
-extern uintptr_t __pointer_chk_guard attribute_relro;
-#  define PTR_MANGLE(var) \
-  (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard)
-# endif
-# define PTR_DEMANGLE(var)     PTR_MANGLE (var)
-#endif
-
-#endif /* POINTER_GUARD_H */
diff --git a/sysdeps/unix/sysv/linux/x86_64/pointer_guard.h b/sysdeps/unix/sysv/linux/x86_64/pointer_guard.h
deleted file mode 100644
index dd3a9752b2..0000000000
--- a/sysdeps/unix/sysv/linux/x86_64/pointer_guard.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* Pointer obfuscation implenentation.  x86-64 version.
-   Copyright (C) 2005-2026 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#ifndef POINTER_GUARD_H
-#define POINTER_GUARD_H
-
-#include <pointer_guard-asm.h>
-
-#ifndef __ASSEMBLER__
-# include <stdbit.h>
-# include <stdint.h>
-
-# if (IS_IN (rtld) \
-      || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread))))
-extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden;
-#  define PTR_MANGLE(var)						      \
-    do {								      \
-      (var) = (__typeof (var)) ((uintptr_t) (var)			      \
-				^ __pointer_chk_guard_local);		      \
-      (var) = (__typeof (var)) stdc_rotate_left ((uintptr_t) (var),	      \
-						 2 * sizeof (uintptr_t) + 1); \
-    } while (0)
-#  define PTR_DEMANGLE(var)						      \
-    do {								      \
-      (var) = (__typeof (var)) stdc_rotate_right ((uintptr_t) (var),	      \
-						  2 * sizeof (uintptr_t) + 1); \
-      (var) = (__typeof (var)) ((uintptr_t) (var)			      \
-				^ __pointer_chk_guard_local);		      \
-    } while (0)
-# else
-extern uintptr_t __pointer_chk_guard attribute_relro;
-#  define PTR_MANGLE(var)						      \
-    do {								      \
-      (var) = (__typeof (var)) ((uintptr_t) (var)			      \
-				^ __pointer_chk_guard);			      \
-      (var) = (__typeof (var)) stdc_rotate_left ((uintptr_t) (var),	      \
-						 2 * sizeof (uintptr_t) + 1); \
-    } while (0)
-#  define PTR_DEMANGLE(var)						      \
-    do {								      \
-      (var) = (__typeof (var)) stdc_rotate_right ((uintptr_t) (var),	      \
-						  2 * sizeof (uintptr_t) + 1); \
-      (var) = (__typeof (var)) ((uintptr_t) (var)			      \
-				^ __pointer_chk_guard);			      \
-    } while (0)
-# endif
-#endif
-
-#endif /* POINTER_GUARD_H */
diff --git a/sysdeps/unix/sysv/linux/x86_64/pointer_guard-asm.h b/sysdeps/x86_64/pointer_guard-asm.h
similarity index 100%
rename from sysdeps/unix/sysv/linux/x86_64/pointer_guard-asm.h
rename to sysdeps/x86_64/pointer_guard-asm.h