authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-02-05 10:27:10+01:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-04-04 06:08:09+02:00
loga89b3432563c20b344bdf3f5ec686021e7de5e23
tree12b67346724f57624e181955c067ffe0572ee5c0
parentce754724b31e141688e1203ba7bb0a2538f2b544
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

libunwind: Update to LLVM 20.


7 files changed, 201 insertions(+), 79 deletions(-)

lib/libunwind/src/DwarfInstructions.hpp+47-12
......@@ -74,8 +74,10 @@ private:
7474 __builtin_unreachable();
7575 }
7676#if defined(_LIBUNWIND_TARGET_AARCH64)
77 static bool getRA_SIGN_STATE(A &addressSpace, R registers, pint_t cfa,
78 PrologInfo &prolog);
77 static bool isReturnAddressSigned(A &addressSpace, R registers, pint_t cfa,
78 PrologInfo &prolog);
79 static bool isReturnAddressSignedWithPC(A &addressSpace, R registers,
80 pint_t cfa, PrologInfo &prolog);
7981#endif
8082};
8183
......@@ -173,8 +175,9 @@ v128 DwarfInstructions<A, R>::getSavedVectorRegister(
173175}
174176#if defined(_LIBUNWIND_TARGET_AARCH64)
175177template <typename A, typename R>
176bool DwarfInstructions<A, R>::getRA_SIGN_STATE(A &addressSpace, R registers,
177 pint_t cfa, PrologInfo &prolog) {
178bool DwarfInstructions<A, R>::isReturnAddressSigned(A &addressSpace,
179 R registers, pint_t cfa,
180 PrologInfo &prolog) {
178181 pint_t raSignState;
179182 auto regloc = prolog.savedRegisters[UNW_AARCH64_RA_SIGN_STATE];
180183 if (regloc.location == CFI_Parser<A>::kRegisterUnused)
......@@ -185,6 +188,22 @@ bool DwarfInstructions<A, R>::getRA_SIGN_STATE(A &addressSpace, R registers,
185188 // Only bit[0] is meaningful.
186189 return raSignState & 0x01;
187190}
191
192template <typename A, typename R>
193bool DwarfInstructions<A, R>::isReturnAddressSignedWithPC(A &addressSpace,
194 R registers,
195 pint_t cfa,
196 PrologInfo &prolog) {
197 pint_t raSignState;
198 auto regloc = prolog.savedRegisters[UNW_AARCH64_RA_SIGN_STATE];
199 if (regloc.location == CFI_Parser<A>::kRegisterUnused)
200 raSignState = static_cast<pint_t>(regloc.value);
201 else
202 raSignState = getSavedRegister(addressSpace, registers, cfa, regloc);
203
204 // Only bit[1] is meaningful.
205 return raSignState & 0x02;
206}
188207#endif
189208
190209template <typename A, typename R>
......@@ -288,7 +307,7 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
288307 // restored. autia1716 is used instead of autia as autia1716 assembles
289308 // to a NOP on pre-v8.3a architectures.
290309 if ((R::getArch() == REGISTERS_ARM64) &&
291 getRA_SIGN_STATE(addressSpace, registers, cfa, prolog) &&
310 isReturnAddressSigned(addressSpace, registers, cfa, prolog) &&
292311 returnAddress != 0) {
293312#if !defined(_LIBUNWIND_IS_NATIVE_ONLY)
294313 return UNW_ECROSSRASIGNING;
......@@ -296,13 +315,29 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
296315 register unsigned long long x17 __asm("x17") = returnAddress;
297316 register unsigned long long x16 __asm("x16") = cfa;
298317
299 // These are the autia1716/autib1716 instructions. The hint instructions
300 // are used here as gcc does not assemble autia1716/autib1716 for pre
301 // armv8.3a targets.
302 if (cieInfo.addressesSignedWithBKey)
303 asm("hint 0xe" : "+r"(x17) : "r"(x16)); // autib1716
304 else
305 asm("hint 0xc" : "+r"(x17) : "r"(x16)); // autia1716
318 // We use the hint versions of the authentication instructions below to
319 // ensure they're assembled by the compiler even for targets with no
320 // FEAT_PAuth/FEAT_PAuth_LR support.
321 if (isReturnAddressSignedWithPC(addressSpace, registers, cfa, prolog)) {
322 register unsigned long long x15 __asm("x15") =
323 prolog.ptrAuthDiversifier;
324 if (cieInfo.addressesSignedWithBKey) {
325 asm("hint 0x27\n\t" // pacm
326 "hint 0xe"
327 : "+r"(x17)
328 : "r"(x16), "r"(x15)); // autib1716
329 } else {
330 asm("hint 0x27\n\t" // pacm
331 "hint 0xc"
332 : "+r"(x17)
333 : "r"(x16), "r"(x15)); // autia1716
334 }
335 } else {
336 if (cieInfo.addressesSignedWithBKey)
337 asm("hint 0xe" : "+r"(x17) : "r"(x16)); // autib1716
338 else
339 asm("hint 0xc" : "+r"(x17) : "r"(x16)); // autia1716
340 }
306341 returnAddress = x17;
307342#endif
308343 }
lib/libunwind/src/DwarfParser.hpp+21
......@@ -91,6 +91,9 @@ public:
9191 int64_t cfaExpression; // CFA = expression
9292 uint32_t spExtraArgSize;
9393 RegisterLocation savedRegisters[kMaxRegisterNumber + 1];
94#if defined(_LIBUNWIND_TARGET_AARCH64)
95 pint_t ptrAuthDiversifier;
96#endif
9497 enum class InitializeTime { kLazy, kNormal };
9598
9699 // When saving registers, this data structure is lazily initialized.
......@@ -799,6 +802,24 @@ bool CFI_Parser<A>::parseFDEInstructions(A &addressSpace,
799802 }
800803 break;
801804
805#if defined(_LIBUNWIND_TARGET_AARCH64)
806 case DW_CFA_AARCH64_negate_ra_state_with_pc: {
807 int64_t value =
808 results->savedRegisters[UNW_AARCH64_RA_SIGN_STATE].value ^ 0x3;
809 results->setRegisterValue(UNW_AARCH64_RA_SIGN_STATE, value,
810 initialState);
811 // When calculating the value of the PC, it is assumed that the CFI
812 // instruction is placed before the signing instruction, however it is
813 // placed after. Because of this, we need to take into account the CFI
814 // instruction is one instruction call later than expected, and reduce
815 // the PC value by 4 bytes to compensate.
816 results->ptrAuthDiversifier = fdeInfo.pcStart + codeOffset - 0x4;
817 _LIBUNWIND_TRACE_DWARF(
818 "DW_CFA_AARCH64_negate_ra_state_with_pc(pc=0x%" PRIx64 ")\n",
819 static_cast<uint64_t>(results->ptrAuthDiversifier));
820 } break;
821#endif
822
802823#else
803824 (void)arch;
804825#endif
lib/libunwind/src/Unwind-sjlj.c+1-1
......@@ -408,7 +408,7 @@ _LIBUNWIND_EXPORT uintptr_t
408408_Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) {
409409 _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context;
410410 _LIBUNWIND_TRACE_API("_Unwind_GetLanguageSpecificData(context=%p) "
411 "=> 0x%" PRIuPTR,
411 "=> 0x%" PRIxPTR,
412412 (void *)context, ufc->lsda);
413413 return ufc->lsda;
414414}
lib/libunwind/src/UnwindCursor.hpp+91-35
......@@ -230,8 +230,8 @@ void DwarfFDECache<A>::iterateCacheEntries(void (*func)(
230230}
231231#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
232232
233
234#define arrayoffsetof(type, index, field) ((size_t)(&((type *)0)[index].field))
233#define arrayoffsetof(type, index, field) \
234 (sizeof(type) * (index) + offsetof(type, field))
235235
236236#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
237237template <typename A> class UnwindSectionHeader {
......@@ -1010,6 +1010,9 @@ private:
10101010 template <typename Registers> int stepThroughSigReturn(Registers &) {
10111011 return UNW_STEP_END;
10121012 }
1013#elif defined(_LIBUNWIND_TARGET_HAIKU)
1014 bool setInfoForSigReturn();
1015 int stepThroughSigReturn();
10131016#endif
10141017
10151018#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
......@@ -1313,7 +1316,8 @@ private:
13131316 unw_proc_info_t _info;
13141317 bool _unwindInfoMissing;
13151318 bool _isSignalFrame;
1316#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN)
1319#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \
1320 defined(_LIBUNWIND_TARGET_HAIKU)
13171321 bool _isSigReturn = false;
13181322#endif
13191323};
......@@ -2033,7 +2037,6 @@ typedef _Unwind_Reason_Code __xlcxx_personality_v0_t(int, _Unwind_Action,
20332037 uint64_t,
20342038 _Unwind_Exception *,
20352039 struct _Unwind_Context *);
2036__attribute__((__weak__)) __xlcxx_personality_v0_t __xlcxx_personality_v0;
20372040}
20382041
20392042static __xlcxx_personality_v0_t *xlcPersonalityV0;
......@@ -2126,42 +2129,35 @@ bool UnwindCursor<A, R>::getInfoFromTBTable(pint_t pc, R &registers) {
21262129 // function __xlcxx_personality_v0(), which is the personality for the state
21272130 // table and is exported from libc++abi, is directly assigned as the
21282131 // handler here. When a legacy XLC++ frame is encountered, the symbol
2129 // is resolved dynamically using dlopen() to avoid hard dependency from
2130 // libunwind on libc++abi.
2132 // is resolved dynamically using dlopen() to avoid a hard dependency of
2133 // libunwind on libc++abi in cases such as non-C++ applications.
21312134
21322135 // Resolve the function pointer to the state table personality if it has
2133 // not already.
2136 // not already been done.
21342137 if (xlcPersonalityV0 == NULL) {
21352138 xlcPersonalityV0InitLock.lock();
21362139 if (xlcPersonalityV0 == NULL) {
2137 // If libc++abi is statically linked in, symbol __xlcxx_personality_v0
2138 // has been resolved at the link time.
2139 xlcPersonalityV0 = &__xlcxx_personality_v0;
2140 // Resolve __xlcxx_personality_v0 using dlopen().
2141 const char *libcxxabi = "libc++abi.a(libc++abi.so.1)";
2142 void *libHandle;
2143 // The AIX dlopen() sets errno to 0 when it is successful, which
2144 // clobbers the value of errno from the user code. This is an AIX
2145 // bug because according to POSIX it should not set errno to 0. To
2146 // workaround before AIX fixes the bug, errno is saved and restored.
2147 int saveErrno = errno;
2148 libHandle = dlopen(libcxxabi, RTLD_MEMBER | RTLD_NOW);
2149 if (libHandle == NULL) {
2150 _LIBUNWIND_TRACE_UNWINDING("dlopen() failed with errno=%d\n", errno);
2151 assert(0 && "dlopen() failed");
2152 }
2153 xlcPersonalityV0 = reinterpret_cast<__xlcxx_personality_v0_t *>(
2154 dlsym(libHandle, "__xlcxx_personality_v0"));
21402155 if (xlcPersonalityV0 == NULL) {
2141 // libc++abi is dynamically linked. Resolve __xlcxx_personality_v0
2142 // using dlopen().
2143 const char libcxxabi[] = "libc++abi.a(libc++abi.so.1)";
2144 void *libHandle;
2145 // The AIX dlopen() sets errno to 0 when it is successful, which
2146 // clobbers the value of errno from the user code. This is an AIX
2147 // bug because according to POSIX it should not set errno to 0. To
2148 // workaround before AIX fixes the bug, errno is saved and restored.
2149 int saveErrno = errno;
2150 libHandle = dlopen(libcxxabi, RTLD_MEMBER | RTLD_NOW);
2151 if (libHandle == NULL) {
2152 _LIBUNWIND_TRACE_UNWINDING("dlopen() failed with errno=%d\n",
2153 errno);
2154 assert(0 && "dlopen() failed");
2155 }
2156 xlcPersonalityV0 = reinterpret_cast<__xlcxx_personality_v0_t *>(
2157 dlsym(libHandle, "__xlcxx_personality_v0"));
2158 if (xlcPersonalityV0 == NULL) {
2159 _LIBUNWIND_TRACE_UNWINDING("dlsym() failed with errno=%d\n", errno);
2160 assert(0 && "dlsym() failed");
2161 }
2156 _LIBUNWIND_TRACE_UNWINDING("dlsym() failed with errno=%d\n", errno);
21622157 dlclose(libHandle);
2163 errno = saveErrno;
2158 assert(0 && "dlsym() failed");
21642159 }
2160 errno = saveErrno;
21652161 }
21662162 xlcPersonalityV0InitLock.unlock();
21672163 }
......@@ -2557,7 +2553,8 @@ int UnwindCursor<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable,
25572553
25582554template <typename A, typename R>
25592555void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {
2560#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN)
2556#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \
2557 defined(_LIBUNWIND_TARGET_HAIKU)
25612558 _isSigReturn = false;
25622559#endif
25632560
......@@ -2681,7 +2678,8 @@ void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {
26812678 }
26822679#endif // #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
26832680
2684#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN)
2681#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \
2682 defined(_LIBUNWIND_TARGET_HAIKU)
26852683 if (setInfoForSigReturn())
26862684 return;
26872685#endif
......@@ -2757,6 +2755,63 @@ int UnwindCursor<A, R>::stepThroughSigReturn(Registers_arm64 &) {
27572755 _isSignalFrame = true;
27582756 return UNW_STEP_SUCCESS;
27592757}
2758
2759#elif defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64)
2760#include <commpage_defs.h>
2761#include <signal.h>
2762
2763extern "C" {
2764extern void *__gCommPageAddress;
2765}
2766
2767template <typename A, typename R>
2768bool UnwindCursor<A, R>::setInfoForSigReturn() {
2769#if defined(_LIBUNWIND_TARGET_X86_64)
2770 addr_t signal_handler =
2771 (((addr_t *)__gCommPageAddress)[COMMPAGE_ENTRY_X86_SIGNAL_HANDLER] +
2772 (addr_t)__gCommPageAddress);
2773 addr_t signal_handler_ret = signal_handler + 45;
2774#endif
2775 pint_t pc = static_cast<pint_t>(this->getReg(UNW_REG_IP));
2776 if (pc == signal_handler_ret) {
2777 _info = {};
2778 _info.start_ip = signal_handler;
2779 _info.end_ip = signal_handler_ret;
2780 _isSigReturn = true;
2781 return true;
2782 }
2783 return false;
2784}
2785
2786template <typename A, typename R>
2787int UnwindCursor<A, R>::stepThroughSigReturn() {
2788 _isSignalFrame = true;
2789 pint_t sp = _registers.getSP();
2790#if defined(_LIBUNWIND_TARGET_X86_64)
2791 vregs *regs = (vregs *)(sp + 0x70);
2792
2793 _registers.setRegister(UNW_REG_IP, regs->rip);
2794 _registers.setRegister(UNW_REG_SP, regs->rsp);
2795 _registers.setRegister(UNW_X86_64_RAX, regs->rax);
2796 _registers.setRegister(UNW_X86_64_RDX, regs->rdx);
2797 _registers.setRegister(UNW_X86_64_RCX, regs->rcx);
2798 _registers.setRegister(UNW_X86_64_RBX, regs->rbx);
2799 _registers.setRegister(UNW_X86_64_RSI, regs->rsi);
2800 _registers.setRegister(UNW_X86_64_RDI, regs->rdi);
2801 _registers.setRegister(UNW_X86_64_RBP, regs->rbp);
2802 _registers.setRegister(UNW_X86_64_R8, regs->r8);
2803 _registers.setRegister(UNW_X86_64_R9, regs->r9);
2804 _registers.setRegister(UNW_X86_64_R10, regs->r10);
2805 _registers.setRegister(UNW_X86_64_R11, regs->r11);
2806 _registers.setRegister(UNW_X86_64_R12, regs->r12);
2807 _registers.setRegister(UNW_X86_64_R13, regs->r13);
2808 _registers.setRegister(UNW_X86_64_R14, regs->r14);
2809 _registers.setRegister(UNW_X86_64_R15, regs->r15);
2810 // TODO: XMM
2811#endif
2812
2813 return UNW_STEP_SUCCESS;
2814}
27602815#endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&
27612816 // defined(_LIBUNWIND_TARGET_AARCH64)
27622817
......@@ -2925,7 +2980,8 @@ template <typename A, typename R> int UnwindCursor<A, R>::step(bool stage2) {
29252980
29262981 // Use unwinding info to modify register set as if function returned.
29272982 int result;
2928#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN)
2983#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \
2984 defined(_LIBUNWIND_TARGET_HAIKU)
29292985 if (_isSigReturn) {
29302986 result = this->stepThroughSigReturn();
29312987 } else
lib/libunwind/src/UnwindRegistersRestore.S+6-2
......@@ -658,7 +658,7 @@ DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)
658658 ldp x26,x27, [x0, #0x0D0]
659659 ldp x28,x29, [x0, #0x0E0]
660660 ldr x30, [x0, #0x100] // restore pc into lr
661
661#if defined(__ARM_FP) && __ARM_FP != 0
662662 ldp d0, d1, [x0, #0x110]
663663 ldp d2, d3, [x0, #0x120]
664664 ldp d4, d5, [x0, #0x130]
......@@ -676,7 +676,7 @@ DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)
676676 ldp d28,d29, [x0, #0x1F0]
677677 ldr d30, [x0, #0x200]
678678 ldr d31, [x0, #0x208]
679
679#endif
680680 // Finally, restore sp. This must be done after the last read from the
681681 // context struct, because it is allocated on the stack, and an exception
682682 // could clobber the de-allocated portion of the stack after sp has been
......@@ -1183,7 +1183,11 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_riscv6jumptoEv)
11831183 ILOAD x\i, (RISCV_ISIZE * \i)(a0)
11841184 .endr
11851185 // skip a0 for now
1186#if defined(__riscv_32e)
1187 .irp i,11,12,13,14,15
1188#else
11861189 .irp i,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
1190#endif
11871191 ILOAD x\i, (RISCV_ISIZE * \i)(a0)
11881192 .endr
11891193 ILOAD x10, (RISCV_ISIZE * 10)(a0) // restore a0
lib/libunwind/src/UnwindRegistersSave.S+6
......@@ -746,6 +746,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
746746 str x1, [x0, #0x0F8]
747747 str x30, [x0, #0x100] // store return address as pc
748748 // skip cpsr
749#if defined(__ARM_FP) && __ARM_FP != 0
749750 stp d0, d1, [x0, #0x110]
750751 stp d2, d3, [x0, #0x120]
751752 stp d4, d5, [x0, #0x130]
......@@ -763,6 +764,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
763764 stp d28,d29, [x0, #0x1F0]
764765 str d30, [x0, #0x200]
765766 str d31, [x0, #0x208]
767#endif
766768 mov x0, #0 // return UNW_ESUCCESS
767769 ret
768770
......@@ -1108,7 +1110,11 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
11081110#
11091111DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
11101112 ISTORE x1, (RISCV_ISIZE * 0)(a0) // store ra as pc
1113#if defined(__riscv_32e)
1114 .irp i,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
1115#else
11111116 .irp i,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
1117#endif
11121118 ISTORE x\i, (RISCV_ISIZE * \i)(a0)
11131119 .endr
11141120
lib/libunwind/src/dwarf2.h+29-29
......@@ -18,43 +18,43 @@
1818
1919// DWARF unwind instructions
2020enum {
21 DW_CFA_nop = 0x0,
22 DW_CFA_set_loc = 0x1,
23 DW_CFA_advance_loc1 = 0x2,
24 DW_CFA_advance_loc2 = 0x3,
25 DW_CFA_advance_loc4 = 0x4,
26 DW_CFA_offset_extended = 0x5,
27 DW_CFA_restore_extended = 0x6,
28 DW_CFA_undefined = 0x7,
29 DW_CFA_same_value = 0x8,
30 DW_CFA_register = 0x9,
31 DW_CFA_remember_state = 0xA,
32 DW_CFA_restore_state = 0xB,
33 DW_CFA_def_cfa = 0xC,
34 DW_CFA_def_cfa_register = 0xD,
35 DW_CFA_def_cfa_offset = 0xE,
36 DW_CFA_def_cfa_expression = 0xF,
37 DW_CFA_expression = 0x10,
21 DW_CFA_nop = 0x0,
22 DW_CFA_set_loc = 0x1,
23 DW_CFA_advance_loc1 = 0x2,
24 DW_CFA_advance_loc2 = 0x3,
25 DW_CFA_advance_loc4 = 0x4,
26 DW_CFA_offset_extended = 0x5,
27 DW_CFA_restore_extended = 0x6,
28 DW_CFA_undefined = 0x7,
29 DW_CFA_same_value = 0x8,
30 DW_CFA_register = 0x9,
31 DW_CFA_remember_state = 0xA,
32 DW_CFA_restore_state = 0xB,
33 DW_CFA_def_cfa = 0xC,
34 DW_CFA_def_cfa_register = 0xD,
35 DW_CFA_def_cfa_offset = 0xE,
36 DW_CFA_def_cfa_expression = 0xF,
37 DW_CFA_expression = 0x10,
3838 DW_CFA_offset_extended_sf = 0x11,
39 DW_CFA_def_cfa_sf = 0x12,
40 DW_CFA_def_cfa_offset_sf = 0x13,
41 DW_CFA_val_offset = 0x14,
42 DW_CFA_val_offset_sf = 0x15,
43 DW_CFA_val_expression = 0x16,
44 DW_CFA_advance_loc = 0x40, // high 2 bits are 0x1, lower 6 bits are delta
45 DW_CFA_offset = 0x80, // high 2 bits are 0x2, lower 6 bits are register
46 DW_CFA_restore = 0xC0, // high 2 bits are 0x3, lower 6 bits are register
39 DW_CFA_def_cfa_sf = 0x12,
40 DW_CFA_def_cfa_offset_sf = 0x13,
41 DW_CFA_val_offset = 0x14,
42 DW_CFA_val_offset_sf = 0x15,
43 DW_CFA_val_expression = 0x16,
44 DW_CFA_advance_loc = 0x40, // high 2 bits are 0x1, lower 6 bits are delta
45 DW_CFA_offset = 0x80, // high 2 bits are 0x2, lower 6 bits are register
46 DW_CFA_restore = 0xC0, // high 2 bits are 0x3, lower 6 bits are register
4747
4848 // GNU extensions
49 DW_CFA_GNU_window_save = 0x2D,
50 DW_CFA_GNU_args_size = 0x2E,
49 DW_CFA_GNU_window_save = 0x2D,
50 DW_CFA_GNU_args_size = 0x2E,
5151 DW_CFA_GNU_negative_offset_extended = 0x2F,
5252
5353 // AARCH64 extensions
54 DW_CFA_AARCH64_negate_ra_state = 0x2D
54 DW_CFA_AARCH64_negate_ra_state_with_pc = 0x2C,
55 DW_CFA_AARCH64_negate_ra_state = 0x2D
5556};
5657
57
5858// FSF exception handling Pointer-Encoding constants
5959// Used in CFI augmentation by GCC
6060enum {