[glibc] Split pointer_guard.h into C and assembly headers

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

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

    Split pointer_guard.h into C and assembly headers
    
    Move the assembly PTR_MANGLE/PTR_DEMANGLE definitions out of each
    pointer_guard.h into a new sibling pointer_guard-asm.h, guarded by
    __ASSEMBLER__.  pointer_guard.h now includes pointer_guard-asm.h and
    keeps only the C definitions.
    
    No functional change: the .S and .c files still include pointer_guard.h
    and get the same macros, and <pointer_guard-asm.h> resolves per-arch
    through the usual sysdeps include path.
    
    Checked with a build for all affected ABIs.
    
    Reviewed-by: DJ Delorie <[email protected]>

Diff:
---
 sysdeps/arm/pointer_guard-asm.h                    | 53 +++++++++++++++++
 sysdeps/arm/pointer_guard.h                        | 37 ++----------
 sysdeps/generic/pointer_guard-asm.h                | 19 +++++++
 sysdeps/generic/pointer_guard.h                    |  4 +-
 .../unix/sysv/linux/aarch64/pointer_guard-asm.h    | 41 ++++++++++++++
 sysdeps/unix/sysv/linux/aarch64/pointer_guard.h    | 26 ++-------
 sysdeps/unix/sysv/linux/alpha/pointer_guard-asm.h  | 45 +++++++++++++++
 sysdeps/unix/sysv/linux/alpha/pointer_guard.h      | 26 +--------
 sysdeps/unix/sysv/linux/csky/pointer_guard-asm.h   | 55 ++++++++++++++++++
 sysdeps/unix/sysv/linux/csky/pointer_guard.h       | 38 ++-----------
 sysdeps/unix/sysv/linux/i386/pointer_guard-asm.h   | 59 +++++++++++++++++++
 sysdeps/unix/sysv/linux/i386/pointer_guard.h       | 35 +-----------
 .../unix/sysv/linux/loongarch/pointer_guard-asm.h  | 52 +++++++++++++++++
 sysdeps/unix/sysv/linux/loongarch/pointer_guard.h  | 51 ++++-------------
 .../unix/sysv/linux/powerpc/pointer_guard-asm.h    | 66 ++++++++++++++++++++++
 sysdeps/unix/sysv/linux/powerpc/pointer_guard.h    | 48 +---------------
 sysdeps/unix/sysv/linux/s390/pointer_guard-asm.h   | 42 ++++++++++++++
 sysdeps/unix/sysv/linux/s390/pointer_guard.h       | 22 +-------
 sysdeps/unix/sysv/linux/sh/pointer_guard-asm.h     | 64 +++++++++++++++++++++
 sysdeps/unix/sysv/linux/sh/pointer_guard.h         | 47 +--------------
 .../sysv/linux/sparc/sparc32/pointer_guard-asm.h   | 51 +++++++++++++++++
 .../unix/sysv/linux/sparc/sparc32/pointer_guard.h  | 33 +----------
 .../sysv/linux/sparc/sparc64/pointer_guard-asm.h   | 51 +++++++++++++++++
 .../unix/sysv/linux/sparc/sparc64/pointer_guard.h  | 32 +----------
 sysdeps/unix/sysv/linux/x86_64/pointer_guard-asm.h | 42 ++++++++++++++
 sysdeps/unix/sysv/linux/x86_64/pointer_guard.h     | 30 +++-------
 26 files changed, 695 insertions(+), 374 deletions(-)

