https://github.com/jroelofs updated 
https://github.com/llvm/llvm-project/pull/202772

>From 25829ccdbe4d045170328a97ba55f23600403e27 Mon Sep 17 00:00:00 2001
From: Jon Roelofs <[email protected]>
Date: Tue, 9 Jun 2026 14:04:32 -0700
Subject: [PATCH 1/6] [libunwind][arm64e] Mach-O Support unwinding PAuth_LR
 frames

Under PAuth_LR, compact unwind entries marked UNWIND_ARM64_MODE_FRAME_PAUTH_LR
are signed with the PC of the pacibsppc at the start of the range. The compiler
may emit those entries with UNWIND_IS_NOT_FUNCTION_START when the pacibsppc is
not the first instruction in the function; the unwinder must scan backwards past
such entries to find the actual function start (and its LSDA pointer).

When unwinding a PAuth_LR frame, authenticate and re-sign using setIPPAuthLR(),
which calls __builtin_ptrauth_auth_with_pc_and_resign when available, falling
back to inline asm (autib171615 + pacib) for compilers that lack the builtin.

To reduce the size of Compact Unwind entries for shrinkwrapped frames, new
offset bits encode the distance in multiples of 4 bytes from the range start to
the pacibsppc. The compiler emits paired FRAMELESS/FRAMELESS+PAUTH_LR entries
that the linker merges into a single FRAME_PAUTH_LR | (offset/4) << 12 encoding.

rdar://161907302&169746432&171118419
---
 .../include/mach-o/compact_unwind_encoding.h  | 13 ++-
 libunwind/src/CompactUnwinder.hpp             | 20 ++++-
 libunwind/src/DwarfInstructions.hpp           | 22 +++--
 libunwind/src/Registers.hpp                   | 25 ++++++
 libunwind/src/UnwindCursor.hpp                | 83 ++++++++++++++-----
 5 files changed, 131 insertions(+), 32 deletions(-)

