diff options
Diffstat (limited to 'src/Unwind/UnwindCursor.hpp')
-rw-r--r-- | src/Unwind/UnwindCursor.hpp | 106 |
1 files changed, 57 insertions, 49 deletions
diff --git a/src/Unwind/UnwindCursor.hpp b/src/Unwind/UnwindCursor.hpp index 0350dfd..b4d413f 100644 --- a/src/Unwind/UnwindCursor.hpp +++ b/src/Unwind/UnwindCursor.hpp @@ -19,17 +19,20 @@ #include <pthread.h> #include <unwind.h> -#if __APPLE__ +#ifdef __APPLE__ #include <mach-o/dyld.h> #endif -#include "libunwind.h" +#include "config.h" #include "AddressSpace.hpp" -#include "Registers.hpp" -#include "DwarfInstructions.hpp" #include "CompactUnwinder.hpp" #include "config.h" +#include "DwarfInstructions.hpp" +#include "EHHeaderParser.hpp" +#include "libunwind.h" +#include "Registers.hpp" +#include "Unwind-EHABI.h" namespace libunwind { @@ -58,7 +61,7 @@ private: // These fields are all static to avoid needing an initializer. // There is only one instance of this class per process. static pthread_rwlock_t _lock; -#if __APPLE__ +#ifdef __APPLE__ static void dyldUnloadHook(const struct mach_header *mh, intptr_t slide); static bool _registeredForDyldUnloads; #endif @@ -87,7 +90,7 @@ typename DwarfFDECache<A>::entry DwarfFDECache<A>::_initialBuffer[64]; template <typename A> pthread_rwlock_t DwarfFDECache<A>::_lock = PTHREAD_RWLOCK_INITIALIZER; -#if __APPLE__ +#ifdef __APPLE__ template <typename A> bool DwarfFDECache<A>::_registeredForDyldUnloads = false; #endif @@ -129,7 +132,7 @@ void DwarfFDECache<A>::add(pint_t mh, pint_t ip_start, pint_t ip_end, _bufferUsed->ip_end = ip_end; _bufferUsed->fde = fde; ++_bufferUsed; -#if __APPLE__ +#ifdef __APPLE__ if (!_registeredForDyldUnloads) { _dyld_register_func_for_remove_image(&dyldUnloadHook); _registeredForDyldUnloads = true; @@ -153,7 +156,7 @@ void DwarfFDECache<A>::removeAllIn(pint_t mh) { _LIBUNWIND_LOG_NON_ZERO(::pthread_rwlock_unlock(&_lock)); } -#if __APPLE__ +#ifdef __APPLE__ template <typename A> void DwarfFDECache<A>::dyldUnloadHook(const struct mach_header *mh, intptr_t ) { removeAllIn((pint_t) mh); @@ -364,29 +367,49 @@ private: }; #endif // _LIBUNWIND_SUPPORT_COMPACT_UNWIND - class _LIBUNWIND_HIDDEN AbstractUnwindCursor { public: - virtual ~AbstractUnwindCursor() {} - virtual bool validReg(int) = 0; - virtual unw_word_t getReg(int) = 0; - virtual void setReg(int, unw_word_t) = 0; - virtual bool validFloatReg(int) = 0; - virtual unw_fpreg_t getFloatReg(int) = 0; - virtual void setFloatReg(int, unw_fpreg_t) = 0; - virtual int step() = 0; - virtual void getInfo(unw_proc_info_t *) = 0; - virtual void jumpto() = 0; - virtual bool isSignalFrame() = 0; - virtual bool getFunctionName(char *bf, size_t ln, unw_word_t *off) = 0; - virtual void setInfoBasedOnIPRegister(bool isReturnAddr = false) = 0; - virtual const char *getRegisterName(int num) = 0; -#if __arm__ - virtual void saveVFPAsX() = 0; + // NOTE: provide a class specific placement deallocation function (S5.3.4 p20) + // This avoids an unnecessary dependency to libc++abi. + void operator delete(void *, size_t) {} + + virtual ~AbstractUnwindCursor() {} + virtual bool validReg(int) { _LIBUNWIND_ABORT("validReg not implemented"); } + virtual unw_word_t getReg(int) { _LIBUNWIND_ABORT("getReg not implemented"); } + virtual void setReg(int, unw_word_t) { + _LIBUNWIND_ABORT("setReg not implemented"); + } + virtual bool validFloatReg(int) { + _LIBUNWIND_ABORT("validFloatReg not implemented"); + } + virtual unw_fpreg_t getFloatReg(int) { + _LIBUNWIND_ABORT("getFloatReg not implemented"); + } + virtual void setFloatReg(int, unw_fpreg_t) { + _LIBUNWIND_ABORT("setFloatReg not implemented"); + } + virtual int step() { _LIBUNWIND_ABORT("step not implemented"); } + virtual void getInfo(unw_proc_info_t *) { + _LIBUNWIND_ABORT("getInfo not implemented"); + } + virtual void jumpto() { _LIBUNWIND_ABORT("jumpto not implemented"); } + virtual bool isSignalFrame() { + _LIBUNWIND_ABORT("isSignalFrame not implemented"); + } + virtual bool getFunctionName(char *, size_t, unw_word_t *) { + _LIBUNWIND_ABORT("getFunctionName not implemented"); + } + virtual void setInfoBasedOnIPRegister(bool = false) { + _LIBUNWIND_ABORT("setInfoBasedOnIPRegister not implemented"); + } + virtual const char *getRegisterName(int) { + _LIBUNWIND_ABORT("getRegisterName not implemented"); + } +#ifdef __arm__ + virtual void saveVFPAsX() { _LIBUNWIND_ABORT("saveVFPAsX not implemented"); } #endif }; - /// UnwindCursor contains all state (including all register values) during /// an unwind. This is normally stack allocated inside a unw_cursor_t. template <typename A, typename R> @@ -409,12 +432,10 @@ public: virtual bool getFunctionName(char *buf, size_t len, unw_word_t *off); virtual void setInfoBasedOnIPRegister(bool isReturnAddress = false); virtual const char *getRegisterName(int num); -#if __arm__ +#ifdef __arm__ virtual void saveVFPAsX(); #endif - void operator delete(void *, size_t) {} - private: #if LIBCXXABI_ARM_EHABI @@ -584,7 +605,7 @@ template <typename A, typename R> void UnwindCursor<A, R>::jumpto() { _registers.jumpto(); } -#if __arm__ +#ifdef __arm__ template <typename A, typename R> void UnwindCursor<A, R>::saveVFPAsX() { _registers.saveVFPAsX(); } @@ -605,20 +626,6 @@ struct EHABIIndexEntry { uint32_t data; }; -// Unable to unwind in the ARM index table (section 5 EHABI). -#define UNW_EXIDX_CANTUNWIND 0x1 - -static inline uint32_t signExtendPrel31(uint32_t data) { - return data | ((data & 0x40000000u) << 1); -} - -extern "C" _Unwind_Reason_Code __aeabi_unwind_cpp_pr0( - _Unwind_State state, _Unwind_Control_Block *ucbp, _Unwind_Context *context); -extern "C" _Unwind_Reason_Code __aeabi_unwind_cpp_pr1( - _Unwind_State state, _Unwind_Control_Block *ucbp, _Unwind_Context *context); -extern "C" _Unwind_Reason_Code __aeabi_unwind_cpp_pr2( - _Unwind_State state, _Unwind_Control_Block *ucbp, _Unwind_Context *context); - template<typename A> struct EHABISectionIterator { typedef EHABISectionIterator _Self; @@ -730,8 +737,8 @@ bool UnwindCursor<A, R>::getInfoFromEHABISection( // in compact form (section 6.3 EHABI). if (exceptionTableData & 0x80000000) { // Grab the index of the personality routine from the compact form. - int choice = (exceptionTableData & 0x0f000000) >> 24; - int extraWords = 0; + uint32_t choice = (exceptionTableData & 0x0f000000) >> 24; + uint32_t extraWords = 0; switch (choice) { case 0: personalityRoutine = (unw_word_t) &__aeabi_unwind_cpp_pr0; @@ -823,8 +830,9 @@ bool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc, } #if _LIBUNWIND_SUPPORT_DWARF_INDEX if (!foundFDE && (sects.dwarf_index_section != 0)) { - // Have eh_frame_hdr section which is index into dwarf section. - // TO DO: implement index search + foundFDE = EHHeaderParser<A>::findFDE( + _addressSpace, pc, sects.dwarf_index_section, + (uint32_t)sects.dwarf_index_section_length, &fdeInfo, &cieInfo); } #endif if (!foundFDE) { @@ -1304,6 +1312,6 @@ bool UnwindCursor<A, R>::getFunctionName(char *buf, size_t bufLen, buf, bufLen, offset); } -}; // namespace libunwind +} // namespace libunwind #endif // __UNWINDCURSOR_HPP__ |