diff --git a/sysdeps/arm/pointer_guard-asm.h b/sysdeps/arm/pointer_guard-asm.h
new file mode 100644
index 0000000000..86a9055b61
--- /dev/null
+++ b/sysdeps/arm/pointer_guard-asm.h
@@ -0,0 +1,53 @@
+/* Pointer guard implementation, assembly version.  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_ASM_H
+#define POINTER_GUARD_ASM_H
+
+#ifdef __ASSEMBLER__
+# if (IS_IN (rtld) \
+      || (!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)                              \
+  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
+#endif
+
+#endif /* POINTER_GUARD_ASM_H */
diff --git a/sysdeps/arm/pointer_guard.h b/sysdeps/arm/pointer_guard.h
index f6556a9a4a..9fa25c708a 100644
--- a/sysdeps/arm/pointer_guard.h
+++ b/sysdeps/arm/pointer_guard.h
@@ -19,42 +19,15 @@
 #ifndef POINTER_GUARD_H
 #define POINTER_GUARD_H
 
-/* Pointer mangling support.  */
-#if (IS_IN (rtld) \
-     || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread))))
-# ifdef __ASSEMBLER__
-#  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
+#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)
-# endif
-#else
-# ifdef __ASSEMBLER__
-#  define PTR_MANGLE_LOAD(guard, tmp)                                   \
-  LDR_GLOBAL (guard, tmp, C_SYMBOL_NAME(__pointer_chk_guard), 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
 #  include <stdint.h>
 extern uintptr_t __pointer_chk_guard attribute_relro;
diff --git a/sysdeps/generic/pointer_guard-asm.h b/sysdeps/generic/pointer_guard-asm.h
new file mode 100644
index 0000000000..bdfd06b92d
--- /dev/null
+++ b/sysdeps/generic/pointer_guard-asm.h
@@ -0,0 +1,19 @@
+/* Pointer obfuscation implementation, assembly version.  Generic (no-op).
+   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/>.  */
+
+/* Assembler definitions for pointer obfuscation, if the ABI required it.  */
diff --git a/sysdeps/generic/pointer_guard.h b/sysdeps/generic/pointer_guard.h
index 9d7a1f51a5..49eb5ca4ba 100644
--- a/sysdeps/generic/pointer_guard.h
+++ b/sysdeps/generic/pointer_guard.h
@@ -19,8 +19,8 @@
 #ifndef POINTER_GUARD_H
 #define POINTER_GUARD_H
 
-/* Assembler code depends on PTR_MANGLE not being defined for
-   optimization purposes.  */
+#include <pointer_guard-asm.h>
+
 #ifndef __ASSEMBLER__
 # define PTR_MANGLE(x) (void) (x)
 # define PTR_DEMANGLE(x) (void) (x)
diff --git a/sysdeps/unix/sysv/linux/aarch64/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/aarch64/pointer_guard-asm.h
new file mode 100644
index 0000000000..ed483a806a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/pointer_guard-asm.h
@@ -0,0 +1,41 @@
+/* Pointer guard implementation, assembly version.  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_ASM_H
+#define POINTER_GUARD_ASM_H
+
+#ifdef __ASSEMBLER__
+# if (IS_IN (rtld) \
+      || (!defined SHARED && (IS_IN (libc) \
+                              || IS_IN (libpthread))))
+#  define PTR_MANGLE(dst, src, 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)
+# else
+#  define PTR_MANGLE(dst, src, 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)
+# endif
+#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
index 4689f29184..7b7d8b0b71 100644
--- a/sysdeps/unix/sysv/linux/aarch64/pointer_guard.h
+++ b/sysdeps/unix/sysv/linux/aarch64/pointer_guard.h
@@ -19,30 +19,16 @@
 #ifndef POINTER_GUARD_H
 #define POINTER_GUARD_H
 
-/* Pointer mangling is supported for AArch64.  */
-#if (IS_IN (rtld) \
-     || (!defined SHARED && (IS_IN (libc) \
-                             || IS_IN (libpthread))))
-# ifdef __ASSEMBLER__
-#  define PTR_MANGLE(dst, src, 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)
-# else
+#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)
-# endif
-#else
-# ifdef __ASSEMBLER__
-#  define PTR_MANGLE(dst, src, 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)
 # else
 #  include <stdint.h>
 extern uintptr_t __pointer_chk_guard attribute_relro;
