Index: include/libunwind.h =================================================================== --- include/libunwind.h +++ include/libunwind.h @@ -46,12 +46,25 @@ }; struct unw_context_t { +#if defined(__arm__) && defined(_LIBUNWIND_IS_BAREMETAL) + // For bare-metal arm targets, use just enough space to hold the + // virtual register set (Registers_arm). This helps limit unwinder's + // stack usage. + uint64_t data[60]; +#else uint64_t data[128]; +#endif }; typedef struct unw_context_t unw_context_t; struct unw_cursor_t { +#if defined(__arm__) && defined(_LIBUNWIND_IS_BAREMETAL) + // As before (unw_context_t), use just enough space to hold the + // unwind cursor. + uint64_t data[68]; +#else uint64_t data[140]; +#endif }; typedef struct unw_cursor_t unw_cursor_t; Index: src/CompactUnwinder.hpp =================================================================== --- src/CompactUnwinder.hpp +++ src/CompactUnwinder.hpp @@ -27,6 +27,7 @@ namespace libunwind { +#if defined(__i386__) /// CompactUnwinder_x86 uses a compact unwind info to virtually "step" (aka /// unwind) by modifying a Registers_x86 register set template @@ -256,7 +257,7 @@ registers.setSP((uint32_t)returnAddressLocation + 4); } - +#elif defined(__x86_64__) /// CompactUnwinder_x86_64 uses a compact unwind info to virtually "step" (aka /// unwind) by modifying a Registers_x86_64 register set template @@ -486,7 +487,7 @@ } - +#elif defined(__arm64__) || defined(__aarch64__) /// CompactUnwinder_arm64 uses a compact unwind info to virtually "step" (aka /// unwind) by modifying a Registers_arm64 register set template @@ -686,6 +687,7 @@ return UNW_STEP_SUCCESS; } +#endif } // namespace libunwind Index: src/Registers.hpp =================================================================== --- src/Registers.hpp +++ src/Registers.hpp @@ -24,7 +24,7 @@ // For emulating 128-bit registers struct v128 { uint32_t vec[4]; }; - +#if defined(__i386__) /// Registers_x86 holds the register state of a thread in a 32-bit intel /// process. class _LIBUNWIND_HIDDEN Registers_x86 { @@ -212,7 +212,7 @@ _LIBUNWIND_ABORT("no x86 vector registers"); } - +#elif defined(__x86_64__) /// Registers_x86_64 holds the register state of a thread in a 64-bit intel /// process. class _LIBUNWIND_HIDDEN Registers_x86_64 { @@ -460,7 +460,7 @@ _LIBUNWIND_ABORT("no x86_64 vector registers"); } - +#elif defined(__ppc__) /// Registers_ppc holds the register state of a thread in a 32-bit PowerPC /// process. class _LIBUNWIND_HIDDEN Registers_ppc { @@ -1024,7 +1024,7 @@ } - +#elif defined(__arm64__) || defined(__aarch64__) /// Registers_arm64 holds the register state of a thread in a 64-bit arm /// process. class _LIBUNWIND_HIDDEN Registers_arm64 { @@ -1290,6 +1290,7 @@ _LIBUNWIND_ABORT("no arm64 vector register support yet"); } +#elif _LIBUNWIND_ARM_EHABI /// Registers_arm holds the register state of a thread in a 32-bit arm /// process. /// @@ -1395,7 +1396,7 @@ _saved_vfp_d16_d31(false), _saved_iwmmx(false), _saved_iwmmx_control(false) { - static_assert(sizeof(Registers_arm) < sizeof(unw_context_t), + static_assert(sizeof(Registers_arm) <= sizeof(unw_context_t), "arm registers do not fit into unw_context_t"); // See unw_getcontext() note about data. memcpy(&_registers, registers, sizeof(_registers)); @@ -1711,6 +1712,8 @@ inline void Registers_arm::setVectorRegister(int, v128) { _LIBUNWIND_ABORT("ARM vector support not implemented"); } + +#elif defined(__or1k__) /// Registers_or1k holds the register state of a thread in an OpenRISC1000 /// process. class _LIBUNWIND_HIDDEN Registers_or1k { @@ -1893,6 +1896,9 @@ } } +#else +#error "Architecture not supported." +#endif } // namespace libunwind #endif // __REGISTERS_HPP__ Index: src/UnwindCursor.hpp =================================================================== --- src/UnwindCursor.hpp +++ src/UnwindCursor.hpp @@ -481,30 +481,36 @@ return stepWithCompactEncoding(dummy); } +#if defined(__x86_64__) int stepWithCompactEncoding(Registers_x86_64 &) { return CompactUnwinder_x86_64::stepWithCompactEncoding( _info.format, _info.start_ip, _addressSpace, _registers); } +#elif defined(__i386__) int stepWithCompactEncoding(Registers_x86 &) { return CompactUnwinder_x86::stepWithCompactEncoding( _info.format, (uint32_t)_info.start_ip, _addressSpace, _registers); } +#elif defined(__ppc__) int stepWithCompactEncoding(Registers_ppc &) { return UNW_EINVAL; } +#elif defined(__arm64__) || defined(__aarch64__) int stepWithCompactEncoding(Registers_arm64 &) { return CompactUnwinder_arm64::stepWithCompactEncoding( _info.format, _info.start_ip, _addressSpace, _registers); } +#endif bool compactSaysUseDwarf(uint32_t *offset=NULL) const { R dummy; return compactSaysUseDwarf(dummy, offset); } +#if defined(__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) @@ -514,6 +520,7 @@ return false; } +#elif defined(__i386__) bool compactSaysUseDwarf(Registers_x86 &, uint32_t *offset) const { if ((_info.format & UNWIND_X86_MODE_MASK) == UNWIND_X86_MODE_DWARF) { if (offset) @@ -523,10 +530,12 @@ return false; } +#elif defined(__ppc__) bool compactSaysUseDwarf(Registers_ppc &, uint32_t *) const { return true; } +#elif defined(__arm64__) || defined(__aarch64__) bool compactSaysUseDwarf(Registers_arm64 &, uint32_t *offset) const { if ((_info.format & UNWIND_ARM64_MODE_MASK) == UNWIND_ARM64_MODE_DWARF) { if (offset) @@ -535,6 +544,7 @@ } return false; } +#endif #endif // _LIBUNWIND_SUPPORT_COMPACT_UNWIND #if _LIBUNWIND_SUPPORT_DWARF_UNWIND @@ -543,25 +553,31 @@ return dwarfEncoding(dummy); } +#if defined(__x86_64__) compact_unwind_encoding_t dwarfEncoding(Registers_x86_64 &) const { return UNWIND_X86_64_MODE_DWARF; } +#elif defined(__i386__) compact_unwind_encoding_t dwarfEncoding(Registers_x86 &) const { return UNWIND_X86_MODE_DWARF; } +#elif defined(__ppc__) compact_unwind_encoding_t dwarfEncoding(Registers_ppc &) const { return 0; } +#elif defined(__arm64__) || defined(__aarch64__) compact_unwind_encoding_t dwarfEncoding(Registers_arm64 &) const { return UNWIND_ARM64_MODE_DWARF; } +#elif defined (__or1k__) compact_unwind_encoding_t dwarfEncoding(Registers_or1k &) const { return 0; } +#endif #endif // _LIBUNWIND_SUPPORT_DWARF_UNWIND Index: src/libunwind.cpp =================================================================== --- src/libunwind.cpp +++ src/libunwind.cpp @@ -45,30 +45,29 @@ _LIBUNWIND_TRACE_API("unw_init_local(cursor=%p, context=%p)\n", static_cast(cursor), static_cast(context)); - // Use "placement new" to allocate UnwindCursor in the cursor buffer. #if defined(__i386__) - new ((void *)cursor) UnwindCursor( - context, LocalAddressSpace::sThisAddressSpace); +# define REGISTER_KIND Registers_x86 #elif defined(__x86_64__) - new ((void *)cursor) UnwindCursor( - context, LocalAddressSpace::sThisAddressSpace); +# define REGISTER_KIND Registers_x86_64 #elif defined(__ppc__) - new ((void *)cursor) UnwindCursor( - context, LocalAddressSpace::sThisAddressSpace); +# define REGISTER_KIND Registers_ppc #elif defined(__arm64__) || defined(__aarch64__) - new ((void *)cursor) UnwindCursor( - context, LocalAddressSpace::sThisAddressSpace); +# define REGISTER_KIND Registers_arm64 #elif _LIBUNWIND_ARM_EHABI - new ((void *)cursor) UnwindCursor( - context, LocalAddressSpace::sThisAddressSpace); +# define REGISTER_KIND Registers_arm #elif defined(__or1k__) - new ((void *)cursor) UnwindCursor( - 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 + static_assert(sizeof(UnwindCursor) <= + sizeof(unw_cursor_t), "Unwind cursor does not fit in unw_cursor_t"); + // Use "placement new" to allocate UnwindCursor in the cursor buffer. + new ((void *)cursor) UnwindCursor( + context, LocalAddressSpace::sThisAddressSpace); +#undef REGISTER_KIND AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; co->setInfoBasedOnIPRegister();