[compiler-rt] [PAC][compiler-rt] Fix init/fini array signing schema (PR #150691)
Daniil Kovalev via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 25 13:06:32 PDT 2025
https://github.com/kovdan01 created https://github.com/llvm/llvm-project/pull/150691
When `ptrauth_calls` is present but `ptrauth_init_fini` is not, compiler emits raw unsigned pointers in `.init_array`/`.fini_array` sections. Previously, `__do_init`/`__do_fini` pointers in these sections were implicitly signed (due to the presense of `ptrauth_calls`). As a result, the sections contained a mix of unsigned function pointers and function pointers signed with default signing schema.
This patch introduces use of inline assembly for this particular case, so we can manually specify that we do not want to sign the pointers.
Note that we cannot use `__builtin_ptrauth_strip` for this purpose since its result is not a constant expression.
>From 9a8bf685ab734bf47ab80b1473e648cf837dc074 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Fri, 25 Jul 2025 20:11:10 +0300
Subject: [PATCH] [PAC][compiler-rt] Fix init/fini array signing schema
When `ptrauth_calls` is present but `ptrauth_init_fini` is not, compiler
emits raw unsigned pointers in `.init_array`/`.fini_array` sections.
Previously, `__do_init`/`__do_fini` pointers in these sections were
implicitly signed (due to the presense of `ptrauth_calls`). As a result,
the sections contained a mix of unsigned function pointers and function
pointers signed with default signing schema.
This patch introduces use of inline assembly for this particular case,
so we can manually specify that we do not want to sign the pointers.
Note that we cannot use `__builtin_ptrauth_strip` for this purpose since
its result is not a constant expression.
---
compiler-rt/lib/builtins/crtbegin.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/compiler-rt/lib/builtins/crtbegin.c b/compiler-rt/lib/builtins/crtbegin.c
index d5f7756308b09..8a0fb3fd9c1c6 100644
--- a/compiler-rt/lib/builtins/crtbegin.c
+++ b/compiler-rt/lib/builtins/crtbegin.c
@@ -67,9 +67,22 @@ __attribute__((section(".init_array"), used)) static void *__init =
__ptrauth_init_fini_discriminator);
#endif
#else
+#if __has_feature(ptrauth_calls)
+#ifdef __aarch64__
+// If ptrauth_init_fini feature is not present, compiler emits raw unsigned
+// pointers in .init_array. Use inline assembly to avoid implicit signing of
+// __do_init function pointer with ptrauth_calls enabled.
+__asm__(".pushsection .init_array,\"aw\", at init_array\n\t"
+ ".xword __do_init\n\t"
+ ".popsection");
+#else
+#error "ptrauth_calls is only supported for AArch64"
+#endif
+#else
__attribute__((section(".init_array"),
used)) static void (*__init)(void) = __do_init;
#endif
+#endif
#elif defined(__i386__) || defined(__x86_64__)
__asm__(".pushsection .init,\"ax\", at progbits\n\t"
"call __do_init\n\t"
@@ -138,9 +151,22 @@ __attribute__((section(".fini_array"), used)) static void *__fini =
__ptrauth_init_fini_discriminator);
#endif
#else
+#if __has_feature(ptrauth_calls)
+#ifdef __aarch64__
+// If ptrauth_init_fini feature is not present, compiler emits raw unsigned
+// pointers in .fini_array. Use inline assembly to avoid implicit signing of
+// __do_fini function pointer with ptrauth_calls enabled.
+__asm__(".pushsection .fini_array,\"aw\", at fini_array\n\t"
+ ".xword __do_fini\n\t"
+ ".popsection");
+#else
+#error "ptrauth_calls is only supported for AArch64"
+#endif
+#else
__attribute__((section(".fini_array"),
used)) static void (*__fini)(void) = __do_fini;
#endif
+#endif
#elif defined(__i386__) || defined(__x86_64__)
__asm__(".pushsection .fini,\"ax\", at progbits\n\t"
"call __do_fini\n\t"
More information about the llvm-commits
mailing list