[libunwind] [libunwind][PAuthLR] Remove PC offset when using FEAT_PAuthLR (PR #164224)

Jack Styles via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 27 02:31:55 PDT 2025


https://github.com/Stylie777 updated https://github.com/llvm/llvm-project/pull/164224

>From 87a7351c13caa4254b8de315e568fe77447ce87d Mon Sep 17 00:00:00 2001
From: Jack Styles <jack.styles at arm.com>
Date: Mon, 20 Oct 2025 09:51:51 +0100
Subject: [PATCH 1/3] [libunwind][PAuthLR] Remove PC offset when using
 FEAT_PAuthLR

When originally introduced to libunwind as part of #112171,
FEAT_PAuthLR had its Call Frame Instruction's (CFI's) in a different
location to other Signing Authentication methods. To incorporate this
in libunwind, an offset was introduced to work with this. However,
this design was reversed in #121551 so the CFI's are emitted in the
same location as other methods. When making this change, the offset
in libunwind was not removed, so libunwinds PC value would be incorrect.

This can be removed from the code, as it is no longer needed.
---
 libunwind/src/DwarfParser.hpp | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/libunwind/src/DwarfParser.hpp b/libunwind/src/DwarfParser.hpp
index 25250e0810987..625780f1f4558 100644
--- a/libunwind/src/DwarfParser.hpp
+++ b/libunwind/src/DwarfParser.hpp
@@ -808,12 +808,6 @@ bool CFI_Parser<A>::parseFDEInstructions(A &addressSpace,
             results->savedRegisters[UNW_AARCH64_RA_SIGN_STATE].value ^ 0x3;
         results->setRegisterValue(UNW_AARCH64_RA_SIGN_STATE, value,
                                   initialState);
-        // When calculating the value of the PC, it is assumed that the CFI
-        // instruction is placed before the signing instruction, however it is
-        // placed after. Because of this, we need to take into account the CFI
-        // instruction is one instruction call later than expected, and reduce
-        // the PC value by 4 bytes to compensate.
-        results->ptrAuthDiversifier = fdeInfo.pcStart + codeOffset - 0x4;
         _LIBUNWIND_TRACE_DWARF(
             "DW_CFA_AARCH64_negate_ra_state_with_pc(pc=0x%" PRIx64 ")\n",
             static_cast<uint64_t>(results->ptrAuthDiversifier));

>From b46d5559306dc3df5ed8e9563de5954849615af7 Mon Sep 17 00:00:00 2001
From: Jack Styles <jack.styles at arm.com>
Date: Tue, 21 Oct 2025 08:46:51 +0100
Subject: [PATCH 2/3] Still set results->ptrAuthDiversifier

We still need to set this value when we look at PAuthLR, it was just
the 4 byte offset that needed removing
---
 libunwind/src/DwarfParser.hpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libunwind/src/DwarfParser.hpp b/libunwind/src/DwarfParser.hpp
index 625780f1f4558..45d7f61e9f10c 100644
--- a/libunwind/src/DwarfParser.hpp
+++ b/libunwind/src/DwarfParser.hpp
@@ -808,6 +808,7 @@ bool CFI_Parser<A>::parseFDEInstructions(A &addressSpace,
             results->savedRegisters[UNW_AARCH64_RA_SIGN_STATE].value ^ 0x3;
         results->setRegisterValue(UNW_AARCH64_RA_SIGN_STATE, value,
                                   initialState);
+        results->ptrAuthDiversifier = fdeInfo.pcStart + codeOffset;
         _LIBUNWIND_TRACE_DWARF(
             "DW_CFA_AARCH64_negate_ra_state_with_pc(pc=0x%" PRIx64 ")\n",
             static_cast<uint64_t>(results->ptrAuthDiversifier));

>From d18b658271267d7c92aa8d1068fd5497af1b0f77 Mon Sep 17 00:00:00 2001
From: Jack Styles <jack.styles at arm.com>
Date: Mon, 27 Oct 2025 09:07:53 +0000
Subject: [PATCH 3/3] Reintroduce comment

---
 libunwind/src/DwarfParser.hpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libunwind/src/DwarfParser.hpp b/libunwind/src/DwarfParser.hpp
index 45d7f61e9f10c..6998be799894b 100644
--- a/libunwind/src/DwarfParser.hpp
+++ b/libunwind/src/DwarfParser.hpp
@@ -808,6 +808,9 @@ bool CFI_Parser<A>::parseFDEInstructions(A &addressSpace,
             results->savedRegisters[UNW_AARCH64_RA_SIGN_STATE].value ^ 0x3;
         results->setRegisterValue(UNW_AARCH64_RA_SIGN_STATE, 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.
         results->ptrAuthDiversifier = fdeInfo.pcStart + codeOffset;
         _LIBUNWIND_TRACE_DWARF(
             "DW_CFA_AARCH64_negate_ra_state_with_pc(pc=0x%" PRIx64 ")\n",



More information about the cfe-commits mailing list