[4/8] Split pointer_guard.h into C and assembly headers

Message ID 20260603000656.3287796-5-adhemerval.zanella@linaro.org (mailing list archive)
State Superseded
Delegated to: DJ Delorie
Headers
Series Pointer guard hardening and consolidation |

Checks

Context Check Description
redhat-pt-bot/TryBot-apply_patch success Patch applied to master at the time it was sent
linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_glibc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_glibc_check--master-arm success Test passed

Commit Message

Adhemerval Zanella Netto June 3, 2026, 12:04 a.m. UTC
  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.
---
 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 +-
 .../sysv/linux/aarch64/pointer_guard-asm.h    | 41 ++++++++++++
 .../unix/sysv/linux/aarch64/pointer_guard.h   | 26 ++------
 .../unix/sysv/linux/alpha/pointer_guard-asm.h | 45 +++++++++++++
 sysdeps/unix/sysv/linux/alpha/pointer_guard.h | 26 +-------
 .../unix/sysv/linux/csky/pointer_guard-asm.h  | 55 ++++++++++++++++
 sysdeps/unix/sysv/linux/csky/pointer_guard.h  | 38 ++---------
 .../unix/sysv/linux/i386/pointer_guard-asm.h  | 51 ++++++++++++++
 sysdeps/unix/sysv/linux/i386/pointer_guard.h  | 30 +--------
 .../sysv/linux/loongarch/pointer_guard-asm.h  | 52 +++++++++++++++
 .../unix/sysv/linux/loongarch/pointer_guard.h | 51 ++++----------
 .../sysv/linux/powerpc/pointer_guard-asm.h    | 66 +++++++++++++++++++
 .../unix/sysv/linux/powerpc/pointer_guard.h   | 54 +--------------
 .../unix/sysv/linux/s390/pointer_guard-asm.h  | 42 ++++++++++++
 sysdeps/unix/sysv/linux/s390/pointer_guard.h  | 26 +-------
 .../unix/sysv/linux/sh/pointer_guard-asm.h    | 64 ++++++++++++++++++
 sysdeps/unix/sysv/linux/sh/pointer_guard.h    | 51 +-------------
 .../linux/sparc/sparc32/pointer_guard-asm.h   | 51 ++++++++++++++
 .../sysv/linux/sparc/sparc32/pointer_guard.h  | 37 +----------
 .../linux/sparc/sparc64/pointer_guard-asm.h   | 51 ++++++++++++++
 .../sysv/linux/sparc/sparc64/pointer_guard.h  | 35 +---------
 .../sysv/linux/x86_64/pointer_guard-asm.h     | 42 ++++++++++++
 .../unix/sysv/linux/x86_64/pointer_guard.h    | 30 ++-------
 26 files changed, 687 insertions(+), 390 deletions(-)
 create mode 100644 sysdeps/arm/pointer_guard-asm.h
 create mode 100644 sysdeps/generic/pointer_guard-asm.h
 create mode 100644 sysdeps/unix/sysv/linux/aarch64/pointer_guard-asm.h
 create mode 100644 sysdeps/unix/sysv/linux/alpha/pointer_guard-asm.h
 create mode 100644 sysdeps/unix/sysv/linux/csky/pointer_guard-asm.h
 create mode 100644 sysdeps/unix/sysv/linux/i386/pointer_guard-asm.h
 create mode 100644 sysdeps/unix/sysv/linux/loongarch/pointer_guard-asm.h
 create mode 100644 sysdeps/unix/sysv/linux/powerpc/pointer_guard-asm.h
 create mode 100644 sysdeps/unix/sysv/linux/s390/pointer_guard-asm.h
 create mode 100644 sysdeps/unix/sysv/linux/sh/pointer_guard-asm.h
 create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard-asm.h
 create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard-asm.h
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/pointer_guard-asm.h
  

Comments

DJ Delorie June 10, 2026, 8:12 p.m. UTC | #1
Adhemerval Zanella <adhemerval.zanella@linaro.org> writes:
> 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.

Agreed; LGTM
Reviewed-by: DJ Delorie <dj@redhat.com>
  

Patch

