UnwindCursor.hpp revision 360784
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
33struct _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
48struct 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
58extern "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
76namespace libunwind {
77
78#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
79/// Cache of recently found FDEs.
80template <typename A>
81class _LIBUNWIND_HIDDEN DwarfFDECache {
82  typedef typename A::pint_t pint_t;
83public:
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
91private:
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
113template <typename A>
114typename DwarfFDECache<A>::entry *
115DwarfFDECache<A>::_buffer = _initialBuffer;
116
117template <typename A>
118typename DwarfFDECache<A>::entry *
119DwarfFDECache<A>::_bufferUsed = _initialBuffer;
120
121template <typename A>
122typename DwarfFDECache<A>::entry *
123DwarfFDECache<A>::_bufferEnd = &_initialBuffer[64];
124
125template <typename A>
126typename DwarfFDECache<A>::entry DwarfFDECache<A>::_initialBuffer[64];
127
128template <typename A>
129RWMutex DwarfFDECache<A>::_lock;
130
131#ifdef __APPLE__
132template <typename A>
133bool DwarfFDECache<A>::_registeredForDyldUnloads = false;
134#endif
135
136template <typename A>
137typename 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
152template <typename A>
153void 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
184template <typename A>
185void 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__
200template <typename A>
201void DwarfFDECache<A>::dyldUnloadHook(const struct mach_header *mh, intptr_t ) {
202  removeAllIn((pint_t) mh);
203}
204#endif
205
206template <typename A>
207void 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)
221template <typename A> class UnwindSectionHeader {
222public:
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
256private:
257  A                     &_addressSpace;
258  typename A::pint_t     _addr;
259};
260
261template <typename A> class UnwindSectionIndexArray {
262public:
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
282private:
283  A                   &_addressSpace;
284  typename A::pint_t   _addr;
285};
286
287template <typename A> class UnwindSectionRegularPageHeader {
288public:
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
307private:
308  A &_addressSpace;
309  typename A::pint_t _addr;
310};
311
312template <typename A> class UnwindSectionRegularArray {
313public:
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
328private:
329  A &_addressSpace;
330  typename A::pint_t _addr;
331};
332
333template <typename A> class UnwindSectionCompressedPageHeader {
334public:
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
364private:
365  A &_addressSpace;
366  typename A::pint_t _addr;
367};
368
369template <typename A> class UnwindSectionCompressedArray {
370public:
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
383private:
384  A &_addressSpace;
385  typename A::pint_t _addr;
386};
387
388template <typename A> class UnwindSectionLsdaArray {
389public:
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
404private:
405  A                   &_addressSpace;
406  typename A::pint_t   _addr;
407};
408#endif // defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
409
410class _LIBUNWIND_HIDDEN AbstractUnwindCursor {
411public:
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.
457template <typename A, typename R>
458class UnwindCursor : public AbstractUnwindCursor {
459  typedef typename A::pint_t pint_t;
460public:
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
489private:
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
528template <typename A, typename R>
529UnwindCursor<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
629template <typename A, typename R>
630UnwindCursor<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
642template <typename A, typename R>
643bool 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
655template <typename A, typename R>
656unw_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
705template <typename A, typename R>
706void 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
786template <typename A, typename R>
787bool 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
799template <typename A, typename R>
800unw_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
827template <typename A, typename R>
828void 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
856template <typename A, typename R> void UnwindCursor<A, R>::jumpto() {
857  RtlRestoreContext(&_msContext, nullptr);
858}
859
860#ifdef __arm__
861template <typename A, typename R> void UnwindCursor<A, R>::saveVFPAsX() {}
862#endif
863
864template <typename A, typename R>
865const char *UnwindCursor<A, R>::getRegisterName(int regNum) {
866  return R::getRegisterName(regNum);
867}
868
869template <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.
877template <typename A, typename R>
878class UnwindCursor : public AbstractUnwindCursor{
879  typedef typename A::pint_t pint_t;
880public:
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
905private:
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, _isSignalFrame);
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#if defined (_LIBUNWIND_TARGET_RISCV)
999  int stepWithCompactEncoding(Registers_riscv &) {
1000    return UNW_EINVAL;
1001  }
1002#endif
1003
1004  bool compactSaysUseDwarf(uint32_t *offset=NULL) const {
1005    R dummy;
1006    return compactSaysUseDwarf(dummy, offset);
1007  }
1008
1009#if defined(_LIBUNWIND_TARGET_X86_64)
1010  bool compactSaysUseDwarf(Registers_x86_64 &, uint32_t *offset) const {
1011    if ((_info.format & UNWIND_X86_64_MODE_MASK) == UNWIND_X86_64_MODE_DWARF) {
1012      if (offset)
1013        *offset = (_info.format & UNWIND_X86_64_DWARF_SECTION_OFFSET);
1014      return true;
1015    }
1016    return false;
1017  }
1018#endif
1019
1020#if defined(_LIBUNWIND_TARGET_I386)
1021  bool compactSaysUseDwarf(Registers_x86 &, uint32_t *offset) const {
1022    if ((_info.format & UNWIND_X86_MODE_MASK) == UNWIND_X86_MODE_DWARF) {
1023      if (offset)
1024        *offset = (_info.format & UNWIND_X86_DWARF_SECTION_OFFSET);
1025      return true;
1026    }
1027    return false;
1028  }
1029#endif
1030
1031#if defined(_LIBUNWIND_TARGET_PPC)
1032  bool compactSaysUseDwarf(Registers_ppc &, uint32_t *) const {
1033    return true;
1034  }
1035#endif
1036
1037#if defined(_LIBUNWIND_TARGET_PPC64)
1038  bool compactSaysUseDwarf(Registers_ppc64 &, uint32_t *) const {
1039    return true;
1040  }
1041#endif
1042
1043#if defined(_LIBUNWIND_TARGET_AARCH64)
1044  bool compactSaysUseDwarf(Registers_arm64 &, uint32_t *offset) const {
1045    if ((_info.format & UNWIND_ARM64_MODE_MASK) == UNWIND_ARM64_MODE_DWARF) {
1046      if (offset)
1047        *offset = (_info.format & UNWIND_ARM64_DWARF_SECTION_OFFSET);
1048      return true;
1049    }
1050    return false;
1051  }
1052#endif
1053
1054#if defined(_LIBUNWIND_TARGET_MIPS_O32)
1055  bool compactSaysUseDwarf(Registers_mips_o32 &, uint32_t *) const {
1056    return true;
1057  }
1058#endif
1059
1060#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI)
1061  bool compactSaysUseDwarf(Registers_mips_newabi &, uint32_t *) const {
1062    return true;
1063  }
1064#endif
1065
1066#if defined(_LIBUNWIND_TARGET_SPARC)
1067  bool compactSaysUseDwarf(Registers_sparc &, uint32_t *) const { return true; }
1068#endif
1069
1070#if defined (_LIBUNWIND_TARGET_RISCV)
1071  bool compactSaysUseDwarf(Registers_riscv &, uint32_t *) const {
1072    return true;
1073  }
1074#endif
1075
1076#endif // defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
1077
1078#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
1079  compact_unwind_encoding_t dwarfEncoding() const {
1080    R dummy;
1081    return dwarfEncoding(dummy);
1082  }
1083
1084#if defined(_LIBUNWIND_TARGET_X86_64)
1085  compact_unwind_encoding_t dwarfEncoding(Registers_x86_64 &) const {
1086    return UNWIND_X86_64_MODE_DWARF;
1087  }
1088#endif
1089
1090#if defined(_LIBUNWIND_TARGET_I386)
1091  compact_unwind_encoding_t dwarfEncoding(Registers_x86 &) const {
1092    return UNWIND_X86_MODE_DWARF;
1093  }
1094#endif
1095
1096#if defined(_LIBUNWIND_TARGET_PPC)
1097  compact_unwind_encoding_t dwarfEncoding(Registers_ppc &) const {
1098    return 0;
1099  }
1100#endif
1101
1102#if defined(_LIBUNWIND_TARGET_PPC64)
1103  compact_unwind_encoding_t dwarfEncoding(Registers_ppc64 &) const {
1104    return 0;
1105  }
1106#endif
1107
1108#if defined(_LIBUNWIND_TARGET_AARCH64)
1109  compact_unwind_encoding_t dwarfEncoding(Registers_arm64 &) const {
1110    return UNWIND_ARM64_MODE_DWARF;
1111  }
1112#endif
1113
1114#if defined(_LIBUNWIND_TARGET_ARM)
1115  compact_unwind_encoding_t dwarfEncoding(Registers_arm &) const {
1116    return 0;
1117  }
1118#endif
1119
1120#if defined (_LIBUNWIND_TARGET_OR1K)
1121  compact_unwind_encoding_t dwarfEncoding(Registers_or1k &) const {
1122    return 0;
1123  }
1124#endif
1125
1126#if defined (_LIBUNWIND_TARGET_MIPS_O32)
1127  compact_unwind_encoding_t dwarfEncoding(Registers_mips_o32 &) const {
1128    return 0;
1129  }
1130#endif
1131
1132#if defined (_LIBUNWIND_TARGET_MIPS_NEWABI)
1133  compact_unwind_encoding_t dwarfEncoding(Registers_mips_newabi &) const {
1134    return 0;
1135  }
1136#endif
1137
1138#if defined(_LIBUNWIND_TARGET_SPARC)
1139  compact_unwind_encoding_t dwarfEncoding(Registers_sparc &) const { return 0; }
1140#endif
1141
1142#if defined (_LIBUNWIND_TARGET_RISCV)
1143  compact_unwind_encoding_t dwarfEncoding(Registers_riscv &) const {
1144    return 0;
1145  }
1146#endif
1147
1148#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
1149
1150#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
1151  // For runtime environments using SEH unwind data without Windows runtime
1152  // support.
1153  pint_t getLastPC() const { /* FIXME: Implement */ return 0; }
1154  void setLastPC(pint_t pc) { /* FIXME: Implement */ }
1155  RUNTIME_FUNCTION *lookUpSEHUnwindInfo(pint_t pc, pint_t *base) {
1156    /* FIXME: Implement */
1157    *base = 0;
1158    return nullptr;
1159  }
1160  bool getInfoFromSEH(pint_t pc);
1161  int stepWithSEHData() { /* FIXME: Implement */ return 0; }
1162#endif // defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
1163
1164
1165  A               &_addressSpace;
1166  R                _registers;
1167  unw_proc_info_t  _info;
1168  bool             _unwindInfoMissing;
1169  bool             _isSignalFrame;
1170};
1171
1172
1173template <typename A, typename R>
1174UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as)
1175    : _addressSpace(as), _registers(context), _unwindInfoMissing(false),
1176      _isSignalFrame(false) {
1177  static_assert((check_fit<UnwindCursor<A, R>, unw_cursor_t>::does_fit),
1178                "UnwindCursor<> does not fit in unw_cursor_t");
1179  memset(&_info, 0, sizeof(_info));
1180}
1181
1182template <typename A, typename R>
1183UnwindCursor<A, R>::UnwindCursor(A &as, void *)
1184    : _addressSpace(as), _unwindInfoMissing(false), _isSignalFrame(false) {
1185  memset(&_info, 0, sizeof(_info));
1186  // FIXME
1187  // fill in _registers from thread arg
1188}
1189
1190
1191template <typename A, typename R>
1192bool UnwindCursor<A, R>::validReg(int regNum) {
1193  return _registers.validRegister(regNum);
1194}
1195
1196template <typename A, typename R>
1197unw_word_t UnwindCursor<A, R>::getReg(int regNum) {
1198  return _registers.getRegister(regNum);
1199}
1200
1201template <typename A, typename R>
1202void UnwindCursor<A, R>::setReg(int regNum, unw_word_t value) {
1203  _registers.setRegister(regNum, (typename A::pint_t)value);
1204}
1205
1206template <typename A, typename R>
1207bool UnwindCursor<A, R>::validFloatReg(int regNum) {
1208  return _registers.validFloatRegister(regNum);
1209}
1210
1211template <typename A, typename R>
1212unw_fpreg_t UnwindCursor<A, R>::getFloatReg(int regNum) {
1213  return _registers.getFloatRegister(regNum);
1214}
1215
1216template <typename A, typename R>
1217void UnwindCursor<A, R>::setFloatReg(int regNum, unw_fpreg_t value) {
1218  _registers.setFloatRegister(regNum, value);
1219}
1220
1221template <typename A, typename R> void UnwindCursor<A, R>::jumpto() {
1222  _registers.jumpto();
1223}
1224
1225#ifdef __arm__
1226template <typename A, typename R> void UnwindCursor<A, R>::saveVFPAsX() {
1227  _registers.saveVFPAsX();
1228}
1229#endif
1230
1231template <typename A, typename R>
1232const char *UnwindCursor<A, R>::getRegisterName(int regNum) {
1233  return _registers.getRegisterName(regNum);
1234}
1235
1236template <typename A, typename R> bool UnwindCursor<A, R>::isSignalFrame() {
1237  return _isSignalFrame;
1238}
1239
1240#endif // defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
1241
1242#if defined(_LIBUNWIND_ARM_EHABI)
1243template<typename A>
1244struct EHABISectionIterator {
1245  typedef EHABISectionIterator _Self;
1246
1247  typedef typename A::pint_t value_type;
1248  typedef typename A::pint_t* pointer;
1249  typedef typename A::pint_t& reference;
1250  typedef size_t size_type;
1251  typedef size_t difference_type;
1252
1253  static _Self begin(A& addressSpace, const UnwindInfoSections& sects) {
1254    return _Self(addressSpace, sects, 0);
1255  }
1256  static _Self end(A& addressSpace, const UnwindInfoSections& sects) {
1257    return _Self(addressSpace, sects,
1258                 sects.arm_section_length / sizeof(EHABIIndexEntry));
1259  }
1260
1261  EHABISectionIterator(A& addressSpace, const UnwindInfoSections& sects, size_t i)
1262      : _i(i), _addressSpace(&addressSpace), _sects(&sects) {}
1263
1264  _Self& operator++() { ++_i; return *this; }
1265  _Self& operator+=(size_t a) { _i += a; return *this; }
1266  _Self& operator--() { assert(_i > 0); --_i; return *this; }
1267  _Self& operator-=(size_t a) { assert(_i >= a); _i -= a; return *this; }
1268
1269  _Self operator+(size_t a) { _Self out = *this; out._i += a; return out; }
1270  _Self operator-(size_t a) { assert(_i >= a); _Self out = *this; out._i -= a; return out; }
1271
1272  size_t operator-(const _Self& other) { return _i - other._i; }
1273
1274  bool operator==(const _Self& other) const {
1275    assert(_addressSpace == other._addressSpace);
1276    assert(_sects == other._sects);
1277    return _i == other._i;
1278  }
1279
1280  typename A::pint_t operator*() const { return functionAddress(); }
1281
1282  typename A::pint_t functionAddress() const {
1283    typename A::pint_t indexAddr = _sects->arm_section + arrayoffsetof(
1284        EHABIIndexEntry, _i, functionOffset);
1285    return indexAddr + signExtendPrel31(_addressSpace->get32(indexAddr));
1286  }
1287
1288  typename A::pint_t dataAddress() {
1289    typename A::pint_t indexAddr = _sects->arm_section + arrayoffsetof(
1290        EHABIIndexEntry, _i, data);
1291    return indexAddr;
1292  }
1293
1294 private:
1295  size_t _i;
1296  A* _addressSpace;
1297  const UnwindInfoSections* _sects;
1298};
1299
1300namespace {
1301
1302template <typename A>
1303EHABISectionIterator<A> EHABISectionUpperBound(
1304    EHABISectionIterator<A> first,
1305    EHABISectionIterator<A> last,
1306    typename A::pint_t value) {
1307  size_t len = last - first;
1308  while (len > 0) {
1309    size_t l2 = len / 2;
1310    EHABISectionIterator<A> m = first + l2;
1311    if (value < *m) {
1312        len = l2;
1313    } else {
1314        first = ++m;
1315        len -= l2 + 1;
1316    }
1317  }
1318  return first;
1319}
1320
1321}
1322
1323template <typename A, typename R>
1324bool UnwindCursor<A, R>::getInfoFromEHABISection(
1325    pint_t pc,
1326    const UnwindInfoSections &sects) {
1327  EHABISectionIterator<A> begin =
1328      EHABISectionIterator<A>::begin(_addressSpace, sects);
1329  EHABISectionIterator<A> end =
1330      EHABISectionIterator<A>::end(_addressSpace, sects);
1331  if (begin == end)
1332    return false;
1333
1334  EHABISectionIterator<A> itNextPC = EHABISectionUpperBound(begin, end, pc);
1335  if (itNextPC == begin)
1336    return false;
1337  EHABISectionIterator<A> itThisPC = itNextPC - 1;
1338
1339  pint_t thisPC = itThisPC.functionAddress();
1340  // If an exception is thrown from a function, corresponding to the last entry
1341  // in the table, we don't really know the function extent and have to choose a
1342  // value for nextPC. Choosing max() will allow the range check during trace to
1343  // succeed.
1344  pint_t nextPC = (itNextPC == end) ? UINTPTR_MAX : itNextPC.functionAddress();
1345  pint_t indexDataAddr = itThisPC.dataAddress();
1346
1347  if (indexDataAddr == 0)
1348    return false;
1349
1350  uint32_t indexData = _addressSpace.get32(indexDataAddr);
1351  if (indexData == UNW_EXIDX_CANTUNWIND)
1352    return false;
1353
1354  // If the high bit is set, the exception handling table entry is inline inside
1355  // the index table entry on the second word (aka |indexDataAddr|). Otherwise,
1356  // the table points at an offset in the exception handling table (section 5
1357  // EHABI).
1358  pint_t exceptionTableAddr;
1359  uint32_t exceptionTableData;
1360  bool isSingleWordEHT;
1361  if (indexData & 0x80000000) {
1362    exceptionTableAddr = indexDataAddr;
1363    // TODO(ajwong): Should this data be 0?
1364    exceptionTableData = indexData;
1365    isSingleWordEHT = true;
1366  } else {
1367    exceptionTableAddr = indexDataAddr + signExtendPrel31(indexData);
1368    exceptionTableData = _addressSpace.get32(exceptionTableAddr);
1369    isSingleWordEHT = false;
1370  }
1371
1372  // Now we know the 3 things:
1373  //   exceptionTableAddr -- exception handler table entry.
1374  //   exceptionTableData -- the data inside the first word of the eht entry.
1375  //   isSingleWordEHT -- whether the entry is in the index.
1376  unw_word_t personalityRoutine = 0xbadf00d;
1377  bool scope32 = false;
1378  uintptr_t lsda;
1379
1380  // If the high bit in the exception handling table entry is set, the entry is
1381  // in compact form (section 6.3 EHABI).
1382  if (exceptionTableData & 0x80000000) {
1383    // Grab the index of the personality routine from the compact form.
1384    uint32_t choice = (exceptionTableData & 0x0f000000) >> 24;
1385    uint32_t extraWords = 0;
1386    switch (choice) {
1387      case 0:
1388        personalityRoutine = (unw_word_t) &__aeabi_unwind_cpp_pr0;
1389        extraWords = 0;
1390        scope32 = false;
1391        lsda = isSingleWordEHT ? 0 : (exceptionTableAddr + 4);
1392        break;
1393      case 1:
1394        personalityRoutine = (unw_word_t) &__aeabi_unwind_cpp_pr1;
1395        extraWords = (exceptionTableData & 0x00ff0000) >> 16;
1396        scope32 = false;
1397        lsda = exceptionTableAddr + (extraWords + 1) * 4;
1398        break;
1399      case 2:
1400        personalityRoutine = (unw_word_t) &__aeabi_unwind_cpp_pr2;
1401        extraWords = (exceptionTableData & 0x00ff0000) >> 16;
1402        scope32 = true;
1403        lsda = exceptionTableAddr + (extraWords + 1) * 4;
1404        break;
1405      default:
1406        _LIBUNWIND_ABORT("unknown personality routine");
1407        return false;
1408    }
1409
1410    if (isSingleWordEHT) {
1411      if (extraWords != 0) {
1412        _LIBUNWIND_ABORT("index inlined table detected but pr function "
1413                         "requires extra words");
1414        return false;
1415      }
1416    }
1417  } else {
1418    pint_t personalityAddr =
1419        exceptionTableAddr + signExtendPrel31(exceptionTableData);
1420    personalityRoutine = personalityAddr;
1421
1422    // ARM EHABI # 6.2, # 9.2
1423    //
1424    //  +---- ehtp
1425    //  v
1426    // +--------------------------------------+
1427    // | +--------+--------+--------+-------+ |
1428    // | |0| prel31 to personalityRoutine   | |
1429    // | +--------+--------+--------+-------+ |
1430    // | |      N |      unwind opcodes     | |  <-- UnwindData
1431    // | +--------+--------+--------+-------+ |
1432    // | | Word 2        unwind opcodes     | |
1433    // | +--------+--------+--------+-------+ |
1434    // | ...                                  |
1435    // | +--------+--------+--------+-------+ |
1436    // | | Word N        unwind opcodes     | |
1437    // | +--------+--------+--------+-------+ |
1438    // | | LSDA                             | |  <-- lsda
1439    // | | ...                              | |
1440    // | +--------+--------+--------+-------+ |
1441    // +--------------------------------------+
1442
1443    uint32_t *UnwindData = reinterpret_cast<uint32_t*>(exceptionTableAddr) + 1;
1444    uint32_t FirstDataWord = *UnwindData;
1445    size_t N = ((FirstDataWord >> 24) & 0xff);
1446    size_t NDataWords = N + 1;
1447    lsda = reinterpret_cast<uintptr_t>(UnwindData + NDataWords);
1448  }
1449
1450  _info.start_ip = thisPC;
1451  _info.end_ip = nextPC;
1452  _info.handler = personalityRoutine;
1453  _info.unwind_info = exceptionTableAddr;
1454  _info.lsda = lsda;
1455  // flags is pr_cache.additional. See EHABI #7.2 for definition of bit 0.
1456  _info.flags = (isSingleWordEHT ? 1 : 0) | (scope32 ? 0x2 : 0);  // Use enum?
1457
1458  return true;
1459}
1460#endif
1461
1462#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
1463template <typename A, typename R>
1464bool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc,
1465                                                const UnwindInfoSections &sects,
1466                                                uint32_t fdeSectionOffsetHint) {
1467  typename CFI_Parser<A>::FDE_Info fdeInfo;
1468  typename CFI_Parser<A>::CIE_Info cieInfo;
1469  bool foundFDE = false;
1470  bool foundInCache = false;
1471  // If compact encoding table gave offset into dwarf section, go directly there
1472  if (fdeSectionOffsetHint != 0) {
1473    foundFDE = CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section,
1474                                    (uint32_t)sects.dwarf_section_length,
1475                                    sects.dwarf_section + fdeSectionOffsetHint,
1476                                    &fdeInfo, &cieInfo);
1477  }
1478#if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX)
1479  if (!foundFDE && (sects.dwarf_index_section != 0)) {
1480    foundFDE = EHHeaderParser<A>::findFDE(
1481        _addressSpace, pc, sects.dwarf_index_section,
1482        (uint32_t)sects.dwarf_index_section_length, &fdeInfo, &cieInfo);
1483  }
1484#endif
1485  if (!foundFDE) {
1486    // otherwise, search cache of previously found FDEs.
1487    pint_t cachedFDE = DwarfFDECache<A>::findFDE(sects.dso_base, pc);
1488    if (cachedFDE != 0) {
1489      foundFDE =
1490          CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section,
1491                                 (uint32_t)sects.dwarf_section_length,
1492                                 cachedFDE, &fdeInfo, &cieInfo);
1493      foundInCache = foundFDE;
1494    }
1495  }
1496  if (!foundFDE) {
1497    // Still not found, do full scan of __eh_frame section.
1498    foundFDE = CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section,
1499                                      (uint32_t)sects.dwarf_section_length, 0,
1500                                      &fdeInfo, &cieInfo);
1501  }
1502  if (foundFDE) {
1503    typename CFI_Parser<A>::PrologInfo prolog;
1504    if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, cieInfo, pc,
1505                                            R::getArch(), &prolog)) {
1506      // Save off parsed FDE info
1507      _info.start_ip          = fdeInfo.pcStart;
1508      _info.end_ip            = fdeInfo.pcEnd;
1509      _info.lsda              = fdeInfo.lsda;
1510      _info.handler           = cieInfo.personality;
1511      _info.gp                = prolog.spExtraArgSize;
1512      _info.flags             = 0;
1513      _info.format            = dwarfEncoding();
1514      _info.unwind_info       = fdeInfo.fdeStart;
1515      _info.unwind_info_size  = (uint32_t)fdeInfo.fdeLength;
1516      _info.extra             = (unw_word_t) sects.dso_base;
1517
1518      // Add to cache (to make next lookup faster) if we had no hint
1519      // and there was no index.
1520      if (!foundInCache && (fdeSectionOffsetHint == 0)) {
1521  #if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX)
1522        if (sects.dwarf_index_section == 0)
1523  #endif
1524        DwarfFDECache<A>::add(sects.dso_base, fdeInfo.pcStart, fdeInfo.pcEnd,
1525                              fdeInfo.fdeStart);
1526      }
1527      return true;
1528    }
1529  }
1530  //_LIBUNWIND_DEBUG_LOG("can't find/use FDE for pc=0x%llX", (uint64_t)pc);
1531  return false;
1532}
1533#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
1534
1535
1536#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
1537template <typename A, typename R>
1538bool UnwindCursor<A, R>::getInfoFromCompactEncodingSection(pint_t pc,
1539                                              const UnwindInfoSections &sects) {
1540  const bool log = false;
1541  if (log)
1542    fprintf(stderr, "getInfoFromCompactEncodingSection(pc=0x%llX, mh=0x%llX)\n",
1543            (uint64_t)pc, (uint64_t)sects.dso_base);
1544
1545  const UnwindSectionHeader<A> sectionHeader(_addressSpace,
1546                                                sects.compact_unwind_section);
1547  if (sectionHeader.version() != UNWIND_SECTION_VERSION)
1548    return false;
1549
1550  // do a binary search of top level index to find page with unwind info
1551  pint_t targetFunctionOffset = pc - sects.dso_base;
1552  const UnwindSectionIndexArray<A> topIndex(_addressSpace,
1553                                           sects.compact_unwind_section
1554                                         + sectionHeader.indexSectionOffset());
1555  uint32_t low = 0;
1556  uint32_t high = sectionHeader.indexCount();
1557  uint32_t last = high - 1;
1558  while (low < high) {
1559    uint32_t mid = (low + high) / 2;
1560    //if ( log ) fprintf(stderr, "\tmid=%d, low=%d, high=%d, *mid=0x%08X\n",
1561    //mid, low, high, topIndex.functionOffset(mid));
1562    if (topIndex.functionOffset(mid) <= targetFunctionOffset) {
1563      if ((mid == last) ||
1564          (topIndex.functionOffset(mid + 1) > targetFunctionOffset)) {
1565        low = mid;
1566        break;
1567      } else {
1568        low = mid + 1;
1569      }
1570    } else {
1571      high = mid;
1572    }
1573  }
1574  const uint32_t firstLevelFunctionOffset = topIndex.functionOffset(low);
1575  const uint32_t firstLevelNextPageFunctionOffset =
1576      topIndex.functionOffset(low + 1);
1577  const pint_t secondLevelAddr =
1578      sects.compact_unwind_section + topIndex.secondLevelPagesSectionOffset(low);
1579  const pint_t lsdaArrayStartAddr =
1580      sects.compact_unwind_section + topIndex.lsdaIndexArraySectionOffset(low);
1581  const pint_t lsdaArrayEndAddr =
1582      sects.compact_unwind_section + topIndex.lsdaIndexArraySectionOffset(low+1);
1583  if (log)
1584    fprintf(stderr, "\tfirst level search for result index=%d "
1585                    "to secondLevelAddr=0x%llX\n",
1586                    low, (uint64_t) secondLevelAddr);
1587  // do a binary search of second level page index
1588  uint32_t encoding = 0;
1589  pint_t funcStart = 0;
1590  pint_t funcEnd = 0;
1591  pint_t lsda = 0;
1592  pint_t personality = 0;
1593  uint32_t pageKind = _addressSpace.get32(secondLevelAddr);
1594  if (pageKind == UNWIND_SECOND_LEVEL_REGULAR) {
1595    // regular page
1596    UnwindSectionRegularPageHeader<A> pageHeader(_addressSpace,
1597                                                 secondLevelAddr);
1598    UnwindSectionRegularArray<A> pageIndex(
1599        _addressSpace, secondLevelAddr + pageHeader.entryPageOffset());
1600    // binary search looks for entry with e where index[e].offset <= pc <
1601    // index[e+1].offset
1602    if (log)
1603      fprintf(stderr, "\tbinary search for targetFunctionOffset=0x%08llX in "
1604                      "regular page starting at secondLevelAddr=0x%llX\n",
1605              (uint64_t) targetFunctionOffset, (uint64_t) secondLevelAddr);
1606    low = 0;
1607    high = pageHeader.entryCount();
1608    while (low < high) {
1609      uint32_t mid = (low + high) / 2;
1610      if (pageIndex.functionOffset(mid) <= targetFunctionOffset) {
1611        if (mid == (uint32_t)(pageHeader.entryCount() - 1)) {
1612          // at end of table
1613          low = mid;
1614          funcEnd = firstLevelNextPageFunctionOffset + sects.dso_base;
1615          break;
1616        } else if (pageIndex.functionOffset(mid + 1) > targetFunctionOffset) {
1617          // next is too big, so we found it
1618          low = mid;
1619          funcEnd = pageIndex.functionOffset(low + 1) + sects.dso_base;
1620          break;
1621        } else {
1622          low = mid + 1;
1623        }
1624      } else {
1625        high = mid;
1626      }
1627    }
1628    encoding = pageIndex.encoding(low);
1629    funcStart = pageIndex.functionOffset(low) + sects.dso_base;
1630    if (pc < funcStart) {
1631      if (log)
1632        fprintf(
1633            stderr,
1634            "\tpc not in table, pc=0x%llX, funcStart=0x%llX, funcEnd=0x%llX\n",
1635            (uint64_t) pc, (uint64_t) funcStart, (uint64_t) funcEnd);
1636      return false;
1637    }
1638    if (pc > funcEnd) {
1639      if (log)
1640        fprintf(
1641            stderr,
1642            "\tpc not in table, pc=0x%llX, funcStart=0x%llX, funcEnd=0x%llX\n",
1643            (uint64_t) pc, (uint64_t) funcStart, (uint64_t) funcEnd);
1644      return false;
1645    }
1646  } else if (pageKind == UNWIND_SECOND_LEVEL_COMPRESSED) {
1647    // compressed page
1648    UnwindSectionCompressedPageHeader<A> pageHeader(_addressSpace,
1649                                                    secondLevelAddr);
1650    UnwindSectionCompressedArray<A> pageIndex(
1651        _addressSpace, secondLevelAddr + pageHeader.entryPageOffset());
1652    const uint32_t targetFunctionPageOffset =
1653        (uint32_t)(targetFunctionOffset - firstLevelFunctionOffset);
1654    // binary search looks for entry with e where index[e].offset <= pc <
1655    // index[e+1].offset
1656    if (log)
1657      fprintf(stderr, "\tbinary search of compressed page starting at "
1658                      "secondLevelAddr=0x%llX\n",
1659              (uint64_t) secondLevelAddr);
1660    low = 0;
1661    last = pageHeader.entryCount() - 1;
1662    high = pageHeader.entryCount();
1663    while (low < high) {
1664      uint32_t mid = (low + high) / 2;
1665      if (pageIndex.functionOffset(mid) <= targetFunctionPageOffset) {
1666        if ((mid == last) ||
1667            (pageIndex.functionOffset(mid + 1) > targetFunctionPageOffset)) {
1668          low = mid;
1669          break;
1670        } else {
1671          low = mid + 1;
1672        }
1673      } else {
1674        high = mid;
1675      }
1676    }
1677    funcStart = pageIndex.functionOffset(low) + firstLevelFunctionOffset
1678                                                              + sects.dso_base;
1679    if (low < last)
1680      funcEnd =
1681          pageIndex.functionOffset(low + 1) + firstLevelFunctionOffset
1682                                                              + sects.dso_base;
1683    else
1684      funcEnd = firstLevelNextPageFunctionOffset + sects.dso_base;
1685    if (pc < funcStart) {
1686      _LIBUNWIND_DEBUG_LOG("malformed __unwind_info, pc=0x%llX not in second  "
1687                           "level compressed unwind table. funcStart=0x%llX",
1688                            (uint64_t) pc, (uint64_t) funcStart);
1689      return false;
1690    }
1691    if (pc > funcEnd) {
1692      _LIBUNWIND_DEBUG_LOG("malformed __unwind_info, pc=0x%llX not in second  "
1693                          "level compressed unwind table. funcEnd=0x%llX",
1694                           (uint64_t) pc, (uint64_t) funcEnd);
1695      return false;
1696    }
1697    uint16_t encodingIndex = pageIndex.encodingIndex(low);
1698    if (encodingIndex < sectionHeader.commonEncodingsArrayCount()) {
1699      // encoding is in common table in section header
1700      encoding = _addressSpace.get32(
1701          sects.compact_unwind_section +
1702          sectionHeader.commonEncodingsArraySectionOffset() +
1703          encodingIndex * sizeof(uint32_t));
1704    } else {
1705      // encoding is in page specific table
1706      uint16_t pageEncodingIndex =
1707          encodingIndex - (uint16_t)sectionHeader.commonEncodingsArrayCount();
1708      encoding = _addressSpace.get32(secondLevelAddr +
1709                                     pageHeader.encodingsPageOffset() +
1710                                     pageEncodingIndex * sizeof(uint32_t));
1711    }
1712  } else {
1713    _LIBUNWIND_DEBUG_LOG("malformed __unwind_info at 0x%0llX bad second "
1714                         "level page",
1715                          (uint64_t) sects.compact_unwind_section);
1716    return false;
1717  }
1718
1719  // look up LSDA, if encoding says function has one
1720  if (encoding & UNWIND_HAS_LSDA) {
1721    UnwindSectionLsdaArray<A> lsdaIndex(_addressSpace, lsdaArrayStartAddr);
1722    uint32_t funcStartOffset = (uint32_t)(funcStart - sects.dso_base);
1723    low = 0;
1724    high = (uint32_t)(lsdaArrayEndAddr - lsdaArrayStartAddr) /
1725                    sizeof(unwind_info_section_header_lsda_index_entry);
1726    // binary search looks for entry with exact match for functionOffset
1727    if (log)
1728      fprintf(stderr,
1729              "\tbinary search of lsda table for targetFunctionOffset=0x%08X\n",
1730              funcStartOffset);
1731    while (low < high) {
1732      uint32_t mid = (low + high) / 2;
1733      if (lsdaIndex.functionOffset(mid) == funcStartOffset) {
1734        lsda = lsdaIndex.lsdaOffset(mid) + sects.dso_base;
1735        break;
1736      } else if (lsdaIndex.functionOffset(mid) < funcStartOffset) {
1737        low = mid + 1;
1738      } else {
1739        high = mid;
1740      }
1741    }
1742    if (lsda == 0) {
1743      _LIBUNWIND_DEBUG_LOG("found encoding 0x%08X with HAS_LSDA bit set for "
1744                    "pc=0x%0llX, but lsda table has no entry",
1745                    encoding, (uint64_t) pc);
1746      return false;
1747    }
1748  }
1749
1750  // extact personality routine, if encoding says function has one
1751  uint32_t personalityIndex = (encoding & UNWIND_PERSONALITY_MASK) >>
1752                              (__builtin_ctz(UNWIND_PERSONALITY_MASK));
1753  if (personalityIndex != 0) {
1754    --personalityIndex; // change 1-based to zero-based index
1755    if (personalityIndex > sectionHeader.personalityArrayCount()) {
1756      _LIBUNWIND_DEBUG_LOG("found encoding 0x%08X with personality index %d,  "
1757                            "but personality table has only %d entries",
1758                            encoding, personalityIndex,
1759                            sectionHeader.personalityArrayCount());
1760      return false;
1761    }
1762    int32_t personalityDelta = (int32_t)_addressSpace.get32(
1763        sects.compact_unwind_section +
1764        sectionHeader.personalityArraySectionOffset() +
1765        personalityIndex * sizeof(uint32_t));
1766    pint_t personalityPointer = sects.dso_base + (pint_t)personalityDelta;
1767    personality = _addressSpace.getP(personalityPointer);
1768    if (log)
1769      fprintf(stderr, "getInfoFromCompactEncodingSection(pc=0x%llX), "
1770                      "personalityDelta=0x%08X, personality=0x%08llX\n",
1771              (uint64_t) pc, personalityDelta, (uint64_t) personality);
1772  }
1773
1774  if (log)
1775    fprintf(stderr, "getInfoFromCompactEncodingSection(pc=0x%llX), "
1776                    "encoding=0x%08X, lsda=0x%08llX for funcStart=0x%llX\n",
1777            (uint64_t) pc, encoding, (uint64_t) lsda, (uint64_t) funcStart);
1778  _info.start_ip = funcStart;
1779  _info.end_ip = funcEnd;
1780  _info.lsda = lsda;
1781  _info.handler = personality;
1782  _info.gp = 0;
1783  _info.flags = 0;
1784  _info.format = encoding;
1785  _info.unwind_info = 0;
1786  _info.unwind_info_size = 0;
1787  _info.extra = sects.dso_base;
1788  return true;
1789}
1790#endif // defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
1791
1792
1793#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
1794template <typename A, typename R>
1795bool UnwindCursor<A, R>::getInfoFromSEH(pint_t pc) {
1796  pint_t base;
1797  RUNTIME_FUNCTION *unwindEntry = lookUpSEHUnwindInfo(pc, &base);
1798  if (!unwindEntry) {
1799    _LIBUNWIND_DEBUG_LOG("\tpc not in table, pc=0x%llX", (uint64_t) pc);
1800    return false;
1801  }
1802  _info.gp = 0;
1803  _info.flags = 0;
1804  _info.format = 0;
1805  _info.unwind_info_size = sizeof(RUNTIME_FUNCTION);
1806  _info.unwind_info = reinterpret_cast<unw_word_t>(unwindEntry);
1807  _info.extra = base;
1808  _info.start_ip = base + unwindEntry->BeginAddress;
1809#ifdef _LIBUNWIND_TARGET_X86_64
1810  _info.end_ip = base + unwindEntry->EndAddress;
1811  // Only fill in the handler and LSDA if they're stale.
1812  if (pc != getLastPC()) {
1813    UNWIND_INFO *xdata = reinterpret_cast<UNWIND_INFO *>(base + unwindEntry->UnwindData);
1814    if (xdata->Flags & (UNW_FLAG_EHANDLER|UNW_FLAG_UHANDLER)) {
1815      // The personality is given in the UNWIND_INFO itself. The LSDA immediately
1816      // follows the UNWIND_INFO. (This follows how both Clang and MSVC emit
1817      // these structures.)
1818      // N.B. UNWIND_INFO structs are DWORD-aligned.
1819      uint32_t lastcode = (xdata->CountOfCodes + 1) & ~1;
1820      const uint32_t *handler = reinterpret_cast<uint32_t *>(&xdata->UnwindCodes[lastcode]);
1821      _info.lsda = reinterpret_cast<unw_word_t>(handler+1);
1822      if (*handler) {
1823        _info.handler = reinterpret_cast<unw_word_t>(__libunwind_seh_personality);
1824      } else
1825        _info.handler = 0;
1826    } else {
1827      _info.lsda = 0;
1828      _info.handler = 0;
1829    }
1830  }
1831#elif defined(_LIBUNWIND_TARGET_ARM)
1832  _info.end_ip = _info.start_ip + unwindEntry->FunctionLength;
1833  _info.lsda = 0; // FIXME
1834  _info.handler = 0; // FIXME
1835#endif
1836  setLastPC(pc);
1837  return true;
1838}
1839#endif
1840
1841
1842template <typename A, typename R>
1843void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {
1844  pint_t pc = (pint_t)this->getReg(UNW_REG_IP);
1845#if defined(_LIBUNWIND_ARM_EHABI)
1846  // Remove the thumb bit so the IP represents the actual instruction address.
1847  // This matches the behaviour of _Unwind_GetIP on arm.
1848  pc &= (pint_t)~0x1;
1849#endif
1850
1851  // If the last line of a function is a "throw" the compiler sometimes
1852  // emits no instructions after the call to __cxa_throw.  This means
1853  // the return address is actually the start of the next function.
1854  // To disambiguate this, back up the pc when we know it is a return
1855  // address.
1856  if (isReturnAddress)
1857    --pc;
1858
1859  // Ask address space object to find unwind sections for this pc.
1860  UnwindInfoSections sects;
1861  if (_addressSpace.findUnwindSections(pc, sects)) {
1862#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
1863    // If there is a compact unwind encoding table, look there first.
1864    if (sects.compact_unwind_section != 0) {
1865      if (this->getInfoFromCompactEncodingSection(pc, sects)) {
1866  #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
1867        // Found info in table, done unless encoding says to use dwarf.
1868        uint32_t dwarfOffset;
1869        if ((sects.dwarf_section != 0) && compactSaysUseDwarf(&dwarfOffset)) {
1870          if (this->getInfoFromDwarfSection(pc, sects, dwarfOffset)) {
1871            // found info in dwarf, done
1872            return;
1873          }
1874        }
1875  #endif
1876        // If unwind table has entry, but entry says there is no unwind info,
1877        // record that we have no unwind info.
1878        if (_info.format == 0)
1879          _unwindInfoMissing = true;
1880        return;
1881      }
1882    }
1883#endif // defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
1884
1885#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
1886    // If there is SEH unwind info, look there next.
1887    if (this->getInfoFromSEH(pc))
1888      return;
1889#endif
1890
1891#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
1892    // If there is dwarf unwind info, look there next.
1893    if (sects.dwarf_section != 0) {
1894      if (this->getInfoFromDwarfSection(pc, sects)) {
1895        // found info in dwarf, done
1896        return;
1897      }
1898    }
1899#endif
1900
1901#if defined(_LIBUNWIND_ARM_EHABI)
1902    // If there is ARM EHABI unwind info, look there next.
1903    if (sects.arm_section != 0 && this->getInfoFromEHABISection(pc, sects))
1904      return;
1905#endif
1906  }
1907
1908#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
1909  // There is no static unwind info for this pc. Look to see if an FDE was
1910  // dynamically registered for it.
1911  pint_t cachedFDE = DwarfFDECache<A>::findFDE(0, pc);
1912  if (cachedFDE != 0) {
1913    CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo;
1914    CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo;
1915    const char *msg = CFI_Parser<A>::decodeFDE(_addressSpace,
1916                                                cachedFDE, &fdeInfo, &cieInfo);
1917    if (msg == NULL) {
1918      typename CFI_Parser<A>::PrologInfo prolog;
1919      if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, cieInfo,
1920                                              pc, R::getArch(), &prolog)) {
1921        // save off parsed FDE info
1922        _info.start_ip         = fdeInfo.pcStart;
1923        _info.end_ip           = fdeInfo.pcEnd;
1924        _info.lsda             = fdeInfo.lsda;
1925        _info.handler          = cieInfo.personality;
1926        _info.gp               = prolog.spExtraArgSize;
1927                                  // Some frameless functions need SP
1928                                  // altered when resuming in function.
1929        _info.flags            = 0;
1930        _info.format           = dwarfEncoding();
1931        _info.unwind_info      = fdeInfo.fdeStart;
1932        _info.unwind_info_size = (uint32_t)fdeInfo.fdeLength;
1933        _info.extra            = 0;
1934        return;
1935      }
1936    }
1937  }
1938
1939  // Lastly, ask AddressSpace object about platform specific ways to locate
1940  // other FDEs.
1941  pint_t fde;
1942  if (_addressSpace.findOtherFDE(pc, fde)) {
1943    CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo;
1944    CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo;
1945    if (!CFI_Parser<A>::decodeFDE(_addressSpace, fde, &fdeInfo, &cieInfo)) {
1946      // Double check this FDE is for a function that includes the pc.
1947      if ((fdeInfo.pcStart <= pc) && (pc < fdeInfo.pcEnd)) {
1948        typename CFI_Parser<A>::PrologInfo prolog;
1949        if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, cieInfo,
1950                                                pc, R::getArch(), &prolog)) {
1951          // save off parsed FDE info
1952          _info.start_ip         = fdeInfo.pcStart;
1953          _info.end_ip           = fdeInfo.pcEnd;
1954          _info.lsda             = fdeInfo.lsda;
1955          _info.handler          = cieInfo.personality;
1956          _info.gp               = prolog.spExtraArgSize;
1957          _info.flags            = 0;
1958          _info.format           = dwarfEncoding();
1959          _info.unwind_info      = fdeInfo.fdeStart;
1960          _info.unwind_info_size = (uint32_t)fdeInfo.fdeLength;
1961          _info.extra            = 0;
1962          return;
1963        }
1964      }
1965    }
1966  }
1967#endif // #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
1968
1969  // no unwind info, flag that we can't reliably unwind
1970  _unwindInfoMissing = true;
1971}
1972
1973template <typename A, typename R>
1974int UnwindCursor<A, R>::step() {
1975  // Bottom of stack is defined is when unwind info cannot be found.
1976  if (_unwindInfoMissing)
1977    return UNW_STEP_END;
1978
1979  // Use unwinding info to modify register set as if function returned.
1980  int result;
1981#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
1982  result = this->stepWithCompactEncoding();
1983#elif defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
1984  result = this->stepWithSEHData();
1985#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
1986  result = this->stepWithDwarfFDE();
1987#elif defined(_LIBUNWIND_ARM_EHABI)
1988  result = this->stepWithEHABI();
1989#else
1990  #error Need _LIBUNWIND_SUPPORT_COMPACT_UNWIND or \
1991              _LIBUNWIND_SUPPORT_SEH_UNWIND or \
1992              _LIBUNWIND_SUPPORT_DWARF_UNWIND or \
1993              _LIBUNWIND_ARM_EHABI
1994#endif
1995
1996  // update info based on new PC
1997  if (result == UNW_STEP_SUCCESS) {
1998    this->setInfoBasedOnIPRegister(true);
1999    if (_unwindInfoMissing)
2000      return UNW_STEP_END;
2001  }
2002
2003  return result;
2004}
2005
2006template <typename A, typename R>
2007void UnwindCursor<A, R>::getInfo(unw_proc_info_t *info) {
2008  if (_unwindInfoMissing)
2009    memset(info, 0, sizeof(*info));
2010  else
2011    *info = _info;
2012}
2013
2014template <typename A, typename R>
2015bool UnwindCursor<A, R>::getFunctionName(char *buf, size_t bufLen,
2016                                                           unw_word_t *offset) {
2017  return _addressSpace.findFunctionName((pint_t)this->getReg(UNW_REG_IP),
2018                                         buf, bufLen, offset);
2019}
2020
2021} // namespace libunwind
2022
2023#endif // __UNWINDCURSOR_HPP__
2024