[libunwind] [libunwind] Fix exposure of UNW_AARCH64_RA_SIGN_STATE through _Unwind… (PR #205188)
Jon Roelofs via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 26 11:02:28 PDT 2026
https://github.com/jroelofs updated https://github.com/llvm/llvm-project/pull/205188
>From c05793d405bb826b25dc54bbb5800d62aee4f34d Mon Sep 17 00:00:00 2001
From: Jon Roelofs <jonathan_roelofs at apple.com>
Date: Thu, 18 Jun 2026 18:13:35 -0700
Subject: [PATCH 01/13] [libunwind] Fix exposure of UNW_AARCH64_RA_SIGN_STATE
through _Unwind_GetGR
The pseudo register was previously hacked in unrder kRegisterIsUndefined,
leaving it in a state that was only accessible from within the unwinder itself.
To fix this, allowing external access to the state (and therefore tests!), we
invent a new register location kRegisterIsPseudo to record the additional state
that the register has been defined by a .cfi_negate_ra_state opcode having been
executed.
---
libunwind/src/DwarfInstructions.hpp | 8 ++
libunwind/src/DwarfParser.hpp | 11 +--
libunwind/test/ra_sign_state.pass.cpp | 125 ++++++++++++++++++++++++++
3 files changed, 139 insertions(+), 5 deletions(-)
create mode 100644 libunwind/test/ra_sign_state.pass.cpp
diff --git a/libunwind/src/DwarfInstructions.hpp b/libunwind/src/DwarfInstructions.hpp
index 165c4a99e9a92..0133b2dd330e7 100644
--- a/libunwind/src/DwarfInstructions.hpp
+++ b/libunwind/src/DwarfInstructions.hpp
@@ -113,8 +113,14 @@ typename A::pint_t DwarfInstructions<A, R>::getSavedRegister(
case CFI_Parser<A>::kRegisterInRegister:
return registers.getRegister((int)savedReg.value);
+
case CFI_Parser<A>::kRegisterUndefined:
return 0;
+
+ case CFI_Parser<A>::kRegisterIsPseudo:
+#if defined(_LIBUNWIND_TARGET_AARCH64)
+ return savedReg.value;
+#endif
case CFI_Parser<A>::kRegisterUnused:
case CFI_Parser<A>::kRegisterOffsetFromCFA:
// FIX ME
@@ -141,6 +147,7 @@ double DwarfInstructions<A, R>::getSavedFloatRegister(
#ifndef _LIBUNWIND_TARGET_ARM
return registers.getFloatRegister((int)savedReg.value);
#endif
+ case CFI_Parser<A>::kRegisterIsPseudo:
case CFI_Parser<A>::kRegisterIsExpression:
case CFI_Parser<A>::kRegisterUnused:
case CFI_Parser<A>::kRegisterOffsetFromCFA:
@@ -164,6 +171,7 @@ v128 DwarfInstructions<A, R>::getSavedVectorRegister(
evaluateExpression((pint_t)savedReg.value, addressSpace,
registers, cfa));
+ case CFI_Parser<A>::kRegisterIsPseudo:
case CFI_Parser<A>::kRegisterIsExpression:
case CFI_Parser<A>::kRegisterUnused:
case CFI_Parser<A>::kRegisterUndefined:
diff --git a/libunwind/src/DwarfParser.hpp b/libunwind/src/DwarfParser.hpp
index 8e080fb33c5f8..ba40b757ab977 100644
--- a/libunwind/src/DwarfParser.hpp
+++ b/libunwind/src/DwarfParser.hpp
@@ -81,7 +81,8 @@ class CFI_Parser {
kRegisterOffsetFromCFA,
kRegisterInRegister,
kRegisterAtExpression,
- kRegisterIsExpression
+ kRegisterIsExpression,
+ kRegisterIsPseudo,
};
struct RegisterLocation {
RegisterSavedWhere location;
@@ -794,8 +795,8 @@ bool CFI_Parser<A>::parseFDEInstructions(
case REGISTERS_ARM64: {
int64_t value =
results->savedRegisters[UNW_AARCH64_RA_SIGN_STATE].value ^ 0x1;
- results->setRegisterValue(UNW_AARCH64_RA_SIGN_STATE, value,
- initialState);
+ results->setRegister(UNW_AARCH64_RA_SIGN_STATE, kRegisterIsPseudo,
+ value, initialState);
_LIBUNWIND_TRACE_DWARF("DW_CFA_AARCH64_negate_ra_state\n");
} break;
#endif
@@ -846,8 +847,8 @@ bool CFI_Parser<A>::parseFDEInstructions(
case DW_CFA_AARCH64_negate_ra_state_with_pc: {
int64_t value =
results->savedRegisters[UNW_AARCH64_RA_SIGN_STATE].value ^ 0x3;
- results->setRegisterValue(UNW_AARCH64_RA_SIGN_STATE, value,
- initialState);
+ results->setRegister(UNW_AARCH64_RA_SIGN_STATE, kRegisterIsPseudo,
+ value, initialState);
// When using Feat_PAuthLR, the PC value needs to be captured so that
// during unwinding, the correct PC value is used for re-authentication.
// It is assumed that the CFI is placed before the signing instruction.
diff --git a/libunwind/test/ra_sign_state.pass.cpp b/libunwind/test/ra_sign_state.pass.cpp
new file mode 100644
index 0000000000000..1e113955db027
--- /dev/null
+++ b/libunwind/test/ra_sign_state.pass.cpp
@@ -0,0 +1,125 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: target={{aarch64.*}}
+// UNSUPPORTED: target={{.*-windows.*}}
+
+#undef NDEBUG
+#include "support/func_bounds.h"
+#include <assert.h>
+#include <inttypes.h>
+#include <libunwind.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <unwind.h>
+
+#if defined(__APPLE__)
+#include <sys/sysctl.h>
+#endif
+
+// Note: This test requires FEAT_PAuth (and is setup to pass on other targets).
+
+#if defined(__APPLE__)
+static bool checkHasPAuth() {
+ int has_pauth = 0;
+ size_t size = sizeof(has_pauth);
+ if (sysctlbyname("hw.optional.arm.FEAT_PAuth", &has_pauth, &size, NULL, 0))
+ return false;
+ return has_pauth != 0;
+}
+#else
+static bool checkHasPAuth() {
+ // TODO: Support other platforms.
+ return false;
+}
+#endif
+
+FUNC_BOUNDS_DECL(main_func);
+
+_Unwind_Reason_Code frame_handler(struct _Unwind_Context *ctx, void *arg) {
+ uint64_t ra_sign_state =
+ (uint64_t)_Unwind_GetGR(ctx, UNW_AARCH64_RA_SIGN_STATE);
+
+ uintptr_t ip = _Unwind_GetIP(ctx);
+ if (ip >= (uintptr_t)FUNC_START(main_func) &&
+ ip < (uintptr_t)FUNC_END(main_func)) {
+
+ // Collect the RA from the callee that will return to main.
+ *(uint64_t *)arg = ra_sign_state;
+
+ // Unwind until main is reached, above frames depend on the platform and
+ // architecture.
+ return _URC_END_OF_STACK;
+ }
+
+#if defined(__PTRAUTH__) || __has_feature(ptrauth_calls)
+ assert(ra_sign_state == 1);
+#else
+ assert(ra_sign_state == 0);
+#endif
+
+ return _URC_NO_REASON;
+}
+
+__attribute__((noinline)) extern "C" uintptr_t get_main_ra_sign_state() {
+ uint64_t sign_state = -1;
+ _Unwind_Backtrace(frame_handler, &sign_state);
+ printf("UNW_AARCH64_RA_SIGN_STATE = %" PRIu64 "\n", sign_state);
+ return sign_state;
+}
+
+__attribute__((noinline)) uint64_t check_vanilla() {
+ return get_main_ra_sign_state();
+}
+
+__attribute__((naked)) uint64_t check_negate() {
+ asm(".cfi_negate_ra_state\n"
+ "pacibsp\n"
+
+ "stp x29, x30, [sp, #-16]!\n"
+ ".cfi_def_cfa_offset 16\n"
+ ".cfi_offset x29, -16\n"
+ ".cfi_offset x30, -8\n"
+
+ "bl _get_main_ra_sign_state\n"
+
+ "ldp x29, x30, [sp], #16\n"
+ ".cfi_def_cfa_offset 0\n"
+ ".cfi_restore x29\n"
+ ".cfi_restore x30\n"
+
+ ".cfi_negate_ra_state\n"
+ "retab");
+}
+
+FUNC_ATTR(main_func) int main(int, char **) {
+ uint64_t ret;
+
+ ret = check_vanilla();
+ assert((ret & 2) == ret);
+
+#if defined(__PTRAUTH__) || __has_feature(ptrauth_calls)
+ assert(ret == 1);
+#else
+ assert(ret == 0);
+#endif
+
+ if (!checkHasPAuth()) {
+ printf("target does not have FEAT_PAuth\n");
+ return 0;
+ }
+
+ ret = check_negate();
+ assert(ret == 1);
+
+ printf("success\n");
+ return 0;
+}
>From b232cd6fe924ff20f7c1f8abca4f3061830a96a1 Mon Sep 17 00:00:00 2001
From: Jon Roelofs <jonathan_roelofs at apple.com>
Date: Tue, 23 Jun 2026 15:20:55 -0700
Subject: [PATCH 02/13] move/fix state range assertion. add missing target
feature.
---
libunwind/test/ra_sign_state.pass.cpp | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/libunwind/test/ra_sign_state.pass.cpp b/libunwind/test/ra_sign_state.pass.cpp
index 1e113955db027..2b31ef4000386 100644
--- a/libunwind/test/ra_sign_state.pass.cpp
+++ b/libunwind/test/ra_sign_state.pass.cpp
@@ -73,6 +73,7 @@ __attribute__((noinline)) extern "C" uintptr_t get_main_ra_sign_state() {
uint64_t sign_state = -1;
_Unwind_Backtrace(frame_handler, &sign_state);
printf("UNW_AARCH64_RA_SIGN_STATE = %" PRIu64 "\n", sign_state);
+ assert((sign_state & 0x3) == sign_state);
return sign_state;
}
@@ -80,7 +81,7 @@ __attribute__((noinline)) uint64_t check_vanilla() {
return get_main_ra_sign_state();
}
-__attribute__((naked)) uint64_t check_negate() {
+__attribute__((naked, target("pauth"))) uint64_t check_negate() {
asm(".cfi_negate_ra_state\n"
"pacibsp\n"
@@ -104,10 +105,8 @@ FUNC_ATTR(main_func) int main(int, char **) {
uint64_t ret;
ret = check_vanilla();
- assert((ret & 2) == ret);
-
#if defined(__PTRAUTH__) || __has_feature(ptrauth_calls)
- assert(ret == 1);
+ assert(ret == 1 || ret == 2);
#else
assert(ret == 0);
#endif
>From 408cdbc859be5961f1d1a66683d9d513ea554a1f Mon Sep 17 00:00:00 2001
From: Jon Roelofs <jonathan_roelofs at apple.com>
Date: Wed, 24 Jun 2026 10:02:34 -0700
Subject: [PATCH 03/13] xfail on stdlib=apple-libc++ &&
target=.*-apple-.*{{<=27.0}}
---
libunwind/test/ra_sign_state.pass.cpp | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/libunwind/test/ra_sign_state.pass.cpp b/libunwind/test/ra_sign_state.pass.cpp
index 2b31ef4000386..7e256316e5a17 100644
--- a/libunwind/test/ra_sign_state.pass.cpp
+++ b/libunwind/test/ra_sign_state.pass.cpp
@@ -10,6 +10,10 @@
// REQUIRES: target={{aarch64.*}}
// UNSUPPORTED: target={{.*-windows.*}}
+// The libSystem unwinder does not correctly read UNW_AARCH64_RA_SIGN_STATE, at
+// least through OS version 27.0
+// XFAIL: stdlib=apple-libc++ && target={{.*}}-apple-{{.*}}{{11|12|13|14|15|26|27.0}}
+
#undef NDEBUG
#include "support/func_bounds.h"
#include <assert.h>
>From bf97dc7d7d95e55e3fa4f7efabf235ff8bfc024a Mon Sep 17 00:00:00 2001
From: Jon Roelofs <jonathan_roelofs at apple.com>
Date: Wed, 24 Jun 2026 10:11:22 -0700
Subject: [PATCH 04/13] HWCAP_PACA checks for getauxval/elf_aux_info platforms
---
libunwind/test/ra_sign_state.pass.cpp | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/libunwind/test/ra_sign_state.pass.cpp b/libunwind/test/ra_sign_state.pass.cpp
index 7e256316e5a17..cbeb5c13694de 100644
--- a/libunwind/test/ra_sign_state.pass.cpp
+++ b/libunwind/test/ra_sign_state.pass.cpp
@@ -28,6 +28,9 @@
#if defined(__APPLE__)
#include <sys/sysctl.h>
#endif
+#if defined(_LIBUNWIND_HAVE_GETAUXVAL) || defined(_LIBUNWIND_HAVE_ELF_AUX_INFO)
+#include <sys/auxv.h>
+#endif
// Note: This test requires FEAT_PAuth (and is setup to pass on other targets).
@@ -39,6 +42,19 @@ static bool checkHasPAuth() {
return false;
return has_pauth != 0;
}
+#elif defined(_LIBUNWIND_HAVE_GETAUXVAL)
+static bool checkHasPAuth() {
+ constexpr unsigned long hwcap_paca = (1UL << 30);
+ unsigned long hwcap = getauxval(AT_HWCAP);
+ return (hwcap & hwcap_paca) != 0;
+}
+#elif defined(_LIBUNWIND_HAVE_ELF_AUX_INFO)
+static bool checkHasPAuth() {
+ constexpr unsigned long hwcap_paca = (1UL << 30);
+ unsigned long hwcap = 0;
+ elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap));
+ return (hwcap & hwcap_paca) != 0;
+}
#else
static bool checkHasPAuth() {
// TODO: Support other platforms.
>From a2bff648464dcbf4802d1436c7c9047717fe6b1f Mon Sep 17 00:00:00 2001
From: Jon Roelofs <jonathan_roelofs at apple.com>
Date: Wed, 24 Jun 2026 10:14:47 -0700
Subject: [PATCH 05/13] tell clang-format to go away
---
libunwind/test/ra_sign_state.pass.cpp | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/libunwind/test/ra_sign_state.pass.cpp b/libunwind/test/ra_sign_state.pass.cpp
index cbeb5c13694de..88b8425073fea 100644
--- a/libunwind/test/ra_sign_state.pass.cpp
+++ b/libunwind/test/ra_sign_state.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// clang-format-off
+
// REQUIRES: target={{aarch64.*}}
// UNSUPPORTED: target={{.*-windows.*}}
@@ -14,6 +16,8 @@
// least through OS version 27.0
// XFAIL: stdlib=apple-libc++ && target={{.*}}-apple-{{.*}}{{11|12|13|14|15|26|27.0}}
+// clang-format-on
+
#undef NDEBUG
#include "support/func_bounds.h"
#include <assert.h>
>From f4f205e35841a9d61520dda56a1cdccc1422dbbc Mon Sep 17 00:00:00 2001
From: Jon Roelofs <jonathan_roelofs at apple.com>
Date: Wed, 24 Jun 2026 10:23:08 -0700
Subject: [PATCH 06/13] really tell clang-format off
---
libunwind/test/ra_sign_state.pass.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libunwind/test/ra_sign_state.pass.cpp b/libunwind/test/ra_sign_state.pass.cpp
index 88b8425073fea..6b8fb3373565d 100644
--- a/libunwind/test/ra_sign_state.pass.cpp
+++ b/libunwind/test/ra_sign_state.pass.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-// clang-format-off
+// clang-format off
// REQUIRES: target={{aarch64.*}}
// UNSUPPORTED: target={{.*-windows.*}}
@@ -16,7 +16,7 @@
// least through OS version 27.0
// XFAIL: stdlib=apple-libc++ && target={{.*}}-apple-{{.*}}{{11|12|13|14|15|26|27.0}}
-// clang-format-on
+// clang-format on
#undef NDEBUG
#include "support/func_bounds.h"
>From 708273e49151faf9c3e9bc479ae5cde5e618f47d Mon Sep 17 00:00:00 2001
From: Jon Roelofs <jonathan_roelofs at apple.com>
Date: Wed, 24 Jun 2026 14:29:14 -0700
Subject: [PATCH 07/13] user-label-prefix extern C symbol
---
libunwind/test/ra_sign_state.pass.cpp | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/libunwind/test/ra_sign_state.pass.cpp b/libunwind/test/ra_sign_state.pass.cpp
index 6b8fb3373565d..8ce0e36dd99a4 100644
--- a/libunwind/test/ra_sign_state.pass.cpp
+++ b/libunwind/test/ra_sign_state.pass.cpp
@@ -19,6 +19,7 @@
// clang-format on
#undef NDEBUG
+#include "../src/config.h"
#include "support/func_bounds.h"
#include <assert.h>
#include <inttypes.h>
@@ -106,6 +107,7 @@ __attribute__((noinline)) uint64_t check_vanilla() {
}
__attribute__((naked, target("pauth"))) uint64_t check_negate() {
+ // clang-format off
asm(".cfi_negate_ra_state\n"
"pacibsp\n"
@@ -114,7 +116,7 @@ __attribute__((naked, target("pauth"))) uint64_t check_negate() {
".cfi_offset x29, -16\n"
".cfi_offset x30, -8\n"
- "bl _get_main_ra_sign_state\n"
+ "bl " SYMBOL_NAME(get_main_ra_sign_state) "\n"
"ldp x29, x30, [sp], #16\n"
".cfi_def_cfa_offset 0\n"
@@ -123,6 +125,7 @@ __attribute__((naked, target("pauth"))) uint64_t check_negate() {
".cfi_negate_ra_state\n"
"retab");
+ // clang-format on
}
FUNC_ATTR(main_func) int main(int, char **) {
>From a9c26c85267293b5949b7d09792af7f1a556e05e Mon Sep 17 00:00:00 2001
From: Jon Roelofs <jonathan_roelofs at apple.com>
Date: Thu, 25 Jun 2026 14:05:02 -0700
Subject: [PATCH 08/13] fix XFAIL regex
---
libunwind/test/ra_sign_state.pass.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libunwind/test/ra_sign_state.pass.cpp b/libunwind/test/ra_sign_state.pass.cpp
index 8ce0e36dd99a4..e6349a83b583a 100644
--- a/libunwind/test/ra_sign_state.pass.cpp
+++ b/libunwind/test/ra_sign_state.pass.cpp
@@ -14,7 +14,8 @@
// The libSystem unwinder does not correctly read UNW_AARCH64_RA_SIGN_STATE, at
// least through OS version 27.0
-// XFAIL: stdlib=apple-libc++ && target={{.*}}-apple-{{.*}}{{11|12|13|14|15|26|27.0}}
+// XFAIL: stdlib=apple-libc++ && target={{.*}}-apple-{{.*}}{{(11|12|13|14|15|26)(\.\d+)?}}
+// XFAIL: stdlib=apple-libc++ && target={{.*}}-apple-{{.*}}27.0
// clang-format on
>From 4a487f5b48fbabcaa3bf4428a3388b35ffe13c12 Mon Sep 17 00:00:00 2001
From: Jon Roelofs <jonathan_roelofs at apple.com>
Date: Wed, 24 Jun 2026 20:24:25 -0700
Subject: [PATCH 09/13] printf debug
premerge testing fails with:
```
-- Testing: 21 tests, 16 workers --
Testing: 0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90
FAIL: llvm-libunwind-shared.cfg.in :: ra_sign_state.pass.cpp (21 of 21)
******************** TEST 'llvm-libunwind-shared.cfg.in :: ra_sign_state.pass.cpp' FAILED ********************
Exit Code: 252
Command Output (stdout):
--
# COMPILED WITH
/__w/llvm-project/llvm-project/build/./bin/clang++ /__w/llvm-project/llvm-project/libunwind/test/ra_sign_state.pass.cpp --target=aarch64-unknown-linux-gnu -nostdinc++ -I /__w/llvm-project/llvm-project/build/runtimes/runtimes-bins/libunwind/test-suite-install/include -D_LIBUNWIND_HAVE_GETAUXVAL -funwind-tables -std=c++26 -Werror -Wall -Wctad-maybe-unsupported -Wextra -Wshadow -Wundef -Wunused-template -Wno-unused-command-line-argument -Wno-attributes -Wno-pessimizing-move -Wno-noexcept-type -Wno-atomic-alignment -Wno-reserved-module-identifier -Wdeprecated-copy -Wdeprecated-copy-dtor -Wshift-negative-value -Wno-user-defined-literals -Wno-tautological-compare -Wno-stringop-overread -Wsign-compare -Wunused-variable -Wunused-parameter -Wunreachable-code -Wno-unused-local-typedef -Wno-local-type-template-args -Wno-c++11-extensions -Wno-unknown-pragmas -Wno-pass-failed -Wno-mismatched-new-delete -Wno-redundant-move -Wno-self-move -Wno-nullability-completeness -flax-vector-conversions=none -D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER -Wuser-defined-warnings -L /__w/llvm-project/llvm-project/build/runtimes/runtimes-bins/libunwind/test-suite-install/lib/aarch64-unknown-linux-gnu -Wl,-rpath,/__w/llvm-project/llvm-project/build/runtimes/runtimes-bins/libunwind/test-suite-install/lib/aarch64-unknown-linux-gnu -lunwind -Wl,--export-dynamic -ldl -latomic -o /__w/llvm-project/llvm-project/build/runtimes/runtimes-bins/libunwind/test/Output/ra_sign_state.pass.cpp.dir/t.tmp.exe
# executed command: /__w/llvm-project/llvm-project/build/./bin/clang++ /__w/llvm-project/llvm-project/libunwind/test/ra_sign_state.pass.cpp --target=aarch64-unknown-linux-gnu -nostdinc++ -I /__w/llvm-project/llvm-project/build/runtimes/runtimes-bins/libunwind/test-suite-install/include -D_LIBUNWIND_HAVE_GETAUXVAL -funwind-tables -std=c++26 -Werror -Wall -Wctad-maybe-unsupported -Wextra -Wshadow -Wundef -Wunused-template -Wno-unused-command-line-argument -Wno-attributes -Wno-pessimizing-move -Wno-noexcept-type -Wno-atomic-alignment -Wno-reserved-module-identifier -Wdeprecated-copy -Wdeprecated-copy-dtor -Wshift-negative-value -Wno-user-defined-literals -Wno-tautological-compare -Wno-stringop-overread -Wsign-compare -Wunused-variable -Wunused-parameter -Wunreachable-code -Wno-unused-local-typedef -Wno-local-type-template-args -Wno-c++11-extensions -Wno-unknown-pragmas -Wno-pass-failed -Wno-mismatched-new-delete -Wno-redundant-move -Wno-self-move -Wno-nullability-completeness -flax-vector-conversions=none -D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER -Wuser-defined-warnings -L /__w/llvm-project/llvm-project/build/runtimes/runtimes-bins/libunwind/test-suite-install/lib/aarch64-unknown-linux-gnu -Wl,-rpath,/__w/llvm-project/llvm-project/build/runtimes/runtimes-bins/libunwind/test-suite-install/lib/aarch64-unknown-linux-gnu -lunwind -Wl,--export-dynamic -ldl -latomic -o /__w/llvm-project/llvm-project/build/runtimes/runtimes-bins/libunwind/test/Output/ra_sign_state.pass.cpp.dir/t.tmp.exe
# note: command had no output on stdout or stderr
# EXECUTED AS
/usr/bin/python3 /__w/llvm-project/llvm-project/libcxx/utils/run.py --execdir /__w/llvm-project/llvm-project/build/runtimes/runtimes-bins/libunwind/test/Output/ra_sign_state.pass.cpp.dir -- /__w/llvm-project/llvm-project/build/runtimes/runtimes-bins/libunwind/test/Output/ra_sign_state.pass.cpp.dir/t.tmp.exe
# executed command: /usr/bin/python3 /__w/llvm-project/llvm-project/libcxx/utils/run.py --execdir /__w/llvm-project/llvm-project/build/runtimes/runtimes-bins/libunwind/test/Output/ra_sign_state.pass.cpp.dir -- /__w/llvm-project/llvm-project/build/runtimes/runtimes-bins/libunwind/test/Output/ra_sign_state.pass.cpp.dir/t.tmp.exe
# note: command had no output on stdout or stderr
# error: command failed with exit status: 252
--
```
https://github.com/llvm/llvm-project/actions/runs/28131005033/job/83306950690?pr=205442
---
libunwind/test/ra_sign_state.pass.cpp | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/libunwind/test/ra_sign_state.pass.cpp b/libunwind/test/ra_sign_state.pass.cpp
index e6349a83b583a..d589a2a787bc0 100644
--- a/libunwind/test/ra_sign_state.pass.cpp
+++ b/libunwind/test/ra_sign_state.pass.cpp
@@ -95,19 +95,20 @@ _Unwind_Reason_Code frame_handler(struct _Unwind_Context *ctx, void *arg) {
return _URC_NO_REASON;
}
-__attribute__((noinline)) extern "C" uintptr_t get_main_ra_sign_state() {
+__attribute__((noinline)) extern "C" uintptr_t get_main_ra_sign_state(const char *note) {
+ printf("check: %s\n", note);
uint64_t sign_state = -1;
_Unwind_Backtrace(frame_handler, &sign_state);
- printf("UNW_AARCH64_RA_SIGN_STATE = %" PRIu64 "\n", sign_state);
+ printf("UNW_AARCH64_RA_SIGN_STATE for %s = %" PRIu64 "\n", note, sign_state);
assert((sign_state & 0x3) == sign_state);
return sign_state;
}
-__attribute__((noinline)) uint64_t check_vanilla() {
- return get_main_ra_sign_state();
+__attribute__((noinline)) uint64_t check_vanilla(const char *note) {
+ return get_main_ra_sign_state(note);
}
-__attribute__((naked, target("pauth"))) uint64_t check_negate() {
+__attribute__((naked, target("pauth"))) uint64_t check_negate(const char *note) {
// clang-format off
asm(".cfi_negate_ra_state\n"
"pacibsp\n"
@@ -132,7 +133,7 @@ __attribute__((naked, target("pauth"))) uint64_t check_negate() {
FUNC_ATTR(main_func) int main(int, char **) {
uint64_t ret;
- ret = check_vanilla();
+ ret = check_vanilla("check_vanilla");
#if defined(__PTRAUTH__) || __has_feature(ptrauth_calls)
assert(ret == 1 || ret == 2);
#else
@@ -144,7 +145,7 @@ FUNC_ATTR(main_func) int main(int, char **) {
return 0;
}
- ret = check_negate();
+ ret = check_negate("check_negate");
assert(ret == 1);
printf("success\n");
>From 8354ca738a056975a66d7c61bc1997d55e68e36c Mon Sep 17 00:00:00 2001
From: Jon Roelofs <jonathan_roelofs at apple.com>
Date: Thu, 25 Jun 2026 14:17:20 -0700
Subject: [PATCH 10/13] clang-format
---
libunwind/test/ra_sign_state.pass.cpp | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/libunwind/test/ra_sign_state.pass.cpp b/libunwind/test/ra_sign_state.pass.cpp
index d589a2a787bc0..9732f85f8a84f 100644
--- a/libunwind/test/ra_sign_state.pass.cpp
+++ b/libunwind/test/ra_sign_state.pass.cpp
@@ -95,7 +95,8 @@ _Unwind_Reason_Code frame_handler(struct _Unwind_Context *ctx, void *arg) {
return _URC_NO_REASON;
}
-__attribute__((noinline)) extern "C" uintptr_t get_main_ra_sign_state(const char *note) {
+__attribute__((noinline)) extern "C" uintptr_t
+get_main_ra_sign_state(const char *note) {
printf("check: %s\n", note);
uint64_t sign_state = -1;
_Unwind_Backtrace(frame_handler, &sign_state);
@@ -108,7 +109,8 @@ __attribute__((noinline)) uint64_t check_vanilla(const char *note) {
return get_main_ra_sign_state(note);
}
-__attribute__((naked, target("pauth"))) uint64_t check_negate(const char *note) {
+__attribute__((naked, target("pauth"))) uint64_t
+check_negate(const char *note) {
// clang-format off
asm(".cfi_negate_ra_state\n"
"pacibsp\n"
>From a3ae8e496cd5aa42283228506d74f05a5f702405 Mon Sep 17 00:00:00 2001
From: Jon Roelofs <jonathan_roelofs at apple.com>
Date: Fri, 26 Jun 2026 10:55:35 -0700
Subject: [PATCH 11/13] static
---
libunwind/test/ra_sign_state.pass.cpp | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/libunwind/test/ra_sign_state.pass.cpp b/libunwind/test/ra_sign_state.pass.cpp
index 9732f85f8a84f..e25a1c12720c9 100644
--- a/libunwind/test/ra_sign_state.pass.cpp
+++ b/libunwind/test/ra_sign_state.pass.cpp
@@ -70,7 +70,8 @@ static bool checkHasPAuth() {
FUNC_BOUNDS_DECL(main_func);
-_Unwind_Reason_Code frame_handler(struct _Unwind_Context *ctx, void *arg) {
+static _Unwind_Reason_Code frame_handler(struct _Unwind_Context *ctx,
+ void *arg) {
uint64_t ra_sign_state =
(uint64_t)_Unwind_GetGR(ctx, UNW_AARCH64_RA_SIGN_STATE);
@@ -105,11 +106,11 @@ get_main_ra_sign_state(const char *note) {
return sign_state;
}
-__attribute__((noinline)) uint64_t check_vanilla(const char *note) {
+__attribute__((noinline)) static uint64_t check_vanilla(const char *note) {
return get_main_ra_sign_state(note);
}
-__attribute__((naked, target("pauth"))) uint64_t
+__attribute__((naked, target("pauth"))) static uint64_t
check_negate(const char *note) {
// clang-format off
asm(".cfi_negate_ra_state\n"
>From 65ac137bf5173e26e1f394a78da0f437a41e08e5 Mon Sep 17 00:00:00 2001
From: Jon Roelofs <jonathan_roelofs at apple.com>
Date: Fri, 26 Jun 2026 10:56:09 -0700
Subject: [PATCH 12/13] _LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING
---
libunwind/test/ra_sign_state.pass.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libunwind/test/ra_sign_state.pass.cpp b/libunwind/test/ra_sign_state.pass.cpp
index e25a1c12720c9..cea5117e09c61 100644
--- a/libunwind/test/ra_sign_state.pass.cpp
+++ b/libunwind/test/ra_sign_state.pass.cpp
@@ -87,7 +87,7 @@ static _Unwind_Reason_Code frame_handler(struct _Unwind_Context *ctx,
return _URC_END_OF_STACK;
}
-#if defined(__PTRAUTH__) || __has_feature(ptrauth_calls)
+#if defined(_LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING)
assert(ra_sign_state == 1);
#else
assert(ra_sign_state == 0);
@@ -137,7 +137,7 @@ FUNC_ATTR(main_func) int main(int, char **) {
uint64_t ret;
ret = check_vanilla("check_vanilla");
-#if defined(__PTRAUTH__) || __has_feature(ptrauth_calls)
+#if defined(_LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING)
assert(ret == 1 || ret == 2);
#else
assert(ret == 0);
>From a6a4939d6e502d466a826c1ac5828237cb3c47bb Mon Sep 17 00:00:00 2001
From: Jon Roelofs <jonathan_roelofs at apple.com>
Date: Fri, 26 Jun 2026 10:57:35 -0700
Subject: [PATCH 13/13] ra_sign_state == 2
---
libunwind/test/ra_sign_state.pass.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libunwind/test/ra_sign_state.pass.cpp b/libunwind/test/ra_sign_state.pass.cpp
index cea5117e09c61..2244cddca0786 100644
--- a/libunwind/test/ra_sign_state.pass.cpp
+++ b/libunwind/test/ra_sign_state.pass.cpp
@@ -88,7 +88,7 @@ static _Unwind_Reason_Code frame_handler(struct _Unwind_Context *ctx,
}
#if defined(_LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING)
- assert(ra_sign_state == 1);
+ assert(ra_sign_state == 1 || ra_sign_state == 2);
#else
assert(ra_sign_state == 0);
#endif
More information about the cfe-commits
mailing list