summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEd Maste <emaste@FreeBSD.org>2016-07-05 18:00:23 +0000
committerEd Maste <emaste@FreeBSD.org>2016-07-05 18:00:23 +0000
commite2fc5d984d0bcb0eba77ce5030f053dfc0eae2a2 (patch)
treeb21dcab8cdbe07ded020ad2c036bd62d4b8d88ce
parentca83053650e2c15214b17a869aae5d544c9a59da (diff)
downloadsrc-test2-vendor/llvm-libunwind/libunwind-r272680.tar.gz
src-test2-vendor/llvm-libunwind/libunwind-r272680.zip
Import LLVM libunwind snapshot revision 272680vendor/llvm-libunwind/libunwind-r272680
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/
-rw-r--r--include/__libunwind_config.h39
-rw-r--r--include/libunwind.h4
-rw-r--r--src/AddressSpace.hpp5
-rw-r--r--src/CompactUnwinder.hpp6
-rw-r--r--src/Registers.hpp38
-rw-r--r--src/Unwind-EHABI.cpp76
-rw-r--r--src/UnwindCursor.hpp28
-rw-r--r--src/UnwindLevel1.c70
-rw-r--r--src/UnwindRegistersRestore.S6
-rw-r--r--src/UnwindRegistersSave.S6
-rw-r--r--src/config.h105
-rw-r--r--src/libunwind.cpp29
12 files changed, 239 insertions, 173 deletions
diff --git a/include/__libunwind_config.h b/include/__libunwind_config.h
index 63393d3058e8..099d133e744b 100644
--- a/include/__libunwind_config.h
+++ b/include/__libunwind_config.h
@@ -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__
diff --git a/include/libunwind.h b/include/libunwind.h
index 6045becc01aa..c5b9633b1506 100644
--- a/include/libunwind.h
+++ b/include/libunwind.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;
diff --git a/src/AddressSpace.hpp b/src/AddressSpace.hpp
index 73013c73ff71..da1b6a43e492 100644
--- a/src/AddressSpace.hpp
+++ b/src/AddressSpace.hpp
@@ -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
diff --git a/src/CompactUnwinder.hpp b/src/CompactUnwinder.hpp
index cd9ce3e5ecd8..f528fba984db 100644
--- a/src/CompactUnwinder.hpp
+++ b/src/CompactUnwinder.hpp
@@ -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
diff --git a/src/Registers.hpp b/src/Registers.hpp
index 875ea2063c84..ab8742840004 100644
--- a/src/Registers.hpp
+++ b/src/Registers.hpp
@@ -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__
diff --git a/src/Unwind-EHABI.cpp b/src/Unwind-EHABI.cpp
index bc3df41f35f7..5950c6902e38 100644
--- a/src/Unwind-EHABI.cpp
+++ b/src/Unwind-EHABI.cpp
@@ -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");
diff --git a/src/UnwindCursor.hpp b/src/UnwindCursor.hpp
index 90683164ff24..18a780919b11 100644
--- a/src/UnwindCursor.hpp
+++ b/src/UnwindCursor.hpp
@@ -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));
}
diff --git a/src/UnwindLevel1.c b/src/UnwindLevel1.c
index ce6eb286bab3..7294f255407e 100644
--- a/src/UnwindLevel1.c
+++ b/src/UnwindLevel1.c
@@ -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);
}
diff --git a/src/UnwindRegistersRestore.S b/src/UnwindRegistersRestore.S
index 3a4ea62f6e29..d5ecc6ed2acd 100644
--- a/src/UnwindRegistersRestore.S
+++ b/src/UnwindRegistersRestore.S
@@ -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__)
diff --git a/src/UnwindRegistersSave.S b/src/UnwindRegistersSave.S
index f84b7114f777..82becffa0e45 100644
--- a/src/UnwindRegistersSave.S
+++ b/src/UnwindRegistersSave.S
@@ -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]
diff --git a/src/config.h b/src/config.h
index ecc0a6b4465d..a50222f7c90d 100644
--- a/src/config.h
+++ b/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>
+ #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")))
- 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();
- }
+#if (defined(__APPLE__) && defined(__arm__)) || defined(__USING_SJLJ_EXCEPTIONS__)
+#define _LIBUNWIND_BUILD_SJLJ_APIS 1
+#else
+#define _LIBUNWIND_BUILD_SJLJ_APIS 0
+#endif
- #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)
+#if defined(__i386__) || defined(__x86_64__)
+#define _LIBUNWIND_SUPPORT_FRAME_APIS 1
+#else
+#define _LIBUNWIND_SUPPORT_FRAME_APIS 0
+#endif
- #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(__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
diff --git a/src/libunwind.cpp b/src/libunwind.cpp
index f9f32f00ece2..95f2dc020dc4 100644
--- a/src/libunwind.cpp
+++ b/src/libunwind.cpp
@@ -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();