diff --git a/libunwind/include/mach-o/compact_unwind_encoding.h 
b/libunwind/include/mach-o/compact_unwind_encoding.h
index c495b83c40b90..b6901cfb9055d 100644
--- a/libunwind/include/mach-o/compact_unwind_encoding.h
+++ b/libunwind/include/mach-o/compact_unwind_encoding.h
@@ -288,6 +288,10 @@ enum {
     UNWIND_ARM64_MODE_FRAMELESS                = 0x02000000,
     UNWIND_ARM64_MODE_DWARF                    = 0x03000000,
     UNWIND_ARM64_MODE_FRAME                    = 0x04000000,
+    UNWIND_ARM64_MODE_FRAME_PAUTH_LR           = 0x05000000,
+
+    UNWIND_ARM64_PAUTH_LR_OFFSET_MASK          = 0x00FFF000,
+    UNWIND_ARM64_PAUTH_LR_OFFSET_SHIFT         = 12,
 
     UNWIND_ARM64_FRAME_X19_X20_PAIR            = 0x00000001,
     UNWIND_ARM64_FRAME_X21_X22_PAIR            = 0x00000002,
@@ -323,8 +327,13 @@ enum {
 //    This mode is never used in object files.  It is only generated by the
 //    linker in final linked images which have only DWARF unwind info for a
 //    function.
-//
-
+// For arm64e there is one more mode for compact unwind encoding:
+// UNWIND_ARM64_MODE_FRAME_PAUTH_LR:
+//    An arm64e prologue, where LR is signed in the range with a `pacibsppc`.
+//    The UNWIND_ARM64_PAUTH_LR_OFFSET_MASK bits specify an unsigned positive
+//    offset (encoded as a multiple of 4 bytes) from the beginning of the range
+//    to the `pacibsppc`, with 0 indicating that the `pacibsppc` is the first
+//    instruction in the range.
 
 
 
diff --git a/libunwind/src/CompactUnwinder.hpp 
b/libunwind/src/CompactUnwinder.hpp
index 929f540b662b4..0daf76a373296 100644
--- a/libunwind/src/CompactUnwinder.hpp
+++ b/libunwind/src/CompactUnwinder.hpp
@@ -520,6 +520,7 @@ int CompactUnwinder_arm64<A>::stepWithCompactEncoding(
     A &addressSpace, Registers_arm64 &registers) {
   switch (compactEncoding & UNWIND_ARM64_MODE_MASK) {
   case UNWIND_ARM64_MODE_FRAME:
+  case UNWIND_ARM64_MODE_FRAME_PAUTH_LR:
     return stepWithCompactEncodingFrame(compactEncoding, functionStart,
                                         addressSpace, registers);
   case UNWIND_ARM64_MODE_FRAMELESS:
@@ -619,7 +620,7 @@ int 
CompactUnwinder_arm64<A>::stepWithCompactEncodingFrameless(
 
 template <typename A>
 int CompactUnwinder_arm64<A>::stepWithCompactEncodingFrame(
-    compact_unwind_encoding_t encoding, uint64_t, A &addressSpace,
+    compact_unwind_encoding_t encoding, uint64_t functionStart, A 
&addressSpace,
     Registers_arm64 &registers) {
   Registers_arm64::reg_t savedRegisterLoc = registers.getFP() - 8;
 
@@ -698,7 +699,22 @@ int CompactUnwinder_arm64<A>::stepWithCompactEncodingFrame(
   registers.setSP(fp + 16);
 
   // pop return address into pc
-  registers.setIP(addressSpace.get64(fp + 8));
+  Registers_arm64::reg_t linkRegister = addressSpace.get64(fp + 8);
+
+  // authenticate lr, if needed
+  if ((encoding & UNWIND_ARM64_MODE_MASK) == UNWIND_ARM64_MODE_FRAME_PAUTH_LR) 
{
+    // Offset from the beginning of the range to the pacibsppc, in words.
+    uint32_t offset = (encoding & UNWIND_ARM64_PAUTH_LR_OFFSET_MASK) >>
+                      UNWIND_ARM64_PAUTH_LR_OFFSET_SHIFT;
+
+    // Address of the pacibsppc
+    uint64_t pacibsppcAddr = functionStart + offset * 4;
+
+    registers.setIPPAuthLR(linkRegister, pacibsppcAddr);
+  } else {
+    registers.setIP(linkRegister);
+  }
+
 
   return UNW_STEP_SUCCESS;
 }
diff --git a/libunwind/src/DwarfInstructions.hpp 
b/libunwind/src/DwarfInstructions.hpp
index 165c4a99e9a92..62c4a71f87be3 100644
--- a/libunwind/src/DwarfInstructions.hpp
+++ b/libunwind/src/DwarfInstructions.hpp
@@ -302,16 +302,27 @@ int DwarfInstructions<A, R>::stepWithDwarf(
 
       isSignalFrame = cieInfo.isSignalFrame;
 
-#if defined(_LIBUNWIND_TARGET_AARCH64) &&                                      
\
-    !defined(_LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING)
+#if defined(_LIBUNWIND_TARGET_AARCH64)
       // There are two ways of return address signing: pac-ret (enabled via
       // -mbranch-protection=pac-ret) and ptrauth-returns (enabled as part of
       // Apple's arm64e or experimental pauthtest ABI on Linux). The code
-      // below handles signed RA for pac-ret, while ptrauth-returns uses
-      // different logic.
+      // below handles signed RA for ptrauth-returns, while pac-ret uses pacm
+      // instructions from the hint space.
+      //
       // TODO: unify logic for both cases, see
       // https://github.com/llvm/llvm-project/issues/160110
-      //
+#if defined(_LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING)
+      if (isReturnAddressSignedWithPC(addressSpace, registers, cfa, prolog)) {
+        newRegisters.setIPPAuthLR(returnAddress, prolog.ptrAuthDiversifier);
+      } else {
+        newRegisters.setIP(returnAddress);
+      }
+
+      // Simulate the step by replacing the register set with the new ones.
+      registers = newRegisters;
+
+      return UNW_STEP_SUCCESS;
+#else
       // If the target is aarch64 then the return address may have been signed
       // using the v8.3 pointer authentication extensions. The original
       // return address needs to be authenticated before the return address is
@@ -353,6 +364,7 @@ int DwarfInstructions<A, R>::stepWithDwarf(
 #endif
       }
 #endif
+#endif
 
 #if defined(_LIBUNWIND_IS_NATIVE_ONLY) && defined(_LIBUNWIND_TARGET_ARM) &&    
\
     defined(__ARM_FEATURE_PAUTH)
diff --git a/libunwind/src/Registers.hpp b/libunwind/src/Registers.hpp
index c88422a6d5f4f..abd0fca239a09 100644
--- a/libunwind/src/Registers.hpp
+++ b/libunwind/src/Registers.hpp
@@ -1917,6 +1917,31 @@ class _LIBUNWIND_HIDDEN Registers_arm64 {
 #endif
     _registers.__pc = value;
   }
+  __attribute__((target("pauth-lr")))
+  void setIPPAuthLR(uint64_t value, uint64_t signing_pc) {
+#if defined(_LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING)
+#if __has_builtin(__builtin_ptrauth_auth_with_pc_and_resign)
+    value = (uint64_t)ptrauth_auth_with_pc_and_resign(
+        (void *)value,
+        ptrauth_key_process_dependent_code,
+        (void *)getSP(),
+        (void *)signing_pc,
+        ptrauth_key_return_address,
+        &_registers.__pc);
+#else
+    register uint64_t x17 __asm("x17") = value;
+    register uint64_t x16 __asm("x16") = getSP();
+    register uint64_t x15 __asm("x15") = signing_pc;
+    uint64_t resignDisc = (uint64_t)&_registers.__pc;
+    asm("autib171615\n\t"
+        "pacib %0, %3"
+        : "+r"(x17) : "r"(x16), "r"(x15), "r"(resignDisc));
+    value = x17;
+#endif
+#endif
+    _registers.__pc = value;
+  }
+
   uint64_t getFP() const { return _registers.__fp; }
   void setFP(uint64_t value) { _registers.__fp = value; }
 
diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp
index ff92c9e0a844a..468107f3ded49 100644
--- a/libunwind/src/UnwindCursor.hpp
+++ b/libunwind/src/UnwindCursor.hpp
@@ -1869,6 +1869,7 @@ bool UnwindCursor<A, 
R>::getInfoFromCompactEncodingSection(
   // do a binary search of second level page index
   uint32_t encoding = 0;
   pint_t funcStart = 0;
+  pint_t rangeStart = 0;
   pint_t funcEnd = 0;
   pint_t lsda = 0;
   pint_t personality = 0;
@@ -1908,21 +1909,32 @@ bool UnwindCursor<A, 
R>::getInfoFromCompactEncodingSection(
       }
     }
     encoding = pageIndex.encoding(low);
-    funcStart = pageIndex.functionOffset(low) + sects.dso_base;
+    rangeStart = pageIndex.functionOffset(low) + sects.dso_base;
+
+    // If UNWIND_IS_NOT_FUNCTION_START is set, walk backwards to find the 
actual function start.
+    funcStart = rangeStart;
+    if (encoding & UNWIND_IS_NOT_FUNCTION_START) {
+      uint32_t backIndex = low;
+      do {
+        --backIndex;
+      } while (backIndex > 0 && (pageIndex.encoding(backIndex) & 
UNWIND_IS_NOT_FUNCTION_START));
+      funcStart = pageIndex.functionOffset(backIndex) + sects.dso_base;
+    }
+
     if (pc < funcStart) {
       if (log)
         fprintf(
             stderr,
-            "\tpc not in table, pc=0x%llX, funcStart=0x%llX, funcEnd=0x%llX\n",
-            (uint64_t) pc, (uint64_t) funcStart, (uint64_t) funcEnd);
+            "\tpc not in table, pc=0x%llX, funcStart=0x%llX, 
rangeStart=0x%llX, funcEnd=0x%llX\n",
+            (uint64_t) pc, (uint64_t) funcStart, (uint64_t) rangeStart, 
(uint64_t) funcEnd);
       return false;
     }
     if (pc > funcEnd) {
       if (log)
         fprintf(
             stderr,
-            "\tpc not in table, pc=0x%llX, funcStart=0x%llX, funcEnd=0x%llX\n",
-            (uint64_t) pc, (uint64_t) funcStart, (uint64_t) funcEnd);
+            "\tpc not in table, pc=0x%llX, funcStart=0x%llX, 
rangeStart=0x%llX, funcEnd=0x%llX\n",
+            (uint64_t) pc, (uint64_t) funcStart, (uint64_t) rangeStart, 
(uint64_t) funcEnd);
       return false;
     }
   } else if (pageKind == UNWIND_SECOND_LEVEL_COMPRESSED) {
@@ -1956,7 +1968,7 @@ bool UnwindCursor<A, 
R>::getInfoFromCompactEncodingSection(
         high = mid;
       }
     }
-    funcStart = pageIndex.functionOffset(low) + firstLevelFunctionOffset
+    rangeStart = pageIndex.functionOffset(low) + firstLevelFunctionOffset
                                                               + sects.dso_base;
     if (low < last)
       funcEnd =
@@ -1964,11 +1976,40 @@ bool UnwindCursor<A, 
R>::getInfoFromCompactEncodingSection(
                                                               + sects.dso_base;
     else
       funcEnd = firstLevelNextPageFunctionOffset + sects.dso_base;
+
+    auto encodingAtIndex = [&](uint32_t idx) -> uint32_t {
+      uint16_t encIdx = pageIndex.encodingIndex(idx);
+      if (encIdx < sectionHeader.commonEncodingsArrayCount()) {
+        return _addressSpace.get32(
+            sects.compact_unwind_section +
+            sectionHeader.commonEncodingsArraySectionOffset() +
+            encIdx * sizeof(uint32_t));
+      } else {
+        uint16_t pageEncIdx = encIdx - 
(uint16_t)sectionHeader.commonEncodingsArrayCount();
+        return _addressSpace.get32(secondLevelAddr +
+                                    pageHeader.encodingsPageOffset() +
+                                    pageEncIdx * sizeof(uint32_t));
+      }
+    };
+
+    encoding = encodingAtIndex(low);
+
+    // If UNWIND_IS_NOT_FUNCTION_START is set, walk backwards to find the 
actual function start.
+    funcStart = rangeStart;
+    if (encoding & UNWIND_IS_NOT_FUNCTION_START) {
+      uint32_t backIndex = low;
+      do {
+        --backIndex;
+      } while (backIndex > 0 && (encodingAtIndex(backIndex) & 
UNWIND_IS_NOT_FUNCTION_START));
+      funcStart = pageIndex.functionOffset(backIndex) + 
firstLevelFunctionOffset
+                                                        + sects.dso_base;
+    }
+
     if (pc < funcStart) {
       _LIBUNWIND_DEBUG_LOG("malformed __unwind_info, pc=0x%llX "
                            "not in second level compressed unwind table. "
-                           "funcStart=0x%llX",
-                            (uint64_t) pc, (uint64_t) funcStart);
+                           "funcStart=0x%llX, rangeStart=0x%llX",
+                            (uint64_t) pc, (uint64_t) funcStart, (uint64_t) 
rangeStart);
       return false;
     }
     if (pc > funcEnd) {
@@ -1978,21 +2019,6 @@ bool UnwindCursor<A, 
R>::getInfoFromCompactEncodingSection(
                            (uint64_t) pc, (uint64_t) funcEnd);
       return false;
     }
-    uint16_t encodingIndex = pageIndex.encodingIndex(low);
-    if (encodingIndex < sectionHeader.commonEncodingsArrayCount()) {
-      // encoding is in common table in section header
-      encoding = _addressSpace.get32(
-          sects.compact_unwind_section +
-          sectionHeader.commonEncodingsArraySectionOffset() +
-          encodingIndex * sizeof(uint32_t));
-    } else {
-      // encoding is in page specific table
-      uint16_t pageEncodingIndex =
-          encodingIndex - (uint16_t)sectionHeader.commonEncodingsArrayCount();
-      encoding = _addressSpace.get32(secondLevelAddr +
-                                     pageHeader.encodingsPageOffset() +
-                                     pageEncodingIndex * sizeof(uint32_t));
-    }
   } else {
     _LIBUNWIND_DEBUG_LOG(
         "malformed __unwind_info at 0x%0llX bad second level page",
@@ -2069,7 +2095,18 @@ bool UnwindCursor<A, 
R>::getInfoFromCompactEncodingSection(
     fprintf(stderr, "getInfoFromCompactEncodingSection(pc=0x%llX), "
                     "encoding=0x%08X, lsda=0x%08llX for funcStart=0x%llX\n",
             (uint64_t) pc, encoding, (uint64_t) lsda, (uint64_t) funcStart);
+
+  // For ARM64 PAuth_LR frames, start_ip should be the pacibsppc address 
(rangeStart).
+  // For all other cases, start_ip should be the function start.
+#if defined(_LIBUNWIND_TARGET_AARCH64)
+  if ((encoding & UNWIND_ARM64_MODE_MASK) == UNWIND_ARM64_MODE_FRAME_PAUTH_LR) 
{
+    _info.start_ip = rangeStart;
+  } else {
+    _info.start_ip = funcStart;
+  }
+#else
   _info.start_ip = funcStart;
+#endif
   _info.end_ip = funcEnd;
   _info.lsda = lsda;
   // We use memmove to copy the personality function as we have already 
manually

>From b4bc71c4aebd6233b6b702b2db4eeda894ddf7e9 Mon Sep 17 00:00:00 2001
From: Jon Roelofs <[email protected]>
Date: Tue, 9 Jun 2026 14:15:26 -0700
Subject: [PATCH 2/6] clang-format

---
 .../include/mach-o/compact_unwind_encoding.h  | 45 ++++++++--------
 libunwind/src/CompactUnwinder.hpp             |  1 -
 libunwind/src/Registers.hpp                   | 15 +++---
 libunwind/src/UnwindCursor.hpp                | 52 +++++++++++--------
 4 files changed, 57 insertions(+), 56 deletions(-)

diff --git a/libunwind/include/mach-o/compact_unwind_encoding.h 
b/libunwind/include/mach-o/compact_unwind_encoding.h
index b6901cfb9055d..029b781287e02 100644
--- a/libunwind/include/mach-o/compact_unwind_encoding.h
+++ b/libunwind/include/mach-o/compact_unwind_encoding.h
@@ -284,27 +284,27 @@ enum {
 //        24-bits offset of DWARF FDE in __eh_frame section
 //
 enum {
-    UNWIND_ARM64_MODE_MASK                     = 0x0F000000,
-    UNWIND_ARM64_MODE_FRAMELESS                = 0x02000000,
-    UNWIND_ARM64_MODE_DWARF                    = 0x03000000,
-    UNWIND_ARM64_MODE_FRAME                    = 0x04000000,
-    UNWIND_ARM64_MODE_FRAME_PAUTH_LR           = 0x05000000,
-
-    UNWIND_ARM64_PAUTH_LR_OFFSET_MASK          = 0x00FFF000,
-    UNWIND_ARM64_PAUTH_LR_OFFSET_SHIFT         = 12,
-
-    UNWIND_ARM64_FRAME_X19_X20_PAIR            = 0x00000001,
-    UNWIND_ARM64_FRAME_X21_X22_PAIR            = 0x00000002,
-    UNWIND_ARM64_FRAME_X23_X24_PAIR            = 0x00000004,
-    UNWIND_ARM64_FRAME_X25_X26_PAIR            = 0x00000008,
-    UNWIND_ARM64_FRAME_X27_X28_PAIR            = 0x00000010,
-    UNWIND_ARM64_FRAME_D8_D9_PAIR              = 0x00000100,
-    UNWIND_ARM64_FRAME_D10_D11_PAIR            = 0x00000200,
-    UNWIND_ARM64_FRAME_D12_D13_PAIR            = 0x00000400,
-    UNWIND_ARM64_FRAME_D14_D15_PAIR            = 0x00000800,
-
-    UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK     = 0x00FFF000,
-    UNWIND_ARM64_DWARF_SECTION_OFFSET          = 0x00FFFFFF,
+  UNWIND_ARM64_MODE_MASK = 0x0F000000,
+  UNWIND_ARM64_MODE_FRAMELESS = 0x02000000,
+  UNWIND_ARM64_MODE_DWARF = 0x03000000,
+  UNWIND_ARM64_MODE_FRAME = 0x04000000,
+  UNWIND_ARM64_MODE_FRAME_PAUTH_LR = 0x05000000,
+
+  UNWIND_ARM64_PAUTH_LR_OFFSET_MASK = 0x00FFF000,
+  UNWIND_ARM64_PAUTH_LR_OFFSET_SHIFT = 12,
+
+  UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001,
+  UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002,
+  UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004,
+  UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008,
+  UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010,
+  UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100,
+  UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200,
+  UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400,
+  UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800,
+
+  UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK = 0x00FFF000,
+  UNWIND_ARM64_DWARF_SECTION_OFFSET = 0x00FFFFFF,
 };
 // For arm64 there are three modes for the compact unwind encoding:
 // UNWIND_ARM64_MODE_FRAME:
@@ -335,9 +335,6 @@ enum {
 //    to the `pacibsppc`, with 0 indicating that the `pacibsppc` is the first
 //    instruction in the range.
 
-
-
-
 
////////////////////////////////////////////////////////////////////////////////
 //
 //  Relocatable Object Files: __LD,__compact_unwind
diff --git a/libunwind/src/CompactUnwinder.hpp 
b/libunwind/src/CompactUnwinder.hpp
index 0daf76a373296..bc9c569a8ccb9 100644
--- a/libunwind/src/CompactUnwinder.hpp
+++ b/libunwind/src/CompactUnwinder.hpp
@@ -715,7 +715,6 @@ int CompactUnwinder_arm64<A>::stepWithCompactEncodingFrame(
     registers.setIP(linkRegister);
   }
 
-
   return UNW_STEP_SUCCESS;
 }
 #endif // _LIBUNWIND_TARGET_AARCH64
diff --git a/libunwind/src/Registers.hpp b/libunwind/src/Registers.hpp
index abd0fca239a09..1dce396d111d3 100644
--- a/libunwind/src/Registers.hpp
+++ b/libunwind/src/Registers.hpp
@@ -1917,17 +1917,13 @@ class _LIBUNWIND_HIDDEN Registers_arm64 {
 #endif
     _registers.__pc = value;
   }
-  __attribute__((target("pauth-lr")))
-  void setIPPAuthLR(uint64_t value, uint64_t signing_pc) {
+  __attribute__((target("pauth-lr"))) void setIPPAuthLR(uint64_t value,
+                                                        uint64_t signing_pc) {
 #if defined(_LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING)
 #if __has_builtin(__builtin_ptrauth_auth_with_pc_and_resign)
     value = (uint64_t)ptrauth_auth_with_pc_and_resign(
-        (void *)value,
-        ptrauth_key_process_dependent_code,
-        (void *)getSP(),
-        (void *)signing_pc,
-        ptrauth_key_return_address,
-        &_registers.__pc);
+        (void *)value, ptrauth_key_process_dependent_code, (void *)getSP(),
+        (void *)signing_pc, ptrauth_key_return_address, &_registers.__pc);
 #else
     register uint64_t x17 __asm("x17") = value;
     register uint64_t x16 __asm("x16") = getSP();
@@ -1935,7 +1931,8 @@ class _LIBUNWIND_HIDDEN Registers_arm64 {
     uint64_t resignDisc = (uint64_t)&_registers.__pc;
     asm("autib171615\n\t"
         "pacib %0, %3"
-        : "+r"(x17) : "r"(x16), "r"(x15), "r"(resignDisc));
+        : "+r"(x17)
+        : "r"(x16), "r"(x15), "r"(resignDisc));
     value = x17;
 #endif
 #endif
diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp
index 468107f3ded49..9e39b6f8b6e7a 100644
--- a/libunwind/src/UnwindCursor.hpp
+++ b/libunwind/src/UnwindCursor.hpp
@@ -1911,30 +1911,34 @@ bool UnwindCursor<A, 
R>::getInfoFromCompactEncodingSection(
     encoding = pageIndex.encoding(low);
     rangeStart = pageIndex.functionOffset(low) + sects.dso_base;
 
-    // If UNWIND_IS_NOT_FUNCTION_START is set, walk backwards to find the 
actual function start.
+    // If UNWIND_IS_NOT_FUNCTION_START is set, walk backwards to find the 
actual
+    // function start.
     funcStart = rangeStart;
     if (encoding & UNWIND_IS_NOT_FUNCTION_START) {
       uint32_t backIndex = low;
       do {
         --backIndex;
-      } while (backIndex > 0 && (pageIndex.encoding(backIndex) & 
UNWIND_IS_NOT_FUNCTION_START));
+      } while (backIndex > 0 &&
+               (pageIndex.encoding(backIndex) & UNWIND_IS_NOT_FUNCTION_START));
       funcStart = pageIndex.functionOffset(backIndex) + sects.dso_base;
     }
 
     if (pc < funcStart) {
       if (log)
-        fprintf(
-            stderr,
-            "\tpc not in table, pc=0x%llX, funcStart=0x%llX, 
rangeStart=0x%llX, funcEnd=0x%llX\n",
-            (uint64_t) pc, (uint64_t) funcStart, (uint64_t) rangeStart, 
(uint64_t) funcEnd);
+        fprintf(stderr,
+                "\tpc not in table, pc=0x%llX, funcStart=0x%llX, "
+                "rangeStart=0x%llX, funcEnd=0x%llX\n",
+                (uint64_t)pc, (uint64_t)funcStart, (uint64_t)rangeStart,
+                (uint64_t)funcEnd);
       return false;
     }
     if (pc > funcEnd) {
       if (log)
-        fprintf(
-            stderr,
-            "\tpc not in table, pc=0x%llX, funcStart=0x%llX, 
rangeStart=0x%llX, funcEnd=0x%llX\n",
-            (uint64_t) pc, (uint64_t) funcStart, (uint64_t) rangeStart, 
(uint64_t) funcEnd);
+        fprintf(stderr,
+                "\tpc not in table, pc=0x%llX, funcStart=0x%llX, "
+                "rangeStart=0x%llX, funcEnd=0x%llX\n",
+                (uint64_t)pc, (uint64_t)funcStart, (uint64_t)rangeStart,
+                (uint64_t)funcEnd);
       return false;
     }
   } else if (pageKind == UNWIND_SECOND_LEVEL_COMPRESSED) {
@@ -1968,8 +1972,8 @@ bool UnwindCursor<A, 
R>::getInfoFromCompactEncodingSection(
         high = mid;
       }
     }
-    rangeStart = pageIndex.functionOffset(low) + firstLevelFunctionOffset
-                                                              + sects.dso_base;
+    rangeStart = pageIndex.functionOffset(low) + firstLevelFunctionOffset +
+                 sects.dso_base;
     if (low < last)
       funcEnd =
           pageIndex.functionOffset(low + 1) + firstLevelFunctionOffset
@@ -1985,31 +1989,35 @@ bool UnwindCursor<A, 
R>::getInfoFromCompactEncodingSection(
             sectionHeader.commonEncodingsArraySectionOffset() +
             encIdx * sizeof(uint32_t));
       } else {
-        uint16_t pageEncIdx = encIdx - 
(uint16_t)sectionHeader.commonEncodingsArrayCount();
+        uint16_t pageEncIdx =
+            encIdx - (uint16_t)sectionHeader.commonEncodingsArrayCount();
         return _addressSpace.get32(secondLevelAddr +
-                                    pageHeader.encodingsPageOffset() +
-                                    pageEncIdx * sizeof(uint32_t));
+                                   pageHeader.encodingsPageOffset() +
+                                   pageEncIdx * sizeof(uint32_t));
       }
     };
 
     encoding = encodingAtIndex(low);
 
-    // If UNWIND_IS_NOT_FUNCTION_START is set, walk backwards to find the 
actual function start.
+    // If UNWIND_IS_NOT_FUNCTION_START is set, walk backwards to find the 
actual
+    // function start.
     funcStart = rangeStart;
     if (encoding & UNWIND_IS_NOT_FUNCTION_START) {
       uint32_t backIndex = low;
       do {
         --backIndex;
-      } while (backIndex > 0 && (encodingAtIndex(backIndex) & 
UNWIND_IS_NOT_FUNCTION_START));
-      funcStart = pageIndex.functionOffset(backIndex) + 
firstLevelFunctionOffset
-                                                        + sects.dso_base;
+      } while (backIndex > 0 &&
+               (encodingAtIndex(backIndex) & UNWIND_IS_NOT_FUNCTION_START));
+      funcStart = pageIndex.functionOffset(backIndex) +
+                  firstLevelFunctionOffset + sects.dso_base;
     }
 
     if (pc < funcStart) {
       _LIBUNWIND_DEBUG_LOG("malformed __unwind_info, pc=0x%llX "
                            "not in second level compressed unwind table. "
                            "funcStart=0x%llX, rangeStart=0x%llX",
-                            (uint64_t) pc, (uint64_t) funcStart, (uint64_t) 
rangeStart);
+                           (uint64_t)pc, (uint64_t)funcStart,
+                           (uint64_t)rangeStart);
       return false;
     }
     if (pc > funcEnd) {
@@ -2096,8 +2104,8 @@ bool UnwindCursor<A, 
R>::getInfoFromCompactEncodingSection(
                     "encoding=0x%08X, lsda=0x%08llX for funcStart=0x%llX\n",
             (uint64_t) pc, encoding, (uint64_t) lsda, (uint64_t) funcStart);
 
-  // For ARM64 PAuth_LR frames, start_ip should be the pacibsppc address 
(rangeStart).
-  // For all other cases, start_ip should be the function start.
+    // For ARM64 PAuth_LR frames, start_ip should be the pacibsppc address
+    // (rangeStart). For all other cases, start_ip should be the function 
start.
 #if defined(_LIBUNWIND_TARGET_AARCH64)
   if ((encoding & UNWIND_ARM64_MODE_MASK) == UNWIND_ARM64_MODE_FRAME_PAUTH_LR) 
{
     _info.start_ip = rangeStart;

>From 92f161ac8e9608b7756b06f1851ebe428b557320 Mon Sep 17 00:00:00 2001
From: Jon Roelofs <[email protected]>
Date: Thu, 11 Jun 2026 16:29:12 -0700
Subject: [PATCH 3/6] clang-format

---
 libunwind/src/UnwindCursor.hpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp
index 9e39b6f8b6e7a..8707d0df09300 100644
--- a/libunwind/src/UnwindCursor.hpp
+++ b/libunwind/src/UnwindCursor.hpp
@@ -2104,8 +2104,8 @@ bool UnwindCursor<A, 
R>::getInfoFromCompactEncodingSection(
                     "encoding=0x%08X, lsda=0x%08llX for funcStart=0x%llX\n",
             (uint64_t) pc, encoding, (uint64_t) lsda, (uint64_t) funcStart);
 
-    // For ARM64 PAuth_LR frames, start_ip should be the pacibsppc address
-    // (rangeStart). For all other cases, start_ip should be the function 
start.
+  // For ARM64 PAuth_LR frames, start_ip should be the pacibsppc address
+  // (rangeStart). For all other cases, start_ip should be the function start.
 #if defined(_LIBUNWIND_TARGET_AARCH64)
   if ((encoding & UNWIND_ARM64_MODE_MASK) == UNWIND_ARM64_MODE_FRAME_PAUTH_LR) 
{
     _info.start_ip = rangeStart;

>From 7449cc4be758b9f8ad8998cde78e1491679beaa5 Mon Sep 17 00:00:00 2001
From: Jon Roelofs <[email protected]>
Date: Fri, 12 Jun 2026 14:16:52 -0700
Subject: [PATCH 4/6] un-clang-format an enum

---
 .../include/mach-o/compact_unwind_encoding.h  | 42 +++++++++----------
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/libunwind/include/mach-o/compact_unwind_encoding.h 
b/libunwind/include/mach-o/compact_unwind_encoding.h
index 029b781287e02..214acc0330d59 100644
--- a/libunwind/include/mach-o/compact_unwind_encoding.h
+++ b/libunwind/include/mach-o/compact_unwind_encoding.h
@@ -284,27 +284,27 @@ enum {
 //        24-bits offset of DWARF FDE in __eh_frame section
 //
 enum {
-  UNWIND_ARM64_MODE_MASK = 0x0F000000,
-  UNWIND_ARM64_MODE_FRAMELESS = 0x02000000,
-  UNWIND_ARM64_MODE_DWARF = 0x03000000,
-  UNWIND_ARM64_MODE_FRAME = 0x04000000,
-  UNWIND_ARM64_MODE_FRAME_PAUTH_LR = 0x05000000,
-
-  UNWIND_ARM64_PAUTH_LR_OFFSET_MASK = 0x00FFF000,
-  UNWIND_ARM64_PAUTH_LR_OFFSET_SHIFT = 12,
-
-  UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001,
-  UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002,
-  UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004,
-  UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008,
-  UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010,
-  UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100,
-  UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200,
-  UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400,
-  UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800,
-
-  UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK = 0x00FFF000,
-  UNWIND_ARM64_DWARF_SECTION_OFFSET = 0x00FFFFFF,
+    UNWIND_ARM64_MODE_MASK                     = 0x0F000000,
+    UNWIND_ARM64_MODE_FRAMELESS                = 0x02000000,
+    UNWIND_ARM64_MODE_DWARF                    = 0x03000000,
+    UNWIND_ARM64_MODE_FRAME                    = 0x04000000,
+    UNWIND_ARM64_MODE_FRAME_PAUTH_LR           = 0x05000000,
+
+    UNWIND_ARM64_PAUTH_LR_OFFSET_MASK          = 0x00FFF000,
+    UNWIND_ARM64_PAUTH_LR_OFFSET_SHIFT         = 12,
+
+    UNWIND_ARM64_FRAME_X19_X20_PAIR            = 0x00000001,
+    UNWIND_ARM64_FRAME_X21_X22_PAIR            = 0x00000002,
+    UNWIND_ARM64_FRAME_X23_X24_PAIR            = 0x00000004,
+    UNWIND_ARM64_FRAME_X25_X26_PAIR            = 0x00000008,
+    UNWIND_ARM64_FRAME_X27_X28_PAIR            = 0x00000010,
+    UNWIND_ARM64_FRAME_D8_D9_PAIR              = 0x00000100,
+    UNWIND_ARM64_FRAME_D10_D11_PAIR            = 0x00000200,
+    UNWIND_ARM64_FRAME_D12_D13_PAIR            = 0x00000400,
+    UNWIND_ARM64_FRAME_D14_D15_PAIR            = 0x00000800,
+
+    UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK     = 0x00FFF000,
+    UNWIND_ARM64_DWARF_SECTION_OFFSET          = 0x00FFFFFF,
 };
 // For arm64 there are three modes for the compact unwind encoding:
 // UNWIND_ARM64_MODE_FRAME:

>From f17e1540821efe359db1f75dd5d5137c1b3a75e2 Mon Sep 17 00:00:00 2001
From: Jon Roelofs <[email protected]>
Date: Fri, 12 Jun 2026 16:29:01 -0700
Subject: [PATCH 5/6] tell clang-format to go away

---
 libunwind/include/mach-o/compact_unwind_encoding.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/libunwind/include/mach-o/compact_unwind_encoding.h 
b/libunwind/include/mach-o/compact_unwind_encoding.h
index 214acc0330d59..d1770864cf647 100644
--- a/libunwind/include/mach-o/compact_unwind_encoding.h
+++ b/libunwind/include/mach-o/compact_unwind_encoding.h
@@ -41,11 +41,13 @@ typedef uint32_t compact_unwind_encoding_t;
 
 
 // architecture independent bits
+// clang-format off
 enum {
     UNWIND_IS_NOT_FUNCTION_START           = 0x80000000,
     UNWIND_HAS_LSDA                        = 0x40000000,
     UNWIND_PERSONALITY_MASK                = 0x30000000,
 };
+// clang-format on
 
 
 
@@ -67,6 +69,7 @@ enum {
 //        3-bits register count
 //        10-bits register permutation
 //
+// clang-format off
 enum {
     UNWIND_X86_MODE_MASK                         = 0x0F000000,
     UNWIND_X86_MODE_EBP_FRAME                    = 0x01000000,
@@ -84,7 +87,9 @@ enum {
 
     UNWIND_X86_DWARF_SECTION_OFFSET              = 0x00FFFFFF,
 };
+// clang-format on
 
+// clang-format off
 enum {
     UNWIND_X86_REG_NONE     = 0,
     UNWIND_X86_REG_EBX      = 1,
@@ -94,6 +99,7 @@ enum {
     UNWIND_X86_REG_ESI      = 5,
     UNWIND_X86_REG_EBP      = 6,
 };
+// clang-format on
 
 //
 // For x86 there are four modes for the compact unwind encoding:
@@ -202,6 +208,7 @@ enum {
 //        3-bits register count
 //        10-bits register permutation
 //
+// clang-format off
 enum {
     UNWIND_X86_64_MODE_MASK                         = 0x0F000000,
     UNWIND_X86_64_MODE_RBP_FRAME                    = 0x01000000,
@@ -219,7 +226,9 @@ enum {
 
     UNWIND_X86_64_DWARF_SECTION_OFFSET              = 0x00FFFFFF,
 };
+// clang-format on
 
+// clang-format off
 enum {
     UNWIND_X86_64_REG_NONE       = 0,
     UNWIND_X86_64_REG_RBX        = 1,
@@ -229,6 +238,8 @@ enum {
     UNWIND_X86_64_REG_R15        = 5,
     UNWIND_X86_64_REG_RBP        = 6,
 };
+// clang-format on
+
 //
 // For x86_64 there are four modes for the compact unwind encoding:
 // UNWIND_X86_64_MODE_RBP_FRAME:
@@ -283,6 +294,7 @@ enum {
 //  DWARF:
 //        24-bits offset of DWARF FDE in __eh_frame section
 //
+// clang-format off
 enum {
     UNWIND_ARM64_MODE_MASK                     = 0x0F000000,
     UNWIND_ARM64_MODE_FRAMELESS                = 0x02000000,
@@ -306,6 +318,8 @@ enum {
     UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK     = 0x00FFF000,
     UNWIND_ARM64_DWARF_SECTION_OFFSET          = 0x00FFFFFF,
 };
+// clang-format on
+//
 // For arm64 there are three modes for the compact unwind encoding:
 // UNWIND_ARM64_MODE_FRAME:
 //    This is a standard arm64 prolog where FP/LR are immediately pushed on the

>From dfbfbaa341b8a4efae73018924f0efd64e9a87ae Mon Sep 17 00:00:00 2001
From: Jon Roelofs <[email protected]>
Date: Mon, 15 Jun 2026 10:51:10 -0700
Subject: [PATCH 6/6] remove blank lines that clang-format insists on

---
 libunwind/include/mach-o/compact_unwind_encoding.h | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/libunwind/include/mach-o/compact_unwind_encoding.h 
b/libunwind/include/mach-o/compact_unwind_encoding.h
index d1770864cf647..2bfa4dd7b13a1 100644
--- a/libunwind/include/mach-o/compact_unwind_encoding.h
+++ b/libunwind/include/mach-o/compact_unwind_encoding.h
@@ -39,7 +39,6 @@
 //
 typedef uint32_t compact_unwind_encoding_t;
 
-
 // architecture independent bits
 // clang-format off
 enum {
@@ -49,9 +48,6 @@ enum {
 };
 // clang-format on
 
-
-
-
 //
 // x86
 //
@@ -188,9 +184,6 @@ enum {
 //}
 //
 
-
-
-
 //
 // x86_64
 //
@@ -278,7 +271,6 @@ enum {
 //    function.
 //
 
-
 // ARM64
 //
 // 1-bit: start

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to