Skip to content

Commit a89b343

Browse files
committed
libunwind: Update to LLVM 20.
1 parent ce75472 commit a89b343

7 files changed

+201
-79
lines changed

lib/libunwind/src/DwarfInstructions.hpp

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,10 @@ class DwarfInstructions {
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)
175177
template <typename A, typename R>
176-
bool DwarfInstructions<A, R>::getRA_SIGN_STATE(A &addressSpace, R registers,
177-
pint_t cfa, PrologInfo &prolog) {
178+
bool 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+
192+
template <typename A, typename R>
193+
bool 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

190209
template <typename A, typename R>
@@ -288,21 +307,37 @@ 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;
295314
#else
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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ class CFI_Parser {
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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 91 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -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)
237237
template <typename A> class UnwindSectionHeader {
@@ -1010,6 +1010,9 @@ class UnwindCursor : public AbstractUnwindCursor{
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 @@ class UnwindCursor : public AbstractUnwindCursor{
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

20392042
static __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

25582554
template <typename A, typename R>
25592555
void 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+
2763+
extern "C" {
2764+
extern void *__gCommPageAddress;
2765+
}
2766+
2767+
template <typename A, typename R>
2768+
bool 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+
2786+
template <typename A, typename R>
2787+
int 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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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
#
11091111
DEFINE_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

0 commit comments

Comments
 (0)