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