[compiler-rt] [libcxxabi] [libunwind] [PAC][libunwind] Fix gcc build of libunwind (PR #164535)

Oliver Hunt via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 21 19:52:27 PDT 2025


https://github.com/ojhunt updated https://github.com/llvm/llvm-project/pull/164535

>From 6dc291683b959808453a077cf016e76652564470 Mon Sep 17 00:00:00 2001
From: Oliver Hunt <oliver at apple.com>
Date: Tue, 21 Oct 2025 19:19:04 -0700
Subject: [PATCH] [PAC][libunwind] Fix gcc build of libunwind and compiler-rt

This adds guards on the ptrauth feature checks so that they are
only performed if __has_feature is actually available.
---
 compiler-rt/lib/builtins/gcc_personality_v0.c | 11 +++++++++--
 libcxxabi/include/__cxxabi_config.h           |  7 ++++++-
 libcxxabi/src/cxa_personality.cpp             |  8 ++++----
 libunwind/include/__libunwind_config.h        | 12 +++++++-----
 libunwind/src/UnwindRegistersRestore.S        | 10 ++++++++--
 libunwind/src/UnwindRegistersSave.S           | 10 ++++++++--
 6 files changed, 42 insertions(+), 16 deletions(-)

diff --git a/compiler-rt/lib/builtins/gcc_personality_v0.c b/compiler-rt/lib/builtins/gcc_personality_v0.c
index 3ed17fa788c28..5b1a6ed772469 100644
--- a/compiler-rt/lib/builtins/gcc_personality_v0.c
+++ b/compiler-rt/lib/builtins/gcc_personality_v0.c
@@ -30,7 +30,13 @@ EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD, void *, PCONTEXT,
                                             _Unwind_Personality_Fn);
 #endif
 
-#if __has_feature(ptrauth_calls)
+#if defined(__has_feature)
+#define __has_ptrauth_calls __has_feature(ptrauth_calls)
+#else
+#define __has_ptrauth_calls 0
+#endif
+
+#if __has_ptrauth_calls
 #include <ptrauth.h>
 
 // `__ptrauth_restricted_intptr` is a feature of apple clang that predates
@@ -48,6 +54,7 @@ EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD, void *, PCONTEXT,
 #else
 #define __ptrauth_gcc_personality_intptr(...)
 #endif
+#else
 
 #define __ptrauth_gcc_personality_func_key ptrauth_key_function_pointer
 
