mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
libunwind: update to LLVM 17
release/17.x branch, commit 8f4dd44097c9ae25dd203d5ac87f3b48f854bba8
This commit is contained in:
parent
6a07b7024a
commit
571a4c86c3
4
lib/libunwind/include/__libunwind_config.h
vendored
4
lib/libunwind/include/__libunwind_config.h
vendored
@ -196,9 +196,9 @@
|
||||
# define _LIBUNWIND_TARGET_RISCV 1
|
||||
# define _LIBUNWIND_TARGET_VE 1
|
||||
# define _LIBUNWIND_TARGET_S390X 1
|
||||
#define _LIBUNWIND_TARGET_LOONGARCH 1
|
||||
#define _LIBUNWIND_TARGET_LOONGARCH 1
|
||||
# define _LIBUNWIND_CONTEXT_SIZE 167
|
||||
# define _LIBUNWIND_CURSOR_SIZE 179
|
||||
# define _LIBUNWIND_CURSOR_SIZE 204
|
||||
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 287
|
||||
#endif // _LIBUNWIND_IS_NATIVE_ONLY
|
||||
|
||||
|
||||
4
lib/libunwind/include/unwind.h
vendored
4
lib/libunwind/include/unwind.h
vendored
@ -56,9 +56,9 @@ typedef enum {
|
||||
typedef struct _Unwind_Context _Unwind_Context; // opaque
|
||||
|
||||
#if defined(_LIBUNWIND_ARM_EHABI)
|
||||
#include "unwind_arm_ehabi.h"
|
||||
#include <unwind_arm_ehabi.h>
|
||||
#else
|
||||
#include "unwind_itanium.h"
|
||||
#include <unwind_itanium.h>
|
||||
#endif
|
||||
|
||||
typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)
|
||||
|
||||
20
lib/libunwind/src/AddressSpace.hpp
vendored
20
lib/libunwind/src/AddressSpace.hpp
vendored
@ -66,6 +66,10 @@ char *getFuncNameFromTBTable(uintptr_t pc, uint16_t &NameLen,
|
||||
// In 10.7.0 or later, libSystem.dylib implements this function.
|
||||
extern "C" bool _dyld_find_unwind_sections(void *, dyld_unwind_sections *);
|
||||
|
||||
namespace libunwind {
|
||||
bool findDynamicUnwindSections(void *, unw_dynamic_unwind_sections *);
|
||||
}
|
||||
|
||||
#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL)
|
||||
|
||||
// When statically linked on bare-metal, the symbols for the EH table are looked
|
||||
@ -497,6 +501,22 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
|
||||
info.compact_unwind_section_length = (size_t)dyldInfo.compact_unwind_section_length;
|
||||
return true;
|
||||
}
|
||||
|
||||
unw_dynamic_unwind_sections dynamicUnwindSectionInfo;
|
||||
if (findDynamicUnwindSections((void *)targetAddr,
|
||||
&dynamicUnwindSectionInfo)) {
|
||||
info.dso_base = dynamicUnwindSectionInfo.dso_base;
|
||||
#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
|
||||
info.dwarf_section = (uintptr_t)dynamicUnwindSectionInfo.dwarf_section;
|
||||
info.dwarf_section_length = dynamicUnwindSectionInfo.dwarf_section_length;
|
||||
#endif
|
||||
info.compact_unwind_section =
|
||||
(uintptr_t)dynamicUnwindSectionInfo.compact_unwind_section;
|
||||
info.compact_unwind_section_length =
|
||||
dynamicUnwindSectionInfo.compact_unwind_section_length;
|
||||
return true;
|
||||
}
|
||||
|
||||
#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL)
|
||||
info.dso_base = 0;
|
||||
// Bare metal is statically linked, so no need to ask the dynamic loader
|
||||
|
||||
3
lib/libunwind/src/DwarfInstructions.hpp
vendored
3
lib/libunwind/src/DwarfInstructions.hpp
vendored
@ -224,7 +224,8 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
|
||||
p &= ~0xfULL;
|
||||
// CFA is the bottom of the current stack frame.
|
||||
for (; p < cfa; p += 16) {
|
||||
__asm__ __volatile__(".arch_extension memtag\n"
|
||||
__asm__ __volatile__(".arch armv8.5-a\n"
|
||||
".arch_extension memtag\n"
|
||||
"stg %[Ptr], [%[Ptr]]\n"
|
||||
:
|
||||
: [Ptr] "r"(p)
|
||||
|
||||
9
lib/libunwind/src/Unwind-EHABI.cpp
vendored
9
lib/libunwind/src/Unwind-EHABI.cpp
vendored
@ -709,7 +709,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,
|
||||
// Update info about this frame.
|
||||
unw_proc_info_t frameInfo;
|
||||
if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
|
||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): __unw_step "
|
||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): __unw_get_proc_info "
|
||||
"failed => _URC_END_OF_STACK",
|
||||
(void *)exception_object);
|
||||
return _URC_FATAL_PHASE2_ERROR;
|
||||
@ -885,8 +885,11 @@ _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) {
|
||||
return result;
|
||||
}
|
||||
|
||||
static uint64_t ValueAsBitPattern(_Unwind_VRS_DataRepresentation representation,
|
||||
void* valuep) {
|
||||
// Only used in _LIBUNWIND_TRACE_API, which is a no-op when assertions are
|
||||
// disabled.
|
||||
[[gnu::unused]] static uint64_t
|
||||
ValueAsBitPattern(_Unwind_VRS_DataRepresentation representation,
|
||||
const void *valuep) {
|
||||
uint64_t value = 0;
|
||||
switch (representation) {
|
||||
case _UVRSD_UINT32:
|
||||
|
||||
19
lib/libunwind/src/Unwind-seh.cpp
vendored
19
lib/libunwind/src/Unwind-seh.cpp
vendored
@ -212,11 +212,20 @@ __libunwind_seh_personality(int version, _Unwind_Action state,
|
||||
ms_exc.ExceptionInformation[2] = state;
|
||||
DISPATCHER_CONTEXT *disp_ctx =
|
||||
__unw_seh_get_disp_ctx((unw_cursor_t *)context);
|
||||
_LIBUNWIND_TRACE_UNWINDING("__libunwind_seh_personality() calling "
|
||||
"LanguageHandler %p(%p, %p, %p, %p)",
|
||||
(void *)disp_ctx->LanguageHandler, (void *)&ms_exc,
|
||||
(void *)disp_ctx->EstablisherFrame,
|
||||
(void *)disp_ctx->ContextRecord, (void *)disp_ctx);
|
||||
EXCEPTION_DISPOSITION ms_act = disp_ctx->LanguageHandler(&ms_exc,
|
||||
(PVOID)disp_ctx->EstablisherFrame,
|
||||
disp_ctx->ContextRecord,
|
||||
disp_ctx);
|
||||
_LIBUNWIND_TRACE_UNWINDING("__libunwind_seh_personality() LanguageHandler "
|
||||
"returned %d",
|
||||
(int)ms_act);
|
||||
switch (ms_act) {
|
||||
case ExceptionContinueExecution: return _URC_END_OF_STACK;
|
||||
case ExceptionContinueSearch: return _URC_CONTINUE_UNWIND;
|
||||
case 4 /*ExceptionExecuteHandler*/:
|
||||
return phase2 ? _URC_INSTALL_CONTEXT : _URC_HANDLER_FOUND;
|
||||
@ -238,7 +247,7 @@ unwind_phase2_forced(unw_context_t *uc,
|
||||
// Update info about this frame.
|
||||
unw_proc_info_t frameInfo;
|
||||
if (__unw_get_proc_info(&cursor2, &frameInfo) != UNW_ESUCCESS) {
|
||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): __unw_step "
|
||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): __unw_get_proc_info "
|
||||
"failed => _URC_END_OF_STACK",
|
||||
(void *)exception_object);
|
||||
return _URC_FATAL_PHASE2_ERROR;
|
||||
@ -304,6 +313,12 @@ unwind_phase2_forced(unw_context_t *uc,
|
||||
// We may get control back if landing pad calls _Unwind_Resume().
|
||||
__unw_resume(&cursor2);
|
||||
break;
|
||||
case _URC_END_OF_STACK:
|
||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
|
||||
"personality returned "
|
||||
"_URC_END_OF_STACK",
|
||||
(void *)exception_object);
|
||||
break;
|
||||
default:
|
||||
// Personality routine returned an unknown result code.
|
||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
|
||||
@ -312,6 +327,8 @@ unwind_phase2_forced(unw_context_t *uc,
|
||||
(void *)exception_object, personalityResult);
|
||||
return _URC_FATAL_PHASE2_ERROR;
|
||||
}
|
||||
if (personalityResult == _URC_END_OF_STACK)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
80
lib/libunwind/src/UnwindCursor.hpp
vendored
80
lib/libunwind/src/UnwindCursor.hpp
vendored
@ -31,7 +31,8 @@
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_LINUX) && \
|
||||
(defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_S390X))
|
||||
(defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_RISCV) || \
|
||||
defined(_LIBUNWIND_TARGET_S390X))
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/uio.h>
|
||||
#include <unistd.h>
|
||||
@ -506,7 +507,14 @@ public:
|
||||
#endif
|
||||
|
||||
DISPATCHER_CONTEXT *getDispatcherContext() { return &_dispContext; }
|
||||
void setDispatcherContext(DISPATCHER_CONTEXT *disp) { _dispContext = *disp; }
|
||||
void setDispatcherContext(DISPATCHER_CONTEXT *disp) {
|
||||
_dispContext = *disp;
|
||||
_info.lsda = reinterpret_cast<unw_word_t>(_dispContext.HandlerData);
|
||||
if (_dispContext.LanguageHandler) {
|
||||
_info.handler = reinterpret_cast<unw_word_t>(__libunwind_seh_personality);
|
||||
} else
|
||||
_info.handler = 0;
|
||||
}
|
||||
|
||||
// libunwind does not and should not depend on C++ library which means that we
|
||||
// need our own definition of inline placement new.
|
||||
@ -568,10 +576,12 @@ UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as)
|
||||
"UnwindCursor<> requires more alignment than unw_cursor_t");
|
||||
memset(&_info, 0, sizeof(_info));
|
||||
memset(&_histTable, 0, sizeof(_histTable));
|
||||
memset(&_dispContext, 0, sizeof(_dispContext));
|
||||
_dispContext.ContextRecord = &_msContext;
|
||||
_dispContext.HistoryTable = &_histTable;
|
||||
// Initialize MS context from ours.
|
||||
R r(context);
|
||||
RtlCaptureContext(&_msContext);
|
||||
_msContext.ContextFlags = CONTEXT_CONTROL|CONTEXT_INTEGER|CONTEXT_FLOATING_POINT;
|
||||
#if defined(_LIBUNWIND_TARGET_X86_64)
|
||||
_msContext.Rax = r.getRegister(UNW_X86_64_RAX);
|
||||
@ -669,6 +679,7 @@ UnwindCursor<A, R>::UnwindCursor(CONTEXT *context, A &as)
|
||||
"UnwindCursor<> does not fit in unw_cursor_t");
|
||||
memset(&_info, 0, sizeof(_info));
|
||||
memset(&_histTable, 0, sizeof(_histTable));
|
||||
memset(&_dispContext, 0, sizeof(_dispContext));
|
||||
_dispContext.ContextRecord = &_msContext;
|
||||
_dispContext.HistoryTable = &_histTable;
|
||||
_msContext = *context;
|
||||
@ -679,7 +690,7 @@ template <typename A, typename R>
|
||||
bool UnwindCursor<A, R>::validReg(int regNum) {
|
||||
if (regNum == UNW_REG_IP || regNum == UNW_REG_SP) return true;
|
||||
#if defined(_LIBUNWIND_TARGET_X86_64)
|
||||
if (regNum >= UNW_X86_64_RAX && regNum <= UNW_X86_64_R15) return true;
|
||||
if (regNum >= UNW_X86_64_RAX && regNum <= UNW_X86_64_RIP) return true;
|
||||
#elif defined(_LIBUNWIND_TARGET_ARM)
|
||||
if ((regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15) ||
|
||||
regNum == UNW_ARM_RA_AUTH_CODE)
|
||||
@ -694,6 +705,7 @@ template <typename A, typename R>
|
||||
unw_word_t UnwindCursor<A, R>::getReg(int regNum) {
|
||||
switch (regNum) {
|
||||
#if defined(_LIBUNWIND_TARGET_X86_64)
|
||||
case UNW_X86_64_RIP:
|
||||
case UNW_REG_IP: return _msContext.Rip;
|
||||
case UNW_X86_64_RAX: return _msContext.Rax;
|
||||
case UNW_X86_64_RDX: return _msContext.Rdx;
|
||||
@ -744,6 +756,7 @@ template <typename A, typename R>
|
||||
void UnwindCursor<A, R>::setReg(int regNum, unw_word_t value) {
|
||||
switch (regNum) {
|
||||
#if defined(_LIBUNWIND_TARGET_X86_64)
|
||||
case UNW_X86_64_RIP:
|
||||
case UNW_REG_IP: _msContext.Rip = value; break;
|
||||
case UNW_X86_64_RAX: _msContext.Rax = value; break;
|
||||
case UNW_X86_64_RDX: _msContext.Rdx = value; break;
|
||||
@ -981,6 +994,10 @@ private:
|
||||
bool setInfoForSigReturn(Registers_arm64 &);
|
||||
int stepThroughSigReturn(Registers_arm64 &);
|
||||
#endif
|
||||
#if defined(_LIBUNWIND_TARGET_RISCV)
|
||||
bool setInfoForSigReturn(Registers_riscv &);
|
||||
int stepThroughSigReturn(Registers_riscv &);
|
||||
#endif
|
||||
#if defined(_LIBUNWIND_TARGET_S390X)
|
||||
bool setInfoForSigReturn(Registers_s390x &);
|
||||
int stepThroughSigReturn(Registers_s390x &);
|
||||
@ -1978,6 +1995,9 @@ bool UnwindCursor<A, R>::getInfoFromSEH(pint_t pc) {
|
||||
uint32_t lastcode = (xdata->CountOfCodes + 1) & ~1;
|
||||
const uint32_t *handler = reinterpret_cast<uint32_t *>(&xdata->UnwindCodes[lastcode]);
|
||||
_info.lsda = reinterpret_cast<unw_word_t>(handler+1);
|
||||
_dispContext.HandlerData = reinterpret_cast<void *>(_info.lsda);
|
||||
_dispContext.LanguageHandler =
|
||||
reinterpret_cast<EXCEPTION_ROUTINE *>(base + *handler);
|
||||
if (*handler) {
|
||||
_info.handler = reinterpret_cast<unw_word_t>(__libunwind_seh_personality);
|
||||
} else
|
||||
@ -2705,6 +2725,60 @@ int UnwindCursor<A, R>::stepThroughSigReturn(Registers_arm64 &) {
|
||||
#endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&
|
||||
// defined(_LIBUNWIND_TARGET_AARCH64)
|
||||
|
||||
#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && \
|
||||
defined(_LIBUNWIND_TARGET_RISCV)
|
||||
template <typename A, typename R>
|
||||
bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_riscv &) {
|
||||
const pint_t pc = static_cast<pint_t>(getReg(UNW_REG_IP));
|
||||
uint32_t instructions[2];
|
||||
struct iovec local_iov = {&instructions, sizeof instructions};
|
||||
struct iovec remote_iov = {reinterpret_cast<void *>(pc), sizeof instructions};
|
||||
long bytesRead =
|
||||
syscall(SYS_process_vm_readv, getpid(), &local_iov, 1, &remote_iov, 1, 0);
|
||||
// Look for the two instructions used in the sigreturn trampoline
|
||||
// __vdso_rt_sigreturn:
|
||||
//
|
||||
// 0x08b00893 li a7,0x8b
|
||||
// 0x00000073 ecall
|
||||
if (bytesRead != sizeof instructions || instructions[0] != 0x08b00893 ||
|
||||
instructions[1] != 0x00000073)
|
||||
return false;
|
||||
|
||||
_info = {};
|
||||
_info.start_ip = pc;
|
||||
_info.end_ip = pc + 4;
|
||||
_isSigReturn = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename A, typename R>
|
||||
int UnwindCursor<A, R>::stepThroughSigReturn(Registers_riscv &) {
|
||||
// In the signal trampoline frame, sp points to an rt_sigframe[1], which is:
|
||||
// - 128-byte siginfo struct
|
||||
// - ucontext_t struct:
|
||||
// - 8-byte long (__uc_flags)
|
||||
// - 8-byte pointer (*uc_link)
|
||||
// - 24-byte uc_stack
|
||||
// - 8-byte uc_sigmask
|
||||
// - 120-byte of padding to allow sigset_t to be expanded in the future
|
||||
// - 8 bytes of padding because sigcontext has 16-byte alignment
|
||||
// - struct sigcontext uc_mcontext
|
||||
// [1]
|
||||
// https://github.com/torvalds/linux/blob/master/arch/riscv/kernel/signal.c
|
||||
const pint_t kOffsetSpToSigcontext = 128 + 8 + 8 + 24 + 8 + 128;
|
||||
|
||||
const pint_t sigctx = _registers.getSP() + kOffsetSpToSigcontext;
|
||||
_registers.setIP(_addressSpace.get64(sigctx));
|
||||
for (int i = UNW_RISCV_X1; i <= UNW_RISCV_X31; ++i) {
|
||||
uint64_t value = _addressSpace.get64(sigctx + static_cast<pint_t>(i * 8));
|
||||
_registers.setRegister(i, value);
|
||||
}
|
||||
_isSignalFrame = true;
|
||||
return UNW_STEP_SUCCESS;
|
||||
}
|
||||
#endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&
|
||||
// defined(_LIBUNWIND_TARGET_RISCV)
|
||||
|
||||
#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && \
|
||||
defined(_LIBUNWIND_TARGET_S390X)
|
||||
template <typename A, typename R>
|
||||
|
||||
2
lib/libunwind/src/UnwindLevel1-gcc-ext.c
vendored
2
lib/libunwind/src/UnwindLevel1-gcc-ext.c
vendored
@ -167,7 +167,7 @@ _Unwind_Backtrace(_Unwind_Trace_Fn callback, void *ref) {
|
||||
}
|
||||
|
||||
// Update the pr_cache in the mock exception object.
|
||||
const uint32_t* unwindInfo = (uint32_t *) frameInfo.unwind_info;
|
||||
uint32_t *unwindInfo = (uint32_t *)frameInfo.unwind_info;
|
||||
ex.pr_cache.fnstart = frameInfo.start_ip;
|
||||
ex.pr_cache.ehtp = (_Unwind_EHT_Header *) unwindInfo;
|
||||
ex.pr_cache.additional= frameInfo.flags;
|
||||
|
||||
2
lib/libunwind/src/UnwindLevel1.c
vendored
2
lib/libunwind/src/UnwindLevel1.c
vendored
@ -321,7 +321,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,
|
||||
unw_proc_info_t frameInfo;
|
||||
if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
|
||||
_LIBUNWIND_TRACE_UNWINDING(
|
||||
"unwind_phase2_forced(ex_obj=%p): __unw_step_stage2 "
|
||||
"unwind_phase2_forced(ex_obj=%p): __unw_get_proc_info "
|
||||
"failed => _URC_END_OF_STACK",
|
||||
(void *)exception_object);
|
||||
return _URC_FATAL_PHASE2_ERROR;
|
||||
|
||||
22
lib/libunwind/src/UnwindRegistersRestore.S
vendored
22
lib/libunwind/src/UnwindRegistersRestore.S
vendored
@ -194,9 +194,20 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv)
|
||||
addi 4, 3, PPC64_OFFS_FP
|
||||
|
||||
// load VS register
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
// For little-endian targets, we need a swap since lxvd2x will load the register
|
||||
// in the incorrect doubleword order.
|
||||
// FIXME: when supporting targets older than Power9 on LE is no longer required,
|
||||
// this can be changed to simply `lxv n, (16 * n)(4)`.
|
||||
#define PPC64_LVS(n) \
|
||||
lxvd2x n, 0, 4 ;\
|
||||
xxswapd n, n ;\
|
||||
addi 4, 4, 16
|
||||
#else
|
||||
#define PPC64_LVS(n) \
|
||||
lxvd2x n, 0, 4 ;\
|
||||
addi 4, 4, 16
|
||||
#endif
|
||||
|
||||
// restore the first 32 VS regs (and also all floating point regs)
|
||||
PPC64_LVS(0)
|
||||
@ -232,9 +243,16 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv)
|
||||
PPC64_LVS(30)
|
||||
PPC64_LVS(31)
|
||||
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
#define PPC64_CLVS_RESTORE(n) \
|
||||
addi 4, 3, PPC64_OFFS_FP + n * 16 ;\
|
||||
lxvd2x n, 0, 4 ;\
|
||||
xxswapd n, n
|
||||
#else
|
||||
#define PPC64_CLVS_RESTORE(n) \
|
||||
addi 4, 3, PPC64_OFFS_FP + n * 16 ;\
|
||||
lxvd2x n, 0, 4
|
||||
#endif
|
||||
|
||||
#if !defined(_AIX)
|
||||
// use VRSAVE to conditionally restore the remaining VS regs, that are
|
||||
@ -1203,8 +1221,8 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind19Registers_loongarch6jumptoEv)
|
||||
ld.d $r\i, $a0, (8 * \i)
|
||||
.endr
|
||||
|
||||
ld.d $r4, $a0, (8 * 4) // restore $a0 last
|
||||
ld.d $r1, $a0, (8 * 32) // load new pc into $ra
|
||||
ld.d $ra, $a0, (8 * 32) // load new pc into $ra
|
||||
ld.d $a0, $a0, (8 * 4) // restore $a0 last
|
||||
|
||||
jr $ra
|
||||
|
||||
|
||||
11
lib/libunwind/src/UnwindRegistersSave.S
vendored
11
lib/libunwind/src/UnwindRegistersSave.S
vendored
@ -351,9 +351,20 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
|
||||
addi 4, 3, PPC64_OFFS_FP
|
||||
|
||||
// store VS register
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
// For little-endian targets, we need a swap since stxvd2x will store the
|
||||
// register in the incorrect doubleword order.
|
||||
// FIXME: when supporting targets older than Power9 on LE is no longer required
|
||||
// this can be changed to simply `stxv n, 16 * n(4)`.
|
||||
#define PPC64_STVS(n) \
|
||||
xxswapd n, n ;\
|
||||
stxvd2x n, 0, 4 ;\
|
||||
addi 4, 4, 16
|
||||
#else
|
||||
#define PPC64_STVS(n) \
|
||||
stxvd2x n, 0, 4 ;\
|
||||
addi 4, 4, 16
|
||||
#endif
|
||||
|
||||
PPC64_STVS(0)
|
||||
PPC64_STVS(1)
|
||||
|
||||
113
lib/libunwind/src/Unwind_AppleExtras.cpp
vendored
113
lib/libunwind/src/Unwind_AppleExtras.cpp
vendored
@ -1,113 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
// static linker symbols to prevent wrong two level namespace for _Unwind symbols
|
||||
#if defined(__arm__)
|
||||
#define NOT_HERE_BEFORE_5_0(sym) \
|
||||
extern const char sym##_tmp30 __asm("$ld$hide$os3.0$_" #sym ); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp30 = 0; \
|
||||
extern const char sym##_tmp31 __asm("$ld$hide$os3.1$_" #sym ); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp31 = 0; \
|
||||
extern const char sym##_tmp32 __asm("$ld$hide$os3.2$_" #sym );\
|
||||
__attribute__((visibility("default"))) const char sym##_tmp32 = 0; \
|
||||
extern const char sym##_tmp40 __asm("$ld$hide$os4.0$_" #sym ); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp40 = 0; \
|
||||
extern const char sym##_tmp41 __asm("$ld$hide$os4.1$_" #sym ); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp41 = 0; \
|
||||
extern const char sym##_tmp42 __asm("$ld$hide$os4.2$_" #sym ); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp42 = 0; \
|
||||
extern const char sym##_tmp43 __asm("$ld$hide$os4.3$_" #sym ); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp43 = 0;
|
||||
#elif defined(__aarch64__)
|
||||
#define NOT_HERE_BEFORE_10_6(sym)
|
||||
#define NEVER_HERE(sym)
|
||||
#else
|
||||
#define NOT_HERE_BEFORE_10_6(sym) \
|
||||
extern const char sym##_tmp4 __asm("$ld$hide$os10.4$_" #sym ); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp4 = 0; \
|
||||
extern const char sym##_tmp5 __asm("$ld$hide$os10.5$_" #sym ); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp5 = 0;
|
||||
#define NEVER_HERE(sym) \
|
||||
extern const char sym##_tmp4 __asm("$ld$hide$os10.4$_" #sym ); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp4 = 0; \
|
||||
extern const char sym##_tmp5 __asm("$ld$hide$os10.5$_" #sym ); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp5 = 0; \
|
||||
extern const char sym##_tmp6 __asm("$ld$hide$os10.6$_" #sym ); \
|
||||
__attribute__((visibility("default"))) const char sym##_tmp6 = 0;
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_LIBUNWIND_BUILD_ZERO_COST_APIS)
|
||||
|
||||
//
|
||||
// symbols in libSystem.dylib in 10.6 and later, but are in libgcc_s.dylib in
|
||||
// earlier versions
|
||||
//
|
||||
NOT_HERE_BEFORE_10_6(_Unwind_DeleteException)
|
||||
NOT_HERE_BEFORE_10_6(_Unwind_Find_FDE)
|
||||
NOT_HERE_BEFORE_10_6(_Unwind_ForcedUnwind)
|
||||
NOT_HERE_BEFORE_10_6(_Unwind_GetGR)
|
||||
NOT_HERE_BEFORE_10_6(_Unwind_GetIP)
|
||||
NOT_HERE_BEFORE_10_6(_Unwind_GetLanguageSpecificData)
|
||||
NOT_HERE_BEFORE_10_6(_Unwind_GetRegionStart)
|
||||
NOT_HERE_BEFORE_10_6(_Unwind_RaiseException)
|
||||
NOT_HERE_BEFORE_10_6(_Unwind_Resume)
|
||||
NOT_HERE_BEFORE_10_6(_Unwind_SetGR)
|
||||
NOT_HERE_BEFORE_10_6(_Unwind_SetIP)
|
||||
NOT_HERE_BEFORE_10_6(_Unwind_Backtrace)
|
||||
NOT_HERE_BEFORE_10_6(_Unwind_FindEnclosingFunction)
|
||||
NOT_HERE_BEFORE_10_6(_Unwind_GetCFA)
|
||||
NOT_HERE_BEFORE_10_6(_Unwind_GetDataRelBase)
|
||||
NOT_HERE_BEFORE_10_6(_Unwind_GetTextRelBase)
|
||||
NOT_HERE_BEFORE_10_6(_Unwind_Resume_or_Rethrow)
|
||||
NOT_HERE_BEFORE_10_6(_Unwind_GetIPInfo)
|
||||
NOT_HERE_BEFORE_10_6(__register_frame)
|
||||
NOT_HERE_BEFORE_10_6(__deregister_frame)
|
||||
|
||||
//
|
||||
// symbols in libSystem.dylib for compatibility, but we don't want any new code
|
||||
// using them
|
||||
//
|
||||
NEVER_HERE(__register_frame_info_bases)
|
||||
NEVER_HERE(__register_frame_info)
|
||||
NEVER_HERE(__register_frame_info_table_bases)
|
||||
NEVER_HERE(__register_frame_info_table)
|
||||
NEVER_HERE(__register_frame_table)
|
||||
NEVER_HERE(__deregister_frame_info)
|
||||
NEVER_HERE(__deregister_frame_info_bases)
|
||||
|
||||
#endif // defined(_LIBUNWIND_BUILD_ZERO_COST_APIS)
|
||||
|
||||
|
||||
|
||||
|
||||
#if defined(_LIBUNWIND_BUILD_SJLJ_APIS)
|
||||
//
|
||||
// symbols in libSystem.dylib in iOS 5.0 and later, but are in libgcc_s.dylib in
|
||||
// earlier versions
|
||||
//
|
||||
NOT_HERE_BEFORE_5_0(_Unwind_GetLanguageSpecificData)
|
||||
NOT_HERE_BEFORE_5_0(_Unwind_GetRegionStart)
|
||||
NOT_HERE_BEFORE_5_0(_Unwind_GetIP)
|
||||
NOT_HERE_BEFORE_5_0(_Unwind_SetGR)
|
||||
NOT_HERE_BEFORE_5_0(_Unwind_SetIP)
|
||||
NOT_HERE_BEFORE_5_0(_Unwind_DeleteException)
|
||||
NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Register)
|
||||
NOT_HERE_BEFORE_5_0(_Unwind_GetGR)
|
||||
NOT_HERE_BEFORE_5_0(_Unwind_GetIPInfo)
|
||||
NOT_HERE_BEFORE_5_0(_Unwind_GetCFA)
|
||||
NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Resume)
|
||||
NOT_HERE_BEFORE_5_0(_Unwind_SjLj_RaiseException)
|
||||
NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Resume_or_Rethrow)
|
||||
NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Unregister)
|
||||
|
||||
#endif // defined(_LIBUNWIND_BUILD_SJLJ_APIS)
|
||||
12
lib/libunwind/src/config.h
vendored
12
lib/libunwind/src/config.h
vendored
@ -162,10 +162,14 @@
|
||||
#define _LIBUNWIND_LOG0(msg)
|
||||
#define _LIBUNWIND_LOG(msg, ...)
|
||||
#else
|
||||
#define _LIBUNWIND_LOG0(msg) \
|
||||
fprintf(stderr, "libunwind: " msg "\n")
|
||||
#define _LIBUNWIND_LOG(msg, ...) \
|
||||
fprintf(stderr, "libunwind: " msg "\n", __VA_ARGS__)
|
||||
#define _LIBUNWIND_LOG0(msg) do { \
|
||||
fprintf(stderr, "libunwind: " msg "\n"); \
|
||||
fflush(stderr); \
|
||||
} while (0)
|
||||
#define _LIBUNWIND_LOG(msg, ...) do { \
|
||||
fprintf(stderr, "libunwind: " msg "\n", __VA_ARGS__); \
|
||||
fflush(stderr); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#if defined(NDEBUG)
|
||||
|
||||
80
lib/libunwind/src/libunwind.cpp
vendored
80
lib/libunwind/src/libunwind.cpp
vendored
@ -349,7 +349,87 @@ void __unw_remove_dynamic_eh_frame_section(unw_word_t eh_frame_start) {
|
||||
#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
|
||||
#endif // !defined(__USING_SJLJ_EXCEPTIONS__)
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
namespace libunwind {
|
||||
|
||||
static constexpr size_t MAX_DYNAMIC_UNWIND_SECTIONS_FINDERS = 8;
|
||||
|
||||
static RWMutex findDynamicUnwindSectionsLock;
|
||||
static size_t numDynamicUnwindSectionsFinders = 0;
|
||||
static unw_find_dynamic_unwind_sections
|
||||
dynamicUnwindSectionsFinders[MAX_DYNAMIC_UNWIND_SECTIONS_FINDERS] = {0};
|
||||
|
||||
bool findDynamicUnwindSections(void *addr, unw_dynamic_unwind_sections *info) {
|
||||
bool found = false;
|
||||
findDynamicUnwindSectionsLock.lock_shared();
|
||||
for (size_t i = 0; i != numDynamicUnwindSectionsFinders; ++i) {
|
||||
if (dynamicUnwindSectionsFinders[i]((unw_word_t)addr, info)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
findDynamicUnwindSectionsLock.unlock_shared();
|
||||
return found;
|
||||
}
|
||||
|
||||
} // namespace libunwind
|
||||
|
||||
int __unw_add_find_dynamic_unwind_sections(
|
||||
unw_find_dynamic_unwind_sections find_dynamic_unwind_sections) {
|
||||
findDynamicUnwindSectionsLock.lock();
|
||||
|
||||
// Check that we have enough space...
|
||||
if (numDynamicUnwindSectionsFinders == MAX_DYNAMIC_UNWIND_SECTIONS_FINDERS) {
|
||||
findDynamicUnwindSectionsLock.unlock();
|
||||
return UNW_ENOMEM;
|
||||
}
|
||||
|
||||
// Check for value already present...
|
||||
for (size_t i = 0; i != numDynamicUnwindSectionsFinders; ++i) {
|
||||
if (dynamicUnwindSectionsFinders[i] == find_dynamic_unwind_sections) {
|
||||
findDynamicUnwindSectionsLock.unlock();
|
||||
return UNW_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
// Success -- add callback entry.
|
||||
dynamicUnwindSectionsFinders[numDynamicUnwindSectionsFinders++] =
|
||||
find_dynamic_unwind_sections;
|
||||
findDynamicUnwindSectionsLock.unlock();
|
||||
|
||||
return UNW_ESUCCESS;
|
||||
}
|
||||
|
||||
int __unw_remove_find_dynamic_unwind_sections(
|
||||
unw_find_dynamic_unwind_sections find_dynamic_unwind_sections) {
|
||||
findDynamicUnwindSectionsLock.lock();
|
||||
|
||||
// Find index to remove.
|
||||
size_t finderIdx = numDynamicUnwindSectionsFinders;
|
||||
for (size_t i = 0; i != numDynamicUnwindSectionsFinders; ++i) {
|
||||
if (dynamicUnwindSectionsFinders[i] == find_dynamic_unwind_sections) {
|
||||
finderIdx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If no such registration is present then error out.
|
||||
if (finderIdx == numDynamicUnwindSectionsFinders) {
|
||||
findDynamicUnwindSectionsLock.unlock();
|
||||
return UNW_EINVAL;
|
||||
}
|
||||
|
||||
// Remove entry.
|
||||
for (size_t i = finderIdx; i != numDynamicUnwindSectionsFinders - 1; ++i)
|
||||
dynamicUnwindSectionsFinders[i] = dynamicUnwindSectionsFinders[i + 1];
|
||||
dynamicUnwindSectionsFinders[--numDynamicUnwindSectionsFinders] = nullptr;
|
||||
|
||||
findDynamicUnwindSectionsLock.unlock();
|
||||
return UNW_ESUCCESS;
|
||||
}
|
||||
|
||||
#endif // __APPLE__
|
||||
|
||||
// Add logging hooks in Debug builds only
|
||||
#ifndef NDEBUG
|
||||
|
||||
65
lib/libunwind/src/libunwind_ext.h
vendored
65
lib/libunwind/src/libunwind_ext.h
vendored
@ -58,6 +58,71 @@ extern void __unw_remove_dynamic_fde(unw_word_t fde);
|
||||
extern void __unw_add_dynamic_eh_frame_section(unw_word_t eh_frame_start);
|
||||
extern void __unw_remove_dynamic_eh_frame_section(unw_word_t eh_frame_start);
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
// Holds a description of the object-format-header (if any) and unwind info
|
||||
// sections for a given address:
|
||||
//
|
||||
// * dso_base should point to a header for the JIT'd object containing the
|
||||
// given address. The header's type should match the format type that
|
||||
// libunwind was compiled for (so a mach_header or mach_header_64 on Darwin).
|
||||
// A value of zero indicates that no such header exists.
|
||||
//
|
||||
// * dwarf_section and dwarf_section_length hold the address range of a DWARF
|
||||
// eh-frame section associated with the given address, if any. If the
|
||||
// dwarf_section_length field is zero it indicates that no such section
|
||||
// exists (and in this case dwarf_section should also be set to zero).
|
||||
//
|
||||
// * compact_unwind_section and compact_unwind_section_length hold the address
|
||||
// range of a compact-unwind info section associated with the given address,
|
||||
// if any. If the compact_unwind_section_length field is zero it indicates
|
||||
// that no such section exists (and in this case compact_unwind_section
|
||||
// should also be set to zero).
|
||||
//
|
||||
// See the unw_find_dynamic_unwind_sections type below for more details.
|
||||
struct unw_dynamic_unwind_sections {
|
||||
unw_word_t dso_base;
|
||||
unw_word_t dwarf_section;
|
||||
size_t dwarf_section_length;
|
||||
unw_word_t compact_unwind_section;
|
||||
size_t compact_unwind_section_length;
|
||||
};
|
||||
|
||||
// Typedef for unwind-info lookup callbacks. Functions of this type can be
|
||||
// registered and deregistered using __unw_add_find_dynamic_unwind_sections
|
||||
// and __unw_remove_find_dynamic_unwind_sections respectively.
|
||||
//
|
||||
// An unwind-info lookup callback should return 1 to indicate that it found
|
||||
// unwind-info for the given address, or 0 to indicate that it did not find
|
||||
// unwind-info for the given address. If found, the callback should populate
|
||||
// some or all of the fields of the info argument (which is guaranteed to be
|
||||
// non-null with all fields zero-initialized):
|
||||
typedef int (*unw_find_dynamic_unwind_sections)(
|
||||
unw_word_t addr, struct unw_dynamic_unwind_sections *info);
|
||||
|
||||
// Register a dynamic unwind-info lookup callback. If libunwind does not find
|
||||
// unwind info for a given frame in the executable program or normal dynamic
|
||||
// shared objects then it will call all registered dynamic lookup functions
|
||||
// in registration order until either one of them returns true, or the end
|
||||
// of the list is reached. This lookup will happen before libunwind searches
|
||||
// any eh-frames registered via __register_frame or
|
||||
// __unw_add_dynamic_eh_frame_section.
|
||||
//
|
||||
// Returns UNW_ESUCCESS for successful registrations. If the given callback
|
||||
// has already been registered then UNW_EINVAL will be returned. If all
|
||||
// available callback entries are in use then UNW_ENOMEM will be returned.
|
||||
extern int __unw_add_find_dynamic_unwind_sections(
|
||||
unw_find_dynamic_unwind_sections find_dynamic_unwind_sections);
|
||||
|
||||
// Deregister a dynacim unwind-info lookup callback.
|
||||
//
|
||||
// Returns UNW_ESUCCESS for successful deregistrations. If the given callback
|
||||
// has already been registered then UNW_EINVAL will be returned.
|
||||
extern int __unw_remove_find_dynamic_unwind_sections(
|
||||
unw_find_dynamic_unwind_sections find_dynamic_unwind_sections);
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_ARM_EHABI)
|
||||
extern const uint32_t* decode_eht_entry(const uint32_t*, size_t*, size_t*);
|
||||
extern _Unwind_Reason_Code _Unwind_VRS_Interpret(_Unwind_Context *context,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user