From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
To: libc-alpha@sourceware.org
Cc: Anderson Nascimento <anderson@allelesecurity.com>,
Carlos O'Donell <carlos@redhat.com>
Subject: [PATCH 4/8] Split pointer_guard.h into C and assembly headers
Date: Tue, 2 Jun 2026 21:04:35 -0300 [thread overview]
Message-ID: <20260603000656.3287796-5-adhemerval.zanella@linaro.org> (raw)
In-Reply-To: <20260603000656.3287796-1-adhemerval.zanella@linaro.org>
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
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 { \
--
2.43.0
next prev parent reply other threads:[~2026-06-03 0:07 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-03 0:04 [PATCH 0/8] Pointer guard hardening and consolidation Adhemerval Zanella
2026-06-03 0:04 ` [PATCH 1/8] elf: Propagate the pointer guard to ld.so loaded via static dlopen (BZ 34196) Adhemerval Zanella
2026-06-10 1:35 ` DJ Delorie
2026-06-10 12:14 ` Adhemerval Zanella Netto
2026-06-30 18:15 ` Sachin Monga
2026-06-30 19:56 ` Adhemerval Zanella Netto
2026-06-03 0:04 ` [PATCH 2/8] Consolidate pointer guard to use a relro variable instead of the TCB Adhemerval Zanella
2026-06-10 3:03 ` DJ Delorie
2026-06-03 0:04 ` [PATCH 3/8] Enable the pointer guard in the dynamic loader Adhemerval Zanella
2026-06-10 19:37 ` DJ Delorie
2026-06-03 0:04 ` Adhemerval Zanella [this message]
2026-06-10 20:12 ` [PATCH 4/8] Split pointer_guard.h into C and assembly headers DJ Delorie
2026-06-03 0:04 ` [PATCH 5/8] Consolidate the C pointer guard implementation into the generic header Adhemerval Zanella
2026-06-10 21:14 ` DJ Delorie
2026-06-11 18:59 ` Adhemerval Zanella Netto
2026-06-03 0:04 ` [PATCH 6/8] Add the pointer guard rotate to the assembly implementations Adhemerval Zanella
2026-06-10 21:36 ` DJ Delorie
2026-06-12 14:18 ` Adhemerval Zanella Netto
2026-06-03 0:04 ` [PATCH 7/8] Consolidate dl-osinfo.h into the generic implementation Adhemerval Zanella
2026-06-10 21:43 ` DJ Delorie
2026-06-03 0:04 ` [PATCH 8/8] elf: Scrub and reseed the AT_RANDOM bytes after deriving the guards (BZ 34197) Adhemerval Zanella
2026-06-10 22:05 ` DJ Delorie
2026-06-11 19:57 ` Adhemerval Zanella Netto
2026-06-11 20:25 ` DJ Delorie
2026-06-11 20:36 ` Adhemerval Zanella Netto
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260603000656.3287796-5-adhemerval.zanella@linaro.org \
--to=adhemerval.zanella@linaro.org \
--cc=anderson@allelesecurity.com \
--cc=carlos@redhat.com \
--cc=libc-alpha@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).