diff --git a/sysdeps/unix/sysv/linux/alpha/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/alpha/pointer_guard-asm.h
new file mode 100644
index 0000000000..15f9e6cace
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/pointer_guard-asm.h
@@ -0,0 +1,45 @@
+/* Pointer guard implementation, assembly version.  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_ASM_H
+#define POINTER_GUARD_ASM_H
+
+#ifdef __ASSEMBLER__
+# if IS_IN (rtld)
+#  define PTR_MANGLE(dst, src, 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
+# elif defined SHARED
+#  define PTR_MANGLE(dst, src, tmp)             \
+        ldq     tmp, __pointer_chk_guard;       \
+        xor     src, tmp, dst
+# else
+#  define PTR_MANGLE(dst, src, tmp)             \
+        ldq     tmp, __pointer_chk_guard_local; \
+        xor     src, tmp, dst
+# 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)
+#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
index f799399e75..0741bf7a18 100644
--- a/sysdeps/unix/sysv/linux/alpha/pointer_guard.h
+++ b/sysdeps/unix/sysv/linux/alpha/pointer_guard.h
@@ -19,31 +19,9 @@
 #ifndef POINTER_GUARD_H
 #define POINTER_GUARD_H
 
-/* Pointer mangling support.  Note that tls access is slow enough that
-   we don't deoptimize things by placing the pointer check value there.  */
+#include <pointer_guard-asm.h>
 