@@ -292,7 +299,7 @@ COMPILER_RT_ABI _Unwind_Reason_Code __gcc_personality_v0(
       _Unwind_SetGR(context, __builtin_eh_return_data_regno(1), 0);
       size_t __ptrauth_gcc_personality_lpad landingPad =
           funcStart + landingPadOffset;
-#if __has_feature(ptrauth_calls)
+#if __has_ptrauth_calls
       uintptr_t stackPointer = _Unwind_GetGR(context, -2);
       const uintptr_t existingDiscriminator = ptrauth_blend_discriminator(
           &landingPad, __ptrauth_gcc_personality_lpad_disc);
diff --git a/libcxxabi/include/__cxxabi_config.h b/libcxxabi/include/__cxxabi_config.h
index f5101dbc9e599..84c14acddbb85 100644
--- a/libcxxabi/include/__cxxabi_config.h
+++ b/libcxxabi/include/__cxxabi_config.h
@@ -107,7 +107,12 @@
 #  include <ptrauth.h>
 #endif
 
-#if __has_feature(ptrauth_calls)
+#if defined(__has_feature)
+#  define __ptrauth_cxxabi_enabled __has_feature(ptrauth_calls)
+#else
+#  define __ptrauth_cxxabi_enabled 0
+#endif
+#if __ptrauth_cxxabi_enabled
 
 // ptrauth_string_discriminator("__cxa_exception::actionRecord") == 0xFC91
 #  define __ptrauth_cxxabi_action_record __ptrauth(ptrauth_key_process_dependent_data, 1, 0xFC91)
diff --git a/libcxxabi/src/cxa_personality.cpp b/libcxxabi/src/cxa_personality.cpp
index b7eb0f23dbe06..b69b10de748ee 100644
--- a/libcxxabi/src/cxa_personality.cpp
+++ b/libcxxabi/src/cxa_personality.cpp
@@ -21,7 +21,7 @@
 #include "cxa_handlers.h"
 #include "private_typeinfo.h"
 
-#if __has_feature(ptrauth_calls)
+#if __ptrauth_cxxabi_enabled
 
 // CXXABI depends on defintions in libunwind as pointer auth couples the
 // definitions
@@ -602,7 +602,7 @@ set_registers(_Unwind_Exception* unwind_exception, _Unwind_Context* context,
                 reinterpret_cast<uintptr_t>(unwind_exception));
   _Unwind_SetGR(context, __builtin_eh_return_data_regno(1),
                 static_cast<uintptr_t>(results.ttypeIndex));
-#if __has_feature(ptrauth_calls)
+#if __ptrauth_cxxabi_enabled
   auto stackPointer = _Unwind_GetGR(context, UNW_REG_SP);
   // We manually re-sign the IP as the __ptrauth qualifiers cannot
   // express the required relationship with the destination address
@@ -973,7 +973,7 @@ _UA_CLEANUP_PHASE
 using __cxa_catch_temp_type = decltype(__cxa_exception::catchTemp);
 static inline void set_landing_pad(scan_results& results,
                                    const __cxa_catch_temp_type& source) {
-#if __has_feature(ptrauth_calls)
+#if __ptrauth_cxxabi_enabled
   const uintptr_t sourceDiscriminator =
       ptrauth_blend_discriminator(&source, __ptrauth_cxxabi_catch_temp_disc);
   const uintptr_t targetDiscriminator =
@@ -995,7 +995,7 @@ static inline void set_landing_pad(scan_results& results,
 
 static inline void get_landing_pad(__cxa_catch_temp_type &dest,
                                    const scan_results &results) {
-#if __has_feature(ptrauth_calls)
+#if __ptrauth_cxxabi_enabled
   const uintptr_t sourceDiscriminator =
       ptrauth_blend_discriminator(&results.landingPad,
                                   __ptrauth_scan_results_landingpad_disc);
diff --git a/libunwind/include/__libunwind_config.h b/libunwind/include/__libunwind_config.h
index 343934e885368..980d11ef5d4f2 100644
--- a/libunwind/include/__libunwind_config.h
+++ b/libunwind/include/__libunwind_config.h
@@ -212,11 +212,13 @@
 # define _LIBUNWIND_HIGHEST_DWARF_REGISTER 287
 #endif // _LIBUNWIND_IS_NATIVE_ONLY
 
-#if __has_feature(ptrauth_calls) && __has_feature(ptrauth_returns)
-#  define _LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING 1
-#elif __has_feature(ptrauth_calls) != __has_feature(ptrauth_returns)
-#  error "Either both or none of ptrauth_calls and ptrauth_returns "\
-         "is allowed to be enabled"
+#if defined(__has_feature)
+#  if __has_feature(ptrauth_calls) && __has_feature(ptrauth_returns)
+#    define _LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING 1
+#  elif __has_feature(ptrauth_calls) != __has_feature(ptrauth_returns)
+#    error "Either both or none of ptrauth_calls and ptrauth_returns "\
+           "is allowed to be enabled"
+#  endif
 #endif
 
 #endif // ____LIBUNWIND_CONFIG_H__
diff --git a/libunwind/src/UnwindRegistersRestore.S b/libunwind/src/UnwindRegistersRestore.S
index 1ab4c43b673b4..2d8322bea092d 100644
--- a/libunwind/src/UnwindRegistersRestore.S
+++ b/libunwind/src/UnwindRegistersRestore.S
@@ -634,6 +634,12 @@ Lnovec:
 
 #elif defined(__aarch64__)
 
+#ifdef __has_feature
+#define __has_ptrauth_calls __has_feature(ptrauth_calls)
+#else
+#define __has_ptrauth_calls 0
+#endif
+
 #if defined(__ARM_FEATURE_GCS_DEFAULT)
 .arch_extension gcs
 #endif
@@ -690,7 +696,7 @@ DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)
   ldr    x16,     [x0, #0x0F8]  // load sp into scratch
   ldr    lr,      [x0, #0x100]  // restore pc into lr
 
-#if __has_feature(ptrauth_calls)
+#if __has_ptrauth_calls
   // The LR is signed with its address inside the register state.  Time
   // to resign to be a regular ROP protected signed pointer
   add    x1, x0, #0x100
@@ -711,7 +717,7 @@ DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)
 Lnogcs:
 #endif
 
-#if __has_feature(ptrauth_calls)
+#if __has_ptrauth_calls
   retab
 #else
   ret    x30                    // jump to pc
diff --git a/libunwind/src/UnwindRegistersSave.S b/libunwind/src/UnwindRegistersSave.S
index 31a177f4a0df4..ce67306571816 100644
--- a/libunwind/src/UnwindRegistersSave.S
+++ b/libunwind/src/UnwindRegistersSave.S
@@ -763,6 +763,12 @@ LnoR2Fix:
 
 #elif defined(__aarch64__)
 
+#ifdef __has_feature
+#define __has_ptrauth_calls __has_feature(ptrauth_calls)
+#else
+#define __has_ptrauth_calls 0
+#endif
+
 //
 // extern int __unw_getcontext(unw_context_t* thread_state)
 //
@@ -772,7 +778,7 @@ LnoR2Fix:
   .p2align 2
 DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
 
-#if __has_feature(ptrauth_calls)
+#if __has_ptrauth_calls
   pacibsp
 #endif
 
@@ -817,7 +823,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
 #endif
   mov    x0, #0                   // return UNW_ESUCCESS
 
-#if __has_feature(ptrauth_calls)
+#if __has_ptrauth_calls
   retab
 #else
   ret



More information about the cfe-commits mailing list