authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-08-03 12:50:27+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-09-05 14:54:30+02:00
log5c17ee74127366ad8cc4d4ce82f11aa51899e28a
treef22071af10195611570f07b92921da0df3f2ac30
parente68a75dabdae364cd50daa11c197ab372149e8a7
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

libunwind: update to LLVM 23


18 files changed, 248 insertions(+), 80 deletions(-)

lib/libunwind/include/__libunwind_config.h+1-1
...@@ -9,7 +9,7 @@...@@ -9,7 +9,7 @@
9#ifndef ____LIBUNWIND_CONFIG_H__9#ifndef ____LIBUNWIND_CONFIG_H__
10#define ____LIBUNWIND_CONFIG_H__10#define ____LIBUNWIND_CONFIG_H__
1111
12#define _LIBUNWIND_VERSION 1500012#define _LIBUNWIND_VERSION 230000
1313
14#if defined(__arm__) && !defined(__USING_SJLJ_EXCEPTIONS__) && \14#if defined(__arm__) && !defined(__USING_SJLJ_EXCEPTIONS__) && \
15 !defined(__ARM_DWARF_EH__) && !defined(__SEH__)15 !defined(__ARM_DWARF_EH__) && !defined(__SEH__)
lib/libunwind/include/libunwind.h+1-1
...@@ -122,7 +122,7 @@...@@ -122,7 +122,7 @@
122 __unwind_ptrauth_restricted_intptr(ptrauth_key_function_pointer, 1, \122 __unwind_ptrauth_restricted_intptr(ptrauth_key_function_pointer, 1, \
123 __ptrauth_unwind_cie_info_personality_disc)123 __ptrauth_unwind_cie_info_personality_disc)
124124
125 // ptrauth_string_discriminator("personality") == 0x7EAD)125 // ptrauth_string_discriminator("personality") == 0x7EAD
126 #define __ptrauth_unwind_pauthtest_personality_disc 0x7EAD126 #define __ptrauth_unwind_pauthtest_personality_disc 0x7EAD
127127
128#else128#else
lib/libunwind/include/mach-o/compact_unwind_encoding.h+1-1
...@@ -443,7 +443,7 @@ struct unwind_info_section_header_lsda_index_entry...@@ -443,7 +443,7 @@ struct unwind_info_section_header_lsda_index_entry
443443
444struct unwind_info_regular_second_level_entry444struct unwind_info_regular_second_level_entry
445{445{
446 uint32_t functionOffset;446 uint32_t functionOffset;
447 compact_unwind_encoding_t encoding;447 compact_unwind_encoding_t encoding;
448};448};
449449
lib/libunwind/include/unwind_itanium.h+1-1
...@@ -32,7 +32,7 @@ struct _Unwind_Exception {...@@ -32,7 +32,7 @@ struct _Unwind_Exception {
32 // The implementation of _Unwind_Exception uses an attribute mode on the32 // The implementation of _Unwind_Exception uses an attribute mode on the
33 // above fields which has the side effect of causing this whole struct to33 // above fields which has the side effect of causing this whole struct to
34 // round up to 32 bytes in size (48 with SEH). To be more explicit, we add34 // round up to 32 bytes in size (48 with SEH). To be more explicit, we add
35 // pad fields added for binary compatibility.35 // pad fields for binary compatibility.
36 uint32_t reserved[3];36 uint32_t reserved[3];
37#endif37#endif
38 // The Itanium ABI requires that _Unwind_Exception objects are "double-word38 // The Itanium ABI requires that _Unwind_Exception objects are "double-word
lib/libunwind/src/AddressSpace.hpp-1
...@@ -666,7 +666,6 @@ inline bool LocalAddressSpace::findUnwindSections(...@@ -666,7 +666,6 @@ inline bool LocalAddressSpace::findUnwindSections(
666 return true;666 return true;
667 }667 }
668#endif668#endif
669 // zig patch: https://github.com/llvm/llvm-project/issues/194228
670 dl_iterate_cb_data cb_data = {this, &info, static_cast<pint_t>(targetAddr)};669 dl_iterate_cb_data cb_data = {this, &info, static_cast<pint_t>(targetAddr)};
671 int found = dl_iterate_phdr(findUnwindSectionsByPhdr, &cb_data);670 int found = dl_iterate_phdr(findUnwindSectionsByPhdr, &cb_data);
672 return static_cast<bool>(found);671 return static_cast<bool>(found);
lib/libunwind/src/CompactUnwinder.hpp+5-4
...@@ -12,6 +12,7 @@...@@ -12,6 +12,7 @@
12#ifndef __COMPACT_UNWINDER_HPP__12#ifndef __COMPACT_UNWINDER_HPP__
13#define __COMPACT_UNWINDER_HPP__13#define __COMPACT_UNWINDER_HPP__
1414
15#include <inttypes.h>
15#include <stdint.h>16#include <stdint.h>
16#include <stdlib.h>17#include <stdlib.h>
1718
...@@ -335,8 +336,8 @@ int CompactUnwinder_x86_64<A>::stepWithCompactEncodingRBPFrame(...@@ -335,8 +336,8 @@ int CompactUnwinder_x86_64<A>::stepWithCompactEncodingRBPFrame(
335 default:336 default:
336 (void)functionStart;337 (void)functionStart;
337 _LIBUNWIND_DEBUG_LOG("bad register for RBP frame, encoding=%08X for "338 _LIBUNWIND_DEBUG_LOG("bad register for RBP frame, encoding=%08X for "
338 "function starting at 0x%llX",339 "function starting at 0x%" PRIu64 "X",
339 compactEncoding, functionStart);340 compactEncoding, functionStart);
340 _LIBUNWIND_ABORT("invalid compact unwind encoding");341 _LIBUNWIND_ABORT("invalid compact unwind encoding");
341 }342 }
342 savedRegisters += 8;343 savedRegisters += 8;
...@@ -454,8 +455,8 @@ int CompactUnwinder_x86_64<A>::stepWithCompactEncodingFrameless(...@@ -454,8 +455,8 @@ int CompactUnwinder_x86_64<A>::stepWithCompactEncodingFrameless(
454 break;455 break;
455 default:456 default:
456 _LIBUNWIND_DEBUG_LOG("bad register for frameless, encoding=%08X for "457 _LIBUNWIND_DEBUG_LOG("bad register for frameless, encoding=%08X for "
457 "function starting at 0x%llX",458 "function starting at 0x%" PRIu64 "X",
458 encoding, functionStart);459 encoding, functionStart);
459 _LIBUNWIND_ABORT("invalid compact unwind encoding");460 _LIBUNWIND_ABORT("invalid compact unwind encoding");
460 }461 }
461 savedRegisters += 8;462 savedRegisters += 8;
lib/libunwind/src/DwarfInstructions.hpp+17-26
...@@ -76,10 +76,14 @@ private:...@@ -76,10 +76,14 @@ private:
76 __builtin_unreachable();76 __builtin_unreachable();
77 }77 }
78#if defined(_LIBUNWIND_TARGET_AARCH64)78#if defined(_LIBUNWIND_TARGET_AARCH64)
79 static bool isReturnAddressSigned(A &addressSpace, R registers, pint_t cfa,79 enum RASignStatus {
80 PrologInfo &prolog);80 RANotSigned = 0,
81 static bool isReturnAddressSignedWithPC(A &addressSpace, R registers,81 RASigned = 1,
82 pint_t cfa, PrologInfo &prolog);82 RASignedWithPC = 2,
83 };
84 static RASignStatus getReturnAddressSignStatus(A &addressSpace, R registers,
85 pint_t cfa,
86 PrologInfo &prolog);
83#endif87#endif
84};88};
8589
...@@ -177,7 +181,8 @@ v128 DwarfInstructions<A, R>::getSavedVectorRegister(...@@ -177,7 +181,8 @@ v128 DwarfInstructions<A, R>::getSavedVectorRegister(
177}181}
178#if defined(_LIBUNWIND_TARGET_AARCH64)182#if defined(_LIBUNWIND_TARGET_AARCH64)
179template <typename A, typename R>183template <typename A, typename R>
180bool DwarfInstructions<A, R>::isReturnAddressSigned(A &addressSpace,184typename DwarfInstructions<A, R>::RASignStatus
185DwarfInstructions<A, R>::getReturnAddressSignStatus(A &addressSpace,
181 R registers, pint_t cfa,186 R registers, pint_t cfa,
182 PrologInfo &prolog) {187 PrologInfo &prolog) {
183 pint_t raSignState;188 pint_t raSignState;
...@@ -187,24 +192,9 @@ bool DwarfInstructions<A, R>::isReturnAddressSigned(A &addressSpace,...@@ -187,24 +192,9 @@ bool DwarfInstructions<A, R>::isReturnAddressSigned(A &addressSpace,
187 else192 else
188 raSignState = getSavedRegister(addressSpace, registers, cfa, regloc);193 raSignState = getSavedRegister(addressSpace, registers, cfa, regloc);
189194
190 // Only bit[0] is meaningful.195 // bits[1:0] describe how RA is signed.
191 return raSignState & 0x01;196 assert((raSignState & 0x3) != 3 && "unexpected RA sign state");
192}197 return static_cast<RASignStatus>(raSignState & 0x3);
193
194template <typename A, typename R>
195bool DwarfInstructions<A, R>::isReturnAddressSignedWithPC(A &addressSpace,
196 R registers,
197 pint_t cfa,
198 PrologInfo &prolog) {
199 pint_t raSignState;
200 auto regloc = prolog.savedRegisters[UNW_AARCH64_RA_SIGN_STATE];
201 if (regloc.location == CFI_Parser<A>::kRegisterUnused)
202 raSignState = static_cast<pint_t>(regloc.value);
203 else
204 raSignState = getSavedRegister(addressSpace, registers, cfa, regloc);
205
206 // Only bit[1] is meaningful.
207 return raSignState & 0x02;
208}198}
209#endif199#endif
210200
...@@ -317,8 +307,9 @@ int DwarfInstructions<A, R>::stepWithDwarf(...@@ -317,8 +307,9 @@ int DwarfInstructions<A, R>::stepWithDwarf(
317 // return address needs to be authenticated before the return address is307 // return address needs to be authenticated before the return address is
318 // restored. autia1716 is used instead of autia as autia1716 assembles308 // restored. autia1716 is used instead of autia as autia1716 assembles
319 // to a NOP on pre-v8.3a architectures.309 // to a NOP on pre-v8.3a architectures.
320 if ((R::getArch() == REGISTERS_ARM64) &&310 RASignStatus RAState =
321 isReturnAddressSigned(addressSpace, registers, cfa, prolog) &&311 getReturnAddressSignStatus(addressSpace, registers, cfa, prolog);
312 if ((R::getArch() == REGISTERS_ARM64) && RAState != RANotSigned &&
322 returnAddress != 0) {313 returnAddress != 0) {
323#if !defined(_LIBUNWIND_IS_NATIVE_ONLY)314#if !defined(_LIBUNWIND_IS_NATIVE_ONLY)
324 return UNW_ECROSSRASIGNING;315 return UNW_ECROSSRASIGNING;
...@@ -329,7 +320,7 @@ int DwarfInstructions<A, R>::stepWithDwarf(...@@ -329,7 +320,7 @@ int DwarfInstructions<A, R>::stepWithDwarf(
329 // We use the hint versions of the authentication instructions below to320 // We use the hint versions of the authentication instructions below to
330 // ensure they're assembled by the compiler even for targets with no321 // ensure they're assembled by the compiler even for targets with no
331 // FEAT_PAuth/FEAT_PAuth_LR support.322 // FEAT_PAuth/FEAT_PAuth_LR support.
332 if (isReturnAddressSignedWithPC(addressSpace, registers, cfa, prolog)) {323 if (RAState == RASignedWithPC) {
333 register unsigned long long x15 __asm("x15") =324 register unsigned long long x15 __asm("x15") =
334 prolog.ptrAuthDiversifier;325 prolog.ptrAuthDiversifier;
335 if (cieInfo.addressesSignedWithBKey) {326 if (cieInfo.addressesSignedWithBKey) {
lib/libunwind/src/DwarfParser.hpp-1
...@@ -473,7 +473,6 @@ bool CFI_Parser<A>::parseFDEInstructions(...@@ -473,7 +473,6 @@ bool CFI_Parser<A>::parseFDEInstructions(
473 pint_t pcoffset;473 pint_t pcoffset;
474 };474 };
475475
476 // zig patch: https://github.com/llvm/llvm-project/issues/194228
477 ParseInfo parseInfoArray[] = {476 ParseInfo parseInfoArray[] = {
478 {cieInfo.cieInstructions, cieInfo.cieStart + cieInfo.cieLength,477 {cieInfo.cieInstructions, cieInfo.cieStart + cieInfo.cieLength,
479 (pint_t)(-1)},478 (pint_t)(-1)},
lib/libunwind/src/FrameHeaderCache.hpp+1-1
...@@ -24,7 +24,7 @@...@@ -24,7 +24,7 @@
24#define _LIBUNWIND_FRAMEHEADERCACHE_TRACE(msg, ...)24#define _LIBUNWIND_FRAMEHEADERCACHE_TRACE(msg, ...)
25#endif25#endif
2626
27// This cache should only be be used from within a dl_iterate_phdr callback.27// This cache should only be used from within a dl_iterate_phdr callback.
28// dl_iterate_phdr does the necessary synchronization to prevent problems28// dl_iterate_phdr does the necessary synchronization to prevent problems
29// with concurrent access via the libc load lock. Adding synchronization29// with concurrent access via the libc load lock. Adding synchronization
30// for other uses is possible, but not currently done.30// for other uses is possible, but not currently done.
lib/libunwind/src/Registers.hpp+17-6
...@@ -20,6 +20,9 @@...@@ -20,6 +20,9 @@
20#include "libunwind_ext.h"20#include "libunwind_ext.h"
21#include "shadow_stack_unwind.h"21#include "shadow_stack_unwind.h"
2222
23#if defined(__APPLE__)
24#include <sys/sysctl.h>
25#endif
23#if defined(_LIBUNWIND_HAVE_GETAUXVAL) || defined(_LIBUNWIND_HAVE_ELF_AUX_INFO)26#if defined(_LIBUNWIND_HAVE_GETAUXVAL) || defined(_LIBUNWIND_HAVE_ELF_AUX_INFO)
24#include <sys/auxv.h>27#include <sys/auxv.h>
25#endif28#endif
...@@ -1892,7 +1895,7 @@ public:...@@ -1892,7 +1895,7 @@ public:
1892 uint64_t value = _registers.__pc;1895 uint64_t value = _registers.__pc;
1893#if defined(_LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING)1896#if defined(_LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING)
1894 // Note the value of the PC was signed to its address in the register state1897 // Note the value of the PC was signed to its address in the register state
1895 // but everyone else expects it to be sign by the SP, so convert on return.1898 // but everyone else expects it to be signed by the SP, so convert on return.
1896 value = (uint64_t)ptrauth_auth_and_resign((void *)_registers.__pc,1899 value = (uint64_t)ptrauth_auth_and_resign((void *)_registers.__pc,
1897 ptrauth_key_return_address,1900 ptrauth_key_return_address,
1898 &_registers.__pc,1901 &_registers.__pc,
...@@ -1940,7 +1943,15 @@ private:...@@ -1940,7 +1943,15 @@ private:
1940 _LIBUNWIND_ABORT("SME ZA disable failed");1943 _LIBUNWIND_ABORT("SME ZA disable failed");
1941 }1944 }
19421945
1943#if defined(_LIBUNWIND_HAVE_GETAUXVAL)1946#if defined(__APPLE__)
1947 static bool checkHasSME() {
1948 int has_sme = 0;
1949 size_t size = sizeof(has_sme);
1950 if (sysctlbyname("hw.optional.arm.FEAT_SME", &has_sme, &size, NULL, 0))
1951 return false;
1952 return has_sme != 0;
1953 }
1954#elif defined(_LIBUNWIND_HAVE_GETAUXVAL)
1944 static bool checkHasSME() {1955 static bool checkHasSME() {
1945 constexpr int hwcap2_sme = (1 << 23);1956 constexpr int hwcap2_sme = (1 << 23);
1946 unsigned long hwcap2 = getauxval(AT_HWCAP2);1957 unsigned long hwcap2 = getauxval(AT_HWCAP2);
...@@ -3724,21 +3735,21 @@ inline void Registers_sparc::setRegister(int regNum, uint32_t value) {...@@ -3724,21 +3735,21 @@ inline void Registers_sparc::setRegister(int regNum, uint32_t value) {
3724inline bool Registers_sparc::validFloatRegister(int) const { return false; }3735inline bool Registers_sparc::validFloatRegister(int) const { return false; }
37253736
3726inline double Registers_sparc::getFloatRegister(int) const {3737inline double Registers_sparc::getFloatRegister(int) const {
3727 _LIBUNWIND_ABORT("no Sparc float registers");3738 _LIBUNWIND_ABORT("no sparc float registers");
3728}3739}
37293740
3730inline void Registers_sparc::setFloatRegister(int, double) {3741inline void Registers_sparc::setFloatRegister(int, double) {
3731 _LIBUNWIND_ABORT("no Sparc float registers");3742 _LIBUNWIND_ABORT("no sparc float registers");
3732}3743}
37333744
3734inline bool Registers_sparc::validVectorRegister(int) const { return false; }3745inline bool Registers_sparc::validVectorRegister(int) const { return false; }
37353746
3736inline v128 Registers_sparc::getVectorRegister(int) const {3747inline v128 Registers_sparc::getVectorRegister(int) const {
3737 _LIBUNWIND_ABORT("no Sparc vector registers");3748 _LIBUNWIND_ABORT("no sparc vector registers");
3738}3749}
37393750
3740inline void Registers_sparc::setVectorRegister(int, v128) {3751inline void Registers_sparc::setVectorRegister(int, v128) {
3741 _LIBUNWIND_ABORT("no Sparc vector registers");3752 _LIBUNWIND_ABORT("no sparc vector registers");
3742}3753}
37433754
3744inline const char *Registers_sparc::getRegisterName(int regNum) {3755inline const char *Registers_sparc::getRegisterName(int regNum) {
lib/libunwind/src/Unwind-wasm.c+20-3
...@@ -54,7 +54,7 @@ _Unwind_Reason_Code _Unwind_CallPersonality(void *exception_ptr) {...@@ -54,7 +54,7 @@ _Unwind_Reason_Code _Unwind_CallPersonality(void *exception_ptr) {
54 __wasm_lpad_context.selector = 0;54 __wasm_lpad_context.selector = 0;
5555
56 // Call personality function. Wasm does not have two-phase unwinding, so we56 // Call personality function. Wasm does not have two-phase unwinding, so we
57 // only do the cleanup phase.57 // only do the search phase.
58 return __gxx_personality_wasm0(58 return __gxx_personality_wasm0(
59 1, _UA_SEARCH_PHASE, exception_object->exception_class, exception_object,59 1, _UA_SEARCH_PHASE, exception_object->exception_class, exception_object,
60 (struct _Unwind_Context *)&__wasm_lpad_context);60 (struct _Unwind_Context *)&__wasm_lpad_context);
...@@ -69,6 +69,21 @@ _Unwind_RaiseException(_Unwind_Exception *exception_object) {...@@ -69,6 +69,21 @@ _Unwind_RaiseException(_Unwind_Exception *exception_object) {
69 __builtin_wasm_throw(0, exception_object);69 __builtin_wasm_throw(0, exception_object);
70}70}
7171
72// Define the `__cpp_exception` symbol which `__builtin_wasm_throw` above will
73// reference. This is defined here in `libunwind` as the single canonical
74// definition for this API and it's required for users to ensure that there's
75// only one copy of `libunwind` within a wasm module to ensure this is only
76// defined once and exactly once.
77__asm__(".globl __cpp_exception\n"
78#if defined(__wasm32__)
79 ".tagtype __cpp_exception i32\n"
80#elif defined(__wasm64__)
81 ".tagtype __cpp_exception i64\n"
82#else
83#error "Unsupported Wasm architecture"
84#endif
85 "__cpp_exception:\n");
86
72/// Called by __cxa_end_catch.87/// Called by __cxa_end_catch.
73_LIBUNWIND_EXPORT void88_LIBUNWIND_EXPORT void
74_Unwind_DeleteException(_Unwind_Exception *exception_object) {89_Unwind_DeleteException(_Unwind_Exception *exception_object) {
...@@ -102,7 +117,8 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) {...@@ -102,7 +117,8 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) {
102}117}
103118
104/// Not used in Wasm.119/// Not used in Wasm.
105_LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *, uintptr_t) {}120_LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context,
121 uintptr_t value) {}
106122
107/// Called by personality handler to get LSDA for current frame.123/// Called by personality handler to get LSDA for current frame.
108_LIBUNWIND_EXPORT uintptr_t124_LIBUNWIND_EXPORT uintptr_t
...@@ -114,7 +130,8 @@ _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) {...@@ -114,7 +130,8 @@ _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) {
114}130}
115131
116/// Not used in Wasm.132/// Not used in Wasm.
117_LIBUNWIND_EXPORT uintptr_t _Unwind_GetRegionStart(struct _Unwind_Context *) {133_LIBUNWIND_EXPORT uintptr_t
134_Unwind_GetRegionStart(struct _Unwind_Context *context) {
118 return 0;135 return 0;
119}136}
120137
lib/libunwind/src/UnwindCursor.hpp+119-7
...@@ -963,7 +963,7 @@ template <typename A, typename R> bool UnwindCursor<A, R>::isSignalFrame() {...@@ -963,7 +963,7 @@ template <typename A, typename R> bool UnwindCursor<A, R>::isSignalFrame() {
963/// UnwindCursor contains all state (including all register values) during963/// UnwindCursor contains all state (including all register values) during
964/// an unwind. This is normally stack allocated inside a unw_cursor_t.964/// an unwind. This is normally stack allocated inside a unw_cursor_t.
965template <typename A, typename R>965template <typename A, typename R>
966class UnwindCursor : public AbstractUnwindCursor{966class UnwindCursor : public AbstractUnwindCursor {
967 typedef typename A::pint_t pint_t;967 typedef typename A::pint_t pint_t;
968public:968public:
969 UnwindCursor(unw_context_t *context, A &as);969 UnwindCursor(unw_context_t *context, A &as);
...@@ -1363,6 +1363,10 @@ private:...@@ -1363,6 +1363,10 @@ private:
1363 reinterpret_cast<tbtable *>(_info.unwind_info),1363 reinterpret_cast<tbtable *>(_info.unwind_info),
1364 _registers, _isSignalFrame);1364 _registers, _isSignalFrame);
1365 }1365 }
1366 bool isKnownVapiNotActive() const { return _isKnownVapiNotActive; }
1367 void setIsKnownVapiNotActive(bool val) { _isKnownVapiNotActive = val; }
1368 static pint_t getVAPILR();
1369
1366#endif // defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND)1370#endif // defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND)
13671371
1368 A &_addressSpace;1372 A &_addressSpace;
...@@ -1377,13 +1381,23 @@ private:...@@ -1377,13 +1381,23 @@ private:
1377#ifdef _LIBUNWIND_TRACE_RET_INJECT1381#ifdef _LIBUNWIND_TRACE_RET_INJECT
1378 uint32_t _walkedFrames;1382 uint32_t _walkedFrames;
1379#endif1383#endif
1384#if defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND)
1385 // TODO: this will need to be recorded in the unw_context_t by unw_getcontext
1386 // to support cases where the cursor is retrieved prior to invocation of the
1387 // Virtual API.
1388 bool _isKnownVapiNotActive;
1389#endif
1380};1390};
13811391
1382
1383template <typename A, typename R>1392template <typename A, typename R>
1384UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as)1393UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as)
1385 : _addressSpace(as), _registers(context), _unwindInfoMissing(false),1394 : _addressSpace(as), _registers(context), _unwindInfoMissing(false),
1386 _isSignalFrame(false) {1395 _isSignalFrame(false)
1396#if defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND)
1397 ,
1398 _isKnownVapiNotActive(false)
1399#endif
1400{
1387 static_assert((check_fit<UnwindCursor<A, R>, unw_cursor_t>::does_fit),1401 static_assert((check_fit<UnwindCursor<A, R>, unw_cursor_t>::does_fit),
1388 "UnwindCursor<> does not fit in unw_cursor_t");1402 "UnwindCursor<> does not fit in unw_cursor_t");
1389 static_assert((alignof(UnwindCursor<A, R>) <= alignof(unw_cursor_t)),1403 static_assert((alignof(UnwindCursor<A, R>) <= alignof(unw_cursor_t)),
...@@ -1393,13 +1407,17 @@ UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as)...@@ -1393,13 +1407,17 @@ UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as)
13931407
1394template <typename A, typename R>1408template <typename A, typename R>
1395UnwindCursor<A, R>::UnwindCursor(A &as, void *)1409UnwindCursor<A, R>::UnwindCursor(A &as, void *)
1396 : _addressSpace(as), _unwindInfoMissing(false), _isSignalFrame(false) {1410 : _addressSpace(as), _unwindInfoMissing(false), _isSignalFrame(false)
1411#if defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND)
1412 ,
1413 _isKnownVapiNotActive(false)
1414#endif
1415{
1397 memset(static_cast<void *>(&_info), 0, sizeof(_info));1416 memset(static_cast<void *>(&_info), 0, sizeof(_info));
1398 // FIXME1417 // FIXME
1399 // fill in _registers from thread arg1418 // fill in _registers from thread arg
1400}1419}
14011420
1402
1403template <typename A, typename R>1421template <typename A, typename R>
1404bool UnwindCursor<A, R>::validReg(int regNum) {1422bool UnwindCursor<A, R>::validReg(int regNum) {
1405 return _registers.validRegister(regNum);1423 return _registers.validRegister(regNum);
...@@ -1469,6 +1487,30 @@ template <typename A, typename R> void UnwindCursor<A, R>::jumpto() {...@@ -1469,6 +1487,30 @@ template <typename A, typename R> void UnwindCursor<A, R>::jumpto() {
1469 static constexpr size_t _EXTRA_LIBUNWIND_FRAMES_WALKED = 5 - 1;1487 static constexpr size_t _EXTRA_LIBUNWIND_FRAMES_WALKED = 5 - 1;
1470 _registers.returnto(_walkedFrames + _EXTRA_LIBUNWIND_FRAMES_WALKED);1488 _registers.returnto(_walkedFrames + _EXTRA_LIBUNWIND_FRAMES_WALKED);
1471#else1489#else
1490#if defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND)
1491 if (isKnownVapiNotActive()) {
1492 // If the current frame is known VAPI not active, execute the VAPI return
1493 // glue to clear the VAPI control block. The VAPI return glue is used by
1494 // AIX longjmp based on the VAPI active status recorded by setjmp in the
1495 // jmp_buf, which means that the VAPI return glue can be called solely on
1496 // the basis of the VAPI active status of the target context.
1497
1498 // VAPI return glue address is the VAPI glue address - 4.
1499#ifdef __64BIT__
1500 constexpr pint_t VAPIReturnGlue = 0x8e40 - 4;
1501#else
1502 constexpr pint_t VAPIReturnGlue = 0x8c40 - 4;
1503#endif
1504
1505 _LIBUNWIND_TRACE_UNWINDING("VAPI: executing return glue %p\n",
1506 reinterpret_cast<void *>(VAPIReturnGlue));
1507 register auto *registers __asm__("r30") = &_registers;
1508 __asm__ __volatile__("bla %[retglue]"
1509 : "+r"(registers)
1510 : [retglue] "i"(VAPIReturnGlue));
1511 registers->jumpto();
1512 }
1513#endif // defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND)
1472 _registers.jumpto();1514 _registers.jumpto();
1473#endif1515#endif
1474}1516}
...@@ -2037,7 +2079,7 @@ bool UnwindCursor<A, R>::getInfoFromCompactEncodingSection(...@@ -2037,7 +2079,7 @@ bool UnwindCursor<A, R>::getInfoFromCompactEncodingSection(
2037 if (personalityIndex != 0) {2079 if (personalityIndex != 0) {
2038 --personalityIndex; // change 1-based to zero-based index2080 --personalityIndex; // change 1-based to zero-based index
2039 if (personalityIndex >= sectionHeader.personalityArrayCount()) {2081 if (personalityIndex >= sectionHeader.personalityArrayCount()) {
2040 _LIBUNWIND_DEBUG_LOG("found encoding 0x%08X with personality index %d, "2082 _LIBUNWIND_DEBUG_LOG("found encoding 0x%08X with personality index %d, "
2041 "but personality table has only %d entries",2083 "but personality table has only %d entries",
2042 encoding, personalityIndex,2084 encoding, personalityIndex,
2043 sectionHeader.personalityArrayCount());2085 sectionHeader.personalityArrayCount());
...@@ -2459,6 +2501,45 @@ bool UnwindCursor<A, R>::getInfoFromTBTable(pint_t pc, R &registers) {...@@ -2459,6 +2501,45 @@ bool UnwindCursor<A, R>::getInfoFromTBTable(pint_t pc, R &registers) {
2459 return true;2501 return true;
2460}2502}
24612503
2504// VAPI glue addresses
2505constexpr uintptr_t vapi_glue_addr_ext_32 = 0x8b80;
2506constexpr uintptr_t vapi_addr_64 = 0x8e00;
2507constexpr size_t vapi_size_64 = 0x0200;
2508constexpr uintptr_t vapi_glue_addr_begin =
2509 vapi_glue_addr_ext_32; // Start address in 32-bit
2510constexpr uintptr_t vapi_glue_addr_end =
2511 vapi_addr_64 + vapi_size_64; // End address in 64-bit
2512
2513#ifdef __64BIT__
2514constexpr size_t VAPI_CB_SIZE = 256;
2515constexpr ptrdiff_t TLS_POINTER_OFFSET = 30 * 1024;
2516constexpr size_t TLSCB_BASE_SIZE = 256;
2517
2518static __inline__ __attribute__((__always_inline__)) char *tptr(void) {
2519 char *result;
2520 __asm__("mr %0, 13" : "=r"(result));
2521 return result;
2522}
2523#else // 32-bit
2524constexpr size_t VAPI_CB_SIZE = 128;
2525constexpr ptrdiff_t TLS_POINTER_OFFSET = 31 * 1024;
2526constexpr size_t TLSCB_BASE_SIZE = 128;
2527
2528static __inline__ __attribute__((__always_inline__)) char *tptr(void) {
2529 char *result;
2530 __asm__("mfspr %0, 259" : "=r"(result));
2531 return result;
2532}
2533#endif
2534
2535constexpr ptrdiff_t VAPI_CB_OFFSET =
2536 TLS_POINTER_OFFSET + VAPI_CB_SIZE + TLSCB_BASE_SIZE;
2537
2538template <typename A, typename R>
2539typename UnwindCursor<A, R>::pint_t UnwindCursor<A, R>::getVAPILR() {
2540 return *reinterpret_cast<pint_t *>(tptr() - VAPI_CB_OFFSET + 8);
2541}
2542
2462// Step back up the stack following the frame back link.2543// Step back up the stack following the frame back link.
2463template <typename A, typename R>2544template <typename A, typename R>
2464int UnwindCursor<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable,2545int UnwindCursor<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable,
...@@ -2511,6 +2592,16 @@ int UnwindCursor<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable,...@@ -2511,6 +2592,16 @@ int UnwindCursor<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable,
2511 _LIBUNWIND_TRACE_UNWINDING("Possible signal handler frame: lastStack=%p",2592 _LIBUNWIND_TRACE_UNWINDING("Possible signal handler frame: lastStack=%p",
2512 reinterpret_cast<void *>(lastStack));2593 reinterpret_cast<void *>(lastStack));
25132594
2595 pint_t returnAddressInStack = reinterpret_cast<pint_t *>(lastStack)[2];
2596 if (vapi_glue_addr_begin <= returnAddressInStack &&
2597 returnAddressInStack < vapi_glue_addr_end) {
2598 _LIBUNWIND_TRACE_UNWINDING(
2599 "The return address in stack %p is within the range of VAPI address;"
2600 " set isKnownVapiNotActive to true\n",
2601 reinterpret_cast<void *>(returnAddressInStack));
2602 setIsKnownVapiNotActive(true);
2603 }
2604
2514 sigcontext *sigContext = reinterpret_cast<sigcontext *>(2605 sigcontext *sigContext = reinterpret_cast<sigcontext *>(
2515 reinterpret_cast<char *>(lastStack) + STKMINALIGN);2606 reinterpret_cast<char *>(lastStack) + STKMINALIGN);
2516 returnAddress = sigContext->sc_jmpbuf.jmp_context.iar;2607 returnAddress = sigContext->sc_jmpbuf.jmp_context.iar;
...@@ -2579,6 +2670,17 @@ int UnwindCursor<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable,...@@ -2579,6 +2670,17 @@ int UnwindCursor<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable,
2579 } else {2670 } else {
2580 // Otherwise, use the LR value in the stack link area.2671 // Otherwise, use the LR value in the stack link area.
2581 returnAddress = reinterpret_cast<pint_t *>(lastStack)[2];2672 returnAddress = reinterpret_cast<pint_t *>(lastStack)[2];
2673
2674 if (vapi_glue_addr_begin <= returnAddress &&
2675 returnAddress < vapi_glue_addr_end) {
2676 _LIBUNWIND_TRACE_UNWINDING(
2677 "The return address=%p is within the range of VAPI address;",
2678 reinterpret_cast<void *>(returnAddress));
2679 setIsKnownVapiNotActive(true);
2680 returnAddress = getVAPILR();
2681 _LIBUNWIND_TRACE_UNWINDING("return address=%p from VAPI\n",
2682 reinterpret_cast<void *>(returnAddress));
2683 }
2582 }2684 }
25832685
2584 // Reset LR in the current context.2686 // Reset LR in the current context.
...@@ -2709,6 +2811,16 @@ int UnwindCursor<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable,...@@ -2709,6 +2811,16 @@ int UnwindCursor<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable,
2709 // Return address is the address after call site instruction.2811 // Return address is the address after call site instruction.
2710 pint_t nextReturnAddress = reinterpret_cast<pint_t *>(nextStack)[2];2812 pint_t nextReturnAddress = reinterpret_cast<pint_t *>(nextStack)[2];
27112813
2814 if (vapi_glue_addr_begin <= nextReturnAddress &&
2815 nextReturnAddress < vapi_glue_addr_end) {
2816 _LIBUNWIND_TRACE_UNWINDING(
2817 "The next return address=%p is within the range of VAPI address;",
2818 reinterpret_cast<void *>(nextReturnAddress));
2819 nextReturnAddress = getVAPILR();
2820 _LIBUNWIND_TRACE_UNWINDING("the next return address=%p from VAPI\n",
2821 reinterpret_cast<void *>(nextReturnAddress));
2822 }
2823
2712 if (nextReturnAddress > 0x01 && nextReturnAddress < 0x10000) {2824 if (nextReturnAddress > 0x01 && nextReturnAddress < 0x10000) {
2713 _LIBUNWIND_TRACE_UNWINDING("The next is a signal handler frame: "2825 _LIBUNWIND_TRACE_UNWINDING("The next is a signal handler frame: "
2714 "nextStack=%p, next return address=%p\n",2826 "nextStack=%p, next return address=%p\n",
...@@ -3256,7 +3368,7 @@ int UnwindCursor<A, R>::stepThroughSigReturn() {...@@ -3256,7 +3368,7 @@ int UnwindCursor<A, R>::stepThroughSigReturn() {
32563368
3257template <typename A, typename R> int UnwindCursor<A, R>::step(bool stage2) {3369template <typename A, typename R> int UnwindCursor<A, R>::step(bool stage2) {
3258 (void)stage2;3370 (void)stage2;
3259 // Bottom of stack is defined is when unwind info cannot be found.3371 // Bottom of stack is defined when unwind info cannot be found.
3260 if (_unwindInfoMissing)3372 if (_unwindInfoMissing)
3261 return UNW_STEP_END;3373 return UNW_STEP_END;
32623374
lib/libunwind/src/UnwindLevel1-gcc-ext.c+1-1
...@@ -284,7 +284,7 @@ _LIBUNWIND_EXPORT void __deregister_frame(const void *fde) {...@@ -284,7 +284,7 @@ _LIBUNWIND_EXPORT void __deregister_frame(const void *fde) {
284// before 10.6 used keymgr to track known FDEs, but these functions284// before 10.6 used keymgr to track known FDEs, but these functions
285// never got updated to use keymgr.285// never got updated to use keymgr.
286// For now, we implement these as do-nothing functions to keep any existing286// For now, we implement these as do-nothing functions to keep any existing
287// applications working. We also add the not in 10.6 symbol so that nwe287// applications working. We also add the not in 10.6 symbol so that new
288// application won't be able to use them.288// application won't be able to use them.
289289
290#if defined(_LIBUNWIND_SUPPORT_FRAME_APIS)290#if defined(_LIBUNWIND_SUPPORT_FRAME_APIS)
lib/libunwind/src/UnwindLevel1.c+1-1
...@@ -14,7 +14,7 @@...@@ -14,7 +14,7 @@
14// ARM EHABI does not specify _Unwind_{Get,Set}{GR,IP}(). Thus, we are14// ARM EHABI does not specify _Unwind_{Get,Set}{GR,IP}(). Thus, we are
15// defining inline functions to delegate the function calls to15// defining inline functions to delegate the function calls to
16// _Unwind_VRS_{Get,Set}(). However, some applications might declare the16// _Unwind_VRS_{Get,Set}(). However, some applications might declare the
17// function protetype directly (instead of including <unwind.h>), thus we need17// function prototype directly (instead of including <unwind.h>), thus we need
18// to export these functions from libunwind.so as well.18// to export these functions from libunwind.so as well.
19#define _LIBUNWIND_UNWIND_LEVEL1_EXTERNAL_LINKAGE 119#define _LIBUNWIND_UNWIND_LEVEL1_EXTERNAL_LINKAGE 1
2020
lib/libunwind/src/UnwindRegistersRestore.S+18-1
...@@ -678,9 +678,15 @@ DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)...@@ -678,9 +678,15 @@ DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)
678 ldp x18,x19, [x0, #0x090]678 ldp x18,x19, [x0, #0x090]
679 ldp x20,x21, [x0, #0x0A0]679 ldp x20,x21, [x0, #0x0A0]
680 ldp x22,x23, [x0, #0x0B0]680 ldp x22,x23, [x0, #0x0B0]
681#if defined(__LFI__)
682 ldr x24, [x0, #0x0C0]
683 // Skip reloading x25-x28; reserved by LFI ABI.
684 ldr x29, [x0, #0x0E8]
685#else
681 ldp x24,x25, [x0, #0x0C0]686 ldp x24,x25, [x0, #0x0C0]
682 ldp x26,x27, [x0, #0x0D0]687 ldp x26,x27, [x0, #0x0D0]
683 ldp x28,x29, [x0, #0x0E0]688 ldp x28,x29, [x0, #0x0E0]
689#endif
684690
685#if defined(__ARM_FP) && __ARM_FP != 0691#if defined(__ARM_FP) && __ARM_FP != 0
686 ldp d0, d1, [x0, #0x110]692 ldp d0, d1, [x0, #0x110]
...@@ -941,11 +947,22 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind14Registers_or1k6jumptoEv)...@@ -941,11 +947,22 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind14Registers_or1k6jumptoEv)
941947
942#elif defined(__hexagon__)948#elif defined(__hexagon__)
943# On entry:949# On entry:
944# thread_state pointer is in r2950# thread_state pointer is in r0
945DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind17Registers_hexagon6jumptoEv)951DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind17Registers_hexagon6jumptoEv)
946#952#
947# void libunwind::Registers_hexagon::jumpto()953# void libunwind::Registers_hexagon::jumpto()
948#954#
955# The context layout is hexagon_thread_state_t: unsigned int __r[35]
956# __r[0..31] = r0..r31, __r[32] = predicates, __r[33] = PC.
957# Offsets: __r[n] is at byte offset n*4. r0 is the context pointer, so
958# it is restored last; r31 is loaded with the saved PC as the jumpr target.
959 r2 = memw(r0+#8)
960 r3 = memw(r0+#12)
961 r4 = memw(r0+#16)
962 r5 = memw(r0+#20)
963 r6 = memw(r0+#24)
964 r7 = memw(r0+#28)
965
949 r8 = memw(r0+#32)966 r8 = memw(r0+#32)
950 r9 = memw(r0+#36)967 r9 = memw(r0+#36)
951 r10 = memw(r0+#40)968 r10 = memw(r0+#40)
lib/libunwind/src/UnwindRegistersSave.S+28-3
...@@ -794,13 +794,20 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)...@@ -794,13 +794,20 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
794 stp x18,x19, [x0, #0x090]794 stp x18,x19, [x0, #0x090]
795 stp x20,x21, [x0, #0x0A0]795 stp x20,x21, [x0, #0x0A0]
796 stp x22,x23, [x0, #0x0B0]796 stp x22,x23, [x0, #0x0B0]
797#if defined(__LFI__)
798 str x24, [x0, #0x0C0]
799 // Skip spilling x25-x28; reserved by LFI ABI.
800 str x29, [x0, #0x0E8]
801#else
797 stp x24,x25, [x0, #0x0C0]802 stp x24,x25, [x0, #0x0C0]
798 stp x26,x27, [x0, #0x0D0]803 stp x26,x27, [x0, #0x0D0]
799 stp x28,x29, [x0, #0x0E0]804 stp x28,x29, [x0, #0x0E0]
805#endif
800 str x30, [x0, #0x0F0]806 str x30, [x0, #0x0F0]
801 mov x1,sp807 mov x1,sp
802 str x1, [x0, #0x0F8]808 str x1, [x0, #0x0F8]
803 str x30, [x0, #0x100] // store return address as pc809 str x30, [x0, #0x100] // store return address as pc
810 str xzr, [x0, #0x108] // zero __ra_sign_state
804 // skip cpsr811 // skip cpsr
805#if defined(__ARM_FP) && __ARM_FP != 0812#if defined(__ARM_FP) && __ARM_FP != 0
806 stp d0, d1, [x0, #0x110]813 stp d0, d1, [x0, #0x110]
...@@ -1096,8 +1103,21 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)...@@ -1096,8 +1103,21 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
1096# On entry:1103# On entry:
1097# thread_state pointer is in r01104# thread_state pointer is in r0
1098#1105#
1106# The context layout is hexagon_thread_state_t: unsigned int __r[35]
1107# __r[0..31] = r0..r31, __r[32] = predicates, __r[33] = PC, __r[34] = unused
1108# Offsets: __r[n] is at byte offset n*4.
1109#
1099#define OFFSET(offset) (offset/4)1110#define OFFSET(offset) (offset/4)
1100DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)1111DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
1112 // Save r1-r7 first (r0 is the context pointer, saved last)
1113 memw(r0+#4) = r1
1114 memw(r0+#8) = r2
1115 memw(r0+#12) = r3
1116 memw(r0+#16) = r4
1117 memw(r0+#20) = r5
1118 memw(r0+#24) = r6
1119 memw(r0+#28) = r7
1120
1101 memw(r0+#32) = r81121 memw(r0+#32) = r8
1102 memw(r0+#36) = r91122 memw(r0+#36) = r9
1103 memw(r0+#40) = r101123 memw(r0+#40) = r10
...@@ -1127,12 +1147,17 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)...@@ -1127,12 +1147,17 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
1127 memw(r0+#116) = r291147 memw(r0+#116) = r29
1128 memw(r0+#120) = r301148 memw(r0+#120) = r30
1129 memw(r0+#124) = r311149 memw(r0+#124) = r31
1130 r1 = c4 // Predicate register1150
1151 r1 = c4 // Predicate register
1131 memw(r0+#128) = r11152 memw(r0+#128) = r1
1132 r1 = memw(r30) // *FP == Saved FP1153
1133 r1 = r311154 r1 = r31 // Store return address as PC
1134 memw(r0+#132) = r11155 memw(r0+#132) = r1
11351156
1157 // Save r0 (the context pointer itself) last
1158 memw(r0+#0) = r0
1159
1160 r0 = #0 // return UNW_ESUCCESS
1136 jumpr r311161 jumpr r31
11371162
1138#elif defined(__sparc__) && defined(__arch64__)1163#elif defined(__sparc__) && defined(__arch64__)
lib/libunwind/src/libunwind.cpp+15-19
...@@ -32,7 +32,7 @@...@@ -32,7 +32,7 @@
3232
33using namespace libunwind;33using namespace libunwind;
3434
35/// internal object to represent this processes address space35/// internal object to represent this process's address space
36LocalAddressSpace LocalAddressSpace::sThisAddressSpace;36LocalAddressSpace LocalAddressSpace::sThisAddressSpace;
3737
38_LIBUNWIND_EXPORT unw_addr_space_t unw_local_addr_space =38_LIBUNWIND_EXPORT unw_addr_space_t unw_local_addr_space =
...@@ -131,23 +131,19 @@ _LIBUNWIND_HIDDEN int __unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum,...@@ -131,23 +131,19 @@ _LIBUNWIND_HIDDEN int __unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum,
131 {131 {
132 // It is only valid to set the IP within the current function. This is132 // It is only valid to set the IP within the current function. This is
133 // important for ptrauth, otherwise the IP cannot be correctly signed.133 // important for ptrauth, otherwise the IP cannot be correctly signed.
134 // The current signature of `value` is via the schema:134 //
135 // __ptrauth(ptrauth_key_return_address, <<sp>>, 0)135 // However many JITs do not configure CFI frames, so we cannot actually
136 // For this to be generally usable we manually re-sign it to the136 // enforce this - at least not without an extremely expensive syscall.
137 // directly supported schema:137 //
138 // __ptrauth(ptrauth_key_return_address, 1, 0)138 // For the forseeable future this will need to be a debug only assertion
139 unw_word_t139 // so we just strip and assert to avoid the unnecessary auths in release
140 __unwind_ptrauth_restricted_intptr(ptrauth_key_return_address, 1,140 // builds.
141 0) authenticated_value;141 unw_word_t stripped_value = (unw_word_t)ptrauth_strip(
142 unw_word_t opaque_value = (uint64_t)ptrauth_auth_and_resign(142 (void *)value, ptrauth_key_return_address);
143 (void *)value, ptrauth_key_return_address, sp,143 if (stripped_value < info.start_ip && stripped_value > info.end_ip)
144 ptrauth_key_return_address, &authenticated_value);144 _LIBUNWIND_LOG("Badly behaved use of unw_set_reg: moving IP(0x%zX) "
145 memmove(reinterpret_cast<void *>(&authenticated_value),145 "outside of CFI bounds function (0x%zX, 0x%zX)",
146 reinterpret_cast<void *>(&opaque_value),146 stripped_value, info.start_ip, info.end_ip);
147 sizeof(authenticated_value));
148 if (authenticated_value < info.start_ip ||
149 authenticated_value > info.end_ip)
150 _LIBUNWIND_ABORT("PC vs frame info mismatch");
151147
152 // PC should have been signed with the sp, so we verify that148 // PC should have been signed with the sp, so we verify that
153 // roundtripping does not fail. The `ptrauth_auth_and_resign` is149 // roundtripping does not fail. The `ptrauth_auth_and_resign` is
...@@ -306,7 +302,7 @@ _LIBUNWIND_HIDDEN int __unw_is_fpreg(unw_cursor_t *cursor,...@@ -306,7 +302,7 @@ _LIBUNWIND_HIDDEN int __unw_is_fpreg(unw_cursor_t *cursor,
306}302}
307_LIBUNWIND_WEAK_ALIAS(__unw_is_fpreg, unw_is_fpreg)303_LIBUNWIND_WEAK_ALIAS(__unw_is_fpreg, unw_is_fpreg)
308304
309/// Checks if a register is a floating-point register.305/// Get name of specified register at cursor position in stack frame.
310_LIBUNWIND_HIDDEN const char *__unw_regname(unw_cursor_t *cursor,306_LIBUNWIND_HIDDEN const char *__unw_regname(unw_cursor_t *cursor,
311 unw_regnum_t regNum) {307 unw_regnum_t regNum) {
312 _LIBUNWIND_TRACE_API("__unw_regname(cursor=%p, regNum=%d)",308 _LIBUNWIND_TRACE_API("__unw_regname(cursor=%p, regNum=%d)",
lib/libunwind/src/libunwind_ext.h+2-2
...@@ -120,10 +120,10 @@ typedef int (*unw_find_dynamic_unwind_sections)(...@@ -120,10 +120,10 @@ typedef int (*unw_find_dynamic_unwind_sections)(
120extern int __unw_add_find_dynamic_unwind_sections(120extern int __unw_add_find_dynamic_unwind_sections(
121 unw_find_dynamic_unwind_sections find_dynamic_unwind_sections);121 unw_find_dynamic_unwind_sections find_dynamic_unwind_sections);
122122
123// Deregister a dynacim unwind-info lookup callback.123// Deregister a dynamic unwind-info lookup callback.
124//124//
125// Returns UNW_ESUCCESS for successful deregistrations. If the given callback125// Returns UNW_ESUCCESS for successful deregistrations. If the given callback
126// has already been registered then UNW_EINVAL will be returned.126// is not present then UNW_EINVAL will be returned.
127extern int __unw_remove_find_dynamic_unwind_sections(127extern int __unw_remove_find_dynamic_unwind_sections(
128 unw_find_dynamic_unwind_sections find_dynamic_unwind_sections);128 unw_find_dynamic_unwind_sections find_dynamic_unwind_sections);
129129