-#ifdef __ASSEMBLER__
-# if IS_IN (rtld)
-#  define PTR_MANGLE(dst, src, 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
-# elif defined SHARED
-#  define PTR_MANGLE(dst, src, tmp)             \
-        ldq     tmp, __pointer_chk_guard;       \
-        xor     src, tmp, dst
-# else
-#  define PTR_MANGLE(dst, src, tmp)             \
-        ldq     tmp, __pointer_chk_guard_local; \
-        xor     src, tmp, dst
-# 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)
-#else
+#ifndef __ASSEMBLER__
 # include <stdint.h>
 # if (IS_IN (rtld) \
       || (!defined SHARED && (IS_IN (libc) \
diff --git a/sysdeps/unix/sysv/linux/csky/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/csky/pointer_guard-asm.h
new file mode 100644
index 0000000000..8eb6d2c1d4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/csky/pointer_guard-asm.h
@@ -0,0 +1,55 @@
+/* Pointer obfuscation implementation, assembly version.  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_ASM_H
+#define POINTER_GUARD_ASM_H
+
+#ifdef __ASSEMBLER__
+# if (IS_IN (rtld) \
+      || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread))))
+#  define PTR_MANGLE(dst, src, 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)
+# 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)
+# endif
+#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
index cdb3917481..2aa044bdc4 100644
--- a/sysdeps/unix/sysv/linux/csky/pointer_guard.h
+++ b/sysdeps/unix/sysv/linux/csky/pointer_guard.h
@@ -19,43 +19,15 @@
 #ifndef POINTER_GUARD_H
 #define POINTER_GUARD_H
 
-#if (IS_IN (rtld) \
-     || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread))))
-# ifdef __ASSEMBLER__
-#  define PTR_MANGLE(dst, src, 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)
-# else
+#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)
-# endif
-#else
-# ifdef __ASSEMBLER__
-#  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)
 # else
 # include <stdint.h>
 extern uintptr_t __pointer_chk_guard;
diff --git a/sysdeps/unix/sysv/linux/i386/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/i386/pointer_guard-asm.h
new file mode 100644
index 0000000000..0dd078ffd9
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/pointer_guard-asm.h
@@ -0,0 +1,59 @@
+/* Pointer obfuscation implementation, assembly version.  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_ASM_H
+#define POINTER_GUARD_ASM_H
+
+#ifdef __ASSEMBLER__
+# 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.  The caller
+   must pass a register that is dead at the expansion point: the macros
+   do not preserve it, and using a callee-saved register would leak the
+   clobber to the caller of the enclosing function.  */
+# if IS_IN (rtld) || !defined SHARED
+#  ifdef PIC
+#   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
+#   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
+#  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, tmp) \
+				rorl $9, reg;				      \
+				LOAD_PIC_REG (tmp);			      \
+				movl __pointer_chk_guard@GOT(%e##tmp), %e##tmp; \
+				xorl (%e##tmp), reg
+# endif
+#endif
+
+#endif /* POINTER_GUARD_ASM_H */
diff --git a/sysdeps/unix/sysv/linux/i386/pointer_guard.h b/sysdeps/unix/sysv/linux/i386/pointer_guard.h
index 421a902ab5..7776c282d8 100644
--- a/sysdeps/unix/sysv/linux/i386/pointer_guard.h
+++ b/sysdeps/unix/sysv/linux/i386/pointer_guard.h
@@ -19,38 +19,9 @@
 #ifndef POINTER_GUARD_H
 #define POINTER_GUARD_H
 
-#ifdef __ASSEMBLER__
-# 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.  */
-# if IS_IN (rtld) || !defined SHARED
-#  ifdef PIC
-#   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
-#   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
-#  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, tmp) \
-				rorl $9, reg;				      \
-				LOAD_PIC_REG (tmp);			      \
-				movl __pointer_chk_guard@GOT(%e##tmp), %e##tmp; \
-				xorl (%e##tmp), reg
-# endif
-#else
+#include <pointer_guard-asm.h>
+
+#ifndef __ASSEMBLER__
 # include <stdbit.h>
 # include <stdint.h>
 # if IS_IN (rtld) || !defined SHARED
diff --git a/sysdeps/unix/sysv/linux/loongarch/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/loongarch/pointer_guard-asm.h
new file mode 100644
index 0000000000..ac55dd8c95
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/loongarch/pointer_guard-asm.h
@@ -0,0 +1,52 @@
+/* Pointer obfuscation implementation, assembly version.  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_ASM_H
+#define POINTER_GUARD_ASM_H
+
+#ifdef __ASSEMBLER__
+# 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);
+# else
+#  define PTR_MANGLE(dst, src, guard) \
+  LOAD_GLOBAL (guard, __pointer_chk_guard); \
+  PTR_MANGLE2 (dst, src, guard);
+#  define PTR_DEMANGLE(dst, src, guard) \
+  LOAD_GLOBAL (guard, __pointer_chk_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
+#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
index 69150c0211..c080bdd0a9 100644
--- a/sysdeps/unix/sysv/linux/loongarch/pointer_guard.h
+++ b/sysdeps/unix/sysv/linux/loongarch/pointer_guard.h
@@ -19,52 +19,23 @@
 #ifndef POINTER_GUARD_H
 #define POINTER_GUARD_H
 
-#if (IS_IN (rtld) \
-     || (!defined SHARED && (IS_IN (libc) \
-     || IS_IN (libpthread))))
+#include <pointer_guard-asm.h>
 
-#ifdef __ASSEMBLER__
-#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);
-#else
+#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) \
+#  define PTR_MANGLE(var) \
   (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local)
-#define PTR_DEMANGLE(var) PTR_MANGLE (var)
-#endif
-
-#else
-
-#ifdef __ASSEMBLER__
-#define PTR_MANGLE(dst, src, guard) \
-  LOAD_GLOBAL (guard, __pointer_chk_guard); \
-  PTR_MANGLE2 (dst, src, guard);
-#define PTR_DEMANGLE(dst, src, guard) \
-  LOAD_GLOBAL (guard, __pointer_chk_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);
-#else
-# include <stdint.h>
+#  define PTR_DEMANGLE(var) PTR_MANGLE (var)
+# else
 extern uintptr_t __pointer_chk_guard attribute_relro;
-#define PTR_MANGLE(var) \
+#  define PTR_MANGLE(var) \
   (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard)
-#define PTR_DEMANGLE(var) PTR_MANGLE (var)
-#endif
-
+#  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
new file mode 100644
index 0000000000..ca4278cc00
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/pointer_guard-asm.h
@@ -0,0 +1,66 @@
+/* Pointer obfuscation implementation, assembly version.  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_ASM_H
+#define POINTER_GUARD_ASM_H
+
+#ifdef __ASSEMBLER__
+# include <sysdep.h>
+
+# if IS_IN (rtld) || !defined SHARED
+#  define PTR_GUARD_SYM	__pointer_chk_guard_local
+# else
+#  define PTR_GUARD_SYM	__pointer_chk_guard
+# 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
+/* Position-dependent 32-bit code can address the variable directly.  */
+#  define PTR_GUARD_LOAD(tmpreg)					\
+	lis	tmpreg,PTR_GUARD_SYM@ha;					\
+	lwz	tmpreg,PTR_GUARD_SYM@l(tmpreg)
+# endif
+
+# define PTR_MANGLE(reg, tmpreg) \
+	PTR_GUARD_LOAD (tmpreg); \
+	xor	reg,tmpreg,reg
+# define PTR_MANGLE2(reg, tmpreg) \
+	xor	reg,tmpreg,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)
+#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
index 9e59c9ce8e..621784ac88 100644
--- a/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h
+++ b/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h
@@ -19,53 +19,9 @@
 #ifndef POINTER_GUARD_H
 #define POINTER_GUARD_H
 
-#ifdef __ASSEMBLER__
-# include <sysdep.h>
-# if IS_IN (rtld) || !defined SHARED
-#  define PTR_GUARD_SYM	__pointer_chk_guard_local
-# else
-#  define PTR_GUARD_SYM	__pointer_chk_guard
-# endif
-
-# if defined(__PPC64__) || defined(__powerpc64__)
-/* r2 (the TOC pointer) is always available, so load the guard's address
-   from the TOC/GOT and dereference it.  */
-#  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
-/* PiC 32-bit code has no dedicated GOT register,  LR is clobbered by the
-   bcl, and r0 must not be used here as temporary register because it holds
-   the saved link register in __longjmp.  */
-#  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
-/* Position-dependent 32-bit code can address the variable directly.  */
-#  define PTR_GUARD_LOAD(tmpreg)					\
-	lis	tmpreg,PTR_GUARD_SYM@ha;					\
-	lwz	tmpreg,PTR_GUARD_SYM@l(tmpreg)
-# endif
+#include <pointer_guard-asm.h>
 
-# define PTR_MANGLE(reg, tmpreg) \
-	PTR_GUARD_LOAD (tmpreg); \
-	xor	reg,tmpreg,reg
-# define PTR_MANGLE2(reg, tmpreg) \
-	xor	reg,tmpreg,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)
-#else
+#ifndef __ASSEMBLER__
 # include <stdint.h>
 # if IS_IN (rtld) || !defined SHARED
 extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden;
diff --git a/sysdeps/unix/sysv/linux/s390/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/s390/pointer_guard-asm.h
new file mode 100644
index 0000000000..71cc0465d1
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/s390/pointer_guard-asm.h
@@ -0,0 +1,42 @@
+/* Pointer obfuscation implementation, assembly version.  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_ASM_H
+#define POINTER_GUARD_ASM_H
+
+#ifdef __ASSEMBLER__
+# if IS_IN (rtld) || !defined SHARED
+#  define PTR_GUARD_LOAD(tmpreg)					\
+	larl	tmpreg,__pointer_chk_guard_local;			\
+	lg	tmpreg,0(tmpreg)
+# else
+#  define PTR_GUARD_LOAD(tmpreg)					\
+	larl	tmpreg,__pointer_chk_guard@GOTENT;			\
+	lg	tmpreg,0(tmpreg);					\
+	lg	tmpreg,0(tmpreg)
+# endif
+# define PTR_MANGLE(reg, tmpreg) \
+	PTR_GUARD_LOAD (tmpreg);					\
+	xgr	reg,tmpreg
+# define PTR_MANGLE2(reg, tmpreg) \
+	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
index 8fce7b15eb..403eff6328 100644
--- a/sysdeps/unix/sysv/linux/s390/pointer_guard.h
+++ b/sysdeps/unix/sysv/linux/s390/pointer_guard.h
@@ -19,25 +19,9 @@
 #ifndef POINTER_GUARD_H
 #define POINTER_GUARD_H
 
-#ifdef __ASSEMBLER__
-# if IS_IN (rtld) || !defined SHARED
-#  define PTR_GUARD_LOAD(tmpreg)					\
-	larl	tmpreg,__pointer_chk_guard_local;			\
-	lg	tmpreg,0(tmpreg)
-# else
-#  define PTR_GUARD_LOAD(tmpreg)					\
-	larl	tmpreg,__pointer_chk_guard@GOTENT;			\
-	lg	tmpreg,0(tmpreg);					\
-	lg	tmpreg,0(tmpreg)
-# endif
-# define PTR_MANGLE(reg, tmpreg) \
-	PTR_GUARD_LOAD (tmpreg);					\
-	xgr	reg,tmpreg
-# define PTR_MANGLE2(reg, tmpreg) \
-	xgr	reg,tmpreg
-# define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg)
-# define PTR_DEMANGLE2(reg, tmpreg) PTR_MANGLE2 (reg, tmpreg)
-#else
+#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;
diff --git a/sysdeps/unix/sysv/linux/sh/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/sh/pointer_guard-asm.h
new file mode 100644
index 0000000000..64e6f6153e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sh/pointer_guard-asm.h
@@ -0,0 +1,64 @@
+/* Pointer obfuscation implementation, assembly version.  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_ASM_H
+#define POINTER_GUARD_ASM_H
+
+#ifdef __ASSEMBLER__
+# if IS_IN (rtld) || !defined SHARED
+#  define PTR_GUARD_SYM	__pointer_chk_guard_local
+# else
+#  define PTR_GUARD_SYM	__pointer_chk_guard
+# 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) \
+     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)
+#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
index ee55ecb1bc..42340faca8 100644
--- a/sysdeps/unix/sysv/linux/sh/pointer_guard.h
+++ b/sysdeps/unix/sysv/linux/sh/pointer_guard.h
@@ -19,50 +19,9 @@
 #ifndef POINTER_GUARD_H
 #define POINTER_GUARD_H
 
-#ifdef __ASSEMBLER__
-# if IS_IN (rtld) || !defined SHARED
-#  define PTR_GUARD_SYM	__pointer_chk_guard_local
-# else
-#  define PTR_GUARD_SYM	__pointer_chk_guard
-# endif
-# ifdef PIC
-/* The GOT pointer is computed with the usual mova/mov.l sequence which
-   clobbers r0; in __longjmp r0 holds the return value, so it is saved in
-   r3 (dead at every mangling site) and restored.  */
-#  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) \
-     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 <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;
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard-asm.h
new file mode 100644
index 0000000000..e1e42f8087
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard-asm.h
@@ -0,0 +1,51 @@
+/* Pointer obfuscation implementation, assembly version.  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_ASM_H
+#define POINTER_GUARD_ASM_H
+
+#ifdef __ASSEMBLER__
+# include <sysdep.h>
+
+# if IS_IN (rtld) || !defined SHARED
+#  define PTR_GUARD_SYM	__pointer_chk_guard_local
+# else
+#  define PTR_GUARD_SYM	__pointer_chk_guard
+# endif
+# ifdef PIC
+#  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) \
+	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)
+#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
index 4a68203e7c..86d3fbb7d2 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h
@@ -19,36 +19,9 @@
 #ifndef POINTER_GUARD_H
 #define POINTER_GUARD_H
 
-#ifdef __ASSEMBLER__
-# include <sysdep.h>
-# if IS_IN (rtld) || !defined SHARED
-#  define PTR_GUARD_SYM	__pointer_chk_guard_local
-# else
-#  define PTR_GUARD_SYM	__pointer_chk_guard
-# 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) \
-	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)
-#else
+#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;
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard-asm.h
new file mode 100644
index 0000000000..f378c88e58
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard-asm.h
@@ -0,0 +1,51 @@
+/* Pointer obfuscation implementation, assembly version.  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_ASM_H
+#define POINTER_GUARD_ASM_H
+
+#ifdef __ASSEMBLER__
+# include <sysdep.h>
+
+# if IS_IN (rtld) || !defined SHARED
+#  define PTR_GUARD_SYM	__pointer_chk_guard_local
+# else
+#  define PTR_GUARD_SYM	__pointer_chk_guard
+# endif
+# ifdef PIC
+#  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) \
+	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)
+#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
index 4549256677..fc0a723905 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h
@@ -19,35 +19,9 @@
 #ifndef POINTER_GUARD_H
 #define POINTER_GUARD_H
 
-#ifdef __ASSEMBLER__
-# include <sysdep.h>
-# if IS_IN (rtld) || !defined SHARED
-#  define PTR_GUARD_SYM	__pointer_chk_guard_local
-# else
-#  define PTR_GUARD_SYM	__pointer_chk_guard
-# 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) \
-	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)
-#else
+#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;
diff --git a/sysdeps/unix/sysv/linux/x86_64/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/x86_64/pointer_guard-asm.h
new file mode 100644
index 0000000000..11b0ea3f83
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86_64/pointer_guard-asm.h
@@ -0,0 +1,42 @@
+/* Pointer obfuscation implementation, assembly version.  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_ASM_H
+#define POINTER_GUARD_ASM_H
+
+#ifdef __ASSEMBLER__
+# include <x86-lp_size.h>
+# include <tcb-offsets.h>
+
+# if (IS_IN (rtld) \
+      || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread))))
+#  define PTR_MANGLE(reg)   xor __pointer_chk_guard_local(%rip), reg;	      \
+			    rol $2*LP_SIZE+1, reg
+#  define PTR_DEMANGLE(reg) ror $2*LP_SIZE+1, reg;			      \
+			    xor __pointer_chk_guard_local(%rip), reg
+# else
+#  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;			      \
+			    mov __pointer_chk_guard@GOTPCREL(%rip), %R11_LP;  \
+			    xor (%R11_LP), reg
+# endif
+#endif
+
+#endif /* POINTER_GUARD_ASM_H */
diff --git a/sysdeps/unix/sysv/linux/x86_64/pointer_guard.h b/sysdeps/unix/sysv/linux/x86_64/pointer_guard.h
index 6d09b429cd..dd3a9752b2 100644
--- a/sysdeps/unix/sysv/linux/x86_64/pointer_guard.h
+++ b/sysdeps/unix/sysv/linux/x86_64/pointer_guard.h
@@ -19,19 +19,14 @@
 #ifndef POINTER_GUARD_H
 #define POINTER_GUARD_H
 
-#include <x86-lp_size.h>
-#include <tcb-offsets.h>
+#include <pointer_guard-asm.h>
 
-#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
-#  define PTR_DEMANGLE(reg)	ror $2*LP_SIZE+1, reg;			      \
-				xor __pointer_chk_guard_local(%rip), reg
-# else
-#  include <stdbit.h>
-#  include <stdint.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 {								      \
@@ -47,18 +42,7 @@ extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden;
       (var) = (__typeof (var)) ((uintptr_t) (var)			      \
 				^ __pointer_chk_guard_local);		      \
     } while (0)
-# endif
-#else
-# ifdef __ASSEMBLER__
-#  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;			      \
-				mov __pointer_chk_guard@GOTPCREL(%rip), %R11_LP;\
-				xor (%R11_LP), reg
 # else
-#  include <stdbit.h>
-#  include <stdint.h>
 extern uintptr_t __pointer_chk_guard attribute_relro;
 #  define PTR_MANGLE(var)						      \
     do {								      \