Home | History | Annotate | Download | only in src
      1 //===------------------------- UnwindCursor.hpp ---------------------------===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //
      8 // C++ interface to lower levels of libunwind
      9 //===----------------------------------------------------------------------===//
     10 
     11 #ifndef __UNWINDCURSOR_HPP__
     12 #define __UNWINDCURSOR_HPP__
     13 
     14 #include <stdint.h>
     15 #include <stdio.h>
     16 #include <stdlib.h>
     17 #include <unwind.h>
     18 
     19 #ifdef _WIN32
     20   #include <windows.h>
     21   #include <ntverp.h>
     22 #endif
     23 #ifdef __APPLE__
     24   #include <mach-o/dyld.h>
     25 #endif
     26 
     27 #if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
     28 // Provide a definition for the DISPATCHER_CONTEXT struct for old (Win7 and
     29 // earlier) SDKs.
     30 // MinGW-w64 has always provided this struct.
     31   #if defined(_WIN32) && defined(_LIBUNWIND_TARGET_X86_64) && \
     32       !defined(__MINGW32__) && VER_PRODUCTBUILD < 8000
     33 struct _DISPATCHER_CONTEXT {
     34   ULONG64 ControlPc;
     35   ULONG64 ImageBase;
     36   PRUNTIME_FUNCTION FunctionEntry;
     37   ULONG64 EstablisherFrame;
     38   ULONG64 TargetIp;
     39   PCONTEXT ContextRecord;
     40   PEXCEPTION_ROUTINE LanguageHandler;
     41   PVOID HandlerData;
     42   PUNWIND_HISTORY_TABLE HistoryTable;
     43   ULONG ScopeIndex;
     44   ULONG Fill0;
     45 };
     46   #endif
     47 
     48 struct UNWIND_INFO {
     49   uint8_t Version : 3;
     50   uint8_t Flags : 5;
     51   uint8_t SizeOfProlog;
     52   uint8_t CountOfCodes;
     53   uint8_t FrameRegister : 4;
     54   uint8_t FrameOffset : 4;
     55   uint16_t UnwindCodes[2];
     56 };
     57 
     58 extern "C" _Unwind_Reason_Code __libunwind_seh_personality(
     59     int, _Unwind_Action, uint64_t, _Unwind_Exception *,
     60     struct _Unwind_Context *);
     61 
     62 #endif
     63 
     64 #include "config.h"
     65 
     66 #include "AddressSpace.hpp"
     67 #include "CompactUnwinder.hpp"
     68 #include "config.h"
     69 #include "DwarfInstructions.hpp"
     70 #include "EHHeaderParser.hpp"
     71 #include "libunwind.h"
     72 #include "Registers.hpp"
     73 #include "RWMutex.hpp"
     74 #include "Unwind-EHABI.h"
     75 
     76 namespace libunwind {
     77 
     78 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
     79 /// Cache of recently found FDEs.
     80 template <typename A>
     81 class _LIBUNWIND_HIDDEN DwarfFDECache {
     82   typedef typename A::pint_t pint_t;
     83 public:
     84   static pint_t findFDE(pint_t mh, pint_t pc);
     85   static void add(pint_t mh, pint_t ip_start, pint_t ip_end, pint_t fde);
     86   static void removeAllIn(pint_t mh);
     87   static void iterateCacheEntries(void (*func)(unw_word_t ip_start,
     88                                                unw_word_t ip_end,
     89                                                unw_word_t fde, unw_word_t mh));
     90 
     91 private:
     92 
     93   struct entry {
     94     pint_t mh;
     95     pint_t ip_start;
     96     pint_t ip_end;
     97     pint_t fde;
     98   };
     99 
    100   // These fields are all static to avoid needing an initializer.
    101   // There is only one instance of this class per process.
    102   static RWMutex _lock;
    103 #ifdef __APPLE__
    104   static void dyldUnloadHook(const struct mach_header *mh, intptr_t slide);
    105   static bool _registeredForDyldUnloads;
    106 #endif
    107   static entry *_buffer;
    108   static entry *_bufferUsed;
    109   static entry *_bufferEnd;
    110   static entry _initialBuffer[64];
    111 };
    112 
    113 template <typename A>
    114 typename DwarfFDECache<A>::entry *
    115 DwarfFDECache<A>::_buffer = _initialBuffer;
    116 
    117 template <typename A>
    118 typename DwarfFDECache<A>::entry *
    119 DwarfFDECache<A>::_bufferUsed = _initialBuffer;
    120 
    121 template <typename A>
    122 typename DwarfFDECache<A>::entry *
    123 DwarfFDECache<A>::_bufferEnd = &_initialBuffer[64];
    124 
    125 template <typename A>
    126 typename DwarfFDECache<A>::entry DwarfFDECache<A>::_initialBuffer[64];
    127 
    128 template <typename A>
    129 RWMutex DwarfFDECache<A>::_lock;
    130 
    131 #ifdef __APPLE__
    132 template <typename A>
    133 bool DwarfFDECache<A>::_registeredForDyldUnloads = false;
    134 #endif
    135 
    136 template <typename A>
    137 typename A::pint_t DwarfFDECache<A>::findFDE(pint_t mh, pint_t pc) {
    138   pint_t result = 0;
    139   _LIBUNWIND_LOG_IF_FALSE(_lock.lock_shared());
    140   for (entry *p = _buffer; p < _bufferUsed; ++p) {
    141     if ((mh == p->mh) || (mh == 0)) {
    142       if ((p->ip_start <= pc) && (pc < p->ip_end)) {
    143         result = p->fde;
    144         break;
    145       }
    146     }
    147   }
    148   _LIBUNWIND_LOG_IF_FALSE(_lock.unlock_shared());
    149   return result;
    150 }
    151 
    152 template <typename A>
    153 void DwarfFDECache<A>::add(pint_t mh, pint_t ip_start, pint_t ip_end,
    154                            pint_t fde) {
    155 #if !defined(_LIBUNWIND_NO_HEAP)
    156   _LIBUNWIND_LOG_IF_FALSE(_lock.lock());
    157   if (_bufferUsed >= _bufferEnd) {
    158     size_t oldSize = (size_t)(_bufferEnd - _buffer);
    159     size_t newSize = oldSize * 4;
    160     // Can't use operator new (we are below it).
    161     entry *newBuffer = (entry *)malloc(newSize * sizeof(entry));
    162     memcpy(newBuffer, _buffer, oldSize * sizeof(entry));
    163     if (_buffer != _initialBuffer)
    164       free(_buffer);
    165     _buffer = newBuffer;
    166     _bufferUsed = &newBuffer[oldSize];
    167     _bufferEnd = &newBuffer[newSize];
    168   }
    169   _bufferUsed->mh = mh;
    170   _bufferUsed->ip_start = ip_start;
    171   _bufferUsed->ip_end = ip_end;
    172   _bufferUsed->fde = fde;
    173   ++_bufferUsed;
    174 #ifdef __APPLE__
    175   if (!_registeredForDyldUnloads) {
    176     _dyld_register_func_for_remove_image(&dyldUnloadHook);
    177     _registeredForDyldUnloads = true;
    178   }
    179 #endif
    180   _LIBUNWIND_LOG_IF_FALSE(_lock.unlock());
    181 #endif
    182 }
    183 
    184 template <typename A>
    185 void DwarfFDECache<A>::removeAllIn(pint_t mh) {
    186   _LIBUNWIND_LOG_IF_FALSE(_lock.lock());
    187   entry *d = _buffer;
    188   for (const entry *s = _buffer; s < _bufferUsed; ++s) {
    189     if (s->mh != mh) {
    190       if (d != s)
    191         *d = *s;
    192       ++d;
    193     }
    194   }
    195   _bufferUsed = d;
    196   _LIBUNWIND_LOG_IF_FALSE(_lock.unlock());
    197 }
    198 
    199 #ifdef __APPLE__
    200 template <typename A>
    201 void DwarfFDECache<A>::dyldUnloadHook(const struct mach_header *mh, intptr_t ) {
    202   removeAllIn((pint_t) mh);
    203 }
    204 #endif
    205 
    206 template <typename A>
    207 void DwarfFDECache<A>::iterateCacheEntries(void (*func)(
    208     unw_word_t ip_start, unw_word_t ip_end, unw_word_t fde, unw_word_t mh)) {
    209   _LIBUNWIND_LOG_IF_FALSE(_lock.lock());
    210   for (entry *p = _buffer; p < _bufferUsed; ++p) {
    211     (*func)(p->ip_start, p->ip_end, p->fde, p->mh);
    212   }
    213   _LIBUNWIND_LOG_IF_FALSE(_lock.unlock());
    214 }
    215 #endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
    216 
    217 
    218 #define arrayoffsetof(type, index, field) ((size_t)(&((type *)0)[index].field))
    219 
    220 #if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
    221 template <typename A> class UnwindSectionHeader {
    222 public:
    223   UnwindSectionHeader(A &addressSpace, typename A::pint_t addr)
    224       : _addressSpace(addressSpace), _addr(addr) {}
    225 
    226   uint32_t version() const {
    227     return _addressSpace.get32(_addr +
    228                                offsetof(unwind_info_section_header, version));
    229   }
    230   uint32_t commonEncodingsArraySectionOffset() const {
    231     return _addressSpace.get32(_addr +
    232                                offsetof(unwind_info_section_header,
    233                                         commonEncodingsArraySectionOffset));
    234   }
    235   uint32_t commonEncodingsArrayCount() const {
    236     return _addressSpace.get32(_addr + offsetof(unwind_info_section_header,
    237                                                 commonEncodingsArrayCount));
    238   }
    239   uint32_t personalityArraySectionOffset() const {
    240     return _addressSpace.get32(_addr + offsetof(unwind_info_section_header,
    241                                                 personalityArraySectionOffset));
    242   }
    243   uint32_t personalityArrayCount() const {
    244     return _addressSpace.get32(
    245         _addr + offsetof(unwind_info_section_header, personalityArrayCount));
    246   }
    247   uint32_t indexSectionOffset() const {
    248     return _addressSpace.get32(
    249         _addr + offsetof(unwind_info_section_header, indexSectionOffset));
    250   }
    251   uint32_t indexCount() const {
    252     return _addressSpace.get32(
    253         _addr + offsetof(unwind_info_section_header, indexCount));
    254   }
    255 
    256 private:
    257   A                     &_addressSpace;
    258   typename A::pint_t     _addr;
    259 };
    260 
    261 template <typename A> class UnwindSectionIndexArray {
    262 public:
    263   UnwindSectionIndexArray(A &addressSpace, typename A::pint_t addr)
    264       : _addressSpace(addressSpace), _addr(addr) {}
    265 
    266   uint32_t functionOffset(uint32_t index) const {
    267     return _addressSpace.get32(
    268         _addr + arrayoffsetof(unwind_info_section_header_index_entry, index,
    269                               functionOffset));
    270   }
    271   uint32_t secondLevelPagesSectionOffset(uint32_t index) const {
    272     return _addressSpace.get32(
    273         _addr + arrayoffsetof(unwind_info_section_header_index_entry, index,
    274                               secondLevelPagesSectionOffset));
    275   }
    276   uint32_t lsdaIndexArraySectionOffset(uint32_t index) const {
    277     return _addressSpace.get32(
    278         _addr + arrayoffsetof(unwind_info_section_header_index_entry, index,
    279                               lsdaIndexArraySectionOffset));
    280   }
    281 
    282 private:
    283   A                   &_addressSpace;
    284   typename A::pint_t   _addr;
    285 };
    286 
    287 template <typename A> class UnwindSectionRegularPageHeader {
    288 public:
    289   UnwindSectionRegularPageHeader(A &addressSpace, typename A::pint_t addr)
    290       : _addressSpace(addressSpace), _addr(addr) {}
    291 
    292   uint32_t kind() const {
    293     return _addressSpace.get32(
    294         _addr + offsetof(unwind_info_regular_second_level_page_header, kind));
    295   }
    296   uint16_t entryPageOffset() const {
    297     return _addressSpace.get16(
    298         _addr + offsetof(unwind_info_regular_second_level_page_header,
    299                          entryPageOffset));
    300   }
    301   uint16_t entryCount() const {
    302     return _addressSpace.get16(
    303         _addr +
    304         offsetof(unwind_info_regular_second_level_page_header, entryCount));
    305   }
    306 
    307 private:
    308   A &_addressSpace;
    309   typename A::pint_t _addr;
    310 };
    311 
    312 template <typename A> class UnwindSectionRegularArray {
    313 public:
    314   UnwindSectionRegularArray(A &addressSpace, typename A::pint_t addr)
    315       : _addressSpace(addressSpace), _addr(addr) {}
    316 
    317   uint32_t functionOffset(uint32_t index) const {
    318     return _addressSpace.get32(
    319         _addr + arrayoffsetof(unwind_info_regular_second_level_entry, index,
    320                               functionOffset));
    321   }
    322   uint32_t encoding(uint32_t index) const {
    323     return _addressSpace.get32(
    324         _addr +
    325         arrayoffsetof(unwind_info_regular_second_level_entry, index, encoding));
    326   }
    327 
    328 private:
    329   A &_addressSpace;
    330   typename A::pint_t _addr;
    331 };
    332 
    333 template <typename A> class UnwindSectionCompressedPageHeader {
    334 public:
    335   UnwindSectionCompressedPageHeader(A &addressSpace, typename A::pint_t addr)
    336       : _addressSpace(addressSpace), _addr(addr) {}
    337 
    338   uint32_t kind() const {
    339     return _addressSpace.get32(
    340         _addr +
    341         offsetof(unwind_info_compressed_second_level_page_header, kind));
    342   }
    343   uint16_t entryPageOffset() const {
    344     return _addressSpace.get16(
    345         _addr + offsetof(unwind_info_compressed_second_level_page_header,
    346                          entryPageOffset));
    347   }
    348   uint16_t entryCount() const {
    349     return _addressSpace.get16(
    350         _addr +
    351         offsetof(unwind_info_compressed_second_level_page_header, entryCount));
    352   }
    353   uint16_t encodingsPageOffset() const {
    354     return _addressSpace.get16(
    355         _addr + offsetof(unwind_info_compressed_second_level_page_header,
    356                          encodingsPageOffset));
    357   }
    358   uint16_t encodingsCount() const {
    359     return _addressSpace.get16(
    360         _addr + offsetof(unwind_info_compressed_second_level_page_header,
    361                          encodingsCount));
    362   }
    363 
    364 private:
    365   A &_addressSpace;
    366   typename A::pint_t _addr;
    367 };
    368 
    369 template <typename A> class UnwindSectionCompressedArray {
    370 public:
    371   UnwindSectionCompressedArray(A &addressSpace, typename A::pint_t addr)
    372       : _addressSpace(addressSpace), _addr(addr) {}
    373 
    374   uint32_t functionOffset(uint32_t index) const {
    375     return UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(
    376         _addressSpace.get32(_addr + index * sizeof(uint32_t)));
    377   }
    378   uint16_t encodingIndex(uint32_t index) const {
    379     return UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX(
    380         _addressSpace.get32(_addr + index * sizeof(uint32_t)));
    381   }
    382 
    383 private:
    384   A &_addressSpace;
    385   typename A::pint_t _addr;
    386 };
    387 
    388 template <typename A> class UnwindSectionLsdaArray {
    389 public:
    390   UnwindSectionLsdaArray(A &addressSpace, typename A::pint_t addr)
    391       : _addressSpace(addressSpace), _addr(addr) {}
    392 
    393   uint32_t functionOffset(uint32_t index) const {
    394     return _addressSpace.get32(
    395         _addr + arrayoffsetof(unwind_info_section_header_lsda_index_entry,
    396                               index, functionOffset));
    397   }
    398   uint32_t lsdaOffset(uint32_t index) const {
    399     return _addressSpace.get32(
    400         _addr + arrayoffsetof(unwind_info_section_header_lsda_index_entry,
    401                               index, lsdaOffset));
    402   }
    403 
    404 private:
    405   A                   &_addressSpace;
    406   typename A::pint_t   _addr;
    407 };
    408 #endif // defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
    409 
    410 class _LIBUNWIND_HIDDEN AbstractUnwindCursor {
    411 public:
    412   // NOTE: provide a class specific placement deallocation function (S5.3.4 p20)
    413   // This avoids an unnecessary dependency to libc++abi.
    414   void operator delete(void *, size_t) {}
    415 
    416   virtual ~AbstractUnwindCursor() {}
    417   virtual bool validReg(int) { _LIBUNWIND_ABORT("validReg not implemented"); }
    418   virtual unw_word_t getReg(int) { _LIBUNWIND_ABORT("getReg not implemented"); }
    419   virtual void setReg(int, unw_word_t) {
    420     _LIBUNWIND_ABORT("setReg not implemented");
    421   }
    422   virtual bool validFloatReg(int) {
    423     _LIBUNWIND_ABORT("validFloatReg not implemented");
    424   }
    425   virtual unw_fpreg_t getFloatReg(int) {
    426     _LIBUNWIND_ABORT("getFloatReg not implemented");
    427   }
    428   virtual void setFloatReg(int, unw_fpreg_t) {
    429     _LIBUNWIND_ABORT("setFloatReg not implemented");
    430   }
    431   virtual int step() { _LIBUNWIND_ABORT("step not implemented"); }
    432   virtual void getInfo(unw_proc_info_t *) {
    433     _LIBUNWIND_ABORT("getInfo not implemented");
    434   }
    435   virtual void jumpto() { _LIBUNWIND_ABORT("jumpto not implemented"); }
    436   virtual bool isSignalFrame() {
    437     _LIBUNWIND_ABORT("isSignalFrame not implemented");
    438   }
    439   virtual bool getFunctionName(char *, size_t, unw_word_t *) {
    440     _LIBUNWIND_ABORT("getFunctionName not implemented");
    441   }
    442   virtual void setInfoBasedOnIPRegister(bool = false) {
    443     _LIBUNWIND_ABORT("setInfoBasedOnIPRegister not implemented");
    444   }
    445   virtual const char *getRegisterName(int) {
    446     _LIBUNWIND_ABORT("getRegisterName not implemented");
    447   }
    448 #ifdef __arm__
    449   virtual void saveVFPAsX() { _LIBUNWIND_ABORT("saveVFPAsX not implemented"); }
    450 #endif
    451 };
    452 
    453 #if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) && defined(_WIN32)
    454 
    455 /// \c UnwindCursor contains all state (including all register values) during
    456 /// an unwind.  This is normally stack-allocated inside a unw_cursor_t.
    457 template <typename A, typename R>
    458 class UnwindCursor : public AbstractUnwindCursor {
    459   typedef typename A::pint_t pint_t;
    460 public:
    461                       UnwindCursor(unw_context_t *context, A &as);
    462                       UnwindCursor(CONTEXT *context, A &as);
    463                       UnwindCursor(A &as, void *threadArg);
    464   virtual             ~UnwindCursor() {}
    465   virtual bool        validReg(int);
    466   virtual unw_word_t  getReg(int);
    467   virtual void        setReg(int, unw_word_t);
    468   virtual bool        validFloatReg(int);
    469   virtual unw_fpreg_t getFloatReg(int);
    470   virtual void        setFloatReg(int, unw_fpreg_t);
    471   virtual int         step();
    472   virtual void        getInfo(unw_proc_info_t *);
    473   virtual void        jumpto();
    474   virtual bool        isSignalFrame();
    475   virtual bool        getFunctionName(char *buf, size_t len, unw_word_t *off);
    476   virtual void        setInfoBasedOnIPRegister(bool isReturnAddress = false);
    477   virtual const char *getRegisterName(int num);
    478 #ifdef __arm__
    479   virtual void        saveVFPAsX();
    480 #endif
    481 
    482   DISPATCHER_CONTEXT *getDispatcherContext() { return &_dispContext; }
    483   void setDispatcherContext(DISPATCHER_CONTEXT *disp) { _dispContext = *disp; }
    484 
    485   // libunwind does not and should not depend on C++ library which means that we
    486   // need our own defition of inline placement new.
    487   static void *operator new(size_t, UnwindCursor<A, R> *p) { return p; }
    488 
    489 private:
    490 
    491   pint_t getLastPC() const { return _dispContext.ControlPc; }
    492   void setLastPC(pint_t pc) { _dispContext.ControlPc = pc; }
    493   RUNTIME_FUNCTION *lookUpSEHUnwindInfo(pint_t pc, pint_t *base) {
    494     _dispContext.FunctionEntry = RtlLookupFunctionEntry(pc,
    495                                                         &_dispContext.ImageBase,
    496                                                         _dispContext.HistoryTable);
    497     *base = _dispContext.ImageBase;
    498     return _dispContext.FunctionEntry;
    499   }
    500   bool getInfoFromSEH(pint_t pc);
    501   int stepWithSEHData() {
    502     _dispContext.LanguageHandler = RtlVirtualUnwind(UNW_FLAG_UHANDLER,
    503                                                     _dispContext.ImageBase,
    504                                                     _dispContext.ControlPc,
    505                                                     _dispContext.FunctionEntry,
    506                                                     _dispContext.ContextRecord,
    507                                                     &_dispContext.HandlerData,
    508                                                     &_dispContext.EstablisherFrame,
    509                                                     NULL);
    510     // Update some fields of the unwind info now, since we have them.
    511     _info.lsda = reinterpret_cast<unw_word_t>(_dispContext.HandlerData);
    512     if (_dispContext.LanguageHandler) {
    513       _info.handler = reinterpret_cast<unw_word_t>(__libunwind_seh_personality);
    514     } else
    515       _info.handler = 0;
    516     return UNW_STEP_SUCCESS;
    517   }
    518 
    519   A                   &_addressSpace;
    520   unw_proc_info_t      _info;
    521   DISPATCHER_CONTEXT   _dispContext;
    522   CONTEXT              _msContext;
    523   UNWIND_HISTORY_TABLE _histTable;
    524   bool                 _unwindInfoMissing;
    525 };
    526 
    527 
    528 template <typename A, typename R>
    529 UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as)
    530     : _addressSpace(as), _unwindInfoMissing(false) {
    531   static_assert((check_fit<UnwindCursor<A, R>, unw_cursor_t>::does_fit),
    532                 "UnwindCursor<> does not fit in unw_cursor_t");
    533   memset(&_info, 0, sizeof(_info));
    534   memset(&_histTable, 0, sizeof(_histTable));
    535   _dispContext.ContextRecord = &_msContext;
    536   _dispContext.HistoryTable = &_histTable;
    537   // Initialize MS context from ours.
    538   R r(context);
    539   _msContext.ContextFlags = CONTEXT_CONTROL|CONTEXT_INTEGER|CONTEXT_FLOATING_POINT;
    540 #if defined(_LIBUNWIND_TARGET_X86_64)
    541   _msContext.Rax = r.getRegister(UNW_X86_64_RAX);
    542   _msContext.Rcx = r.getRegister(UNW_X86_64_RCX);
    543   _msContext.Rdx = r.getRegister(UNW_X86_64_RDX);
    544   _msContext.Rbx = r.getRegister(UNW_X86_64_RBX);
    545   _msContext.Rsp = r.getRegister(UNW_X86_64_RSP);
    546   _msContext.Rbp = r.getRegister(UNW_X86_64_RBP);
    547   _msContext.Rsi = r.getRegister(UNW_X86_64_RSI);
    548   _msContext.Rdi = r.getRegister(UNW_X86_64_RDI);
    549   _msContext.R8 = r.getRegister(UNW_X86_64_R8);
    550   _msContext.R9 = r.getRegister(UNW_X86_64_R9);
    551   _msContext.R10 = r.getRegister(UNW_X86_64_R10);
    552   _msContext.R11 = r.getRegister(UNW_X86_64_R11);
    553   _msContext.R12 = r.getRegister(UNW_X86_64_R12);
    554   _msContext.R13 = r.getRegister(UNW_X86_64_R13);
    555   _msContext.R14 = r.getRegister(UNW_X86_64_R14);
    556   _msContext.R15 = r.getRegister(UNW_X86_64_R15);
    557   _msContext.Rip = r.getRegister(UNW_REG_IP);
    558   union {
    559     v128 v;
    560     M128A m;
    561   } t;
    562   t.v = r.getVectorRegister(UNW_X86_64_XMM0);
    563   _msContext.Xmm0 = t.m;
    564   t.v = r.getVectorRegister(UNW_X86_64_XMM1);
    565   _msContext.Xmm1 = t.m;
    566   t.v = r.getVectorRegister(UNW_X86_64_XMM2);
    567   _msContext.Xmm2 = t.m;
    568   t.v = r.getVectorRegister(UNW_X86_64_XMM3);
    569   _msContext.Xmm3 = t.m;
    570   t.v = r.getVectorRegister(UNW_X86_64_XMM4);
    571   _msContext.Xmm4 = t.m;
    572   t.v = r.getVectorRegister(UNW_X86_64_XMM5);
    573   _msContext.Xmm5 = t.m;
    574   t.v = r.getVectorRegister(UNW_X86_64_XMM6);
    575   _msContext.Xmm6 = t.m;
    576   t.v = r.getVectorRegister(UNW_X86_64_XMM7);
    577   _msContext.Xmm7 = t.m;
    578   t.v = r.getVectorRegister(UNW_X86_64_XMM8);
    579   _msContext.Xmm8 = t.m;
    580   t.v = r.getVectorRegister(UNW_X86_64_XMM9);
    581   _msContext.Xmm9 = t.m;
    582   t.v = r.getVectorRegister(UNW_X86_64_XMM10);
    583   _msContext.Xmm10 = t.m;
    584   t.v = r.getVectorRegister(UNW_X86_64_XMM11);
    585   _msContext.Xmm11 = t.m;
    586   t.v = r.getVectorRegister(UNW_X86_64_XMM12);
    587   _msContext.Xmm12 = t.m;
    588   t.v = r.getVectorRegister(UNW_X86_64_XMM13);
    589   _msContext.Xmm13 = t.m;
    590   t.v = r.getVectorRegister(UNW_X86_64_XMM14);
    591   _msContext.Xmm14 = t.m;
    592   t.v = r.getVectorRegister(UNW_X86_64_XMM15);
    593   _msContext.Xmm15 = t.m;
    594 #elif defined(_LIBUNWIND_TARGET_ARM)
    595   _msContext.R0 = r.getRegister(UNW_ARM_R0);
    596   _msContext.R1 = r.getRegister(UNW_ARM_R1);
    597   _msContext.R2 = r.getRegister(UNW_ARM_R2);
    598   _msContext.R3 = r.getRegister(UNW_ARM_R3);
    599   _msContext.R4 = r.getRegister(UNW_ARM_R4);
    600   _msContext.R5 = r.getRegister(UNW_ARM_R5);
    601   _msContext.R6 = r.getRegister(UNW_ARM_R6);
    602   _msContext.R7 = r.getRegister(UNW_ARM_R7);
    603   _msContext.R8 = r.getRegister(UNW_ARM_R8);
    604   _msContext.R9 = r.getRegister(UNW_ARM_R9);
    605   _msContext.R10 = r.getRegister(UNW_ARM_R10);
    606   _msContext.R11 = r.getRegister(UNW_ARM_R11);
    607   _msContext.R12 = r.getRegister(UNW_ARM_R12);
    608   _msContext.Sp = r.getRegister(UNW_ARM_SP);
    609   _msContext.Lr = r.getRegister(UNW_ARM_LR);
    610   _msContext.Pc = r.getRegister(UNW_ARM_IP);
    611   for (int i = UNW_ARM_D0; i <= UNW_ARM_D31; ++i) {
    612     union {
    613       uint64_t w;
    614       double d;
    615     } d;
    616     d.d = r.getFloatRegister(i);
    617     _msContext.D[i - UNW_ARM_D0] = d.w;
    618   }
    619 #elif defined(_LIBUNWIND_TARGET_AARCH64)
    620   for (int i = UNW_ARM64_X0; i <= UNW_ARM64_X30; ++i)
    621     _msContext.X[i - UNW_ARM64_X0] = r.getRegister(i);
    622   _msContext.Sp = r.getRegister(UNW_REG_SP);
    623   _msContext.Pc = r.getRegister(UNW_REG_IP);
    624   for (int i = UNW_ARM64_D0; i <= UNW_ARM64_D31; ++i)
    625     _msContext.V[i - UNW_ARM64_D0].D[0] = r.getFloatRegister(i);
    626 #endif
    627 }
    628 
    629 template <typename A, typename R>
    630 UnwindCursor<A, R>::UnwindCursor(CONTEXT *context, A &as)
    631     : _addressSpace(as), _unwindInfoMissing(false) {
    632   static_assert((check_fit<UnwindCursor<A, R>, unw_cursor_t>::does_fit),
    633                 "UnwindCursor<> does not fit in unw_cursor_t");
    634   memset(&_info, 0, sizeof(_info));
    635   memset(&_histTable, 0, sizeof(_histTable));
    636   _dispContext.ContextRecord = &_msContext;
    637   _dispContext.HistoryTable = &_histTable;
    638   _msContext = *context;
    639 }
    640 
    641 
    642 template <typename A, typename R>
    643 bool UnwindCursor<A, R>::validReg(int regNum) {
    644   if (regNum == UNW_REG_IP || regNum == UNW_REG_SP) return true;
    645 #if defined(_LIBUNWIND_TARGET_X86_64)
    646   if (regNum >= UNW_X86_64_RAX && regNum <= UNW_X86_64_R15) return true;
    647 #elif defined(_LIBUNWIND_TARGET_ARM)
    648   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15) return true;
    649 #elif defined(_LIBUNWIND_TARGET_AARCH64)
    650   if (regNum >= UNW_ARM64_X0 && regNum <= UNW_ARM64_X30) return true;
    651 #endif
    652   return false;
    653 }
    654 
    655 template <typename A, typename R>
    656 unw_word_t UnwindCursor<A, R>::getReg(int regNum) {
    657   switch (regNum) {
    658 #if defined(_LIBUNWIND_TARGET_X86_64)
    659   case UNW_REG_IP: return _msContext.Rip;
    660   case UNW_X86_64_RAX: return _msContext.Rax;
    661   case UNW_X86_64_RDX: return _msContext.Rdx;
    662   case UNW_X86_64_RCX: return _msContext.Rcx;
    663   case UNW_X86_64_RBX: return _msContext.Rbx;
    664   case UNW_REG_SP:
    665   case UNW_X86_64_RSP: return _msContext.Rsp;
    666   case UNW_X86_64_RBP: return _msContext.Rbp;
    667   case UNW_X86_64_RSI: return _msContext.Rsi;
    668   case UNW_X86_64_RDI: return _msContext.Rdi;
    669   case UNW_X86_64_R8: return _msContext.R8;
    670   case UNW_X86_64_R9: return _msContext.R9;
    671   case UNW_X86_64_R10: return _msContext.R10;
    672   case UNW_X86_64_R11: return _msContext.R11;
    673   case UNW_X86_64_R12: return _msContext.R12;
    674   case UNW_X86_64_R13: return _msContext.R13;
    675   case UNW_X86_64_R14: return _msContext.R14;
    676   case UNW_X86_64_R15: return _msContext.R15;
    677 #elif defined(_LIBUNWIND_TARGET_ARM)
    678   case UNW_ARM_R0: return _msContext.R0;
    679   case UNW_ARM_R1: return _msContext.R1;
    680   case UNW_ARM_R2: return _msContext.R2;
    681   case UNW_ARM_R3: return _msContext.R3;
    682   case UNW_ARM_R4: return _msContext.R4;
    683   case UNW_ARM_R5: return _msContext.R5;
    684   case UNW_ARM_R6: return _msContext.R6;
    685   case UNW_ARM_R7: return _msContext.R7;
    686   case UNW_ARM_R8: return _msContext.R8;
    687   case UNW_ARM_R9: return _msContext.R9;
    688   case UNW_ARM_R10: return _msContext.R10;
    689   case UNW_ARM_R11: return _msContext.R11;
    690   case UNW_ARM_R12: return _msContext.R12;
    691   case UNW_REG_SP:
    692   case UNW_ARM_SP: return _msContext.Sp;
    693   case UNW_ARM_LR: return _msContext.Lr;
    694   case UNW_REG_IP:
    695   case UNW_ARM_IP: return _msContext.Pc;
    696 #elif defined(_LIBUNWIND_TARGET_AARCH64)
    697   case UNW_REG_SP: return _msContext.Sp;
    698   case UNW_REG_IP: return _msContext.Pc;
    699   default: return _msContext.X[regNum - UNW_ARM64_X0];
    700 #endif
    701   }
    702   _LIBUNWIND_ABORT("unsupported register");
    703 }
    704 
    705 template <typename A, typename R>
    706 void UnwindCursor<A, R>::setReg(int regNum, unw_word_t value) {
    707   switch (regNum) {
    708 #if defined(_LIBUNWIND_TARGET_X86_64)
    709   case UNW_REG_IP: _msContext.Rip = value; break;
    710   case UNW_X86_64_RAX: _msContext.Rax = value; break;
    711   case UNW_X86_64_RDX: _msContext.Rdx = value; break;
    712   case UNW_X86_64_RCX: _msContext.Rcx = value; break;
    713   case UNW_X86_64_RBX: _msContext.Rbx = value; break;
    714   case UNW_REG_SP:
    715   case UNW_X86_64_RSP: _msContext.Rsp = value; break;
    716   case UNW_X86_64_RBP: _msContext.Rbp = value; break;
    717   case UNW_X86_64_RSI: _msContext.Rsi = value; break;
    718   case UNW_X86_64_RDI: _msContext.Rdi = value; break;
    719   case UNW_X86_64_R8: _msContext.R8 = value; break;
    720   case UNW_X86_64_R9: _msContext.R9 = value; break;
    721   case UNW_X86_64_R10: _msContext.R10 = value; break;
    722   case UNW_X86_64_R11: _msContext.R11 = value; break;
    723   case UNW_X86_64_R12: _msContext.R12 = value; break;
    724   case UNW_X86_64_R13: _msContext.R13 = value; break;
    725   case UNW_X86_64_R14: _msContext.R14 = value; break;
    726   case UNW_X86_64_R15: _msContext.R15 = value; break;
    727 #elif defined(_LIBUNWIND_TARGET_ARM)
    728   case UNW_ARM_R0: _msContext.R0 = value; break;
    729   case UNW_ARM_R1: _msContext.R1 = value; break;
    730   case UNW_ARM_R2: _msContext.R2 = value; break;
    731   case UNW_ARM_R3: _msContext.R3 = value; break;
    732   case UNW_ARM_R4: _msContext.R4 = value; break;
    733   case UNW_ARM_R5: _msContext.R5 = value; break;
    734   case UNW_ARM_R6: _msContext.R6 = value; break;
    735   case UNW_ARM_R7: _msContext.R7 = value; break;
    736   case UNW_ARM_R8: _msContext.R8 = value; break;
    737   case UNW_ARM_R9: _msContext.R9 = value; break;
    738   case UNW_ARM_R10: _msContext.R10 = value; break;
    739   case UNW_ARM_R11: _msContext.R11 = value; break;
    740   case UNW_ARM_R12: _msContext.R12 = value; break;
    741   case UNW_REG_SP:
    742   case UNW_ARM_SP: _msContext.Sp = value; break;
    743   case UNW_ARM_LR: _msContext.Lr = value; break;
    744   case UNW_REG_IP:
    745   case UNW_ARM_IP: _msContext.Pc = value; break;
    746 #elif defined(_LIBUNWIND_TARGET_AARCH64)
    747   case UNW_REG_SP: _msContext.Sp = value; break;
    748   case UNW_REG_IP: _msContext.Pc = value; break;
    749   case UNW_ARM64_X0:
    750   case UNW_ARM64_X1:
    751   case UNW_ARM64_X2:
    752   case UNW_ARM64_X3:
    753   case UNW_ARM64_X4:
    754   case UNW_ARM64_X5:
    755   case UNW_ARM64_X6:
    756   case UNW_ARM64_X7:
    757   case UNW_ARM64_X8:
    758   case UNW_ARM64_X9:
    759   case UNW_ARM64_X10:
    760   case UNW_ARM64_X11:
    761   case UNW_ARM64_X12:
    762   case UNW_ARM64_X13:
    763   case UNW_ARM64_X14:
    764   case UNW_ARM64_X15:
    765   case UNW_ARM64_X16:
    766   case UNW_ARM64_X17:
    767   case UNW_ARM64_X18:
    768   case UNW_ARM64_X19:
    769   case UNW_ARM64_X20:
    770   case UNW_ARM64_X21:
    771   case UNW_ARM64_X22:
    772   case UNW_ARM64_X23:
    773   case UNW_ARM64_X24:
    774   case UNW_ARM64_X25:
    775   case UNW_ARM64_X26:
    776   case UNW_ARM64_X27:
    777   case UNW_ARM64_X28:
    778   case UNW_ARM64_FP:
    779   case UNW_ARM64_LR: _msContext.X[regNum - UNW_ARM64_X0] = value; break;
    780 #endif
    781   default:
    782     _LIBUNWIND_ABORT("unsupported register");
    783   }
    784 }
    785 
    786 template <typename A, typename R>
    787 bool UnwindCursor<A, R>::validFloatReg(int regNum) {
    788 #if defined(_LIBUNWIND_TARGET_ARM)
    789   if (regNum >= UNW_ARM_S0 && regNum <= UNW_ARM_S31) return true;
    790   if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D31) return true;
    791 #elif defined(_LIBUNWIND_TARGET_AARCH64)
    792   if (regNum >= UNW_ARM64_D0 && regNum <= UNW_ARM64_D31) return true;
    793 #else
    794   (void)regNum;
    795 #endif
    796   return false;
    797 }
    798 
    799 template <typename A, typename R>
    800 unw_fpreg_t UnwindCursor<A, R>::getFloatReg(int regNum) {
    801 #if defined(_LIBUNWIND_TARGET_ARM)
    802   if (regNum >= UNW_ARM_S0 && regNum <= UNW_ARM_S31) {
    803     union {
    804       uint32_t w;
    805       float f;
    806     } d;
    807     d.w = _msContext.S[regNum - UNW_ARM_S0];
    808     return d.f;
    809   }
    810   if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D31) {
    811     union {
    812       uint64_t w;
    813       double d;
    814     } d;
    815     d.w = _msContext.D[regNum - UNW_ARM_D0];
    816     return d.d;
    817   }
    818   _LIBUNWIND_ABORT("unsupported float register");
    819 #elif defined(_LIBUNWIND_TARGET_AARCH64)
    820   return _msContext.V[regNum - UNW_ARM64_D0].D[0];
    821 #else
    822   (void)regNum;
    823   _LIBUNWIND_ABORT("float registers unimplemented");
    824 #endif
    825 }
    826 
    827 template <typename A, typename R>
    828 void UnwindCursor<A, R>::setFloatReg(int regNum, unw_fpreg_t value) {
    829 #if defined(_LIBUNWIND_TARGET_ARM)
    830   if (regNum >= UNW_ARM_S0 && regNum <= UNW_ARM_S31) {
    831     union {
    832       uint32_t w;
    833       float f;
    834     } d;
    835     d.f = value;
    836     _msContext.S[regNum - UNW_ARM_S0] = d.w;
    837   }
    838   if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D31) {
    839     union {
    840       uint64_t w;
    841       double d;
    842     } d;
    843     d.d = value;
    844     _msContext.D[regNum - UNW_ARM_D0] = d.w;
    845   }
    846   _LIBUNWIND_ABORT("unsupported float register");
    847 #elif defined(_LIBUNWIND_TARGET_AARCH64)
    848   _msContext.V[regNum - UNW_ARM64_D0].D[0] = value;
    849 #else
    850   (void)regNum;
    851   (void)value;
    852   _LIBUNWIND_ABORT("float registers unimplemented");
    853 #endif
    854 }
    855 
    856 template <typename A, typename R> void UnwindCursor<A, R>::jumpto() {
    857   RtlRestoreContext(&_msContext, nullptr);
    858 }
    859 
    860 #ifdef __arm__
    861 template <typename A, typename R> void UnwindCursor<A, R>::saveVFPAsX() {}
    862 #endif
    863 
    864 template <typename A, typename R>
    865 const char *UnwindCursor<A, R>::getRegisterName(int regNum) {
    866   return R::getRegisterName(regNum);
    867 }
    868 
    869 template <typename A, typename R> bool UnwindCursor<A, R>::isSignalFrame() {
    870   return false;
    871 }
    872 
    873 #else  // !defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) || !defined(_WIN32)
    874 
    875 /// UnwindCursor contains all state (including all register values) during
    876 /// an unwind.  This is normally stack allocated inside a unw_cursor_t.
    877 template <typename A, typename R>
    878 class UnwindCursor : public AbstractUnwindCursor{
    879   typedef typename A::pint_t pint_t;
    880 public:
    881                       UnwindCursor(unw_context_t *context, A &as);
    882                       UnwindCursor(A &as, void *threadArg);
    883   virtual             ~UnwindCursor() {}
    884   virtual bool        validReg(int);
    885   virtual unw_word_t  getReg(int);
    886   virtual void        setReg(int, unw_word_t);
    887   virtual bool        validFloatReg(int);
    888   virtual unw_fpreg_t getFloatReg(int);
    889   virtual void        setFloatReg(int, unw_fpreg_t);
    890   virtual int         step();
    891   virtual void        getInfo(unw_proc_info_t *);
    892   virtual void        jumpto();
    893   virtual bool        isSignalFrame();
    894   virtual bool        getFunctionName(char *buf, size_t len, unw_word_t *off);
    895   virtual void        setInfoBasedOnIPRegister(bool isReturnAddress = false);
    896   virtual const char *getRegisterName(int num);
    897 #ifdef __arm__
    898   virtual void        saveVFPAsX();
    899 #endif
    900 
    901   // libunwind does not and should not depend on C++ library which means that we
    902   // need our own defition of inline placement new.
    903   static void *operator new(size_t, UnwindCursor<A, R> *p) { return p; }
    904 
    905 private:
    906 
    907 #if defined(_LIBUNWIND_ARM_EHABI)
    908   bool getInfoFromEHABISection(pint_t pc, const UnwindInfoSections &sects);
    909 
    910   int stepWithEHABI() {
    911     size_t len = 0;
    912     size_t off = 0;
    913     // FIXME: Calling decode_eht_entry() here is violating the libunwind
    914     // abstraction layer.
    915     const uint32_t *ehtp =
    916         decode_eht_entry(reinterpret_cast<const uint32_t *>(_info.unwind_info),
    917                          &off, &len);
    918     if (_Unwind_VRS_Interpret((_Unwind_Context *)this, ehtp, off, len) !=
    919             _URC_CONTINUE_UNWIND)
    920       return UNW_STEP_END;
    921     return UNW_STEP_SUCCESS;
    922   }
    923 #endif
    924 
    925 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
    926   bool getInfoFromDwarfSection(pint_t pc, const UnwindInfoSections &sects,
    927                                             uint32_t fdeSectionOffsetHint=0);
    928   int stepWithDwarfFDE() {
    929     return DwarfInstructions<A, R>::stepWithDwarf(_addressSpace,
    930                                               (pint_t)this->getReg(UNW_REG_IP),
    931                                               (pint_t)_info.unwind_info,
    932                                               _registers);
    933   }
    934 #endif
    935 
    936 #if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
    937   bool getInfoFromCompactEncodingSection(pint_t pc,
    938                                             const UnwindInfoSections &sects);
    939   int stepWithCompactEncoding() {
    940   #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
    941     if ( compactSaysUseDwarf() )
    942       return stepWithDwarfFDE();
    943   #endif
    944     R dummy;
    945     return stepWithCompactEncoding(dummy);
    946   }
    947 
    948 #if defined(_LIBUNWIND_TARGET_X86_64)
    949   int stepWithCompactEncoding(Registers_x86_64 &) {
    950     return CompactUnwinder_x86_64<A>::stepWithCompactEncoding(
    951         _info.format, _info.start_ip, _addressSpace, _registers);
    952   }
    953 #endif
    954 
    955 #if defined(_LIBUNWIND_TARGET_I386)
    956   int stepWithCompactEncoding(Registers_x86 &) {
    957     return CompactUnwinder_x86<A>::stepWithCompactEncoding(
    958         _info.format, (uint32_t)_info.start_ip, _addressSpace, _registers);
    959   }
    960 #endif
    961 
    962 #if defined(_LIBUNWIND_TARGET_PPC)
    963   int stepWithCompactEncoding(Registers_ppc &) {
    964     return UNW_EINVAL;
    965   }
    966 #endif
    967 
    968 #if defined(_LIBUNWIND_TARGET_PPC64)
    969   int stepWithCompactEncoding(Registers_ppc64 &) {
    970     return UNW_EINVAL;
    971   }
    972 #endif
    973 
    974 
    975 #if defined(_LIBUNWIND_TARGET_AARCH64)
    976   int stepWithCompactEncoding(Registers_arm64 &) {
    977     return CompactUnwinder_arm64<A>::stepWithCompactEncoding(
    978         _info.format, _info.start_ip, _addressSpace, _registers);
    979   }
    980 #endif
    981 
    982 #if defined(_LIBUNWIND_TARGET_MIPS_O32)
    983   int stepWithCompactEncoding(Registers_mips_o32 &) {
    984     return UNW_EINVAL;
    985   }
    986 #endif
    987 
    988 #if defined(_LIBUNWIND_TARGET_MIPS_NEWABI)
    989   int stepWithCompactEncoding(Registers_mips_newabi &) {
    990     return UNW_EINVAL;
    991   }
    992 #endif
    993 
    994 #if defined(_LIBUNWIND_TARGET_SPARC)
    995   int stepWithCompactEncoding(Registers_sparc &) { return UNW_EINVAL; }
    996 #endif
    997 
    998   bool compactSaysUseDwarf(uint32_t *offset=NULL) const {
    999     R dummy;
   1000     return compactSaysUseDwarf(dummy, offset);
   1001   }
   1002 
   1003 #if defined(_LIBUNWIND_TARGET_X86_64)
   1004   bool compactSaysUseDwarf(Registers_x86_64 &, uint32_t *offset) const {
   1005     if ((_info.format & UNWIND_X86_64_MODE_MASK) == UNWIND_X86_64_MODE_DWARF) {
   1006       if (offset)
   1007         *offset = (_info.format & UNWIND_X86_64_DWARF_SECTION_OFFSET);
   1008       return true;
   1009     }
   1010     return false;
   1011   }
   1012 #endif
   1013 
   1014 #if defined(_LIBUNWIND_TARGET_I386)
   1015   bool compactSaysUseDwarf(Registers_x86 &, uint32_t *offset) const {
   1016     if ((_info.format & UNWIND_X86_MODE_MASK) == UNWIND_X86_MODE_DWARF) {
   1017       if (offset)
   1018         *offset = (_info.format & UNWIND_X86_DWARF_SECTION_OFFSET);
   1019       return true;
   1020     }
   1021     return false;
   1022   }
   1023 #endif
   1024 
   1025 #if defined(_LIBUNWIND_TARGET_PPC)
   1026   bool compactSaysUseDwarf(Registers_ppc &, uint32_t *) const {
   1027     return true;
   1028   }
   1029 #endif
   1030 
   1031 #if defined(_LIBUNWIND_TARGET_PPC64)
   1032   bool compactSaysUseDwarf(Registers_ppc64 &, uint32_t *) const {
   1033     return true;
   1034   }
   1035 #endif
   1036 
   1037 #if defined(_LIBUNWIND_TARGET_AARCH64)
   1038   bool compactSaysUseDwarf(Registers_arm64 &, uint32_t *offset) const {
   1039     if ((_info.format & UNWIND_ARM64_MODE_MASK) == UNWIND_ARM64_MODE_DWARF) {
   1040       if (offset)
   1041         *offset = (_info.format & UNWIND_ARM64_DWARF_SECTION_OFFSET);
   1042       return true;
   1043     }
   1044     return false;
   1045   }
   1046 #endif
   1047 
   1048 #if defined(_LIBUNWIND_TARGET_MIPS_O32)
   1049   bool compactSaysUseDwarf(Registers_mips_o32 &, uint32_t *) const {
   1050     return true;
   1051   }
   1052 #endif
   1053 
   1054 #if defined(_LIBUNWIND_TARGET_MIPS_NEWABI)
   1055   bool compactSaysUseDwarf(Registers_mips_newabi &, uint32_t *) const {
   1056     return true;
   1057   }
   1058 #endif
   1059 
   1060 #if defined(_LIBUNWIND_TARGET_SPARC)
   1061   bool compactSaysUseDwarf(Registers_sparc &, uint32_t *) const { return true; }
   1062 #endif
   1063 
   1064 #endif // defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
   1065 
   1066 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
   1067   compact_unwind_encoding_t dwarfEncoding() const {
   1068     R dummy;
   1069     return dwarfEncoding(dummy);
   1070   }
   1071 
   1072 #if defined(_LIBUNWIND_TARGET_X86_64)
   1073   compact_unwind_encoding_t dwarfEncoding(Registers_x86_64 &) const {
   1074     return UNWIND_X86_64_MODE_DWARF;
   1075   }
   1076 #endif
   1077 
   1078 #if defined(_LIBUNWIND_TARGET_I386)
   1079   compact_unwind_encoding_t dwarfEncoding(Registers_x86 &) const {
   1080     return UNWIND_X86_MODE_DWARF;
   1081   }
   1082 #endif
   1083 
   1084 #if defined(_LIBUNWIND_TARGET_PPC)
   1085   compact_unwind_encoding_t dwarfEncoding(Registers_ppc &) const {
   1086     return 0;
   1087   }
   1088 #endif
   1089 
   1090 #if defined(_LIBUNWIND_TARGET_PPC64)
   1091   compact_unwind_encoding_t dwarfEncoding(Registers_ppc64 &) const {
   1092     return 0;
   1093   }
   1094 #endif
   1095 
   1096 #if defined(_LIBUNWIND_TARGET_AARCH64)
   1097   compact_unwind_encoding_t dwarfEncoding(Registers_arm64 &) const {
   1098     return UNWIND_ARM64_MODE_DWARF;
   1099   }
   1100 #endif
   1101 
   1102 #if defined(_LIBUNWIND_TARGET_ARM)
   1103   compact_unwind_encoding_t dwarfEncoding(Registers_arm &) const {
   1104     return 0;
   1105   }
   1106 #endif
   1107 
   1108 #if defined (_LIBUNWIND_TARGET_OR1K)
   1109   compact_unwind_encoding_t dwarfEncoding(Registers_or1k &) const {
   1110     return 0;
   1111   }
   1112 #endif
   1113 
   1114 #if defined (_LIBUNWIND_TARGET_MIPS_O32)
   1115   compact_unwind_encoding_t dwarfEncoding(Registers_mips_o32 &) const {
   1116     return 0;
   1117   }
   1118 #endif
   1119 
   1120 #if defined (_LIBUNWIND_TARGET_MIPS_NEWABI)
   1121   compact_unwind_encoding_t dwarfEncoding(Registers_mips_newabi &) const {
   1122     return 0;
   1123   }
   1124 #endif
   1125 
   1126 #if defined(_LIBUNWIND_TARGET_SPARC)
   1127   compact_unwind_encoding_t dwarfEncoding(Registers_sparc &) const { return 0; }
   1128 #endif
   1129 
   1130 #endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
   1131 
   1132 #if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
   1133   // For runtime environments using SEH unwind data without Windows runtime
   1134   // support.
   1135   pint_t getLastPC() const { /* FIXME: Implement */ return 0; }
   1136   void setLastPC(pint_t pc) { /* FIXME: Implement */ }
   1137   RUNTIME_FUNCTION *lookUpSEHUnwindInfo(pint_t pc, pint_t *base) {
   1138     /* FIXME: Implement */
   1139     *base = 0;
   1140     return nullptr;
   1141   }
   1142   bool getInfoFromSEH(pint_t pc);
   1143   int stepWithSEHData() { /* FIXME: Implement */ return 0; }
   1144 #endif // defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
   1145 
   1146 
   1147   A               &_addressSpace;
   1148   R                _registers;
   1149   unw_proc_info_t  _info;
   1150   bool             _unwindInfoMissing;
   1151   bool             _isSignalFrame;
   1152 };
   1153 
   1154 
   1155 template <typename A, typename R>
   1156 UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as)
   1157     : _addressSpace(as), _registers(context), _unwindInfoMissing(false),
   1158       _isSignalFrame(false) {
   1159   static_assert((check_fit<UnwindCursor<A, R>, unw_cursor_t>::does_fit),
   1160                 "UnwindCursor<> does not fit in unw_cursor_t");
   1161   memset(&_info, 0, sizeof(_info));
   1162 }
   1163 
   1164 template <typename A, typename R>
   1165 UnwindCursor<A, R>::UnwindCursor(A &as, void *)
   1166     : _addressSpace(as), _unwindInfoMissing(false), _isSignalFrame(false) {
   1167   memset(&_info, 0, sizeof(_info));
   1168   // FIXME
   1169   // fill in _registers from thread arg
   1170 }
   1171 
   1172 
   1173 template <typename A, typename R>
   1174 bool UnwindCursor<A, R>::validReg(int regNum) {
   1175   return _registers.validRegister(regNum);
   1176 }
   1177 
   1178 template <typename A, typename R>
   1179 unw_word_t UnwindCursor<A, R>::getReg(int regNum) {
   1180   return _registers.getRegister(regNum);
   1181 }
   1182 
   1183 template <typename A, typename R>
   1184 void UnwindCursor<A, R>::setReg(int regNum, unw_word_t value) {
   1185   _registers.setRegister(regNum, (typename A::pint_t)value);
   1186 }
   1187 
   1188 template <typename A, typename R>
   1189 bool UnwindCursor<A, R>::validFloatReg(int regNum) {
   1190   return _registers.validFloatRegister(regNum);
   1191 }
   1192 
   1193 template <typename A, typename R>
   1194 unw_fpreg_t UnwindCursor<A, R>::getFloatReg(int regNum) {
   1195   return _registers.getFloatRegister(regNum);
   1196 }
   1197 
   1198 template <typename A, typename R>
   1199 void UnwindCursor<A, R>::setFloatReg(int regNum, unw_fpreg_t value) {
   1200   _registers.setFloatRegister(regNum, value);
   1201 }
   1202 
   1203 template <typename A, typename R> void UnwindCursor<A, R>::jumpto() {
   1204   _registers.jumpto();
   1205 }
   1206 
   1207 #ifdef __arm__
   1208 template <typename A, typename R> void UnwindCursor<A, R>::saveVFPAsX() {
   1209   _registers.saveVFPAsX();
   1210 }
   1211 #endif
   1212 
   1213 template <typename A, typename R>
   1214 const char *UnwindCursor<A, R>::getRegisterName(int regNum) {
   1215   return _registers.getRegisterName(regNum);
   1216 }
   1217 
   1218 template <typename A, typename R> bool UnwindCursor<A, R>::isSignalFrame() {
   1219   return _isSignalFrame;
   1220 }
   1221 
   1222 #endif // defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
   1223 
   1224 #if defined(_LIBUNWIND_ARM_EHABI)
   1225 struct EHABIIndexEntry {
   1226   uint32_t functionOffset;
   1227   uint32_t data;
   1228 };
   1229 
   1230 template<typename A>
   1231 struct EHABISectionIterator {
   1232   typedef EHABISectionIterator _Self;
   1233 
   1234   typedef typename A::pint_t value_type;
   1235   typedef typename A::pint_t* pointer;
   1236   typedef typename A::pint_t& reference;
   1237   typedef size_t size_type;
   1238   typedef size_t difference_type;
   1239 
   1240   static _Self begin(A& addressSpace, const UnwindInfoSections& sects) {
   1241     return _Self(addressSpace, sects, 0);
   1242   }
   1243   static _Self end(A& addressSpace, const UnwindInfoSections& sects) {
   1244     return _Self(addressSpace, sects,
   1245                  sects.arm_section_length / sizeof(EHABIIndexEntry));
   1246   }
   1247 
   1248   EHABISectionIterator(A& addressSpace, const UnwindInfoSections& sects, size_t i)
   1249       : _i(i), _addressSpace(&addressSpace), _sects(&sects) {}
   1250 
   1251   _Self& operator++() { ++_i; return *this; }
   1252   _Self& operator+=(size_t a) { _i += a; return *this; }
   1253   _Self& operator--() { assert(_i > 0); --_i; return *this; }
   1254   _Self& operator-=(size_t a) { assert(_i >= a); _i -= a; return *this; }
   1255 
   1256   _Self operator+(size_t a) { _Self out = *this; out._i += a; return out; }
   1257   _Self operator-(size_t a) { assert(_i >= a); _Self out = *this; out._i -= a; return out; }
   1258 
   1259   size_t operator-(const _Self& other) { return _i - other._i; }
   1260 
   1261   bool operator==(const _Self& other) const {
   1262     assert(_addressSpace == other._addressSpace);
   1263     assert(_sects == other._sects);
   1264     return _i == other._i;
   1265   }
   1266 
   1267   typename A::pint_t operator*() const { return functionAddress(); }
   1268 
   1269   typename A::pint_t functionAddress() const {
   1270     typename A::pint_t indexAddr = _sects->arm_section + arrayoffsetof(
   1271         EHABIIndexEntry, _i, functionOffset);
   1272     return indexAddr + signExtendPrel31(_addressSpace->get32(indexAddr));
   1273   }
   1274 
   1275   typename A::pint_t dataAddress() {
   1276     typename A::pint_t indexAddr = _sects->arm_section + arrayoffsetof(
   1277         EHABIIndexEntry, _i, data);
   1278     return indexAddr;
   1279   }
   1280 
   1281  private:
   1282   size_t _i;
   1283   A* _addressSpace;
   1284   const UnwindInfoSections* _sects;
   1285 };
   1286 
   1287 namespace {
   1288 
   1289 template <typename A>
   1290 EHABISectionIterator<A> EHABISectionUpperBound(
   1291     EHABISectionIterator<A> first,
   1292     EHABISectionIterator<A> last,
   1293     typename A::pint_t value) {
   1294   size_t len = last - first;
   1295   while (len > 0) {
   1296     size_t l2 = len / 2;
   1297     EHABISectionIterator<A> m = first + l2;
   1298     if (value < *m) {
   1299         len = l2;
   1300     } else {
   1301         first = ++m;
   1302         len -= l2 + 1;
   1303     }
   1304   }
   1305   return first;
   1306 }
   1307 
   1308 }
   1309 
   1310 template <typename A, typename R>
   1311 bool UnwindCursor<A, R>::getInfoFromEHABISection(
   1312     pint_t pc,
   1313     const UnwindInfoSections &sects) {
   1314   EHABISectionIterator<A> begin =
   1315       EHABISectionIterator<A>::begin(_addressSpace, sects);
   1316   EHABISectionIterator<A> end =
   1317       EHABISectionIterator<A>::end(_addressSpace, sects);
   1318   if (begin == end)
   1319     return false;
   1320 
   1321   EHABISectionIterator<A> itNextPC = EHABISectionUpperBound(begin, end, pc);
   1322   if (itNextPC == begin)
   1323     return false;
   1324   EHABISectionIterator<A> itThisPC = itNextPC - 1;
   1325 
   1326   pint_t thisPC = itThisPC.functionAddress();
   1327   // If an exception is thrown from a function, corresponding to the last entry
   1328   // in the table, we don't really know the function extent and have to choose a
   1329   // value for nextPC. Choosing max() will allow the range check during trace to
   1330   // succeed.
   1331   pint_t nextPC = (itNextPC == end) ? UINTPTR_MAX : itNextPC.functionAddress();
   1332   pint_t indexDataAddr = itThisPC.dataAddress();
   1333 
   1334   if (indexDataAddr == 0)
   1335     return false;
   1336 
   1337   uint32_t indexData = _addressSpace.get32(indexDataAddr);
   1338   if (indexData == UNW_EXIDX_CANTUNWIND)
   1339     return false;
   1340 
   1341   // If the high bit is set, the exception handling table entry is inline inside
   1342   // the index table entry on the second word (aka |indexDataAddr|). Otherwise,
   1343   // the table points at an offset in the exception handling table (section 5 EHABI).
   1344   pint_t exceptionTableAddr;
   1345   uint32_t exceptionTableData;
   1346   bool isSingleWordEHT;
   1347   if (indexData & 0x80000000) {
   1348     exceptionTableAddr = indexDataAddr;
   1349     // TODO(ajwong): Should this data be 0?
   1350     exceptionTableData = indexData;
   1351     isSingleWordEHT = true;
   1352   } else {
   1353     exceptionTableAddr = indexDataAddr + signExtendPrel31(indexData);
   1354     exceptionTableData = _addressSpace.get32(exceptionTableAddr);
   1355     isSingleWordEHT = false;
   1356   }
   1357 
   1358   // Now we know the 3 things:
   1359   //   exceptionTableAddr -- exception handler table entry.
   1360   //   exceptionTableData -- the data inside the first word of the eht entry.
   1361   //   isSingleWordEHT -- whether the entry is in the index.
   1362   unw_word_t personalityRoutine = 0xbadf00d;
   1363   bool scope32 = false;
   1364   uintptr_t lsda;
   1365 
   1366   // If the high bit in the exception handling table entry is set, the entry is
   1367   // in compact form (section 6.3 EHABI).
   1368   if (exceptionTableData & 0x80000000) {
   1369     // Grab the index of the personality routine from the compact form.
   1370     uint32_t choice = (exceptionTableData & 0x0f000000) >> 24;
   1371     uint32_t extraWords = 0;
   1372     switch (choice) {
   1373       case 0:
   1374         personalityRoutine = (unw_word_t) &__aeabi_unwind_cpp_pr0;
   1375         extraWords = 0;
   1376         scope32 = false;
   1377         lsda = isSingleWordEHT ? 0 : (exceptionTableAddr + 4);
   1378         break;
   1379       case 1:
   1380         personalityRoutine = (unw_word_t) &__aeabi_unwind_cpp_pr1;
   1381         extraWords = (exceptionTableData & 0x00ff0000) >> 16;
   1382         scope32 = false;
   1383         lsda = exceptionTableAddr + (extraWords + 1) * 4;
   1384         break;
   1385       case 2:
   1386         personalityRoutine = (unw_word_t) &__aeabi_unwind_cpp_pr2;
   1387         extraWords = (exceptionTableData & 0x00ff0000) >> 16;
   1388         scope32 = true;
   1389         lsda = exceptionTableAddr + (extraWords + 1) * 4;
   1390         break;
   1391       default:
   1392         _LIBUNWIND_ABORT("unknown personality routine");
   1393         return false;
   1394     }
   1395 
   1396     if (isSingleWordEHT) {
   1397       if (extraWords != 0) {
   1398         _LIBUNWIND_ABORT("index inlined table detected but pr function "
   1399                          "requires extra words");
   1400         return false;
   1401       }
   1402     }
   1403   } else {
   1404     pint_t personalityAddr =
   1405         exceptionTableAddr + signExtendPrel31(exceptionTableData);
   1406     personalityRoutine = personalityAddr;
   1407 
   1408     // ARM EHABI # 6.2, # 9.2
   1409     //
   1410     //  +---- ehtp
   1411     //  v
   1412     // +--------------------------------------+
   1413     // | +--------+--------+--------+-------+ |
   1414     // | |0| prel31 to personalityRoutine   | |
   1415     // | +--------+--------+--------+-------+ |
   1416     // | |      N |      unwind opcodes     | |  <-- UnwindData
   1417     // | +--------+--------+--------+-------+ |
   1418     // | | Word 2        unwind opcodes     | |
   1419     // | +--------+--------+--------+-------+ |
   1420     // | ...                                  |
   1421     // | +--------+--------+--------+-------+ |
   1422     // | | Word N        unwind opcodes     | |
   1423     // | +--------+--------+--------+-------+ |
   1424     // | | LSDA                             | |  <-- lsda
   1425     // | | ...                              | |
   1426     // | +--------+--------+--------+-------+ |
   1427     // +--------------------------------------+
   1428 
   1429     uint32_t *UnwindData = reinterpret_cast<uint32_t*>(exceptionTableAddr) + 1;
   1430     uint32_t FirstDataWord = *UnwindData;
   1431     size_t N = ((FirstDataWord >> 24) & 0xff);
   1432     size_t NDataWords = N + 1;
   1433     lsda = reinterpret_cast<uintptr_t>(UnwindData + NDataWords);
   1434   }
   1435 
   1436   _info.start_ip = thisPC;
   1437   _info.end_ip = nextPC;
   1438   _info.handler = personalityRoutine;
   1439   _info.unwind_info = exceptionTableAddr;
   1440   _info.lsda = lsda;
   1441   // flags is pr_cache.additional. See EHABI #7.2 for definition of bit 0.
   1442   _info.flags = isSingleWordEHT ? 1 : 0 | scope32 ? 0x2 : 0;  // Use enum?
   1443 
   1444   return true;
   1445 }
   1446 #endif
   1447 
   1448 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
   1449 template <typename A, typename R>
   1450 bool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc,
   1451                                                 const UnwindInfoSections &sects,
   1452                                                 uint32_t fdeSectionOffsetHint) {
   1453   typename CFI_Parser<A>::FDE_Info fdeInfo;
   1454   typename CFI_Parser<A>::CIE_Info cieInfo;
   1455   bool foundFDE = false;
   1456   bool foundInCache = false;
   1457   // If compact encoding table gave offset into dwarf section, go directly there
   1458   if (fdeSectionOffsetHint != 0) {
   1459     foundFDE = CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section,
   1460                                     (uint32_t)sects.dwarf_section_length,
   1461                                     sects.dwarf_section + fdeSectionOffsetHint,
   1462                                     &fdeInfo, &cieInfo);
   1463   }
   1464 #if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX)
   1465   if (!foundFDE && (sects.dwarf_index_section != 0)) {
   1466     foundFDE = EHHeaderParser<A>::findFDE(
   1467         _addressSpace, pc, sects.dwarf_index_section,
   1468         (uint32_t)sects.dwarf_index_section_length, &fdeInfo, &cieInfo);
   1469   }
   1470 #endif
   1471   if (!foundFDE) {
   1472     // otherwise, search cache of previously found FDEs.
   1473     pint_t cachedFDE = DwarfFDECache<A>::findFDE(sects.dso_base, pc);
   1474     if (cachedFDE != 0) {
   1475       foundFDE =
   1476           CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section,
   1477                                  (uint32_t)sects.dwarf_section_length,
   1478                                  cachedFDE, &fdeInfo, &cieInfo);
   1479       foundInCache = foundFDE;
   1480     }
   1481   }
   1482   if (!foundFDE) {
   1483     // Still not found, do full scan of __eh_frame section.
   1484     foundFDE = CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section,
   1485                                       (uint32_t)sects.dwarf_section_length, 0,
   1486                                       &fdeInfo, &cieInfo);
   1487   }
   1488   if (foundFDE) {
   1489     typename CFI_Parser<A>::PrologInfo prolog;
   1490     if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, cieInfo, pc,
   1491                                             R::getArch(), &prolog)) {
   1492       // Save off parsed FDE info
   1493       _info.start_ip          = fdeInfo.pcStart;
   1494       _info.end_ip            = fdeInfo.pcEnd;
   1495       _info.lsda              = fdeInfo.lsda;
   1496       _info.handler           = cieInfo.personality;
   1497       _info.gp                = prolog.spExtraArgSize;
   1498       _info.flags             = 0;
   1499       _info.format            = dwarfEncoding();
   1500       _info.unwind_info       = fdeInfo.fdeStart;
   1501       _info.unwind_info_size  = (uint32_t)fdeInfo.fdeLength;
   1502       _info.extra             = (unw_word_t) sects.dso_base;
   1503 
   1504       // Add to cache (to make next lookup faster) if we had no hint
   1505       // and there was no index.
   1506       if (!foundInCache && (fdeSectionOffsetHint == 0)) {
   1507   #if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX)
   1508         if (sects.dwarf_index_section == 0)
   1509   #endif
   1510         DwarfFDECache<A>::add(sects.dso_base, fdeInfo.pcStart, fdeInfo.pcEnd,
   1511                               fdeInfo.fdeStart);
   1512       }
   1513       return true;
   1514     }
   1515   }
   1516   //_LIBUNWIND_DEBUG_LOG("can't find/use FDE for pc=0x%llX", (uint64_t)pc);
   1517   return false;
   1518 }
   1519 #endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
   1520 
   1521 
   1522 #if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
   1523 template <typename A, typename R>
   1524 bool UnwindCursor<A, R>::getInfoFromCompactEncodingSection(pint_t pc,
   1525                                               const UnwindInfoSections &sects) {
   1526   const bool log = false;
   1527   if (log)
   1528     fprintf(stderr, "getInfoFromCompactEncodingSection(pc=0x%llX, mh=0x%llX)\n",
   1529             (uint64_t)pc, (uint64_t)sects.dso_base);
   1530 
   1531   const UnwindSectionHeader<A> sectionHeader(_addressSpace,
   1532                                                 sects.compact_unwind_section);
   1533   if (sectionHeader.version() != UNWIND_SECTION_VERSION)
   1534     return false;
   1535 
   1536   // do a binary search of top level index to find page with unwind info
   1537   pint_t targetFunctionOffset = pc - sects.dso_base;
   1538   const UnwindSectionIndexArray<A> topIndex(_addressSpace,
   1539                                            sects.compact_unwind_section
   1540                                          + sectionHeader.indexSectionOffset());
   1541   uint32_t low = 0;
   1542   uint32_t high = sectionHeader.indexCount();
   1543   uint32_t last = high - 1;
   1544   while (low < high) {
   1545     uint32_t mid = (low + high) / 2;
   1546     //if ( log ) fprintf(stderr, "\tmid=%d, low=%d, high=%d, *mid=0x%08X\n",
   1547     //mid, low, high, topIndex.functionOffset(mid));
   1548     if (topIndex.functionOffset(mid) <= targetFunctionOffset) {
   1549       if ((mid == last) ||
   1550           (topIndex.functionOffset(mid + 1) > targetFunctionOffset)) {
   1551         low = mid;
   1552         break;
   1553       } else {
   1554         low = mid + 1;
   1555       }
   1556     } else {
   1557       high = mid;
   1558     }
   1559   }
   1560   const uint32_t firstLevelFunctionOffset = topIndex.functionOffset(low);
   1561   const uint32_t firstLevelNextPageFunctionOffset =
   1562       topIndex.functionOffset(low + 1);
   1563   const pint_t secondLevelAddr =
   1564       sects.compact_unwind_section + topIndex.secondLevelPagesSectionOffset(low);
   1565   const pint_t lsdaArrayStartAddr =
   1566       sects.compact_unwind_section + topIndex.lsdaIndexArraySectionOffset(low);
   1567   const pint_t lsdaArrayEndAddr =
   1568       sects.compact_unwind_section + topIndex.lsdaIndexArraySectionOffset(low+1);
   1569   if (log)
   1570     fprintf(stderr, "\tfirst level search for result index=%d "
   1571                     "to secondLevelAddr=0x%llX\n",
   1572                     low, (uint64_t) secondLevelAddr);
   1573   // do a binary search of second level page index
   1574   uint32_t encoding = 0;
   1575   pint_t funcStart = 0;
   1576   pint_t funcEnd = 0;
   1577   pint_t lsda = 0;
   1578   pint_t personality = 0;
   1579   uint32_t pageKind = _addressSpace.get32(secondLevelAddr);
   1580   if (pageKind == UNWIND_SECOND_LEVEL_REGULAR) {
   1581     // regular page
   1582     UnwindSectionRegularPageHeader<A> pageHeader(_addressSpace,
   1583                                                  secondLevelAddr);
   1584     UnwindSectionRegularArray<A> pageIndex(
   1585         _addressSpace, secondLevelAddr + pageHeader.entryPageOffset());
   1586     // binary search looks for entry with e where index[e].offset <= pc <
   1587     // index[e+1].offset
   1588     if (log)
   1589       fprintf(stderr, "\tbinary search for targetFunctionOffset=0x%08llX in "
   1590                       "regular page starting at secondLevelAddr=0x%llX\n",
   1591               (uint64_t) targetFunctionOffset, (uint64_t) secondLevelAddr);
   1592     low = 0;
   1593     high = pageHeader.entryCount();
   1594     while (low < high) {
   1595       uint32_t mid = (low + high) / 2;
   1596       if (pageIndex.functionOffset(mid) <= targetFunctionOffset) {
   1597         if (mid == (uint32_t)(pageHeader.entryCount() - 1)) {
   1598           // at end of table
   1599           low = mid;
   1600           funcEnd = firstLevelNextPageFunctionOffset + sects.dso_base;
   1601           break;
   1602         } else if (pageIndex.functionOffset(mid + 1) > targetFunctionOffset) {
   1603           // next is too big, so we found it
   1604           low = mid;
   1605           funcEnd = pageIndex.functionOffset(low + 1) + sects.dso_base;
   1606           break;
   1607         } else {
   1608           low = mid + 1;
   1609         }
   1610       } else {
   1611         high = mid;
   1612       }
   1613     }
   1614     encoding = pageIndex.encoding(low);
   1615     funcStart = pageIndex.functionOffset(low) + sects.dso_base;
   1616     if (pc < funcStart) {
   1617       if (log)
   1618         fprintf(
   1619             stderr,
   1620             "\tpc not in table, pc=0x%llX, funcStart=0x%llX, funcEnd=0x%llX\n",
   1621             (uint64_t) pc, (uint64_t) funcStart, (uint64_t) funcEnd);
   1622       return false;
   1623     }
   1624     if (pc > funcEnd) {
   1625       if (log)
   1626         fprintf(
   1627             stderr,
   1628             "\tpc not in table, pc=0x%llX, funcStart=0x%llX, funcEnd=0x%llX\n",
   1629             (uint64_t) pc, (uint64_t) funcStart, (uint64_t) funcEnd);
   1630       return false;
   1631     }
   1632   } else if (pageKind == UNWIND_SECOND_LEVEL_COMPRESSED) {
   1633     // compressed page
   1634     UnwindSectionCompressedPageHeader<A> pageHeader(_addressSpace,
   1635                                                     secondLevelAddr);
   1636     UnwindSectionCompressedArray<A> pageIndex(
   1637         _addressSpace, secondLevelAddr + pageHeader.entryPageOffset());
   1638     const uint32_t targetFunctionPageOffset =
   1639         (uint32_t)(targetFunctionOffset - firstLevelFunctionOffset);
   1640     // binary search looks for entry with e where index[e].offset <= pc <
   1641     // index[e+1].offset
   1642     if (log)
   1643       fprintf(stderr, "\tbinary search of compressed page starting at "
   1644                       "secondLevelAddr=0x%llX\n",
   1645               (uint64_t) secondLevelAddr);
   1646     low = 0;
   1647     last = pageHeader.entryCount() - 1;
   1648     high = pageHeader.entryCount();
   1649     while (low < high) {
   1650       uint32_t mid = (low + high) / 2;
   1651       if (pageIndex.functionOffset(mid) <= targetFunctionPageOffset) {
   1652         if ((mid == last) ||
   1653             (pageIndex.functionOffset(mid + 1) > targetFunctionPageOffset)) {
   1654           low = mid;
   1655           break;
   1656         } else {
   1657           low = mid + 1;
   1658         }
   1659       } else {
   1660         high = mid;
   1661       }
   1662     }
   1663     funcStart = pageIndex.functionOffset(low) + firstLevelFunctionOffset
   1664                                                               + sects.dso_base;
   1665     if (low < last)
   1666       funcEnd =
   1667           pageIndex.functionOffset(low + 1) + firstLevelFunctionOffset
   1668                                                               + sects.dso_base;
   1669     else
   1670       funcEnd = firstLevelNextPageFunctionOffset + sects.dso_base;
   1671     if (pc < funcStart) {
   1672       _LIBUNWIND_DEBUG_LOG("malformed __unwind_info, pc=0x%llX not in second  "
   1673                            "level compressed unwind table. funcStart=0x%llX",
   1674                             (uint64_t) pc, (uint64_t) funcStart);
   1675       return false;
   1676     }
   1677     if (pc > funcEnd) {
   1678       _LIBUNWIND_DEBUG_LOG("malformed __unwind_info, pc=0x%llX not in second  "
   1679                           "level compressed unwind table. funcEnd=0x%llX",
   1680                            (uint64_t) pc, (uint64_t) funcEnd);
   1681       return false;
   1682     }
   1683     uint16_t encodingIndex = pageIndex.encodingIndex(low);
   1684     if (encodingIndex < sectionHeader.commonEncodingsArrayCount()) {
   1685       // encoding is in common table in section header
   1686       encoding = _addressSpace.get32(
   1687           sects.compact_unwind_section +
   1688           sectionHeader.commonEncodingsArraySectionOffset() +
   1689           encodingIndex * sizeof(uint32_t));
   1690     } else {
   1691       // encoding is in page specific table
   1692       uint16_t pageEncodingIndex =
   1693           encodingIndex - (uint16_t)sectionHeader.commonEncodingsArrayCount();
   1694       encoding = _addressSpace.get32(secondLevelAddr +
   1695                                      pageHeader.encodingsPageOffset() +
   1696                                      pageEncodingIndex * sizeof(uint32_t));
   1697     }
   1698   } else {
   1699     _LIBUNWIND_DEBUG_LOG("malformed __unwind_info at 0x%0llX bad second "
   1700                          "level page",
   1701                           (uint64_t) sects.compact_unwind_section);
   1702     return false;
   1703   }
   1704 
   1705   // look up LSDA, if encoding says function has one
   1706   if (encoding & UNWIND_HAS_LSDA) {
   1707     UnwindSectionLsdaArray<A> lsdaIndex(_addressSpace, lsdaArrayStartAddr);
   1708     uint32_t funcStartOffset = (uint32_t)(funcStart - sects.dso_base);
   1709     low = 0;
   1710     high = (uint32_t)(lsdaArrayEndAddr - lsdaArrayStartAddr) /
   1711                     sizeof(unwind_info_section_header_lsda_index_entry);
   1712     // binary search looks for entry with exact match for functionOffset
   1713     if (log)
   1714       fprintf(stderr,
   1715               "\tbinary search of lsda table for targetFunctionOffset=0x%08X\n",
   1716               funcStartOffset);
   1717     while (low < high) {
   1718       uint32_t mid = (low + high) / 2;
   1719       if (lsdaIndex.functionOffset(mid) == funcStartOffset) {
   1720         lsda = lsdaIndex.lsdaOffset(mid) + sects.dso_base;
   1721         break;
   1722       } else if (lsdaIndex.functionOffset(mid) < funcStartOffset) {
   1723         low = mid + 1;
   1724       } else {
   1725         high = mid;
   1726       }
   1727     }
   1728     if (lsda == 0) {
   1729       _LIBUNWIND_DEBUG_LOG("found encoding 0x%08X with HAS_LSDA bit set for "
   1730                     "pc=0x%0llX, but lsda table has no entry",
   1731                     encoding, (uint64_t) pc);
   1732       return false;
   1733     }
   1734   }
   1735 
   1736   // extact personality routine, if encoding says function has one
   1737   uint32_t personalityIndex = (encoding & UNWIND_PERSONALITY_MASK) >>
   1738                               (__builtin_ctz(UNWIND_PERSONALITY_MASK));
   1739   if (personalityIndex != 0) {
   1740     --personalityIndex; // change 1-based to zero-based index
   1741     if (personalityIndex > sectionHeader.personalityArrayCount()) {
   1742       _LIBUNWIND_DEBUG_LOG("found encoding 0x%08X with personality index %d,  "
   1743                             "but personality table has only %d entires",
   1744                             encoding, personalityIndex,
   1745                             sectionHeader.personalityArrayCount());
   1746       return false;
   1747     }
   1748     int32_t personalityDelta = (int32_t)_addressSpace.get32(
   1749         sects.compact_unwind_section +
   1750         sectionHeader.personalityArraySectionOffset() +
   1751         personalityIndex * sizeof(uint32_t));
   1752     pint_t personalityPointer = sects.dso_base + (pint_t)personalityDelta;
   1753     personality = _addressSpace.getP(personalityPointer);
   1754     if (log)
   1755       fprintf(stderr, "getInfoFromCompactEncodingSection(pc=0x%llX), "
   1756                       "personalityDelta=0x%08X, personality=0x%08llX\n",
   1757               (uint64_t) pc, personalityDelta, (uint64_t) personality);
   1758   }
   1759 
   1760   if (log)
   1761     fprintf(stderr, "getInfoFromCompactEncodingSection(pc=0x%llX), "
   1762                     "encoding=0x%08X, lsda=0x%08llX for funcStart=0x%llX\n",
   1763             (uint64_t) pc, encoding, (uint64_t) lsda, (uint64_t) funcStart);
   1764   _info.start_ip = funcStart;
   1765   _info.end_ip = funcEnd;
   1766   _info.lsda = lsda;
   1767   _info.handler = personality;
   1768   _info.gp = 0;
   1769   _info.flags = 0;
   1770   _info.format = encoding;
   1771   _info.unwind_info = 0;
   1772   _info.unwind_info_size = 0;
   1773   _info.extra = sects.dso_base;
   1774   return true;
   1775 }
   1776 #endif // defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
   1777 
   1778 
   1779 #if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
   1780 template <typename A, typename R>
   1781 bool UnwindCursor<A, R>::getInfoFromSEH(pint_t pc) {
   1782   pint_t base;
   1783   RUNTIME_FUNCTION *unwindEntry = lookUpSEHUnwindInfo(pc, &base);
   1784   if (!unwindEntry) {
   1785     _LIBUNWIND_DEBUG_LOG("\tpc not in table, pc=0x%llX", (uint64_t) pc);
   1786     return false;
   1787   }
   1788   _info.gp = 0;
   1789   _info.flags = 0;
   1790   _info.format = 0;
   1791   _info.unwind_info_size = sizeof(RUNTIME_FUNCTION);
   1792   _info.unwind_info = reinterpret_cast<unw_word_t>(unwindEntry);
   1793   _info.extra = base;
   1794   _info.start_ip = base + unwindEntry->BeginAddress;
   1795 #ifdef _LIBUNWIND_TARGET_X86_64
   1796   _info.end_ip = base + unwindEntry->EndAddress;
   1797   // Only fill in the handler and LSDA if they're stale.
   1798   if (pc != getLastPC()) {
   1799     UNWIND_INFO *xdata = reinterpret_cast<UNWIND_INFO *>(base + unwindEntry->UnwindData);
   1800     if (xdata->Flags & (UNW_FLAG_EHANDLER|UNW_FLAG_UHANDLER)) {
   1801       // The personality is given in the UNWIND_INFO itself. The LSDA immediately
   1802       // follows the UNWIND_INFO. (This follows how both Clang and MSVC emit
   1803       // these structures.)
   1804       // N.B. UNWIND_INFO structs are DWORD-aligned.
   1805       uint32_t lastcode = (xdata->CountOfCodes + 1) & ~1;
   1806       const uint32_t *handler = reinterpret_cast<uint32_t *>(&xdata->UnwindCodes[lastcode]);
   1807       _info.lsda = reinterpret_cast<unw_word_t>(handler+1);
   1808       if (*handler) {
   1809         _info.handler = reinterpret_cast<unw_word_t>(__libunwind_seh_personality);
   1810       } else
   1811         _info.handler = 0;
   1812     } else {
   1813       _info.lsda = 0;
   1814       _info.handler = 0;
   1815     }
   1816   }
   1817 #elif defined(_LIBUNWIND_TARGET_ARM)
   1818   _info.end_ip = _info.start_ip + unwindEntry->FunctionLength;
   1819   _info.lsda = 0; // FIXME
   1820   _info.handler = 0; // FIXME
   1821 #endif
   1822   setLastPC(pc);
   1823   return true;
   1824 }
   1825 #endif
   1826 
   1827 
   1828 template <typename A, typename R>
   1829 void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {
   1830   pint_t pc = (pint_t)this->getReg(UNW_REG_IP);
   1831 #if defined(_LIBUNWIND_ARM_EHABI)
   1832   // Remove the thumb bit so the IP represents the actual instruction address.
   1833   // This matches the behaviour of _Unwind_GetIP on arm.
   1834   pc &= (pint_t)~0x1;
   1835 #endif
   1836 
   1837   // If the last line of a function is a "throw" the compiler sometimes
   1838   // emits no instructions after the call to __cxa_throw.  This means
   1839   // the return address is actually the start of the next function.
   1840   // To disambiguate this, back up the pc when we know it is a return
   1841   // address.
   1842   if (isReturnAddress)
   1843     --pc;
   1844 
   1845   // Ask address space object to find unwind sections for this pc.
   1846   UnwindInfoSections sects;
   1847   if (_addressSpace.findUnwindSections(pc, sects)) {
   1848 #if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
   1849     // If there is a compact unwind encoding table, look there first.
   1850     if (sects.compact_unwind_section != 0) {
   1851       if (this->getInfoFromCompactEncodingSection(pc, sects)) {
   1852   #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
   1853         // Found info in table, done unless encoding says to use dwarf.
   1854         uint32_t dwarfOffset;
   1855         if ((sects.dwarf_section != 0) && compactSaysUseDwarf(&dwarfOffset)) {
   1856           if (this->getInfoFromDwarfSection(pc, sects, dwarfOffset)) {
   1857             // found info in dwarf, done
   1858             return;
   1859           }
   1860         }
   1861   #endif
   1862         // If unwind table has entry, but entry says there is no unwind info,
   1863         // record that we have no unwind info.
   1864         if (_info.format == 0)
   1865           _unwindInfoMissing = true;
   1866         return;
   1867       }
   1868     }
   1869 #endif // defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
   1870 
   1871 #if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
   1872     // If there is SEH unwind info, look there next.
   1873     if (this->getInfoFromSEH(pc))
   1874       return;
   1875 #endif
   1876 
   1877 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
   1878     // If there is dwarf unwind info, look there next.
   1879     if (sects.dwarf_section != 0) {
   1880       if (this->getInfoFromDwarfSection(pc, sects)) {
   1881         // found info in dwarf, done
   1882         return;
   1883       }
   1884     }
   1885 #endif
   1886 
   1887 #if defined(_LIBUNWIND_ARM_EHABI)
   1888     // If there is ARM EHABI unwind info, look there next.
   1889     if (sects.arm_section != 0 && this->getInfoFromEHABISection(pc, sects))
   1890       return;
   1891 #endif
   1892   }
   1893 
   1894 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
   1895   // There is no static unwind info for this pc. Look to see if an FDE was
   1896   // dynamically registered for it.
   1897   pint_t cachedFDE = DwarfFDECache<A>::findFDE(0, pc);
   1898   if (cachedFDE != 0) {
   1899     CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo;
   1900     CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo;
   1901     const char *msg = CFI_Parser<A>::decodeFDE(_addressSpace,
   1902                                                 cachedFDE, &fdeInfo, &cieInfo);
   1903     if (msg == NULL) {
   1904       typename CFI_Parser<A>::PrologInfo prolog;
   1905       if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, cieInfo,
   1906                                               pc, R::getArch(), &prolog)) {
   1907         // save off parsed FDE info
   1908         _info.start_ip         = fdeInfo.pcStart;
   1909         _info.end_ip           = fdeInfo.pcEnd;
   1910         _info.lsda             = fdeInfo.lsda;
   1911         _info.handler          = cieInfo.personality;
   1912         _info.gp               = prolog.spExtraArgSize;
   1913                                   // Some frameless functions need SP
   1914                                   // altered when resuming in function.
   1915         _info.flags            = 0;
   1916         _info.format           = dwarfEncoding();
   1917         _info.unwind_info      = fdeInfo.fdeStart;
   1918         _info.unwind_info_size = (uint32_t)fdeInfo.fdeLength;
   1919         _info.extra            = 0;
   1920         return;
   1921       }
   1922     }
   1923   }
   1924 
   1925   // Lastly, ask AddressSpace object about platform specific ways to locate
   1926   // other FDEs.
   1927   pint_t fde;
   1928   if (_addressSpace.findOtherFDE(pc, fde)) {
   1929     CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo;
   1930     CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo;
   1931     if (!CFI_Parser<A>::decodeFDE(_addressSpace, fde, &fdeInfo, &cieInfo)) {
   1932       // Double check this FDE is for a function that includes the pc.
   1933       if ((fdeInfo.pcStart <= pc) && (pc < fdeInfo.pcEnd)) {
   1934         typename CFI_Parser<A>::PrologInfo prolog;
   1935         if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, cieInfo,
   1936                                                 pc, R::getArch(), &prolog)) {
   1937           // save off parsed FDE info
   1938           _info.start_ip         = fdeInfo.pcStart;
   1939           _info.end_ip           = fdeInfo.pcEnd;
   1940           _info.lsda             = fdeInfo.lsda;
   1941           _info.handler          = cieInfo.personality;
   1942           _info.gp               = prolog.spExtraArgSize;
   1943           _info.flags            = 0;
   1944           _info.format           = dwarfEncoding();
   1945           _info.unwind_info      = fdeInfo.fdeStart;
   1946           _info.unwind_info_size = (uint32_t)fdeInfo.fdeLength;
   1947           _info.extra            = 0;
   1948           return;
   1949         }
   1950       }
   1951     }
   1952   }
   1953 #endif // #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
   1954 
   1955   // no unwind info, flag that we can't reliably unwind
   1956   _unwindInfoMissing = true;
   1957 }
   1958 
   1959 template <typename A, typename R>
   1960 int UnwindCursor<A, R>::step() {
   1961   // Bottom of stack is defined is when unwind info cannot be found.
   1962   if (_unwindInfoMissing)
   1963     return UNW_STEP_END;
   1964 
   1965   // Use unwinding info to modify register set as if function returned.
   1966   int result;
   1967 #if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
   1968   result = this->stepWithCompactEncoding();
   1969 #elif defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
   1970   result = this->stepWithSEHData();
   1971 #elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
   1972   result = this->stepWithDwarfFDE();
   1973 #elif defined(_LIBUNWIND_ARM_EHABI)
   1974   result = this->stepWithEHABI();
   1975 #else
   1976   #error Need _LIBUNWIND_SUPPORT_COMPACT_UNWIND or \
   1977               _LIBUNWIND_SUPPORT_SEH_UNWIND or \
   1978               _LIBUNWIND_SUPPORT_DWARF_UNWIND or \
   1979               _LIBUNWIND_ARM_EHABI
   1980 #endif
   1981 
   1982   // update info based on new PC
   1983   if (result == UNW_STEP_SUCCESS) {
   1984     this->setInfoBasedOnIPRegister(true);
   1985     if (_unwindInfoMissing)
   1986       return UNW_STEP_END;
   1987   }
   1988 
   1989   return result;
   1990 }
   1991 
   1992 template <typename A, typename R>
   1993 void UnwindCursor<A, R>::getInfo(unw_proc_info_t *info) {
   1994   *info = _info;
   1995 }
   1996 
   1997 template <typename A, typename R>
   1998 bool UnwindCursor<A, R>::getFunctionName(char *buf, size_t bufLen,
   1999                                                            unw_word_t *offset) {
   2000   return _addressSpace.findFunctionName((pint_t)this->getReg(UNW_REG_IP),
   2001                                          buf, bufLen, offset);
   2002 }
   2003 
   2004 } // namespace libunwind
   2005 
   2006 #endif // __UNWINDCURSOR_HPP__
   2007