diff --git a/sysdeps/arm/pointer_guard-asm.h b/sysdeps/arm/pointer_guard-asm.h
new file mode 100644
index 00000000000..86a9055b617
--- /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 f6556a9a4af..9fa25c708a9 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 00000000000..bdfd06b92d1
--- /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 9d7a1f51a51..49eb5ca4ba2 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 00000000000..ed483a806a6
--- /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 4689f29184d..7b7d8b0b714 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 00000000000..15f9e6cacef
--- /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 f799399e754..0741bf7a183 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 00000000000..8eb6d2c1d42
--- /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 cdb3917481a..2aa044bdc42 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 00000000000..19ee959e8fd
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/pointer_guard-asm.h
@@ -0,0 +1,51 @@ 
+/* 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>
+
+# if IS_IN (rtld) || !defined SHARED
+#  ifdef PIC
+#   define PTR_MANGLE(reg)	LOAD_PIC_REG (bx);			      \
+				xorl __pointer_chk_guard_local@GOTOFF(%ebx), reg; \
+				roll $9, reg
+#   define PTR_DEMANGLE(reg)	rorl $9, reg;				      \
+				LOAD_PIC_REG (bx);			      \
+				xorl __pointer_chk_guard_local@GOTOFF(%ebx), reg
+#  else
+#   define PTR_MANGLE(reg)	xorl __pointer_chk_guard_local, reg;	      \
+				roll $9, reg
+#   define PTR_DEMANGLE(reg)	rorl $9, reg;				      \
+				xorl __pointer_chk_guard_local, reg
+#  endif
+# else
+#  define PTR_MANGLE(reg)	LOAD_PIC_REG (bx);			      \
+				movl __pointer_chk_guard@GOT(%ebx), %esi;     \
+				xorl (%esi), reg;			      \
+				roll $9, reg
+#  define PTR_DEMANGLE(reg)	rorl $9, reg;				      \
+				LOAD_PIC_REG (bx);			      \
+				movl __pointer_chk_guard@GOT(%ebx), %esi;     \
+				xorl (%esi), 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 63308d84e76..7776c282d81 100644
--- a/sysdeps/unix/sysv/linux/i386/pointer_guard.h
+++ b/sysdeps/unix/sysv/linux/i386/pointer_guard.h
@@ -19,33 +19,9 @@ 
 #ifndef POINTER_GUARD_H
 #define POINTER_GUARD_H
 
-#ifdef __ASSEMBLER__
-# include <sysdep.h>
-# if IS_IN (rtld) || !defined SHARED
-#  ifdef PIC
-#   define PTR_MANGLE(reg)	LOAD_PIC_REG (bx);			      \
-				xorl __pointer_chk_guard_local@GOTOFF(%ebx), reg; \
-				roll $9, reg
-#   define PTR_DEMANGLE(reg)	rorl $9, reg;				      \
-				LOAD_PIC_REG (bx);			      \
-				xorl __pointer_chk_guard_local@GOTOFF(%ebx), reg
-#  else
-#   define PTR_MANGLE(reg)	xorl __pointer_chk_guard_local, reg;	      \
-				roll $9, reg
-#   define PTR_DEMANGLE(reg)	rorl $9, reg;				      \
-				xorl __pointer_chk_guard_local, reg
-#  endif
-# else
-#  define PTR_MANGLE(reg)	LOAD_PIC_REG (bx);			      \
-				movl __pointer_chk_guard@GOT(%ebx), %esi;     \
-				xorl (%esi), reg;			      \
-				roll $9, reg
-#  define PTR_DEMANGLE(reg)	rorl $9, reg;				      \
-				LOAD_PIC_REG (bx);			      \
-				movl __pointer_chk_guard@GOT(%ebx), %esi;     \
-				xorl (%esi), 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 00000000000..ac55dd8c95c
--- /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 69150c0211f..c080bdd0a9d 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 00000000000..ca4278cc00a
--- /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 271cf93c2f4..51f588ec11c 100644
--- a/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h
+++ b/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h
@@ -19,59 +19,9 @@ 
 #ifndef POINTER_GUARD_H
 #define POINTER_GUARD_H
 
-/* In ld.so and in statically linked programs the guard is the module-local
-   relro variable __pointer_chk_guard_local; in other shared objects it is
-   the global __pointer_chk_guard provided by the dynamic loader.  */
-#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
+#include <pointer_guard-asm.h>
 
-# 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
-/* Position-independent 32-bit code has no dedicated GOT register here, so
-   establish one with the usual bcl/mflr sequence.  GAS numeric local labels
-   are used so the sequence can be expanded more than once per file.  LR is
-   clobbered by the bcl, so it is saved in r12 (a volatile register that is
-   not otherwise live at the mangling points) and restored; r0 must not be
-   used here as 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
-
-# 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 00000000000..71cc0465d13
--- /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 a4ec92f6655..403eff63282 100644
--- a/sysdeps/unix/sysv/linux/s390/pointer_guard.h
+++ b/sysdeps/unix/sysv/linux/s390/pointer_guard.h
@@ -19,29 +19,9 @@ 
 #ifndef POINTER_GUARD_H
 #define POINTER_GUARD_H
 
-/* In ld.so and in statically linked programs the guard is the module-local
-   relro variable __pointer_chk_guard_local, reached PC-relatively with larl;
-   in other shared objects it is the global __pointer_chk_guard provided by
-   the dynamic loader, reached through the GOT.  */
-#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 00000000000..64e6f6153e8
--- /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 9a1e01a452c..42340faca83 100644
--- a/sysdeps/unix/sysv/linux/sh/pointer_guard.h
+++ b/sysdeps/unix/sysv/linux/sh/pointer_guard.h
@@ -19,54 +19,9 @@ 
 #ifndef POINTER_GUARD_H
 #define POINTER_GUARD_H
 
-/* In ld.so and in statically linked programs the guard is the module-local
-   relro variable __pointer_chk_guard_local; in other shared objects it is
-   the global __pointer_chk_guard provided by the dynamic loader.  */
-#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
-/* Load the guard through the GOT.  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.  A literal pool is emitted inline and branched over.  */
-#  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 00000000000..e1e42f8087a
--- /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 2242981f6bd..86d3fbb7d27 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h
@@ -19,40 +19,9 @@ 
 #ifndef POINTER_GUARD_H
 #define POINTER_GUARD_H
 
-/* In ld.so and in statically linked programs the guard is the module-local
-   relro variable __pointer_chk_guard_local; in other shared objects it is
-   the global __pointer_chk_guard provided by the dynamic loader.  */
-#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; both are dead at every
-   mangling site.  */
-#  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 00000000000..f378c88e58c
--- /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 8cdb2edf7be..fc0a723905e 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h
@@ -19,38 +19,9 @@ 
 #ifndef POINTER_GUARD_H
 #define POINTER_GUARD_H
 
-/* In ld.so and in statically linked programs the guard is the module-local
-   relro variable __pointer_chk_guard_local; in other shared objects it is
-   the global __pointer_chk_guard provided by the dynamic loader.  */
-#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 00000000000..11b0ea3f83b
--- /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 6d09b429cd2..dd3a9752b2a 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 {								      \