mirror of
https://github.com/opnsense/src.git
synced 2026-06-08 16:22:46 -04:00
Import LLVM libunwind snapshot revision 272680
Significant upstream revisions: 260595: [AArch64] Fix libunwind build when using GNU assembler 270692: Introduce a native-only unwinder build. 270972: Disable cross-unwinding by default. 271004: [libunwind] Improve unwinder stack usage - II 272680: [libunwind] Improve unwinder stack usage - III Obtained from: https://llvm.org/svn/llvm-project/libunwind/trunk/
This commit is contained in:
parent
ca83053650
commit
e2fc5d984d
12 changed files with 242 additions and 176 deletions
|
|
@ -17,4 +17,43 @@
|
|||
#define _LIBUNWIND_ARM_EHABI 0
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_IS_NATIVE_ONLY)
|
||||
# if defined(__i386__)
|
||||
# define _LIBUNWIND_TARGET_I386 1
|
||||
# define _LIBUNWIND_CONTEXT_SIZE 8
|
||||
# define _LIBUNWIND_CURSOR_SIZE 19
|
||||
# elif defined(__x86_64__)
|
||||
# define _LIBUNWIND_TARGET_X86_64 1
|
||||
# define _LIBUNWIND_CONTEXT_SIZE 21
|
||||
# define _LIBUNWIND_CURSOR_SIZE 33
|
||||
# elif defined(__ppc__)
|
||||
# define _LIBUNWIND_TARGET_PPC 1
|
||||
# define _LIBUNWIND_CONTEXT_SIZE 117
|
||||
# define _LIBUNWIND_CURSOR_SIZE 128
|
||||
# elif defined(__aarch64__)
|
||||
# define _LIBUNWIND_TARGET_AARCH64 1
|
||||
# define _LIBUNWIND_CONTEXT_SIZE 66
|
||||
# define _LIBUNWIND_CURSOR_SIZE 78
|
||||
# elif defined(__arm__)
|
||||
# define _LIBUNWIND_TARGET_ARM 1
|
||||
# define _LIBUNWIND_CONTEXT_SIZE 60
|
||||
# define _LIBUNWIND_CURSOR_SIZE 67
|
||||
# elif defined(__or1k__)
|
||||
# define _LIBUNWIND_TARGET_OR1K 1
|
||||
# define _LIBUNWIND_CONTEXT_SIZE 16
|
||||
# define _LIBUNWIND_CURSOR_SIZE 28
|
||||
# else
|
||||
# error "Unsupported architecture."
|
||||
# endif
|
||||
#else // !_LIBUNWIND_IS_NATIVE_ONLY
|
||||
# define _LIBUNWIND_TARGET_I386 1
|
||||
# define _LIBUNWIND_TARGET_X86_64 1
|
||||
# define _LIBUNWIND_TARGET_PPC 1
|
||||
# define _LIBUNWIND_TARGET_AARCH64 1
|
||||
# define _LIBUNWIND_TARGET_ARM 1
|
||||
# define _LIBUNWIND_TARGET_OR1K 1
|
||||
# define _LIBUNWIND_CONTEXT_SIZE 128
|
||||
# define _LIBUNWIND_CURSOR_SIZE 140
|
||||
#endif // _LIBUNWIND_IS_NATIVE_ONLY
|
||||
|
||||
#endif // ____LIBUNWIND_CONFIG_H__
|
||||
|
|
|
|||
|
|
@ -46,12 +46,12 @@ enum {
|
|||
};
|
||||
|
||||
struct unw_context_t {
|
||||
uint64_t data[128];
|
||||
uint64_t data[_LIBUNWIND_CONTEXT_SIZE];
|
||||
};
|
||||
typedef struct unw_context_t unw_context_t;
|
||||
|
||||
struct unw_cursor_t {
|
||||
uint64_t data[140];
|
||||
uint64_t data[_LIBUNWIND_CURSOR_SIZE];
|
||||
};
|
||||
typedef struct unw_cursor_t unw_cursor_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ namespace libunwind {
|
|||
#include "Registers.hpp"
|
||||
|
||||
#if _LIBUNWIND_ARM_EHABI
|
||||
#if defined(__FreeBSD__)
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
|
||||
typedef void *_Unwind_Ptr;
|
||||
|
||||
|
|
@ -61,7 +61,8 @@ extern EHTEntry __exidx_end;
|
|||
#endif // !defined(_LIBUNWIND_IS_BAREMETAL)
|
||||
#endif // _LIBUNWIND_ARM_EHABI
|
||||
|
||||
#if defined(__CloudABI__) || defined(__FreeBSD__) || defined(__linux__)
|
||||
#if defined(__CloudABI__) || defined(__FreeBSD__) || defined(__linux__) || \
|
||||
defined(__NetBSD__)
|
||||
#if _LIBUNWIND_SUPPORT_DWARF_UNWIND && _LIBUNWIND_SUPPORT_DWARF_INDEX
|
||||
#include <link.h>
|
||||
// Macro for machine-independent access to the ELF program headers. This
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
namespace libunwind {
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_I386)
|
||||
/// CompactUnwinder_x86 uses a compact unwind info to virtually "step" (aka
|
||||
/// unwind) by modifying a Registers_x86 register set
|
||||
template <typename A>
|
||||
|
|
@ -255,8 +256,10 @@ void CompactUnwinder_x86<A>::framelessUnwind(
|
|||
// old esp is before return address
|
||||
registers.setSP((uint32_t)returnAddressLocation + 4);
|
||||
}
|
||||
#endif // _LIBUNWIND_TARGET_I386
|
||||
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_X86_64)
|
||||
/// CompactUnwinder_x86_64 uses a compact unwind info to virtually "step" (aka
|
||||
/// unwind) by modifying a Registers_x86_64 register set
|
||||
template <typename A>
|
||||
|
|
@ -484,9 +487,11 @@ void CompactUnwinder_x86_64<A>::framelessUnwind(A &addressSpace,
|
|||
// old esp is before return address
|
||||
registers.setSP(returnAddressLocation + 8);
|
||||
}
|
||||
#endif // _LIBUNWIND_TARGET_X86_64
|
||||
|
||||
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_AARCH64)
|
||||
/// CompactUnwinder_arm64 uses a compact unwind info to virtually "step" (aka
|
||||
/// unwind) by modifying a Registers_arm64 register set
|
||||
template <typename A>
|
||||
|
|
@ -686,6 +691,7 @@ int CompactUnwinder_arm64<A>::stepWithCompactEncodingFrame(
|
|||
|
||||
return UNW_STEP_SUCCESS;
|
||||
}
|
||||
#endif // _LIBUNWIND_TARGET_AARCH64
|
||||
|
||||
|
||||
} // namespace libunwind
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ namespace libunwind {
|
|||
struct v128 { uint32_t vec[4]; };
|
||||
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_I386)
|
||||
/// Registers_x86 holds the register state of a thread in a 32-bit intel
|
||||
/// process.
|
||||
class _LIBUNWIND_HIDDEN Registers_x86 {
|
||||
|
|
@ -86,8 +87,8 @@ private:
|
|||
};
|
||||
|
||||
inline Registers_x86::Registers_x86(const void *registers) {
|
||||
static_assert(sizeof(Registers_x86) < sizeof(unw_context_t),
|
||||
"x86 registers do not fit into unw_context_t");
|
||||
static_assert((check_fit<Registers_x86, unw_context_t>::does_fit),
|
||||
"x86 registers do not fit into unw_context_t");
|
||||
memcpy(&_registers, registers, sizeof(_registers));
|
||||
}
|
||||
|
||||
|
|
@ -211,8 +212,10 @@ inline v128 Registers_x86::getVectorRegister(int) const {
|
|||
inline void Registers_x86::setVectorRegister(int, v128) {
|
||||
_LIBUNWIND_ABORT("no x86 vector registers");
|
||||
}
|
||||
#endif // _LIBUNWIND_TARGET_I386
|
||||
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_X86_64)
|
||||
/// Registers_x86_64 holds the register state of a thread in a 64-bit intel
|
||||
/// process.
|
||||
class _LIBUNWIND_HIDDEN Registers_x86_64 {
|
||||
|
|
@ -278,8 +281,8 @@ private:
|
|||
};
|
||||
|
||||
inline Registers_x86_64::Registers_x86_64(const void *registers) {
|
||||
static_assert(sizeof(Registers_x86_64) < sizeof(unw_context_t),
|
||||
"x86_64 registers do not fit into unw_context_t");
|
||||
static_assert((check_fit<Registers_x86_64, unw_context_t>::does_fit),
|
||||
"x86_64 registers do not fit into unw_context_t");
|
||||
memcpy(&_registers, registers, sizeof(_registers));
|
||||
}
|
||||
|
||||
|
|
@ -459,8 +462,10 @@ inline v128 Registers_x86_64::getVectorRegister(int) const {
|
|||
inline void Registers_x86_64::setVectorRegister(int, v128) {
|
||||
_LIBUNWIND_ABORT("no x86_64 vector registers");
|
||||
}
|
||||
#endif // _LIBUNWIND_TARGET_X86_64
|
||||
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_PPC)
|
||||
/// Registers_ppc holds the register state of a thread in a 32-bit PowerPC
|
||||
/// process.
|
||||
class _LIBUNWIND_HIDDEN Registers_ppc {
|
||||
|
|
@ -543,8 +548,8 @@ private:
|
|||
};
|
||||
|
||||
inline Registers_ppc::Registers_ppc(const void *registers) {
|
||||
static_assert(sizeof(Registers_ppc) < sizeof(unw_context_t),
|
||||
"ppc registers do not fit into unw_context_t");
|
||||
static_assert((check_fit<Registers_ppc, unw_context_t>::does_fit),
|
||||
"ppc registers do not fit into unw_context_t");
|
||||
memcpy(&_registers, static_cast<const uint8_t *>(registers),
|
||||
sizeof(_registers));
|
||||
static_assert(sizeof(ppc_thread_state_t) == 160,
|
||||
|
|
@ -1023,8 +1028,10 @@ inline const char *Registers_ppc::getRegisterName(int regNum) {
|
|||
}
|
||||
|
||||
}
|
||||
#endif // _LIBUNWIND_TARGET_PPC
|
||||
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_AARCH64)
|
||||
/// Registers_arm64 holds the register state of a thread in a 64-bit arm
|
||||
/// process.
|
||||
class _LIBUNWIND_HIDDEN Registers_arm64 {
|
||||
|
|
@ -1071,8 +1078,8 @@ private:
|
|||
};
|
||||
|
||||
inline Registers_arm64::Registers_arm64(const void *registers) {
|
||||
static_assert(sizeof(Registers_arm64) < sizeof(unw_context_t),
|
||||
"arm64 registers do not fit into unw_context_t");
|
||||
static_assert((check_fit<Registers_arm64, unw_context_t>::does_fit),
|
||||
"arm64 registers do not fit into unw_context_t");
|
||||
memcpy(&_registers, registers, sizeof(_registers));
|
||||
static_assert(sizeof(GPRs) == 0x110,
|
||||
"expected VFP registers to be at offset 272");
|
||||
|
|
@ -1289,7 +1296,9 @@ inline v128 Registers_arm64::getVectorRegister(int) const {
|
|||
inline void Registers_arm64::setVectorRegister(int, v128) {
|
||||
_LIBUNWIND_ABORT("no arm64 vector register support yet");
|
||||
}
|
||||
#endif // _LIBUNWIND_TARGET_AARCH64
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_ARM)
|
||||
/// Registers_arm holds the register state of a thread in a 32-bit arm
|
||||
/// process.
|
||||
///
|
||||
|
|
@ -1395,8 +1404,8 @@ inline Registers_arm::Registers_arm(const void *registers)
|
|||
_saved_vfp_d16_d31(false),
|
||||
_saved_iwmmx(false),
|
||||
_saved_iwmmx_control(false) {
|
||||
static_assert(sizeof(Registers_arm) < sizeof(unw_context_t),
|
||||
"arm registers do not fit into unw_context_t");
|
||||
static_assert((check_fit<Registers_arm, unw_context_t>::does_fit),
|
||||
"arm registers do not fit into unw_context_t");
|
||||
// See unw_getcontext() note about data.
|
||||
memcpy(&_registers, registers, sizeof(_registers));
|
||||
memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
|
||||
|
|
@ -1711,6 +1720,10 @@ inline v128 Registers_arm::getVectorRegister(int) const {
|
|||
inline void Registers_arm::setVectorRegister(int, v128) {
|
||||
_LIBUNWIND_ABORT("ARM vector support not implemented");
|
||||
}
|
||||
#endif // _LIBUNWIND_TARGET_ARM
|
||||
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_OR1K)
|
||||
/// Registers_or1k holds the register state of a thread in an OpenRISC1000
|
||||
/// process.
|
||||
class _LIBUNWIND_HIDDEN Registers_or1k {
|
||||
|
|
@ -1745,8 +1758,8 @@ private:
|
|||
};
|
||||
|
||||
inline Registers_or1k::Registers_or1k(const void *registers) {
|
||||
static_assert(sizeof(Registers_or1k) < sizeof(unw_context_t),
|
||||
"or1k registers do not fit into unw_context_t");
|
||||
static_assert((check_fit<Registers_or1k, unw_context_t>::does_fit),
|
||||
"or1k registers do not fit into unw_context_t");
|
||||
memcpy(&_registers, static_cast<const uint8_t *>(registers),
|
||||
sizeof(_registers));
|
||||
}
|
||||
|
|
@ -1893,6 +1906,7 @@ inline const char *Registers_or1k::getRegisterName(int regNum) {
|
|||
}
|
||||
|
||||
}
|
||||
#endif // _LIBUNWIND_TARGET_OR1K
|
||||
} // namespace libunwind
|
||||
|
||||
#endif // __REGISTERS_HPP__
|
||||
|
|
|
|||
|
|
@ -438,39 +438,21 @@ extern "C" _Unwind_Reason_Code __aeabi_unwind_cpp_pr2(
|
|||
}
|
||||
|
||||
static _Unwind_Reason_Code
|
||||
unwind_phase1(unw_context_t *uc, _Unwind_Exception *exception_object) {
|
||||
unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) {
|
||||
// EHABI #7.3 discusses preserving the VRS in a "temporary VRS" during
|
||||
// phase 1 and then restoring it to the "primary VRS" for phase 2. The
|
||||
// effect is phase 2 doesn't see any of the VRS manipulations from phase 1.
|
||||
// In this implementation, the phases don't share the VRS backing store.
|
||||
// Instead, they are passed the original |uc| and they create a new VRS
|
||||
// from scratch thus achieving the same effect.
|
||||
unw_cursor_t cursor1;
|
||||
unw_init_local(&cursor1, uc);
|
||||
unw_init_local(cursor, uc);
|
||||
|
||||
// Walk each frame looking for a place to stop.
|
||||
for (bool handlerNotFound = true; handlerNotFound;) {
|
||||
|
||||
#if !_LIBUNWIND_ARM_EHABI
|
||||
// Ask libuwind to get next frame (skip over first which is
|
||||
// _Unwind_RaiseException).
|
||||
int stepResult = unw_step(&cursor1);
|
||||
if (stepResult == 0) {
|
||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_step() reached "
|
||||
"bottom => _URC_END_OF_STACK\n",
|
||||
static_cast<void *>(exception_object));
|
||||
return _URC_END_OF_STACK;
|
||||
} else if (stepResult < 0) {
|
||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_step failed => "
|
||||
"_URC_FATAL_PHASE1_ERROR\n",
|
||||
static_cast<void *>(exception_object));
|
||||
return _URC_FATAL_PHASE1_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
// See if frame has code to run (has personality routine).
|
||||
unw_proc_info_t frameInfo;
|
||||
if (unw_get_proc_info(&cursor1, &frameInfo) != UNW_ESUCCESS) {
|
||||
if (unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
|
||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_get_proc_info "
|
||||
"failed => _URC_FATAL_PHASE1_ERROR\n",
|
||||
static_cast<void *>(exception_object));
|
||||
|
|
@ -482,12 +464,12 @@ unwind_phase1(unw_context_t *uc, _Unwind_Exception *exception_object) {
|
|||
char functionBuf[512];
|
||||
const char *functionName = functionBuf;
|
||||
unw_word_t offset;
|
||||
if ((unw_get_proc_name(&cursor1, functionBuf, sizeof(functionBuf),
|
||||
if ((unw_get_proc_name(cursor, functionBuf, sizeof(functionBuf),
|
||||
&offset) != UNW_ESUCCESS) ||
|
||||
(frameInfo.start_ip + offset > frameInfo.end_ip))
|
||||
functionName = ".anonymous.";
|
||||
unw_word_t pc;
|
||||
unw_get_reg(&cursor1, UNW_REG_IP, &pc);
|
||||
unw_get_reg(cursor, UNW_REG_IP, &pc);
|
||||
_LIBUNWIND_TRACE_UNWINDING(
|
||||
"unwind_phase1(ex_ojb=%p): pc=0x%llX, start_ip=0x%llX, func=%s, "
|
||||
"lsda=0x%llX, personality=0x%llX\n",
|
||||
|
|
@ -505,7 +487,7 @@ unwind_phase1(unw_context_t *uc, _Unwind_Exception *exception_object) {
|
|||
"unwind_phase1(ex_ojb=%p): calling personality function %p\n",
|
||||
static_cast<void *>(exception_object),
|
||||
reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(p)));
|
||||
struct _Unwind_Context *context = (struct _Unwind_Context *)(&cursor1);
|
||||
struct _Unwind_Context *context = (struct _Unwind_Context *)(cursor);
|
||||
exception_object->pr_cache.fnstart = frameInfo.start_ip;
|
||||
exception_object->pr_cache.ehtp =
|
||||
(_Unwind_EHT_Header *)frameInfo.unwind_info;
|
||||
|
|
@ -553,12 +535,11 @@ unwind_phase1(unw_context_t *uc, _Unwind_Exception *exception_object) {
|
|||
return _URC_NO_REASON;
|
||||
}
|
||||
|
||||
static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc,
|
||||
static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor,
|
||||
_Unwind_Exception *exception_object,
|
||||
bool resume) {
|
||||
// See comment at the start of unwind_phase1 regarding VRS integrity.
|
||||
unw_cursor_t cursor2;
|
||||
unw_init_local(&cursor2, uc);
|
||||
unw_init_local(cursor, uc);
|
||||
|
||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)\n",
|
||||
static_cast<void *>(exception_object));
|
||||
|
|
@ -580,31 +561,16 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc,
|
|||
// for. After this, continue unwinding as if normal.
|
||||
//
|
||||
// See #7.4.6 for details.
|
||||
unw_set_reg(&cursor2, UNW_REG_IP,
|
||||
unw_set_reg(cursor, UNW_REG_IP,
|
||||
exception_object->unwinder_cache.reserved2);
|
||||
resume = false;
|
||||
}
|
||||
|
||||
#if !_LIBUNWIND_ARM_EHABI
|
||||
int stepResult = unw_step(&cursor2);
|
||||
if (stepResult == 0) {
|
||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step() reached "
|
||||
"bottom => _URC_END_OF_STACK\n",
|
||||
static_cast<void *>(exception_object));
|
||||
return _URC_END_OF_STACK;
|
||||
} else if (stepResult < 0) {
|
||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step failed => "
|
||||
"_URC_FATAL_PHASE1_ERROR\n",
|
||||
static_cast<void *>(exception_object));
|
||||
return _URC_FATAL_PHASE2_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Get info about this frame.
|
||||
unw_word_t sp;
|
||||
unw_proc_info_t frameInfo;
|
||||
unw_get_reg(&cursor2, UNW_REG_SP, &sp);
|
||||
if (unw_get_proc_info(&cursor2, &frameInfo) != UNW_ESUCCESS) {
|
||||
unw_get_reg(cursor, UNW_REG_SP, &sp);
|
||||
if (unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
|
||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_get_proc_info "
|
||||
"failed => _URC_FATAL_PHASE1_ERROR\n",
|
||||
static_cast<void *>(exception_object));
|
||||
|
|
@ -616,7 +582,7 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc,
|
|||
char functionBuf[512];
|
||||
const char *functionName = functionBuf;
|
||||
unw_word_t offset;
|
||||
if ((unw_get_proc_name(&cursor2, functionBuf, sizeof(functionBuf),
|
||||
if ((unw_get_proc_name(cursor, functionBuf, sizeof(functionBuf),
|
||||
&offset) != UNW_ESUCCESS) ||
|
||||
(frameInfo.start_ip + offset > frameInfo.end_ip))
|
||||
functionName = ".anonymous.";
|
||||
|
|
@ -632,7 +598,7 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc,
|
|||
if (frameInfo.handler != 0) {
|
||||
__personality_routine p =
|
||||
(__personality_routine)(long)(frameInfo.handler);
|
||||
struct _Unwind_Context *context = (struct _Unwind_Context *)(&cursor2);
|
||||
struct _Unwind_Context *context = (struct _Unwind_Context *)(cursor);
|
||||
// EHABI #7.2
|
||||
exception_object->pr_cache.fnstart = frameInfo.start_ip;
|
||||
exception_object->pr_cache.ehtp =
|
||||
|
|
@ -661,8 +627,8 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc,
|
|||
// We may get control back if landing pad calls _Unwind_Resume().
|
||||
if (_LIBUNWIND_TRACING_UNWINDING) {
|
||||
unw_word_t pc;
|
||||
unw_get_reg(&cursor2, UNW_REG_IP, &pc);
|
||||
unw_get_reg(&cursor2, UNW_REG_SP, &sp);
|
||||
unw_get_reg(cursor, UNW_REG_IP, &pc);
|
||||
unw_get_reg(cursor, UNW_REG_SP, &sp);
|
||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): re-entering "
|
||||
"user code with ip=0x%llX, sp=0x%llX\n",
|
||||
static_cast<void *>(exception_object),
|
||||
|
|
@ -673,10 +639,10 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc,
|
|||
// EHABI #7.4.1 says we need to preserve pc for when _Unwind_Resume
|
||||
// is called back, to find this same frame.
|
||||
unw_word_t pc;
|
||||
unw_get_reg(&cursor2, UNW_REG_IP, &pc);
|
||||
unw_get_reg(cursor, UNW_REG_IP, &pc);
|
||||
exception_object->unwinder_cache.reserved2 = (uint32_t)pc;
|
||||
}
|
||||
unw_resume(&cursor2);
|
||||
unw_resume(cursor);
|
||||
// unw_resume() only returns if there was an error.
|
||||
return _URC_FATAL_PHASE2_ERROR;
|
||||
|
||||
|
|
@ -705,6 +671,7 @@ _Unwind_RaiseException(_Unwind_Exception *exception_object) {
|
|||
_LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)\n",
|
||||
static_cast<void *>(exception_object));
|
||||
unw_context_t uc;
|
||||
unw_cursor_t cursor;
|
||||
unw_getcontext(&uc);
|
||||
|
||||
// This field for is for compatibility with GCC to say this isn't a forced
|
||||
|
|
@ -712,12 +679,12 @@ _Unwind_RaiseException(_Unwind_Exception *exception_object) {
|
|||
exception_object->unwinder_cache.reserved1 = 0;
|
||||
|
||||
// phase 1: the search phase
|
||||
_Unwind_Reason_Code phase1 = unwind_phase1(&uc, exception_object);
|
||||
_Unwind_Reason_Code phase1 = unwind_phase1(&uc, &cursor, exception_object);
|
||||
if (phase1 != _URC_NO_REASON)
|
||||
return phase1;
|
||||
|
||||
// phase 2: the clean up phase
|
||||
return unwind_phase2(&uc, exception_object, false);
|
||||
return unwind_phase2(&uc, &cursor, exception_object, false);
|
||||
}
|
||||
|
||||
_LIBUNWIND_EXPORT void _Unwind_Complete(_Unwind_Exception* exception_object) {
|
||||
|
|
@ -742,12 +709,13 @@ _Unwind_Resume(_Unwind_Exception *exception_object) {
|
|||
_LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)\n",
|
||||
static_cast<void *>(exception_object));
|
||||
unw_context_t uc;
|
||||
unw_cursor_t cursor;
|
||||
unw_getcontext(&uc);
|
||||
|
||||
// _Unwind_RaiseException on EHABI will always set the reserved1 field to 0,
|
||||
// which is in the same position as private_1 below.
|
||||
// TODO(ajwong): Who wronte the above? Why is it true?
|
||||
unwind_phase2(&uc, exception_object, true);
|
||||
unwind_phase2(&uc, &cursor, exception_object, true);
|
||||
|
||||
// Clients assume _Unwind_Resume() does not return, so all we can do is abort.
|
||||
_LIBUNWIND_ABORT("_Unwind_Resume() can't return");
|
||||
|
|
|
|||
|
|
@ -481,30 +481,39 @@ private:
|
|||
return stepWithCompactEncoding(dummy);
|
||||
}
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_X86_64)
|
||||
int stepWithCompactEncoding(Registers_x86_64 &) {
|
||||
return CompactUnwinder_x86_64<A>::stepWithCompactEncoding(
|
||||
_info.format, _info.start_ip, _addressSpace, _registers);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_I386)
|
||||
int stepWithCompactEncoding(Registers_x86 &) {
|
||||
return CompactUnwinder_x86<A>::stepWithCompactEncoding(
|
||||
_info.format, (uint32_t)_info.start_ip, _addressSpace, _registers);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_PPC)
|
||||
int stepWithCompactEncoding(Registers_ppc &) {
|
||||
return UNW_EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_AARCH64)
|
||||
int stepWithCompactEncoding(Registers_arm64 &) {
|
||||
return CompactUnwinder_arm64<A>::stepWithCompactEncoding(
|
||||
_info.format, _info.start_ip, _addressSpace, _registers);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool compactSaysUseDwarf(uint32_t *offset=NULL) const {
|
||||
R dummy;
|
||||
return compactSaysUseDwarf(dummy, offset);
|
||||
}
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_X86_64)
|
||||
bool compactSaysUseDwarf(Registers_x86_64 &, uint32_t *offset) const {
|
||||
if ((_info.format & UNWIND_X86_64_MODE_MASK) == UNWIND_X86_64_MODE_DWARF) {
|
||||
if (offset)
|
||||
|
|
@ -513,7 +522,9 @@ private:
|
|||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_I386)
|
||||
bool compactSaysUseDwarf(Registers_x86 &, uint32_t *offset) const {
|
||||
if ((_info.format & UNWIND_X86_MODE_MASK) == UNWIND_X86_MODE_DWARF) {
|
||||
if (offset)
|
||||
|
|
@ -522,11 +533,15 @@ private:
|
|||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_PPC)
|
||||
bool compactSaysUseDwarf(Registers_ppc &, uint32_t *) const {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_AARCH64)
|
||||
bool compactSaysUseDwarf(Registers_arm64 &, uint32_t *offset) const {
|
||||
if ((_info.format & UNWIND_ARM64_MODE_MASK) == UNWIND_ARM64_MODE_DWARF) {
|
||||
if (offset)
|
||||
|
|
@ -535,6 +550,7 @@ private:
|
|||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#endif // _LIBUNWIND_SUPPORT_COMPACT_UNWIND
|
||||
|
||||
#if _LIBUNWIND_SUPPORT_DWARF_UNWIND
|
||||
|
|
@ -543,25 +559,35 @@ private:
|
|||
return dwarfEncoding(dummy);
|
||||
}
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_X86_64)
|
||||
compact_unwind_encoding_t dwarfEncoding(Registers_x86_64 &) const {
|
||||
return UNWIND_X86_64_MODE_DWARF;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_I386)
|
||||
compact_unwind_encoding_t dwarfEncoding(Registers_x86 &) const {
|
||||
return UNWIND_X86_MODE_DWARF;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_PPC)
|
||||
compact_unwind_encoding_t dwarfEncoding(Registers_ppc &) const {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_AARCH64)
|
||||
compact_unwind_encoding_t dwarfEncoding(Registers_arm64 &) const {
|
||||
return UNWIND_ARM64_MODE_DWARF;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (_LIBUNWIND_TARGET_OR1K)
|
||||
compact_unwind_encoding_t dwarfEncoding(Registers_or1k &) const {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif // _LIBUNWIND_SUPPORT_DWARF_UNWIND
|
||||
|
||||
|
||||
|
|
@ -577,7 +603,7 @@ template <typename A, typename R>
|
|||
UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as)
|
||||
: _addressSpace(as), _registers(context), _unwindInfoMissing(false),
|
||||
_isSignalFrame(false) {
|
||||
static_assert(sizeof(UnwindCursor<A, R>) < sizeof(unw_cursor_t),
|
||||
static_assert((check_fit<UnwindCursor<A, R>, unw_cursor_t>::does_fit),
|
||||
"UnwindCursor<> does not fit in unw_cursor_t");
|
||||
memset(&_info, 0, sizeof(_info));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,16 +33,15 @@
|
|||
#if !_LIBUNWIND_ARM_EHABI
|
||||
|
||||
static _Unwind_Reason_Code
|
||||
unwind_phase1(unw_context_t *uc, _Unwind_Exception *exception_object) {
|
||||
unw_cursor_t cursor1;
|
||||
unw_init_local(&cursor1, uc);
|
||||
unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) {
|
||||
unw_init_local(cursor, uc);
|
||||
|
||||
// Walk each frame looking for a place to stop.
|
||||
bool handlerNotFound = true;
|
||||
while (handlerNotFound) {
|
||||
// Ask libuwind to get next frame (skip over first which is
|
||||
// _Unwind_RaiseException).
|
||||
int stepResult = unw_step(&cursor1);
|
||||
int stepResult = unw_step(cursor);
|
||||
if (stepResult == 0) {
|
||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_step() reached "
|
||||
"bottom => _URC_END_OF_STACK\n",
|
||||
|
|
@ -58,7 +57,7 @@ unwind_phase1(unw_context_t *uc, _Unwind_Exception *exception_object) {
|
|||
// See if frame has code to run (has personality routine).
|
||||
unw_proc_info_t frameInfo;
|
||||
unw_word_t sp;
|
||||
if (unw_get_proc_info(&cursor1, &frameInfo) != UNW_ESUCCESS) {
|
||||
if (unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
|
||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_get_proc_info "
|
||||
"failed => _URC_FATAL_PHASE1_ERROR\n",
|
||||
(void *)exception_object);
|
||||
|
|
@ -70,12 +69,12 @@ unwind_phase1(unw_context_t *uc, _Unwind_Exception *exception_object) {
|
|||
char functionBuf[512];
|
||||
const char *functionName = functionBuf;
|
||||
unw_word_t offset;
|
||||
if ((unw_get_proc_name(&cursor1, functionBuf, sizeof(functionBuf),
|
||||
if ((unw_get_proc_name(cursor, functionBuf, sizeof(functionBuf),
|
||||
&offset) != UNW_ESUCCESS) ||
|
||||
(frameInfo.start_ip + offset > frameInfo.end_ip))
|
||||
functionName = ".anonymous.";
|
||||
unw_word_t pc;
|
||||
unw_get_reg(&cursor1, UNW_REG_IP, &pc);
|
||||
unw_get_reg(cursor, UNW_REG_IP, &pc);
|
||||
_LIBUNWIND_TRACE_UNWINDING(
|
||||
"unwind_phase1(ex_ojb=%p): pc=0x%" PRIx64 ", start_ip=0x%" PRIx64
|
||||
", func=%s, lsda=0x%" PRIx64 ", personality=0x%" PRIx64 "\n",
|
||||
|
|
@ -93,13 +92,13 @@ unwind_phase1(unw_context_t *uc, _Unwind_Exception *exception_object) {
|
|||
(void *)exception_object, (void *)(uintptr_t)p);
|
||||
_Unwind_Reason_Code personalityResult =
|
||||
(*p)(1, _UA_SEARCH_PHASE, exception_object->exception_class,
|
||||
exception_object, (struct _Unwind_Context *)(&cursor1));
|
||||
exception_object, (struct _Unwind_Context *)(cursor));
|
||||
switch (personalityResult) {
|
||||
case _URC_HANDLER_FOUND:
|
||||
// found a catch clause or locals that need destructing in this frame
|
||||
// stop search and remember stack pointer at the frame
|
||||
handlerNotFound = false;
|
||||
unw_get_reg(&cursor1, UNW_REG_SP, &sp);
|
||||
unw_get_reg(cursor, UNW_REG_SP, &sp);
|
||||
exception_object->private_2 = (uintptr_t)sp;
|
||||
_LIBUNWIND_TRACE_UNWINDING(
|
||||
"unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND \n",
|
||||
|
|
@ -127,9 +126,8 @@ unwind_phase1(unw_context_t *uc, _Unwind_Exception *exception_object) {
|
|||
|
||||
|
||||
static _Unwind_Reason_Code
|
||||
unwind_phase2(unw_context_t *uc, _Unwind_Exception *exception_object) {
|
||||
unw_cursor_t cursor2;
|
||||
unw_init_local(&cursor2, uc);
|
||||
unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) {
|
||||
unw_init_local(cursor, uc);
|
||||
|
||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)\n",
|
||||
(void *)exception_object);
|
||||
|
|
@ -139,7 +137,7 @@ unwind_phase2(unw_context_t *uc, _Unwind_Exception *exception_object) {
|
|||
|
||||
// Ask libuwind to get next frame (skip over first which is
|
||||
// _Unwind_RaiseException).
|
||||
int stepResult = unw_step(&cursor2);
|
||||
int stepResult = unw_step(cursor);
|
||||
if (stepResult == 0) {
|
||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step() reached "
|
||||
"bottom => _URC_END_OF_STACK\n",
|
||||
|
|
@ -155,8 +153,8 @@ unwind_phase2(unw_context_t *uc, _Unwind_Exception *exception_object) {
|
|||
// Get info about this frame.
|
||||
unw_word_t sp;
|
||||
unw_proc_info_t frameInfo;
|
||||
unw_get_reg(&cursor2, UNW_REG_SP, &sp);
|
||||
if (unw_get_proc_info(&cursor2, &frameInfo) != UNW_ESUCCESS) {
|
||||
unw_get_reg(cursor, UNW_REG_SP, &sp);
|
||||
if (unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
|
||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_get_proc_info "
|
||||
"failed => _URC_FATAL_PHASE1_ERROR\n",
|
||||
(void *)exception_object);
|
||||
|
|
@ -168,7 +166,7 @@ unwind_phase2(unw_context_t *uc, _Unwind_Exception *exception_object) {
|
|||
char functionBuf[512];
|
||||
const char *functionName = functionBuf;
|
||||
unw_word_t offset;
|
||||
if ((unw_get_proc_name(&cursor2, functionBuf, sizeof(functionBuf),
|
||||
if ((unw_get_proc_name(cursor, functionBuf, sizeof(functionBuf),
|
||||
&offset) != UNW_ESUCCESS) ||
|
||||
(frameInfo.start_ip + offset > frameInfo.end_ip))
|
||||
functionName = ".anonymous.";
|
||||
|
|
@ -191,7 +189,7 @@ unwind_phase2(unw_context_t *uc, _Unwind_Exception *exception_object) {
|
|||
}
|
||||
_Unwind_Reason_Code personalityResult =
|
||||
(*p)(1, action, exception_object->exception_class, exception_object,
|
||||
(struct _Unwind_Context *)(&cursor2));
|
||||
(struct _Unwind_Context *)(cursor));
|
||||
switch (personalityResult) {
|
||||
case _URC_CONTINUE_UNWIND:
|
||||
// Continue unwinding
|
||||
|
|
@ -212,14 +210,14 @@ unwind_phase2(unw_context_t *uc, _Unwind_Exception *exception_object) {
|
|||
// We may get control back if landing pad calls _Unwind_Resume().
|
||||
if (_LIBUNWIND_TRACING_UNWINDING) {
|
||||
unw_word_t pc;
|
||||
unw_get_reg(&cursor2, UNW_REG_IP, &pc);
|
||||
unw_get_reg(&cursor2, UNW_REG_SP, &sp);
|
||||
unw_get_reg(cursor, UNW_REG_IP, &pc);
|
||||
unw_get_reg(cursor, UNW_REG_SP, &sp);
|
||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): re-entering "
|
||||
"user code with ip=0x%" PRIx64
|
||||
", sp=0x%" PRIx64 "\n",
|
||||
(void *)exception_object, pc, sp);
|
||||
}
|
||||
unw_resume(&cursor2);
|
||||
unw_resume(cursor);
|
||||
// unw_resume() only returns if there was an error.
|
||||
return _URC_FATAL_PHASE2_ERROR;
|
||||
default:
|
||||
|
|
@ -237,18 +235,17 @@ unwind_phase2(unw_context_t *uc, _Unwind_Exception *exception_object) {
|
|||
}
|
||||
|
||||
static _Unwind_Reason_Code
|
||||
unwind_phase2_forced(unw_context_t *uc,
|
||||
unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,
|
||||
_Unwind_Exception *exception_object,
|
||||
_Unwind_Stop_Fn stop, void *stop_parameter) {
|
||||
unw_cursor_t cursor2;
|
||||
unw_init_local(&cursor2, uc);
|
||||
unw_init_local(cursor, uc);
|
||||
|
||||
// Walk each frame until we reach where search phase said to stop
|
||||
while (unw_step(&cursor2) > 0) {
|
||||
while (unw_step(cursor) > 0) {
|
||||
|
||||
// Update info about this frame.
|
||||
unw_proc_info_t frameInfo;
|
||||
if (unw_get_proc_info(&cursor2, &frameInfo) != UNW_ESUCCESS) {
|
||||
if (unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
|
||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): unw_step "
|
||||
"failed => _URC_END_OF_STACK\n",
|
||||
(void *)exception_object);
|
||||
|
|
@ -260,7 +257,7 @@ unwind_phase2_forced(unw_context_t *uc,
|
|||
char functionBuf[512];
|
||||
const char *functionName = functionBuf;
|
||||
unw_word_t offset;
|
||||
if ((unw_get_proc_name(&cursor2, functionBuf, sizeof(functionBuf),
|
||||
if ((unw_get_proc_name(cursor, functionBuf, sizeof(functionBuf),
|
||||
&offset) != UNW_ESUCCESS) ||
|
||||
(frameInfo.start_ip + offset > frameInfo.end_ip))
|
||||
functionName = ".anonymous.";
|
||||
|
|
@ -276,7 +273,7 @@ unwind_phase2_forced(unw_context_t *uc,
|
|||
(_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE);
|
||||
_Unwind_Reason_Code stopResult =
|
||||
(*stop)(1, action, exception_object->exception_class, exception_object,
|
||||
(struct _Unwind_Context *)(&cursor2), stop_parameter);
|
||||
(struct _Unwind_Context *)(cursor), stop_parameter);
|
||||
_LIBUNWIND_TRACE_UNWINDING(
|
||||
"unwind_phase2_forced(ex_ojb=%p): stop function returned %d\n",
|
||||
(void *)exception_object, stopResult);
|
||||
|
|
@ -296,7 +293,7 @@ unwind_phase2_forced(unw_context_t *uc,
|
|||
(void *)exception_object, (void *)(uintptr_t)p);
|
||||
_Unwind_Reason_Code personalityResult =
|
||||
(*p)(1, action, exception_object->exception_class, exception_object,
|
||||
(struct _Unwind_Context *)(&cursor2));
|
||||
(struct _Unwind_Context *)(cursor));
|
||||
switch (personalityResult) {
|
||||
case _URC_CONTINUE_UNWIND:
|
||||
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
|
||||
|
|
@ -311,7 +308,7 @@ unwind_phase2_forced(unw_context_t *uc,
|
|||
"_URC_INSTALL_CONTEXT\n",
|
||||
(void *)exception_object);
|
||||
// We may get control back if landing pad calls _Unwind_Resume().
|
||||
unw_resume(&cursor2);
|
||||
unw_resume(cursor);
|
||||
break;
|
||||
default:
|
||||
// Personality routine returned an unknown result code.
|
||||
|
|
@ -332,7 +329,7 @@ unwind_phase2_forced(unw_context_t *uc,
|
|||
_Unwind_Action lastAction =
|
||||
(_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE | _UA_END_OF_STACK);
|
||||
(*stop)(1, lastAction, exception_object->exception_class, exception_object,
|
||||
(struct _Unwind_Context *)(&cursor2), stop_parameter);
|
||||
(struct _Unwind_Context *)(cursor), stop_parameter);
|
||||
|
||||
// Clean up phase did not resume at the frame that the search phase said it
|
||||
// would.
|
||||
|
|
@ -346,6 +343,7 @@ _Unwind_RaiseException(_Unwind_Exception *exception_object) {
|
|||
_LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)\n",
|
||||
(void *)exception_object);
|
||||
unw_context_t uc;
|
||||
unw_cursor_t cursor;
|
||||
unw_getcontext(&uc);
|
||||
|
||||
// Mark that this is a non-forced unwind, so _Unwind_Resume()
|
||||
|
|
@ -354,12 +352,12 @@ _Unwind_RaiseException(_Unwind_Exception *exception_object) {
|
|||
exception_object->private_2 = 0;
|
||||
|
||||
// phase 1: the search phase
|
||||
_Unwind_Reason_Code phase1 = unwind_phase1(&uc, exception_object);
|
||||
_Unwind_Reason_Code phase1 = unwind_phase1(&uc, &cursor, exception_object);
|
||||
if (phase1 != _URC_NO_REASON)
|
||||
return phase1;
|
||||
|
||||
// phase 2: the clean up phase
|
||||
return unwind_phase2(&uc, exception_object);
|
||||
return unwind_phase2(&uc, &cursor, exception_object);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -379,14 +377,15 @@ _LIBUNWIND_EXPORT void
|
|||
_Unwind_Resume(_Unwind_Exception *exception_object) {
|
||||
_LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)\n", (void *)exception_object);
|
||||
unw_context_t uc;
|
||||
unw_cursor_t cursor;
|
||||
unw_getcontext(&uc);
|
||||
|
||||
if (exception_object->private_1 != 0)
|
||||
unwind_phase2_forced(&uc, exception_object,
|
||||
unwind_phase2_forced(&uc, &cursor, exception_object,
|
||||
(_Unwind_Stop_Fn) exception_object->private_1,
|
||||
(void *)exception_object->private_2);
|
||||
else
|
||||
unwind_phase2(&uc, exception_object);
|
||||
unwind_phase2(&uc, &cursor, exception_object);
|
||||
|
||||
// Clients assume _Unwind_Resume() does not return, so all we can do is abort.
|
||||
_LIBUNWIND_ABORT("_Unwind_Resume() can't return");
|
||||
|
|
@ -403,6 +402,7 @@ _Unwind_ForcedUnwind(_Unwind_Exception *exception_object,
|
|||
_LIBUNWIND_TRACE_API("_Unwind_ForcedUnwind(ex_obj=%p, stop=%p)\n",
|
||||
(void *)exception_object, (void *)(uintptr_t)stop);
|
||||
unw_context_t uc;
|
||||
unw_cursor_t cursor;
|
||||
unw_getcontext(&uc);
|
||||
|
||||
// Mark that this is a forced unwind, so _Unwind_Resume() can do
|
||||
|
|
@ -411,7 +411,7 @@ _Unwind_ForcedUnwind(_Unwind_Exception *exception_object,
|
|||
exception_object->private_2 = (uintptr_t) stop_parameter;
|
||||
|
||||
// do it
|
||||
return unwind_phase2_forced(&uc, exception_object, stop, stop_parameter);
|
||||
return unwind_phase2_forced(&uc, &cursor, exception_object, stop, stop_parameter);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -282,8 +282,8 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind15Registers_arm646jumptoEv)
|
|||
ldp x22,x23, [x0, #0x0B0]
|
||||
ldp x24,x25, [x0, #0x0C0]
|
||||
ldp x26,x27, [x0, #0x0D0]
|
||||
ldp x28,fp, [x0, #0x0E0]
|
||||
ldr lr, [x0, #0x100] // restore pc into lr
|
||||
ldp x28,x29, [x0, #0x0E0]
|
||||
ldr x30, [x0, #0x100] // restore pc into lr
|
||||
ldr x1, [x0, #0x0F8]
|
||||
mov sp,x1 // restore sp
|
||||
|
||||
|
|
@ -306,7 +306,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind15Registers_arm646jumptoEv)
|
|||
ldr d31, [x0, #0x208]
|
||||
|
||||
ldp x0, x1, [x0, #0x000] // restore x0,x1
|
||||
ret lr // jump to pc
|
||||
ret x30 // jump to pc
|
||||
|
||||
#elif defined(__arm__) && !defined(__APPLE__)
|
||||
|
||||
|
|
|
|||
|
|
@ -263,11 +263,11 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
|
|||
stp x22,x23, [x0, #0x0B0]
|
||||
stp x24,x25, [x0, #0x0C0]
|
||||
stp x26,x27, [x0, #0x0D0]
|
||||
stp x28,fp, [x0, #0x0E0]
|
||||
str lr, [x0, #0x0F0]
|
||||
stp x28,x29, [x0, #0x0E0]
|
||||
str x30, [x0, #0x0F0]
|
||||
mov x1,sp
|
||||
str x1, [x0, #0x0F8]
|
||||
str lr, [x0, #0x100] // store return address as pc
|
||||
str x30, [x0, #0x100] // store return address as pc
|
||||
// skip cpsr
|
||||
stp d0, d1, [x0, #0x110]
|
||||
stp d2, d3, [x0, #0x120]
|
||||
|
|
|
|||
111
src/config.h
111
src/config.h
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Define static_assert() unless already defined by compiler.
|
||||
#ifndef __has_feature
|
||||
|
|
@ -29,28 +30,6 @@
|
|||
|
||||
// Platform specific configuration defines.
|
||||
#ifdef __APPLE__
|
||||
#include <Availability.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void __assert_rtn(const char *, const char *, int, const char *)
|
||||
__attribute__((noreturn));
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#define _LIBUNWIND_BUILD_ZERO_COST_APIS (defined(__i386__) || \
|
||||
defined(__x86_64__) || \
|
||||
defined(__arm64__) || \
|
||||
defined(__mips__))
|
||||
#define _LIBUNWIND_BUILD_SJLJ_APIS defined(__arm__)
|
||||
#define _LIBUNWIND_SUPPORT_FRAME_APIS (defined(__i386__) || \
|
||||
defined(__x86_64__))
|
||||
#define _LIBUNWIND_EXPORT __attribute__((visibility("default")))
|
||||
#define _LIBUNWIND_HIDDEN __attribute__((visibility("hidden")))
|
||||
#define _LIBUNWIND_LOG(msg, ...) fprintf(stderr, "libuwind: " msg, __VA_ARGS__)
|
||||
#define _LIBUNWIND_ABORT(msg) __assert_rtn(__func__, __FILE__, __LINE__, msg)
|
||||
|
||||
#if defined(FOR_DYLD)
|
||||
#define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 1
|
||||
#define _LIBUNWIND_SUPPORT_DWARF_UNWIND 0
|
||||
|
|
@ -60,35 +39,51 @@
|
|||
#define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
|
||||
#define _LIBUNWIND_SUPPORT_DWARF_INDEX 0
|
||||
#endif
|
||||
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
|
||||
static inline void assert_rtn(const char* func, const char* file, int line, const char* msg) __attribute__ ((noreturn));
|
||||
static inline void assert_rtn(const char* func, const char* file, int line, const char* msg) {
|
||||
fprintf(stderr, "libunwind: %s %s:%d - %s\n", func, file, line, msg);
|
||||
assert(false);
|
||||
abort();
|
||||
}
|
||||
|
||||
#define _LIBUNWIND_BUILD_ZERO_COST_APIS (defined(__i386__) || \
|
||||
defined(__x86_64__) || \
|
||||
defined(__arm__) || \
|
||||
defined(__aarch64__))
|
||||
#define _LIBUNWIND_BUILD_SJLJ_APIS 0
|
||||
#define _LIBUNWIND_SUPPORT_FRAME_APIS (defined(__i386__) || \
|
||||
defined(__x86_64__))
|
||||
#define _LIBUNWIND_EXPORT __attribute__((visibility("default")))
|
||||
#define _LIBUNWIND_HIDDEN __attribute__((visibility("hidden")))
|
||||
#define _LIBUNWIND_LOG(msg, ...) fprintf(stderr, "libuwind: " msg, __VA_ARGS__)
|
||||
#define _LIBUNWIND_ABORT(msg) assert_rtn(__func__, __FILE__, __LINE__, msg)
|
||||
|
||||
#define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 0
|
||||
#define _LIBUNWIND_SUPPORT_DWARF_UNWIND !defined(__arm__) || \
|
||||
defined(__ARM_DWARF_EH__)
|
||||
#define _LIBUNWIND_SUPPORT_DWARF_INDEX _LIBUNWIND_SUPPORT_DWARF_UNWIND
|
||||
#if defined(__ARM_DWARF_EH__) || !defined(__arm__)
|
||||
#define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 0
|
||||
#define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
|
||||
#define _LIBUNWIND_SUPPORT_DWARF_INDEX 1
|
||||
#else
|
||||
#define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 0
|
||||
#define _LIBUNWIND_SUPPORT_DWARF_UNWIND 0
|
||||
#define _LIBUNWIND_SUPPORT_DWARF_INDEX 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// FIXME: these macros are not correct for COFF targets
|
||||
#define _LIBUNWIND_EXPORT __attribute__((visibility("default")))
|
||||
#define _LIBUNWIND_HIDDEN __attribute__((visibility("hidden")))
|
||||
|
||||
#if (defined(__APPLE__) && defined(__arm__)) || defined(__USING_SJLJ_EXCEPTIONS__)
|
||||
#define _LIBUNWIND_BUILD_SJLJ_APIS 1
|
||||
#else
|
||||
#define _LIBUNWIND_BUILD_SJLJ_APIS 0
|
||||
#endif
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
#define _LIBUNWIND_SUPPORT_FRAME_APIS 1
|
||||
#else
|
||||
#define _LIBUNWIND_SUPPORT_FRAME_APIS 0
|
||||
#endif
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__) || \
|
||||
(!defined(__APPLE__) && defined(__arm__)) || \
|
||||
(defined(__arm64__) || defined(__aarch64__)) || \
|
||||
(defined(__APPLE__) && defined(__mips__))
|
||||
#define _LIBUNWIND_BUILD_ZERO_COST_APIS 1
|
||||
#else
|
||||
#define _LIBUNWIND_BUILD_ZERO_COST_APIS 0
|
||||
#endif
|
||||
|
||||
#define _LIBUNWIND_ABORT(msg) \
|
||||
do { \
|
||||
fprintf(stderr, "libunwind: %s %s:%d - %s\n", __func__, __FILE__, \
|
||||
__LINE__, msg); \
|
||||
fflush(stderr); \
|
||||
abort(); \
|
||||
} while (0)
|
||||
#define _LIBUNWIND_LOG(msg, ...) fprintf(stderr, "libuwind: " msg, __VA_ARGS__)
|
||||
|
||||
// Macros that define away in non-Debug builds
|
||||
#ifdef NDEBUG
|
||||
|
|
@ -124,5 +119,25 @@
|
|||
#define _LIBUNWIND_TRACING_UNWINDING logUnwinding()
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
// Used to fit UnwindCursor and Registers_xxx types against unw_context_t /
|
||||
// unw_cursor_t sized memory blocks.
|
||||
#if defined(_LIBUNWIND_IS_NATIVE_ONLY)
|
||||
# define COMP_OP ==
|
||||
#else
|
||||
# define COMP_OP <
|
||||
#endif
|
||||
template <typename _Type, typename _Mem>
|
||||
struct check_fit {
|
||||
template <typename T>
|
||||
struct blk_count {
|
||||
static const size_t count =
|
||||
(sizeof(T) + sizeof(uint64_t) - 1) / sizeof(uint64_t);
|
||||
};
|
||||
static const bool does_fit =
|
||||
(blk_count<_Type>::count COMP_OP blk_count<_Mem>::count);
|
||||
};
|
||||
#undef COMP_OP
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // LIBUNWIND_CONFIG_H
|
||||
|
|
|
|||
|
|
@ -45,30 +45,27 @@ _LIBUNWIND_EXPORT int unw_init_local(unw_cursor_t *cursor,
|
|||
_LIBUNWIND_TRACE_API("unw_init_local(cursor=%p, context=%p)\n",
|
||||
static_cast<void *>(cursor),
|
||||
static_cast<void *>(context));
|
||||
// Use "placement new" to allocate UnwindCursor in the cursor buffer.
|
||||
#if defined(__i386__)
|
||||
new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_x86>(
|
||||
context, LocalAddressSpace::sThisAddressSpace);
|
||||
# define REGISTER_KIND Registers_x86
|
||||
#elif defined(__x86_64__)
|
||||
new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_x86_64>(
|
||||
context, LocalAddressSpace::sThisAddressSpace);
|
||||
# define REGISTER_KIND Registers_x86_64
|
||||
#elif defined(__ppc__)
|
||||
new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_ppc>(
|
||||
context, LocalAddressSpace::sThisAddressSpace);
|
||||
#elif defined(__arm64__) || defined(__aarch64__)
|
||||
new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_arm64>(
|
||||
context, LocalAddressSpace::sThisAddressSpace);
|
||||
# define REGISTER_KIND Registers_ppc
|
||||
#elif defined(__aarch64__)
|
||||
# define REGISTER_KIND Registers_arm64
|
||||
#elif _LIBUNWIND_ARM_EHABI
|
||||
new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_arm>(
|
||||
context, LocalAddressSpace::sThisAddressSpace);
|
||||
# define REGISTER_KIND Registers_arm
|
||||
#elif defined(__or1k__)
|
||||
new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_or1k>(
|
||||
context, LocalAddressSpace::sThisAddressSpace);
|
||||
# define REGISTER_KIND Registers_or1k
|
||||
#elif defined(__mips__)
|
||||
#warning The MIPS architecture is not supported.
|
||||
# warning The MIPS architecture is not supported.
|
||||
#else
|
||||
#error Architecture not supported
|
||||
# error Architecture not supported
|
||||
#endif
|
||||
// Use "placement new" to allocate UnwindCursor in the cursor buffer.
|
||||
new ((void *)cursor) UnwindCursor<LocalAddressSpace, REGISTER_KIND>(
|
||||
context, LocalAddressSpace::sThisAddressSpace);
|
||||
#undef REGISTER_KIND
|
||||
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
|
||||
co->setInfoBasedOnIPRegister();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue