xref: /freebsd/contrib/llvm-project/libunwind/src/UnwindCursor.hpp (revision 725a9f47324d42037db93c27ceb40d4956872f3e)
1 //===----------------------------------------------------------------------===//
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 "cet_unwind.h"
15 #include <stdint.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <unwind.h>
19 
20 #ifdef _WIN32
21   #include <windows.h>
22   #include <ntverp.h>
23 #endif
24 #ifdef __APPLE__
25   #include <mach-o/dyld.h>
26 #endif
27 #ifdef _AIX
28 #include <dlfcn.h>
29 #include <sys/debug.h>
30 #include <sys/pseg.h>
31 #endif
32 
33 #if defined(_LIBUNWIND_TARGET_LINUX) &&                                        \
34     (defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_RISCV) || \
35      defined(_LIBUNWIND_TARGET_S390X))
36 #include <errno.h>
37 #include <signal.h>
38 #include <sys/syscall.h>
39 #include <sys/uio.h>
40 #include <unistd.h>
41 #define _LIBUNWIND_CHECK_LINUX_SIGRETURN 1
42 #endif
43 
44 #include "AddressSpace.hpp"
45 #include "CompactUnwinder.hpp"
46 #include "config.h"
47 #include "DwarfInstructions.hpp"
48 #include "EHHeaderParser.hpp"
49 #include "libunwind.h"
50 #include "libunwind_ext.h"
51 #include "Registers.hpp"
52 #include "RWMutex.hpp"
53 #include "Unwind-EHABI.h"
54 
55 #if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
56 // Provide a definition for the DISPATCHER_CONTEXT struct for old (Win7 and
57 // earlier) SDKs.
58 // MinGW-w64 has always provided this struct.
59   #if defined(_WIN32) && defined(_LIBUNWIND_TARGET_X86_64) && \
60       !defined(__MINGW32__) && VER_PRODUCTBUILD < 8000
61 struct _DISPATCHER_CONTEXT {
62   ULONG64 ControlPc;
63   ULONG64 ImageBase;
64   PRUNTIME_FUNCTION FunctionEntry;
65   ULONG64 EstablisherFrame;
66   ULONG64 TargetIp;
67   PCONTEXT ContextRecord;
68   PEXCEPTION_ROUTINE LanguageHandler;
69   PVOID HandlerData;
70   PUNWIND_HISTORY_TABLE HistoryTable;
71   ULONG ScopeIndex;
72   ULONG Fill0;
73 };
74   #endif
75 
76 struct UNWIND_INFO {
77   uint8_t Version : 3;
78   uint8_t Flags : 5;
79   uint8_t SizeOfProlog;
80   uint8_t CountOfCodes;
81   uint8_t FrameRegister : 4;
82   uint8_t FrameOffset : 4;
83   uint16_t UnwindCodes[2];
84 };
85 
86 extern "C" _Unwind_Reason_Code __libunwind_seh_personality(
87     int, _Unwind_Action, uint64_t, _Unwind_Exception *,
88     struct _Unwind_Context *);
89 
90 #endif
91 
92 namespace libunwind {
93 
94 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
95 /// Cache of recently found FDEs.
96 template <typename A>
97 class _LIBUNWIND_HIDDEN DwarfFDECache {
98   typedef typename A::pint_t pint_t;
99 public:
100   static constexpr pint_t kSearchAll = static_cast<pint_t>(-1);
101   static pint_t findFDE(pint_t mh, pint_t pc);
102   static void add(pint_t mh, pint_t ip_start, pint_t ip_end, pint_t fde);
103   static void removeAllIn(pint_t mh);
104   static void iterateCacheEntries(void (*func)(unw_word_t ip_start,
105                                                unw_word_t ip_end,
106                                                unw_word_t fde, unw_word_t mh));
107 
108 private:
109 
110   struct entry {
111     pint_t mh;
112     pint_t ip_start;
113     pint_t ip_end;
114     pint_t fde;
115   };
116 
117   // These fields are all static to avoid needing an initializer.
118   // There is only one instance of this class per process.
119   static RWMutex _lock;
120 #ifdef __APPLE__
121   static void dyldUnloadHook(const struct mach_header *mh, intptr_t slide);
122   static bool _registeredForDyldUnloads;
123 #endif
124   static entry *_buffer;
125   static entry *_bufferUsed;
126   static entry *_bufferEnd;
127   static entry _initialBuffer[64];
128 };
129 
130 template <typename A>
131 typename DwarfFDECache<A>::entry *
132 DwarfFDECache<A>::_buffer = _initialBuffer;
133 
134 template <typename A>
135 typename DwarfFDECache<A>::entry *
136 DwarfFDECache<A>::_bufferUsed = _initialBuffer;
137 
138 template <typename A>
139 typename DwarfFDECache<A>::entry *
140 DwarfFDECache<A>::_bufferEnd = &_initialBuffer[64];
141 
142 template <typename A>
143 typename DwarfFDECache<A>::entry DwarfFDECache<A>::_initialBuffer[64];
144 
145 template <typename A>
146 RWMutex DwarfFDECache<A>::_lock;
147 
148 #ifdef __APPLE__
149 template <typename A>
150 bool DwarfFDECache<A>::_registeredForDyldUnloads = false;
151 #endif
152 
153 template <typename A>
154 typename A::pint_t DwarfFDECache<A>::findFDE(pint_t mh, pint_t pc) {
155   pint_t result = 0;
156   _LIBUNWIND_LOG_IF_FALSE(_lock.lock_shared());
157   for (entry *p = _buffer; p < _bufferUsed; ++p) {
158     if ((mh == p->mh) || (mh == kSearchAll)) {
159       if ((p->ip_start <= pc) && (pc < p->ip_end)) {
160         result = p->fde;
161         break;
162       }
163     }
164   }
165   _LIBUNWIND_LOG_IF_FALSE(_lock.unlock_shared());
166   return result;
167 }
168 
169 template <typename A>
170 void DwarfFDECache<A>::add(pint_t mh, pint_t ip_start, pint_t ip_end,
171                            pint_t fde) {
172 #if !defined(_LIBUNWIND_NO_HEAP)
173   _LIBUNWIND_LOG_IF_FALSE(_lock.lock());
174   if (_bufferUsed >= _bufferEnd) {
175     size_t oldSize = (size_t)(_bufferEnd - _buffer);
176     size_t newSize = oldSize * 4;
177     // Can't use operator new (we are below it).
178     entry *newBuffer = (entry *)malloc(newSize * sizeof(entry));
179     memcpy(newBuffer, _buffer, oldSize * sizeof(entry));
180     if (_buffer != _initialBuffer)
181       free(_buffer);
182     _buffer = newBuffer;
183     _bufferUsed = &newBuffer[oldSize];
184     _bufferEnd = &newBuffer[newSize];
185   }
186   _bufferUsed->mh = mh;
187   _bufferUsed->ip_start = ip_start;
188   _bufferUsed->ip_end = ip_end;
189   _bufferUsed->fde = fde;
190   ++_bufferUsed;
191 #ifdef __APPLE__
192   if (!_registeredForDyldUnloads) {
193     _dyld_register_func_for_remove_image(&dyldUnloadHook);
194     _registeredForDyldUnloads = true;
195   }
196 #endif
197   _LIBUNWIND_LOG_IF_FALSE(_lock.unlock());
198 #endif
199 }
200 
201 template <typename A>
202 void DwarfFDECache<A>::removeAllIn(pint_t mh) {
203   _LIBUNWIND_LOG_IF_FALSE(_lock.lock());
204   entry *d = _buffer;
205   for (const entry *s = _buffer; s < _bufferUsed; ++s) {
206     if (s->mh != mh) {
207       if (d != s)
208         *d = *s;
209       ++d;
210     }
211   }
212   _bufferUsed = d;
213   _LIBUNWIND_LOG_IF_FALSE(_lock.unlock());
214 }
215 
216 #ifdef __APPLE__
217 template <typename A>
218 void DwarfFDECache<A>::dyldUnloadHook(const struct mach_header *mh, intptr_t ) {
219   removeAllIn((pint_t) mh);
220 }
221 #endif
222 
223 template <typename A>
224 void DwarfFDECache<A>::iterateCacheEntries(void (*func)(
225     unw_word_t ip_start, unw_word_t ip_end, unw_word_t fde, unw_word_t mh)) {
226   _LIBUNWIND_LOG_IF_FALSE(_lock.lock());
227   for (entry *p = _buffer; p < _bufferUsed; ++p) {
228     (*func)(p->ip_start, p->ip_end, p->fde, p->mh);
229   }
230   _LIBUNWIND_LOG_IF_FALSE(_lock.unlock());
231 }
232 #endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
233 
234 
235 #define arrayoffsetof(type, index, field) ((size_t)(&((type *)0)[index].field))
236 
237 #if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
238 template <typename A> class UnwindSectionHeader {
239 public:
240   UnwindSectionHeader(A &addressSpace, typename A::pint_t addr)
241       : _addressSpace(addressSpace), _addr(addr) {}
242 
243   uint32_t version() const {
244     return _addressSpace.get32(_addr +
245                                offsetof(unwind_info_section_header, version));
246   }
247   uint32_t commonEncodingsArraySectionOffset() const {
248     return _addressSpace.get32(_addr +
249                                offsetof(unwind_info_section_header,
250                                         commonEncodingsArraySectionOffset));
251   }
252   uint32_t commonEncodingsArrayCount() const {
253     return _addressSpace.get32(_addr + offsetof(unwind_info_section_header,
254                                                 commonEncodingsArrayCount));
255   }
256   uint32_t personalityArraySectionOffset() const {
257     return _addressSpace.get32(_addr + offsetof(unwind_info_section_header,
258                                                 personalityArraySectionOffset));
259   }
260   uint32_t personalityArrayCount() const {
261     return _addressSpace.get32(
262         _addr + offsetof(unwind_info_section_header, personalityArrayCount));
263   }
264   uint32_t indexSectionOffset() const {
265     return _addressSpace.get32(
266         _addr + offsetof(unwind_info_section_header, indexSectionOffset));
267   }
268   uint32_t indexCount() const {
269     return _addressSpace.get32(
270         _addr + offsetof(unwind_info_section_header, indexCount));
271   }
272 
273 private:
274   A                     &_addressSpace;
275   typename A::pint_t     _addr;
276 };
277 
278 template <typename A> class UnwindSectionIndexArray {
279 public:
280   UnwindSectionIndexArray(A &addressSpace, typename A::pint_t addr)
281       : _addressSpace(addressSpace), _addr(addr) {}
282 
283   uint32_t functionOffset(uint32_t index) const {
284     return _addressSpace.get32(
285         _addr + arrayoffsetof(unwind_info_section_header_index_entry, index,
286                               functionOffset));
287   }
288   uint32_t secondLevelPagesSectionOffset(uint32_t index) const {
289     return _addressSpace.get32(
290         _addr + arrayoffsetof(unwind_info_section_header_index_entry, index,
291                               secondLevelPagesSectionOffset));
292   }
293   uint32_t lsdaIndexArraySectionOffset(uint32_t index) const {
294     return _addressSpace.get32(
295         _addr + arrayoffsetof(unwind_info_section_header_index_entry, index,
296                               lsdaIndexArraySectionOffset));
297   }
298 
299 private:
300   A                   &_addressSpace;
301   typename A::pint_t   _addr;
302 };
303 
304 template <typename A> class UnwindSectionRegularPageHeader {
305 public:
306   UnwindSectionRegularPageHeader(A &addressSpace, typename A::pint_t addr)
307       : _addressSpace(addressSpace), _addr(addr) {}
308 
309   uint32_t kind() const {
310     return _addressSpace.get32(
311         _addr + offsetof(unwind_info_regular_second_level_page_header, kind));
312   }
313   uint16_t entryPageOffset() const {
314     return _addressSpace.get16(
315         _addr + offsetof(unwind_info_regular_second_level_page_header,
316                          entryPageOffset));
317   }
318   uint16_t entryCount() const {
319     return _addressSpace.get16(
320         _addr +
321         offsetof(unwind_info_regular_second_level_page_header, entryCount));
322   }
323 
324 private:
325   A &_addressSpace;
326   typename A::pint_t _addr;
327 };
328 
329 template <typename A> class UnwindSectionRegularArray {
330 public:
331   UnwindSectionRegularArray(A &addressSpace, typename A::pint_t addr)
332       : _addressSpace(addressSpace), _addr(addr) {}
333 
334   uint32_t functionOffset(uint32_t index) const {
335     return _addressSpace.get32(
336         _addr + arrayoffsetof(unwind_info_regular_second_level_entry, index,
337                               functionOffset));
338   }
339   uint32_t encoding(uint32_t index) const {
340     return _addressSpace.get32(
341         _addr +
342         arrayoffsetof(unwind_info_regular_second_level_entry, index, encoding));
343   }
344 
345 private:
346   A &_addressSpace;
347   typename A::pint_t _addr;
348 };
349 
350 template <typename A> class UnwindSectionCompressedPageHeader {
351 public:
352   UnwindSectionCompressedPageHeader(A &addressSpace, typename A::pint_t addr)
353       : _addressSpace(addressSpace), _addr(addr) {}
354 
355   uint32_t kind() const {
356     return _addressSpace.get32(
357         _addr +
358         offsetof(unwind_info_compressed_second_level_page_header, kind));
359   }
360   uint16_t entryPageOffset() const {
361     return _addressSpace.get16(
362         _addr + offsetof(unwind_info_compressed_second_level_page_header,
363                          entryPageOffset));
364   }
365   uint16_t entryCount() const {
366     return _addressSpace.get16(
367         _addr +
368         offsetof(unwind_info_compressed_second_level_page_header, entryCount));
369   }
370   uint16_t encodingsPageOffset() const {
371     return _addressSpace.get16(
372         _addr + offsetof(unwind_info_compressed_second_level_page_header,
373                          encodingsPageOffset));
374   }
375   uint16_t encodingsCount() const {
376     return _addressSpace.get16(
377         _addr + offsetof(unwind_info_compressed_second_level_page_header,
378                          encodingsCount));
379   }
380 
381 private:
382   A &_addressSpace;
383   typename A::pint_t _addr;
384 };
385 
386 template <typename A> class UnwindSectionCompressedArray {
387 public:
388   UnwindSectionCompressedArray(A &addressSpace, typename A::pint_t addr)
389       : _addressSpace(addressSpace), _addr(addr) {}
390 
391   uint32_t functionOffset(uint32_t index) const {
392     return UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(
393         _addressSpace.get32(_addr + index * sizeof(uint32_t)));
394   }
395   uint16_t encodingIndex(uint32_t index) const {
396     return UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX(
397         _addressSpace.get32(_addr + index * sizeof(uint32_t)));
398   }
399 
400 private:
401   A &_addressSpace;
402   typename A::pint_t _addr;
403 };
404 
405 template <typename A> class UnwindSectionLsdaArray {
406 public:
407   UnwindSectionLsdaArray(A &addressSpace, typename A::pint_t addr)
408       : _addressSpace(addressSpace), _addr(addr) {}
409 
410   uint32_t functionOffset(uint32_t index) const {
411     return _addressSpace.get32(
412         _addr + arrayoffsetof(unwind_info_section_header_lsda_index_entry,
413                               index, functionOffset));
414   }
415   uint32_t lsdaOffset(uint32_t index) const {
416     return _addressSpace.get32(
417         _addr + arrayoffsetof(unwind_info_section_header_lsda_index_entry,
418                               index, lsdaOffset));
419   }
420 
421 private:
422   A                   &_addressSpace;
423   typename A::pint_t   _addr;
424 };
425 #endif // defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
426 
427 class _LIBUNWIND_HIDDEN AbstractUnwindCursor {
428 public:
429   // NOTE: provide a class specific placement deallocation function (S5.3.4 p20)
430   // This avoids an unnecessary dependency to libc++abi.
431   void operator delete(void *, size_t) {}
432 
433   virtual ~AbstractUnwindCursor() {}
434   virtual bool validReg(int) { _LIBUNWIND_ABORT("validReg not implemented"); }
435   virtual unw_word_t getReg(int) { _LIBUNWIND_ABORT("getReg not implemented"); }
436   virtual void setReg(int, unw_word_t) {
437     _LIBUNWIND_ABORT("setReg not implemented");
438   }
439   virtual bool validFloatReg(int) {
440     _LIBUNWIND_ABORT("validFloatReg not implemented");
441   }
442   virtual unw_fpreg_t getFloatReg(int) {
443     _LIBUNWIND_ABORT("getFloatReg not implemented");
444   }
445   virtual void setFloatReg(int, unw_fpreg_t) {
446     _LIBUNWIND_ABORT("setFloatReg not implemented");
447   }
448   virtual int step(bool = false) { _LIBUNWIND_ABORT("step not implemented"); }
449   virtual void getInfo(unw_proc_info_t *) {
450     _LIBUNWIND_ABORT("getInfo not implemented");
451   }
452   virtual void jumpto() { _LIBUNWIND_ABORT("jumpto not implemented"); }
453   virtual bool isSignalFrame() {
454     _LIBUNWIND_ABORT("isSignalFrame not implemented");
455   }
456   virtual bool getFunctionName(char *, size_t, unw_word_t *) {
457     _LIBUNWIND_ABORT("getFunctionName not implemented");
458   }
459   virtual void setInfoBasedOnIPRegister(bool = false) {
460     _LIBUNWIND_ABORT("setInfoBasedOnIPRegister not implemented");
461   }
462   virtual const char *getRegisterName(int) {
463     _LIBUNWIND_ABORT("getRegisterName not implemented");
464   }
465 #ifdef __arm__
466   virtual void saveVFPAsX() { _LIBUNWIND_ABORT("saveVFPAsX not implemented"); }
467 #endif
468 
469 #ifdef _AIX
470   virtual uintptr_t getDataRelBase() {
471     _LIBUNWIND_ABORT("getDataRelBase not implemented");
472   }
473 #endif
474 
475 #if defined(_LIBUNWIND_USE_CET)
476   virtual void *get_registers() {
477     _LIBUNWIND_ABORT("get_registers not implemented");
478   }
479 #endif
480 };
481 
482 #if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) && defined(_WIN32)
483 
484 /// \c UnwindCursor contains all state (including all register values) during
485 /// an unwind.  This is normally stack-allocated inside a unw_cursor_t.
486 template <typename A, typename R>
487 class UnwindCursor : public AbstractUnwindCursor {
488   typedef typename A::pint_t pint_t;
489 public:
490                       UnwindCursor(unw_context_t *context, A &as);
491                       UnwindCursor(CONTEXT *context, A &as);
492                       UnwindCursor(A &as, void *threadArg);
493   virtual             ~UnwindCursor() {}
494   virtual bool        validReg(int);
495   virtual unw_word_t  getReg(int);
496   virtual void        setReg(int, unw_word_t);
497   virtual bool        validFloatReg(int);
498   virtual unw_fpreg_t getFloatReg(int);
499   virtual void        setFloatReg(int, unw_fpreg_t);
500   virtual int         step(bool = false);
501   virtual void        getInfo(unw_proc_info_t *);
502   virtual void        jumpto();
503   virtual bool        isSignalFrame();
504   virtual bool        getFunctionName(char *buf, size_t len, unw_word_t *off);
505   virtual void        setInfoBasedOnIPRegister(bool isReturnAddress = false);
506   virtual const char *getRegisterName(int num);
507 #ifdef __arm__
508   virtual void        saveVFPAsX();
509 #endif
510 
511   DISPATCHER_CONTEXT *getDispatcherContext() { return &_dispContext; }
512   void setDispatcherContext(DISPATCHER_CONTEXT *disp) {
513     _dispContext = *disp;
514     _info.lsda = reinterpret_cast<unw_word_t>(_dispContext.HandlerData);
515     if (_dispContext.LanguageHandler) {
516       _info.handler = reinterpret_cast<unw_word_t>(__libunwind_seh_personality);
517     } else
518       _info.handler = 0;
519   }
520 
521   // libunwind does not and should not depend on C++ library which means that we
522   // need our own definition of inline placement new.
523   static void *operator new(size_t, UnwindCursor<A, R> *p) { return p; }
524 
525 private:
526 
527   pint_t getLastPC() const { return _dispContext.ControlPc; }
528   void setLastPC(pint_t pc) { _dispContext.ControlPc = pc; }
529   RUNTIME_FUNCTION *lookUpSEHUnwindInfo(pint_t pc, pint_t *base) {
530 #ifdef __arm__
531     // Remove the thumb bit; FunctionEntry ranges don't include the thumb bit.
532     pc &= ~1U;
533 #endif
534     // If pc points exactly at the end of the range, we might resolve the
535     // next function instead. Decrement pc by 1 to fit inside the current
536     // function.
537     pc -= 1;
538     _dispContext.FunctionEntry = RtlLookupFunctionEntry(pc,
539                                                         &_dispContext.ImageBase,
540                                                         _dispContext.HistoryTable);
541     *base = _dispContext.ImageBase;
542     return _dispContext.FunctionEntry;
543   }
544   bool getInfoFromSEH(pint_t pc);
545   int stepWithSEHData() {
546     _dispContext.LanguageHandler = RtlVirtualUnwind(UNW_FLAG_UHANDLER,
547                                                     _dispContext.ImageBase,
548                                                     _dispContext.ControlPc,
549                                                     _dispContext.FunctionEntry,
550                                                     _dispContext.ContextRecord,
551                                                     &_dispContext.HandlerData,
552                                                     &_dispContext.EstablisherFrame,
553                                                     NULL);
554     // Update some fields of the unwind info now, since we have them.
555     _info.lsda = reinterpret_cast<unw_word_t>(_dispContext.HandlerData);
556     if (_dispContext.LanguageHandler) {
557       _info.handler = reinterpret_cast<unw_word_t>(__libunwind_seh_personality);
558     } else
559       _info.handler = 0;
560     return UNW_STEP_SUCCESS;
561   }
562 
563   A                   &_addressSpace;
564   unw_proc_info_t      _info;
565   DISPATCHER_CONTEXT   _dispContext;
566   CONTEXT              _msContext;
567   UNWIND_HISTORY_TABLE _histTable;
568   bool                 _unwindInfoMissing;
569 };
570 
571 
572 template <typename A, typename R>
573 UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as)
574     : _addressSpace(as), _unwindInfoMissing(false) {
575   static_assert((check_fit<UnwindCursor<A, R>, unw_cursor_t>::does_fit),
576                 "UnwindCursor<> does not fit in unw_cursor_t");
577   static_assert((alignof(UnwindCursor<A, R>) <= alignof(unw_cursor_t)),
578                 "UnwindCursor<> requires more alignment than unw_cursor_t");
579   memset(&_info, 0, sizeof(_info));
580   memset(&_histTable, 0, sizeof(_histTable));
581   memset(&_dispContext, 0, sizeof(_dispContext));
582   _dispContext.ContextRecord = &_msContext;
583   _dispContext.HistoryTable = &_histTable;
584   // Initialize MS context from ours.
585   R r(context);
586   RtlCaptureContext(&_msContext);
587   _msContext.ContextFlags = CONTEXT_CONTROL|CONTEXT_INTEGER|CONTEXT_FLOATING_POINT;
588 #if defined(_LIBUNWIND_TARGET_X86_64)
589   _msContext.Rax = r.getRegister(UNW_X86_64_RAX);
590   _msContext.Rcx = r.getRegister(UNW_X86_64_RCX);
591   _msContext.Rdx = r.getRegister(UNW_X86_64_RDX);
592   _msContext.Rbx = r.getRegister(UNW_X86_64_RBX);
593   _msContext.Rsp = r.getRegister(UNW_X86_64_RSP);
594   _msContext.Rbp = r.getRegister(UNW_X86_64_RBP);
595   _msContext.Rsi = r.getRegister(UNW_X86_64_RSI);
596   _msContext.Rdi = r.getRegister(UNW_X86_64_RDI);
597   _msContext.R8 = r.getRegister(UNW_X86_64_R8);
598   _msContext.R9 = r.getRegister(UNW_X86_64_R9);
599   _msContext.R10 = r.getRegister(UNW_X86_64_R10);
600   _msContext.R11 = r.getRegister(UNW_X86_64_R11);
601   _msContext.R12 = r.getRegister(UNW_X86_64_R12);
602   _msContext.R13 = r.getRegister(UNW_X86_64_R13);
603   _msContext.R14 = r.getRegister(UNW_X86_64_R14);
604   _msContext.R15 = r.getRegister(UNW_X86_64_R15);
605   _msContext.Rip = r.getRegister(UNW_REG_IP);
606   union {
607     v128 v;
608     M128A m;
609   } t;
610   t.v = r.getVectorRegister(UNW_X86_64_XMM0);
611   _msContext.Xmm0 = t.m;
612   t.v = r.getVectorRegister(UNW_X86_64_XMM1);
613   _msContext.Xmm1 = t.m;
614   t.v = r.getVectorRegister(UNW_X86_64_XMM2);
615   _msContext.Xmm2 = t.m;
616   t.v = r.getVectorRegister(UNW_X86_64_XMM3);
617   _msContext.Xmm3 = t.m;
618   t.v = r.getVectorRegister(UNW_X86_64_XMM4);
619   _msContext.Xmm4 = t.m;
620   t.v = r.getVectorRegister(UNW_X86_64_XMM5);
621   _msContext.Xmm5 = t.m;
622   t.v = r.getVectorRegister(UNW_X86_64_XMM6);
623   _msContext.Xmm6 = t.m;
624   t.v = r.getVectorRegister(UNW_X86_64_XMM7);
625   _msContext.Xmm7 = t.m;
626   t.v = r.getVectorRegister(UNW_X86_64_XMM8);
627   _msContext.Xmm8 = t.m;
628   t.v = r.getVectorRegister(UNW_X86_64_XMM9);
629   _msContext.Xmm9 = t.m;
630   t.v = r.getVectorRegister(UNW_X86_64_XMM10);
631   _msContext.Xmm10 = t.m;
632   t.v = r.getVectorRegister(UNW_X86_64_XMM11);
633   _msContext.Xmm11 = t.m;
634   t.v = r.getVectorRegister(UNW_X86_64_XMM12);
635   _msContext.Xmm12 = t.m;
636   t.v = r.getVectorRegister(UNW_X86_64_XMM13);
637   _msContext.Xmm13 = t.m;
638   t.v = r.getVectorRegister(UNW_X86_64_XMM14);
639   _msContext.Xmm14 = t.m;
640   t.v = r.getVectorRegister(UNW_X86_64_XMM15);
641   _msContext.Xmm15 = t.m;
642 #elif defined(_LIBUNWIND_TARGET_ARM)
643   _msContext.R0 = r.getRegister(UNW_ARM_R0);
644   _msContext.R1 = r.getRegister(UNW_ARM_R1);
645   _msContext.R2 = r.getRegister(UNW_ARM_R2);
646   _msContext.R3 = r.getRegister(UNW_ARM_R3);
647   _msContext.R4 = r.getRegister(UNW_ARM_R4);
648   _msContext.R5 = r.getRegister(UNW_ARM_R5);
649   _msContext.R6 = r.getRegister(UNW_ARM_R6);
650   _msContext.R7 = r.getRegister(UNW_ARM_R7);
651   _msContext.R8 = r.getRegister(UNW_ARM_R8);
652   _msContext.R9 = r.getRegister(UNW_ARM_R9);
653   _msContext.R10 = r.getRegister(UNW_ARM_R10);
654   _msContext.R11 = r.getRegister(UNW_ARM_R11);
655   _msContext.R12 = r.getRegister(UNW_ARM_R12);
656   _msContext.Sp = r.getRegister(UNW_ARM_SP);
657   _msContext.Lr = r.getRegister(UNW_ARM_LR);
658   _msContext.Pc = r.getRegister(UNW_ARM_IP);
659   for (int i = UNW_ARM_D0; i <= UNW_ARM_D31; ++i) {
660     union {
661       uint64_t w;
662       double d;
663     } d;
664     d.d = r.getFloatRegister(i);
665     _msContext.D[i - UNW_ARM_D0] = d.w;
666   }
667 #elif defined(_LIBUNWIND_TARGET_AARCH64)
668   for (int i = UNW_AARCH64_X0; i <= UNW_ARM64_X30; ++i)
669     _msContext.X[i - UNW_AARCH64_X0] = r.getRegister(i);
670   _msContext.Sp = r.getRegister(UNW_REG_SP);
671   _msContext.Pc = r.getRegister(UNW_REG_IP);
672   for (int i = UNW_AARCH64_V0; i <= UNW_ARM64_D31; ++i)
673     _msContext.V[i - UNW_AARCH64_V0].D[0] = r.getFloatRegister(i);
674 #endif
675 }
676 
677 template <typename A, typename R>
678 UnwindCursor<A, R>::UnwindCursor(CONTEXT *context, A &as)
679     : _addressSpace(as), _unwindInfoMissing(false) {
680   static_assert((check_fit<UnwindCursor<A, R>, unw_cursor_t>::does_fit),
681                 "UnwindCursor<> does not fit in unw_cursor_t");
682   memset(&_info, 0, sizeof(_info));
683   memset(&_histTable, 0, sizeof(_histTable));
684   memset(&_dispContext, 0, sizeof(_dispContext));
685   _dispContext.ContextRecord = &_msContext;
686   _dispContext.HistoryTable = &_histTable;
687   _msContext = *context;
688 }
689 
690 
691 template <typename A, typename R>
692 bool UnwindCursor<A, R>::validReg(int regNum) {
693   if (regNum == UNW_REG_IP || regNum == UNW_REG_SP) return true;
694 #if defined(_LIBUNWIND_TARGET_X86_64)
695   if (regNum >= UNW_X86_64_RAX && regNum <= UNW_X86_64_RIP) return true;
696 #elif defined(_LIBUNWIND_TARGET_ARM)
697   if ((regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15) ||
698       regNum == UNW_ARM_RA_AUTH_CODE)
699     return true;
700 #elif defined(_LIBUNWIND_TARGET_AARCH64)
701   if (regNum >= UNW_AARCH64_X0 && regNum <= UNW_ARM64_X30) return true;
702 #endif
703   return false;
704 }
705 
706 template <typename A, typename R>
707 unw_word_t UnwindCursor<A, R>::getReg(int regNum) {
708   switch (regNum) {
709 #if defined(_LIBUNWIND_TARGET_X86_64)
710   case UNW_X86_64_RIP:
711   case UNW_REG_IP: return _msContext.Rip;
712   case UNW_X86_64_RAX: return _msContext.Rax;
713   case UNW_X86_64_RDX: return _msContext.Rdx;
714   case UNW_X86_64_RCX: return _msContext.Rcx;
715   case UNW_X86_64_RBX: return _msContext.Rbx;
716   case UNW_REG_SP:
717   case UNW_X86_64_RSP: return _msContext.Rsp;
718   case UNW_X86_64_RBP: return _msContext.Rbp;
719   case UNW_X86_64_RSI: return _msContext.Rsi;
720   case UNW_X86_64_RDI: return _msContext.Rdi;
721   case UNW_X86_64_R8: return _msContext.R8;
722   case UNW_X86_64_R9: return _msContext.R9;
723   case UNW_X86_64_R10: return _msContext.R10;
724   case UNW_X86_64_R11: return _msContext.R11;
725   case UNW_X86_64_R12: return _msContext.R12;
726   case UNW_X86_64_R13: return _msContext.R13;
727   case UNW_X86_64_R14: return _msContext.R14;
728   case UNW_X86_64_R15: return _msContext.R15;
729 #elif defined(_LIBUNWIND_TARGET_ARM)
730   case UNW_ARM_R0: return _msContext.R0;
731   case UNW_ARM_R1: return _msContext.R1;
732   case UNW_ARM_R2: return _msContext.R2;
733   case UNW_ARM_R3: return _msContext.R3;
734   case UNW_ARM_R4: return _msContext.R4;
735   case UNW_ARM_R5: return _msContext.R5;
736   case UNW_ARM_R6: return _msContext.R6;
737   case UNW_ARM_R7: return _msContext.R7;
738   case UNW_ARM_R8: return _msContext.R8;
739   case UNW_ARM_R9: return _msContext.R9;
740   case UNW_ARM_R10: return _msContext.R10;
741   case UNW_ARM_R11: return _msContext.R11;
742   case UNW_ARM_R12: return _msContext.R12;
743   case UNW_REG_SP:
744   case UNW_ARM_SP: return _msContext.Sp;
745   case UNW_ARM_LR: return _msContext.Lr;
746   case UNW_REG_IP:
747   case UNW_ARM_IP: return _msContext.Pc;
748 #elif defined(_LIBUNWIND_TARGET_AARCH64)
749   case UNW_REG_SP: return _msContext.Sp;
750   case UNW_REG_IP: return _msContext.Pc;
751   default: return _msContext.X[regNum - UNW_AARCH64_X0];
752 #endif
753   }
754   _LIBUNWIND_ABORT("unsupported register");
755 }
756 
757 template <typename A, typename R>
758 void UnwindCursor<A, R>::setReg(int regNum, unw_word_t value) {
759   switch (regNum) {
760 #if defined(_LIBUNWIND_TARGET_X86_64)
761   case UNW_X86_64_RIP:
762   case UNW_REG_IP: _msContext.Rip = value; break;
763   case UNW_X86_64_RAX: _msContext.Rax = value; break;
764   case UNW_X86_64_RDX: _msContext.Rdx = value; break;
765   case UNW_X86_64_RCX: _msContext.Rcx = value; break;
766   case UNW_X86_64_RBX: _msContext.Rbx = value; break;
767   case UNW_REG_SP:
768   case UNW_X86_64_RSP: _msContext.Rsp = value; break;
769   case UNW_X86_64_RBP: _msContext.Rbp = value; break;
770   case UNW_X86_64_RSI: _msContext.Rsi = value; break;
771   case UNW_X86_64_RDI: _msContext.Rdi = value; break;
772   case UNW_X86_64_R8: _msContext.R8 = value; break;
773   case UNW_X86_64_R9: _msContext.R9 = value; break;
774   case UNW_X86_64_R10: _msContext.R10 = value; break;
775   case UNW_X86_64_R11: _msContext.R11 = value; break;
776   case UNW_X86_64_R12: _msContext.R12 = value; break;
777   case UNW_X86_64_R13: _msContext.R13 = value; break;
778   case UNW_X86_64_R14: _msContext.R14 = value; break;
779   case UNW_X86_64_R15: _msContext.R15 = value; break;
780 #elif defined(_LIBUNWIND_TARGET_ARM)
781   case UNW_ARM_R0: _msContext.R0 = value; break;
782   case UNW_ARM_R1: _msContext.R1 = value; break;
783   case UNW_ARM_R2: _msContext.R2 = value; break;
784   case UNW_ARM_R3: _msContext.R3 = value; break;
785   case UNW_ARM_R4: _msContext.R4 = value; break;
786   case UNW_ARM_R5: _msContext.R5 = value; break;
787   case UNW_ARM_R6: _msContext.R6 = value; break;
788   case UNW_ARM_R7: _msContext.R7 = value; break;
789   case UNW_ARM_R8: _msContext.R8 = value; break;
790   case UNW_ARM_R9: _msContext.R9 = value; break;
791   case UNW_ARM_R10: _msContext.R10 = value; break;
792   case UNW_ARM_R11: _msContext.R11 = value; break;
793   case UNW_ARM_R12: _msContext.R12 = value; break;
794   case UNW_REG_SP:
795   case UNW_ARM_SP: _msContext.Sp = value; break;
796   case UNW_ARM_LR: _msContext.Lr = value; break;
797   case UNW_REG_IP:
798   case UNW_ARM_IP: _msContext.Pc = value; break;
799 #elif defined(_LIBUNWIND_TARGET_AARCH64)
800   case UNW_REG_SP: _msContext.Sp = value; break;
801   case UNW_REG_IP: _msContext.Pc = value; break;
802   case UNW_AARCH64_X0:
803   case UNW_AARCH64_X1:
804   case UNW_AARCH64_X2:
805   case UNW_AARCH64_X3:
806   case UNW_AARCH64_X4:
807   case UNW_AARCH64_X5:
808   case UNW_AARCH64_X6:
809   case UNW_AARCH64_X7:
810   case UNW_AARCH64_X8:
811   case UNW_AARCH64_X9:
812   case UNW_AARCH64_X10:
813   case UNW_AARCH64_X11:
814   case UNW_AARCH64_X12:
815   case UNW_AARCH64_X13:
816   case UNW_AARCH64_X14:
817   case UNW_AARCH64_X15:
818   case UNW_AARCH64_X16:
819   case UNW_AARCH64_X17:
820   case UNW_AARCH64_X18:
821   case UNW_AARCH64_X19:
822   case UNW_AARCH64_X20:
823   case UNW_AARCH64_X21:
824   case UNW_AARCH64_X22:
825   case UNW_AARCH64_X23:
826   case UNW_AARCH64_X24:
827   case UNW_AARCH64_X25:
828   case UNW_AARCH64_X26:
829   case UNW_AARCH64_X27:
830   case UNW_AARCH64_X28:
831   case UNW_AARCH64_FP:
832   case UNW_AARCH64_LR: _msContext.X[regNum - UNW_ARM64_X0] = value; break;
833 #endif
834   default:
835     _LIBUNWIND_ABORT("unsupported register");
836   }
837 }
838 
839 template <typename A, typename R>
840 bool UnwindCursor<A, R>::validFloatReg(int regNum) {
841 #if defined(_LIBUNWIND_TARGET_ARM)
842   if (regNum >= UNW_ARM_S0 && regNum <= UNW_ARM_S31) return true;
843   if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D31) return true;
844 #elif defined(_LIBUNWIND_TARGET_AARCH64)
845   if (regNum >= UNW_AARCH64_V0 && regNum <= UNW_ARM64_D31) return true;
846 #else
847   (void)regNum;
848 #endif
849   return false;
850 }
851 
852 template <typename A, typename R>
853 unw_fpreg_t UnwindCursor<A, R>::getFloatReg(int regNum) {
854 #if defined(_LIBUNWIND_TARGET_ARM)
855   if (regNum >= UNW_ARM_S0 && regNum <= UNW_ARM_S31) {
856     union {
857       uint32_t w;
858       float f;
859     } d;
860     d.w = _msContext.S[regNum - UNW_ARM_S0];
861     return d.f;
862   }
863   if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D31) {
864     union {
865       uint64_t w;
866       double d;
867     } d;
868     d.w = _msContext.D[regNum - UNW_ARM_D0];
869     return d.d;
870   }
871   _LIBUNWIND_ABORT("unsupported float register");
872 #elif defined(_LIBUNWIND_TARGET_AARCH64)
873   return _msContext.V[regNum - UNW_AARCH64_V0].D[0];
874 #else
875   (void)regNum;
876   _LIBUNWIND_ABORT("float registers unimplemented");
877 #endif
878 }
879 
880 template <typename A, typename R>
881 void UnwindCursor<A, R>::setFloatReg(int regNum, unw_fpreg_t value) {
882 #if defined(_LIBUNWIND_TARGET_ARM)
883   if (regNum >= UNW_ARM_S0 && regNum <= UNW_ARM_S31) {
884     union {
885       uint32_t w;
886       float f;
887     } d;
888     d.f = (float)value;
889     _msContext.S[regNum - UNW_ARM_S0] = d.w;
890   }
891   if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D31) {
892     union {
893       uint64_t w;
894       double d;
895     } d;
896     d.d = value;
897     _msContext.D[regNum - UNW_ARM_D0] = d.w;
898   }
899   _LIBUNWIND_ABORT("unsupported float register");
900 #elif defined(_LIBUNWIND_TARGET_AARCH64)
901   _msContext.V[regNum - UNW_AARCH64_V0].D[0] = value;
902 #else
903   (void)regNum;
904   (void)value;
905   _LIBUNWIND_ABORT("float registers unimplemented");
906 #endif
907 }
908 
909 template <typename A, typename R> void UnwindCursor<A, R>::jumpto() {
910   RtlRestoreContext(&_msContext, nullptr);
911 }
912 
913 #ifdef __arm__
914 template <typename A, typename R> void UnwindCursor<A, R>::saveVFPAsX() {}
915 #endif
916 
917 template <typename A, typename R>
918 const char *UnwindCursor<A, R>::getRegisterName(int regNum) {
919   return R::getRegisterName(regNum);
920 }
921 
922 template <typename A, typename R> bool UnwindCursor<A, R>::isSignalFrame() {
923   return false;
924 }
925 
926 #else  // !defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) || !defined(_WIN32)
927 
928 /// UnwindCursor contains all state (including all register values) during
929 /// an unwind.  This is normally stack allocated inside a unw_cursor_t.
930 template <typename A, typename R>
931 class UnwindCursor : public AbstractUnwindCursor{
932   typedef typename A::pint_t pint_t;
933 public:
934                       UnwindCursor(unw_context_t *context, A &as);
935                       UnwindCursor(A &as, void *threadArg);
936   virtual             ~UnwindCursor() {}
937   virtual bool        validReg(int);
938   virtual unw_word_t  getReg(int);
939   virtual void        setReg(int, unw_word_t);
940   virtual bool        validFloatReg(int);
941   virtual unw_fpreg_t getFloatReg(int);
942   virtual void        setFloatReg(int, unw_fpreg_t);
943   virtual int         step(bool stage2 = false);
944   virtual void        getInfo(unw_proc_info_t *);
945   virtual void        jumpto();
946   virtual bool        isSignalFrame();
947   virtual bool        getFunctionName(char *buf, size_t len, unw_word_t *off);
948   virtual void        setInfoBasedOnIPRegister(bool isReturnAddress = false);
949   virtual const char *getRegisterName(int num);
950 #ifdef __arm__
951   virtual void        saveVFPAsX();
952 #endif
953 
954 #ifdef _AIX
955   virtual uintptr_t getDataRelBase();
956 #endif
957 
958 #if defined(_LIBUNWIND_USE_CET)
959   virtual void *get_registers() { return &_registers; }
960 #endif
961 
962   // libunwind does not and should not depend on C++ library which means that we
963   // need our own definition of inline placement new.
964   static void *operator new(size_t, UnwindCursor<A, R> *p) { return p; }
965 
966 private:
967 
968 #if defined(_LIBUNWIND_ARM_EHABI)
969   bool getInfoFromEHABISection(pint_t pc, const UnwindInfoSections &sects);
970 
971   int stepWithEHABI() {
972     size_t len = 0;
973     size_t off = 0;
974     // FIXME: Calling decode_eht_entry() here is violating the libunwind
975     // abstraction layer.
976     const uint32_t *ehtp =
977         decode_eht_entry(reinterpret_cast<const uint32_t *>(_info.unwind_info),
978                          &off, &len);
979     if (_Unwind_VRS_Interpret((_Unwind_Context *)this, ehtp, off, len) !=
980             _URC_CONTINUE_UNWIND)
981       return UNW_STEP_END;
982     return UNW_STEP_SUCCESS;
983   }
984 #endif
985 
986 #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN)
987   bool setInfoForSigReturn() {
988     R dummy;
989     return setInfoForSigReturn(dummy);
990   }
991   int stepThroughSigReturn() {
992     R dummy;
993     return stepThroughSigReturn(dummy);
994   }
995   bool isReadableAddr(const pint_t addr) const;
996 #if defined(_LIBUNWIND_TARGET_AARCH64)
997   bool setInfoForSigReturn(Registers_arm64 &);
998   int stepThroughSigReturn(Registers_arm64 &);
999 #endif
1000 #if defined(_LIBUNWIND_TARGET_RISCV)
1001   bool setInfoForSigReturn(Registers_riscv &);
1002   int stepThroughSigReturn(Registers_riscv &);
1003 #endif
1004 #if defined(_LIBUNWIND_TARGET_S390X)
1005   bool setInfoForSigReturn(Registers_s390x &);
1006   int stepThroughSigReturn(Registers_s390x &);
1007 #endif
1008   template <typename Registers> bool setInfoForSigReturn(Registers &) {
1009     return false;
1010   }
1011   template <typename Registers> int stepThroughSigReturn(Registers &) {
1012     return UNW_STEP_END;
1013   }
1014 #endif
1015 
1016 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
1017   bool getInfoFromFdeCie(const typename CFI_Parser<A>::FDE_Info &fdeInfo,
1018                          const typename CFI_Parser<A>::CIE_Info &cieInfo,
1019                          pint_t pc, uintptr_t dso_base);
1020   bool getInfoFromDwarfSection(pint_t pc, const UnwindInfoSections &sects,
1021                                             uint32_t fdeSectionOffsetHint=0);
1022   int stepWithDwarfFDE(bool stage2) {
1023     return DwarfInstructions<A, R>::stepWithDwarf(
1024         _addressSpace, (pint_t)this->getReg(UNW_REG_IP),
1025         (pint_t)_info.unwind_info, _registers, _isSignalFrame, stage2);
1026   }
1027 #endif
1028 
1029 #if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
1030   bool getInfoFromCompactEncodingSection(pint_t pc,
1031                                             const UnwindInfoSections &sects);
1032   int stepWithCompactEncoding(bool stage2 = false) {
1033 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
1034     if ( compactSaysUseDwarf() )
1035       return stepWithDwarfFDE(stage2);
1036 #endif
1037     R dummy;
1038     return stepWithCompactEncoding(dummy);
1039   }
1040 
1041 #if defined(_LIBUNWIND_TARGET_X86_64)
1042   int stepWithCompactEncoding(Registers_x86_64 &) {
1043     return CompactUnwinder_x86_64<A>::stepWithCompactEncoding(
1044         _info.format, _info.start_ip, _addressSpace, _registers);
1045   }
1046 #endif
1047 
1048 #if defined(_LIBUNWIND_TARGET_I386)
1049   int stepWithCompactEncoding(Registers_x86 &) {
1050     return CompactUnwinder_x86<A>::stepWithCompactEncoding(
1051         _info.format, (uint32_t)_info.start_ip, _addressSpace, _registers);
1052   }
1053 #endif
1054 
1055 #if defined(_LIBUNWIND_TARGET_PPC)
1056   int stepWithCompactEncoding(Registers_ppc &) {
1057     return UNW_EINVAL;
1058   }
1059 #endif
1060 
1061 #if defined(_LIBUNWIND_TARGET_PPC64)
1062   int stepWithCompactEncoding(Registers_ppc64 &) {
1063     return UNW_EINVAL;
1064   }
1065 #endif
1066 
1067 
1068 #if defined(_LIBUNWIND_TARGET_AARCH64)
1069   int stepWithCompactEncoding(Registers_arm64 &) {
1070     return CompactUnwinder_arm64<A>::stepWithCompactEncoding(
1071         _info.format, _info.start_ip, _addressSpace, _registers);
1072   }
1073 #endif
1074 
1075 #if defined(_LIBUNWIND_TARGET_MIPS_O32)
1076   int stepWithCompactEncoding(Registers_mips_o32 &) {
1077     return UNW_EINVAL;
1078   }
1079 #endif
1080 
1081 #if defined(_LIBUNWIND_TARGET_MIPS_NEWABI)
1082   int stepWithCompactEncoding(Registers_mips_newabi &) {
1083     return UNW_EINVAL;
1084   }
1085 #endif
1086 
1087 #if defined(_LIBUNWIND_TARGET_LOONGARCH)
1088   int stepWithCompactEncoding(Registers_loongarch &) { return UNW_EINVAL; }
1089 #endif
1090 
1091 #if defined(_LIBUNWIND_TARGET_SPARC)
1092   int stepWithCompactEncoding(Registers_sparc &) { return UNW_EINVAL; }
1093 #endif
1094 
1095 #if defined(_LIBUNWIND_TARGET_SPARC64)
1096   int stepWithCompactEncoding(Registers_sparc64 &) { return UNW_EINVAL; }
1097 #endif
1098 
1099 #if defined (_LIBUNWIND_TARGET_RISCV)
1100   int stepWithCompactEncoding(Registers_riscv &) {
1101     return UNW_EINVAL;
1102   }
1103 #endif
1104 
1105   bool compactSaysUseDwarf(uint32_t *offset=NULL) const {
1106     R dummy;
1107     return compactSaysUseDwarf(dummy, offset);
1108   }
1109 
1110 #if defined(_LIBUNWIND_TARGET_X86_64)
1111   bool compactSaysUseDwarf(Registers_x86_64 &, uint32_t *offset) const {
1112     if ((_info.format & UNWIND_X86_64_MODE_MASK) == UNWIND_X86_64_MODE_DWARF) {
1113       if (offset)
1114         *offset = (_info.format & UNWIND_X86_64_DWARF_SECTION_OFFSET);
1115       return true;
1116     }
1117     return false;
1118   }
1119 #endif
1120 
1121 #if defined(_LIBUNWIND_TARGET_I386)
1122   bool compactSaysUseDwarf(Registers_x86 &, uint32_t *offset) const {
1123     if ((_info.format & UNWIND_X86_MODE_MASK) == UNWIND_X86_MODE_DWARF) {
1124       if (offset)
1125         *offset = (_info.format & UNWIND_X86_DWARF_SECTION_OFFSET);
1126       return true;
1127     }
1128     return false;
1129   }
1130 #endif
1131 
1132 #if defined(_LIBUNWIND_TARGET_PPC)
1133   bool compactSaysUseDwarf(Registers_ppc &, uint32_t *) const {
1134     return true;
1135   }
1136 #endif
1137 
1138 #if defined(_LIBUNWIND_TARGET_PPC64)
1139   bool compactSaysUseDwarf(Registers_ppc64 &, uint32_t *) const {
1140     return true;
1141   }
1142 #endif
1143 
1144 #if defined(_LIBUNWIND_TARGET_AARCH64)
1145   bool compactSaysUseDwarf(Registers_arm64 &, uint32_t *offset) const {
1146     if ((_info.format & UNWIND_ARM64_MODE_MASK) == UNWIND_ARM64_MODE_DWARF) {
1147       if (offset)
1148         *offset = (_info.format & UNWIND_ARM64_DWARF_SECTION_OFFSET);
1149       return true;
1150     }
1151     return false;
1152   }
1153 #endif
1154 
1155 #if defined(_LIBUNWIND_TARGET_MIPS_O32)
1156   bool compactSaysUseDwarf(Registers_mips_o32 &, uint32_t *) const {
1157     return true;
1158   }
1159 #endif
1160 
1161 #if defined(_LIBUNWIND_TARGET_MIPS_NEWABI)
1162   bool compactSaysUseDwarf(Registers_mips_newabi &, uint32_t *) const {
1163     return true;
1164   }
1165 #endif
1166 
1167 #if defined(_LIBUNWIND_TARGET_LOONGARCH)
1168   bool compactSaysUseDwarf(Registers_loongarch &, uint32_t *) const {
1169     return true;
1170   }
1171 #endif
1172 
1173 #if defined(_LIBUNWIND_TARGET_SPARC)
1174   bool compactSaysUseDwarf(Registers_sparc &, uint32_t *) const { return true; }
1175 #endif
1176 
1177 #if defined(_LIBUNWIND_TARGET_SPARC64)
1178   bool compactSaysUseDwarf(Registers_sparc64 &, uint32_t *) const {
1179     return true;
1180   }
1181 #endif
1182 
1183 #if defined (_LIBUNWIND_TARGET_RISCV)
1184   bool compactSaysUseDwarf(Registers_riscv &, uint32_t *) const {
1185     return true;
1186   }
1187 #endif
1188 
1189 #endif // defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
1190 
1191 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
1192   compact_unwind_encoding_t dwarfEncoding() const {
1193     R dummy;
1194     return dwarfEncoding(dummy);
1195   }
1196 
1197 #if defined(_LIBUNWIND_TARGET_X86_64)
1198   compact_unwind_encoding_t dwarfEncoding(Registers_x86_64 &) const {
1199     return UNWIND_X86_64_MODE_DWARF;
1200   }
1201 #endif
1202 
1203 #if defined(_LIBUNWIND_TARGET_I386)
1204   compact_unwind_encoding_t dwarfEncoding(Registers_x86 &) const {
1205     return UNWIND_X86_MODE_DWARF;
1206   }
1207 #endif
1208 
1209 #if defined(_LIBUNWIND_TARGET_PPC)
1210   compact_unwind_encoding_t dwarfEncoding(Registers_ppc &) const {
1211     return 0;
1212   }
1213 #endif
1214 
1215 #if defined(_LIBUNWIND_TARGET_PPC64)
1216   compact_unwind_encoding_t dwarfEncoding(Registers_ppc64 &) const {
1217     return 0;
1218   }
1219 #endif
1220 
1221 #if defined(_LIBUNWIND_TARGET_AARCH64)
1222   compact_unwind_encoding_t dwarfEncoding(Registers_arm64 &) const {
1223     return UNWIND_ARM64_MODE_DWARF;
1224   }
1225 #endif
1226 
1227 #if defined(_LIBUNWIND_TARGET_ARM)
1228   compact_unwind_encoding_t dwarfEncoding(Registers_arm &) const {
1229     return 0;
1230   }
1231 #endif
1232 
1233 #if defined (_LIBUNWIND_TARGET_OR1K)
1234   compact_unwind_encoding_t dwarfEncoding(Registers_or1k &) const {
1235     return 0;
1236   }
1237 #endif
1238 
1239 #if defined (_LIBUNWIND_TARGET_HEXAGON)
1240   compact_unwind_encoding_t dwarfEncoding(Registers_hexagon &) const {
1241     return 0;
1242   }
1243 #endif
1244 
1245 #if defined (_LIBUNWIND_TARGET_MIPS_O32)
1246   compact_unwind_encoding_t dwarfEncoding(Registers_mips_o32 &) const {
1247     return 0;
1248   }
1249 #endif
1250 
1251 #if defined (_LIBUNWIND_TARGET_MIPS_NEWABI)
1252   compact_unwind_encoding_t dwarfEncoding(Registers_mips_newabi &) const {
1253     return 0;
1254   }
1255 #endif
1256 
1257 #if defined(_LIBUNWIND_TARGET_LOONGARCH)
1258   compact_unwind_encoding_t dwarfEncoding(Registers_loongarch &) const {
1259     return 0;
1260   }
1261 #endif
1262 
1263 #if defined(_LIBUNWIND_TARGET_SPARC)
1264   compact_unwind_encoding_t dwarfEncoding(Registers_sparc &) const { return 0; }
1265 #endif
1266 
1267 #if defined(_LIBUNWIND_TARGET_SPARC64)
1268   compact_unwind_encoding_t dwarfEncoding(Registers_sparc64 &) const {
1269     return 0;
1270   }
1271 #endif
1272 
1273 #if defined (_LIBUNWIND_TARGET_RISCV)
1274   compact_unwind_encoding_t dwarfEncoding(Registers_riscv &) const {
1275     return 0;
1276   }
1277 #endif
1278 
1279 #if defined (_LIBUNWIND_TARGET_S390X)
1280   compact_unwind_encoding_t dwarfEncoding(Registers_s390x &) const {
1281     return 0;
1282   }
1283 #endif
1284 
1285 #endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
1286 
1287 #if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
1288   // For runtime environments using SEH unwind data without Windows runtime
1289   // support.
1290   pint_t getLastPC() const { /* FIXME: Implement */ return 0; }
1291   void setLastPC(pint_t pc) { /* FIXME: Implement */ }
1292   RUNTIME_FUNCTION *lookUpSEHUnwindInfo(pint_t pc, pint_t *base) {
1293     /* FIXME: Implement */
1294     *base = 0;
1295     return nullptr;
1296   }
1297   bool getInfoFromSEH(pint_t pc);
1298   int stepWithSEHData() { /* FIXME: Implement */ return 0; }
1299 #endif // defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
1300 
1301 #if defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND)
1302   bool getInfoFromTBTable(pint_t pc, R &registers);
1303   int stepWithTBTable(pint_t pc, tbtable *TBTable, R &registers,
1304                       bool &isSignalFrame);
1305   int stepWithTBTableData() {
1306     return stepWithTBTable(reinterpret_cast<pint_t>(this->getReg(UNW_REG_IP)),
1307                            reinterpret_cast<tbtable *>(_info.unwind_info),
1308                            _registers, _isSignalFrame);
1309   }
1310 #endif // defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND)
1311 
1312   A               &_addressSpace;
1313   R                _registers;
1314   unw_proc_info_t  _info;
1315   bool             _unwindInfoMissing;
1316   bool             _isSignalFrame;
1317 #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN)
1318   bool             _isSigReturn = false;
1319 #endif
1320 };
1321 
1322 
1323 template <typename A, typename R>
1324 UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as)
1325     : _addressSpace(as), _registers(context), _unwindInfoMissing(false),
1326       _isSignalFrame(false) {
1327   static_assert((check_fit<UnwindCursor<A, R>, unw_cursor_t>::does_fit),
1328                 "UnwindCursor<> does not fit in unw_cursor_t");
1329   static_assert((alignof(UnwindCursor<A, R>) <= alignof(unw_cursor_t)),
1330                 "UnwindCursor<> requires more alignment than unw_cursor_t");
1331   memset(&_info, 0, sizeof(_info));
1332 }
1333 
1334 template <typename A, typename R>
1335 UnwindCursor<A, R>::UnwindCursor(A &as, void *)
1336     : _addressSpace(as), _unwindInfoMissing(false), _isSignalFrame(false) {
1337   memset(&_info, 0, sizeof(_info));
1338   // FIXME
1339   // fill in _registers from thread arg
1340 }
1341 
1342 
1343 template <typename A, typename R>
1344 bool UnwindCursor<A, R>::validReg(int regNum) {
1345   return _registers.validRegister(regNum);
1346 }
1347 
1348 template <typename A, typename R>
1349 unw_word_t UnwindCursor<A, R>::getReg(int regNum) {
1350   return _registers.getRegister(regNum);
1351 }
1352 
1353 template <typename A, typename R>
1354 void UnwindCursor<A, R>::setReg(int regNum, unw_word_t value) {
1355   _registers.setRegister(regNum, (typename A::pint_t)value);
1356 }
1357 
1358 template <typename A, typename R>
1359 bool UnwindCursor<A, R>::validFloatReg(int regNum) {
1360   return _registers.validFloatRegister(regNum);
1361 }
1362 
1363 template <typename A, typename R>
1364 unw_fpreg_t UnwindCursor<A, R>::getFloatReg(int regNum) {
1365   return _registers.getFloatRegister(regNum);
1366 }
1367 
1368 template <typename A, typename R>
1369 void UnwindCursor<A, R>::setFloatReg(int regNum, unw_fpreg_t value) {
1370   _registers.setFloatRegister(regNum, value);
1371 }
1372 
1373 template <typename A, typename R> void UnwindCursor<A, R>::jumpto() {
1374   _registers.jumpto();
1375 }
1376 
1377 #ifdef __arm__
1378 template <typename A, typename R> void UnwindCursor<A, R>::saveVFPAsX() {
1379   _registers.saveVFPAsX();
1380 }
1381 #endif
1382 
1383 #ifdef _AIX
1384 template <typename A, typename R>
1385 uintptr_t UnwindCursor<A, R>::getDataRelBase() {
1386   return reinterpret_cast<uintptr_t>(_info.extra);
1387 }
1388 #endif
1389 
1390 template <typename A, typename R>
1391 const char *UnwindCursor<A, R>::getRegisterName(int regNum) {
1392   return _registers.getRegisterName(regNum);
1393 }
1394 
1395 template <typename A, typename R> bool UnwindCursor<A, R>::isSignalFrame() {
1396   return _isSignalFrame;
1397 }
1398 
1399 #endif // defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
1400 
1401 #if defined(_LIBUNWIND_ARM_EHABI)
1402 template<typename A>
1403 struct EHABISectionIterator {
1404   typedef EHABISectionIterator _Self;
1405 
1406   typedef typename A::pint_t value_type;
1407   typedef typename A::pint_t* pointer;
1408   typedef typename A::pint_t& reference;
1409   typedef size_t size_type;
1410   typedef size_t difference_type;
1411 
1412   static _Self begin(A& addressSpace, const UnwindInfoSections& sects) {
1413     return _Self(addressSpace, sects, 0);
1414   }
1415   static _Self end(A& addressSpace, const UnwindInfoSections& sects) {
1416     return _Self(addressSpace, sects,
1417                  sects.arm_section_length / sizeof(EHABIIndexEntry));
1418   }
1419 
1420   EHABISectionIterator(A& addressSpace, const UnwindInfoSections& sects, size_t i)
1421       : _i(i), _addressSpace(&addressSpace), _sects(&sects) {}
1422 
1423   _Self& operator++() { ++_i; return *this; }
1424   _Self& operator+=(size_t a) { _i += a; return *this; }
1425   _Self& operator--() { assert(_i > 0); --_i; return *this; }
1426   _Self& operator-=(size_t a) { assert(_i >= a); _i -= a; return *this; }
1427 
1428   _Self operator+(size_t a) { _Self out = *this; out._i += a; return out; }
1429   _Self operator-(size_t a) { assert(_i >= a); _Self out = *this; out._i -= a; return out; }
1430 
1431   size_t operator-(const _Self& other) const { return _i - other._i; }
1432 
1433   bool operator==(const _Self& other) const {
1434     assert(_addressSpace == other._addressSpace);
1435     assert(_sects == other._sects);
1436     return _i == other._i;
1437   }
1438 
1439   bool operator!=(const _Self& other) const {
1440     assert(_addressSpace == other._addressSpace);
1441     assert(_sects == other._sects);
1442     return _i != other._i;
1443   }
1444 
1445   typename A::pint_t operator*() const { return functionAddress(); }
1446 
1447   typename A::pint_t functionAddress() const {
1448     typename A::pint_t indexAddr = _sects->arm_section + arrayoffsetof(
1449         EHABIIndexEntry, _i, functionOffset);
1450     return indexAddr + signExtendPrel31(_addressSpace->get32(indexAddr));
1451   }
1452 
1453   typename A::pint_t dataAddress() {
1454     typename A::pint_t indexAddr = _sects->arm_section + arrayoffsetof(
1455         EHABIIndexEntry, _i, data);
1456     return indexAddr;
1457   }
1458 
1459  private:
1460   size_t _i;
1461   A* _addressSpace;
1462   const UnwindInfoSections* _sects;
1463 };
1464 
1465 namespace {
1466 
1467 template <typename A>
1468 EHABISectionIterator<A> EHABISectionUpperBound(
1469     EHABISectionIterator<A> first,
1470     EHABISectionIterator<A> last,
1471     typename A::pint_t value) {
1472   size_t len = last - first;
1473   while (len > 0) {
1474     size_t l2 = len / 2;
1475     EHABISectionIterator<A> m = first + l2;
1476     if (value < *m) {
1477         len = l2;
1478     } else {
1479         first = ++m;
1480         len -= l2 + 1;
1481     }
1482   }
1483   return first;
1484 }
1485 
1486 }
1487 
1488 template <typename A, typename R>
1489 bool UnwindCursor<A, R>::getInfoFromEHABISection(
1490     pint_t pc,
1491     const UnwindInfoSections &sects) {
1492   EHABISectionIterator<A> begin =
1493       EHABISectionIterator<A>::begin(_addressSpace, sects);
1494   EHABISectionIterator<A> end =
1495       EHABISectionIterator<A>::end(_addressSpace, sects);
1496   if (begin == end)
1497     return false;
1498 
1499   EHABISectionIterator<A> itNextPC = EHABISectionUpperBound(begin, end, pc);
1500   if (itNextPC == begin)
1501     return false;
1502   EHABISectionIterator<A> itThisPC = itNextPC - 1;
1503 
1504   pint_t thisPC = itThisPC.functionAddress();
1505   // If an exception is thrown from a function, corresponding to the last entry
1506   // in the table, we don't really know the function extent and have to choose a
1507   // value for nextPC. Choosing max() will allow the range check during trace to
1508   // succeed.
1509   pint_t nextPC = (itNextPC == end) ? UINTPTR_MAX : itNextPC.functionAddress();
1510   pint_t indexDataAddr = itThisPC.dataAddress();
1511 
1512   if (indexDataAddr == 0)
1513     return false;
1514 
1515   uint32_t indexData = _addressSpace.get32(indexDataAddr);
1516   if (indexData == UNW_EXIDX_CANTUNWIND)
1517     return false;
1518 
1519   // If the high bit is set, the exception handling table entry is inline inside
1520   // the index table entry on the second word (aka |indexDataAddr|). Otherwise,
1521   // the table points at an offset in the exception handling table (section 5
1522   // EHABI).
1523   pint_t exceptionTableAddr;
1524   uint32_t exceptionTableData;
1525   bool isSingleWordEHT;
1526   if (indexData & 0x80000000) {
1527     exceptionTableAddr = indexDataAddr;
1528     // TODO(ajwong): Should this data be 0?
1529     exceptionTableData = indexData;
1530     isSingleWordEHT = true;
1531   } else {
1532     exceptionTableAddr = indexDataAddr + signExtendPrel31(indexData);
1533     exceptionTableData = _addressSpace.get32(exceptionTableAddr);
1534     isSingleWordEHT = false;
1535   }
1536 
1537   // Now we know the 3 things:
1538   //   exceptionTableAddr -- exception handler table entry.
1539   //   exceptionTableData -- the data inside the first word of the eht entry.
1540   //   isSingleWordEHT -- whether the entry is in the index.
1541   unw_word_t personalityRoutine = 0xbadf00d;
1542   bool scope32 = false;
1543   uintptr_t lsda;
1544 
1545   // If the high bit in the exception handling table entry is set, the entry is
1546   // in compact form (section 6.3 EHABI).
1547   if (exceptionTableData & 0x80000000) {
1548     // Grab the index of the personality routine from the compact form.
1549     uint32_t choice = (exceptionTableData & 0x0f000000) >> 24;
1550     uint32_t extraWords = 0;
1551     switch (choice) {
1552       case 0:
1553         personalityRoutine = (unw_word_t) &__aeabi_unwind_cpp_pr0;
1554         extraWords = 0;
1555         scope32 = false;
1556         lsda = isSingleWordEHT ? 0 : (exceptionTableAddr + 4);
1557         break;
1558       case 1:
1559         personalityRoutine = (unw_word_t) &__aeabi_unwind_cpp_pr1;
1560         extraWords = (exceptionTableData & 0x00ff0000) >> 16;
1561         scope32 = false;
1562         lsda = exceptionTableAddr + (extraWords + 1) * 4;
1563         break;
1564       case 2:
1565         personalityRoutine = (unw_word_t) &__aeabi_unwind_cpp_pr2;
1566         extraWords = (exceptionTableData & 0x00ff0000) >> 16;
1567         scope32 = true;
1568         lsda = exceptionTableAddr + (extraWords + 1) * 4;
1569         break;
1570       default:
1571         _LIBUNWIND_ABORT("unknown personality routine");
1572         return false;
1573     }
1574 
1575     if (isSingleWordEHT) {
1576       if (extraWords != 0) {
1577         _LIBUNWIND_ABORT("index inlined table detected but pr function "
1578                          "requires extra words");
1579         return false;
1580       }
1581     }
1582   } else {
1583     pint_t personalityAddr =
1584         exceptionTableAddr + signExtendPrel31(exceptionTableData);
1585     personalityRoutine = personalityAddr;
1586 
1587     // ARM EHABI # 6.2, # 9.2
1588     //
1589     //  +---- ehtp
1590     //  v
1591     // +--------------------------------------+
1592     // | +--------+--------+--------+-------+ |
1593     // | |0| prel31 to personalityRoutine   | |
1594     // | +--------+--------+--------+-------+ |
1595     // | |      N |      unwind opcodes     | |  <-- UnwindData
1596     // | +--------+--------+--------+-------+ |
1597     // | | Word 2        unwind opcodes     | |
1598     // | +--------+--------+--------+-------+ |
1599     // | ...                                  |
1600     // | +--------+--------+--------+-------+ |
1601     // | | Word N        unwind opcodes     | |
1602     // | +--------+--------+--------+-------+ |
1603     // | | LSDA                             | |  <-- lsda
1604     // | | ...                              | |
1605     // | +--------+--------+--------+-------+ |
1606     // +--------------------------------------+
1607 
1608     uint32_t *UnwindData = reinterpret_cast<uint32_t*>(exceptionTableAddr) + 1;
1609     uint32_t FirstDataWord = *UnwindData;
1610     size_t N = ((FirstDataWord >> 24) & 0xff);
1611     size_t NDataWords = N + 1;
1612     lsda = reinterpret_cast<uintptr_t>(UnwindData + NDataWords);
1613   }
1614 
1615   _info.start_ip = thisPC;
1616   _info.end_ip = nextPC;
1617   _info.handler = personalityRoutine;
1618   _info.unwind_info = exceptionTableAddr;
1619   _info.lsda = lsda;
1620   // flags is pr_cache.additional. See EHABI #7.2 for definition of bit 0.
1621   _info.flags = (isSingleWordEHT ? 1 : 0) | (scope32 ? 0x2 : 0);  // Use enum?
1622 
1623   return true;
1624 }
1625 #endif
1626 
1627 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
1628 template <typename A, typename R>
1629 bool UnwindCursor<A, R>::getInfoFromFdeCie(
1630     const typename CFI_Parser<A>::FDE_Info &fdeInfo,
1631     const typename CFI_Parser<A>::CIE_Info &cieInfo, pint_t pc,
1632     uintptr_t dso_base) {
1633   typename CFI_Parser<A>::PrologInfo prolog;
1634   if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, cieInfo, pc,
1635                                           R::getArch(), &prolog)) {
1636     // Save off parsed FDE info
1637     _info.start_ip          = fdeInfo.pcStart;
1638     _info.end_ip            = fdeInfo.pcEnd;
1639     _info.lsda              = fdeInfo.lsda;
1640     _info.handler           = cieInfo.personality;
1641     // Some frameless functions need SP altered when resuming in function, so
1642     // propagate spExtraArgSize.
1643     _info.gp                = prolog.spExtraArgSize;
1644     _info.flags             = 0;
1645     _info.format            = dwarfEncoding();
1646     _info.unwind_info       = fdeInfo.fdeStart;
1647     _info.unwind_info_size  = static_cast<uint32_t>(fdeInfo.fdeLength);
1648     _info.extra             = static_cast<unw_word_t>(dso_base);
1649     return true;
1650   }
1651   return false;
1652 }
1653 
1654 template <typename A, typename R>
1655 bool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc,
1656                                                 const UnwindInfoSections &sects,
1657                                                 uint32_t fdeSectionOffsetHint) {
1658   typename CFI_Parser<A>::FDE_Info fdeInfo;
1659   typename CFI_Parser<A>::CIE_Info cieInfo;
1660   bool foundFDE = false;
1661   bool foundInCache = false;
1662   // If compact encoding table gave offset into dwarf section, go directly there
1663   if (fdeSectionOffsetHint != 0) {
1664     foundFDE = CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section,
1665                                     sects.dwarf_section_length,
1666                                     sects.dwarf_section + fdeSectionOffsetHint,
1667                                     &fdeInfo, &cieInfo);
1668   }
1669 #if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX)
1670   if (!foundFDE && (sects.dwarf_index_section != 0)) {
1671     foundFDE = EHHeaderParser<A>::findFDE(
1672         _addressSpace, pc, sects.dwarf_index_section,
1673         (uint32_t)sects.dwarf_index_section_length, &fdeInfo, &cieInfo);
1674   }
1675 #endif
1676   if (!foundFDE) {
1677     // otherwise, search cache of previously found FDEs.
1678     pint_t cachedFDE = DwarfFDECache<A>::findFDE(sects.dso_base, pc);
1679     if (cachedFDE != 0) {
1680       foundFDE =
1681           CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section,
1682                                  sects.dwarf_section_length,
1683                                  cachedFDE, &fdeInfo, &cieInfo);
1684       foundInCache = foundFDE;
1685     }
1686   }
1687   if (!foundFDE) {
1688     // Still not found, do full scan of __eh_frame section.
1689     foundFDE = CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section,
1690                                       sects.dwarf_section_length, 0,
1691                                       &fdeInfo, &cieInfo);
1692   }
1693   if (foundFDE) {
1694     if (getInfoFromFdeCie(fdeInfo, cieInfo, pc, sects.dso_base)) {
1695       // Add to cache (to make next lookup faster) if we had no hint
1696       // and there was no index.
1697       if (!foundInCache && (fdeSectionOffsetHint == 0)) {
1698   #if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX)
1699         if (sects.dwarf_index_section == 0)
1700   #endif
1701         DwarfFDECache<A>::add(sects.dso_base, fdeInfo.pcStart, fdeInfo.pcEnd,
1702                               fdeInfo.fdeStart);
1703       }
1704       return true;
1705     }
1706   }
1707   //_LIBUNWIND_DEBUG_LOG("can't find/use FDE for pc=0x%llX", (uint64_t)pc);
1708   return false;
1709 }
1710 #endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
1711 
1712 
1713 #if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
1714 template <typename A, typename R>
1715 bool UnwindCursor<A, R>::getInfoFromCompactEncodingSection(pint_t pc,
1716                                               const UnwindInfoSections &sects) {
1717   const bool log = false;
1718   if (log)
1719     fprintf(stderr, "getInfoFromCompactEncodingSection(pc=0x%llX, mh=0x%llX)\n",
1720             (uint64_t)pc, (uint64_t)sects.dso_base);
1721 
1722   const UnwindSectionHeader<A> sectionHeader(_addressSpace,
1723                                                 sects.compact_unwind_section);
1724   if (sectionHeader.version() != UNWIND_SECTION_VERSION)
1725     return false;
1726 
1727   // do a binary search of top level index to find page with unwind info
1728   pint_t targetFunctionOffset = pc - sects.dso_base;
1729   const UnwindSectionIndexArray<A> topIndex(_addressSpace,
1730                                            sects.compact_unwind_section
1731                                          + sectionHeader.indexSectionOffset());
1732   uint32_t low = 0;
1733   uint32_t high = sectionHeader.indexCount();
1734   uint32_t last = high - 1;
1735   while (low < high) {
1736     uint32_t mid = (low + high) / 2;
1737     //if ( log ) fprintf(stderr, "\tmid=%d, low=%d, high=%d, *mid=0x%08X\n",
1738     //mid, low, high, topIndex.functionOffset(mid));
1739     if (topIndex.functionOffset(mid) <= targetFunctionOffset) {
1740       if ((mid == last) ||
1741           (topIndex.functionOffset(mid + 1) > targetFunctionOffset)) {
1742         low = mid;
1743         break;
1744       } else {
1745         low = mid + 1;
1746       }
1747     } else {
1748       high = mid;
1749     }
1750   }
1751   const uint32_t firstLevelFunctionOffset = topIndex.functionOffset(low);
1752   const uint32_t firstLevelNextPageFunctionOffset =
1753       topIndex.functionOffset(low + 1);
1754   const pint_t secondLevelAddr =
1755       sects.compact_unwind_section + topIndex.secondLevelPagesSectionOffset(low);
1756   const pint_t lsdaArrayStartAddr =
1757       sects.compact_unwind_section + topIndex.lsdaIndexArraySectionOffset(low);
1758   const pint_t lsdaArrayEndAddr =
1759       sects.compact_unwind_section + topIndex.lsdaIndexArraySectionOffset(low+1);
1760   if (log)
1761     fprintf(stderr, "\tfirst level search for result index=%d "
1762                     "to secondLevelAddr=0x%llX\n",
1763                     low, (uint64_t) secondLevelAddr);
1764   // do a binary search of second level page index
1765   uint32_t encoding = 0;
1766   pint_t funcStart = 0;
1767   pint_t funcEnd = 0;
1768   pint_t lsda = 0;
1769   pint_t personality = 0;
1770   uint32_t pageKind = _addressSpace.get32(secondLevelAddr);
1771   if (pageKind == UNWIND_SECOND_LEVEL_REGULAR) {
1772     // regular page
1773     UnwindSectionRegularPageHeader<A> pageHeader(_addressSpace,
1774                                                  secondLevelAddr);
1775     UnwindSectionRegularArray<A> pageIndex(
1776         _addressSpace, secondLevelAddr + pageHeader.entryPageOffset());
1777     // binary search looks for entry with e where index[e].offset <= pc <
1778     // index[e+1].offset
1779     if (log)
1780       fprintf(stderr, "\tbinary search for targetFunctionOffset=0x%08llX in "
1781                       "regular page starting at secondLevelAddr=0x%llX\n",
1782               (uint64_t) targetFunctionOffset, (uint64_t) secondLevelAddr);
1783     low = 0;
1784     high = pageHeader.entryCount();
1785     while (low < high) {
1786       uint32_t mid = (low + high) / 2;
1787       if (pageIndex.functionOffset(mid) <= targetFunctionOffset) {
1788         if (mid == (uint32_t)(pageHeader.entryCount() - 1)) {
1789           // at end of table
1790           low = mid;
1791           funcEnd = firstLevelNextPageFunctionOffset + sects.dso_base;
1792           break;
1793         } else if (pageIndex.functionOffset(mid + 1) > targetFunctionOffset) {
1794           // next is too big, so we found it
1795           low = mid;
1796           funcEnd = pageIndex.functionOffset(low + 1) + sects.dso_base;
1797           break;
1798         } else {
1799           low = mid + 1;
1800         }
1801       } else {
1802         high = mid;
1803       }
1804     }
1805     encoding = pageIndex.encoding(low);
1806     funcStart = pageIndex.functionOffset(low) + sects.dso_base;
1807     if (pc < funcStart) {
1808       if (log)
1809         fprintf(
1810             stderr,
1811             "\tpc not in table, pc=0x%llX, funcStart=0x%llX, funcEnd=0x%llX\n",
1812             (uint64_t) pc, (uint64_t) funcStart, (uint64_t) funcEnd);
1813       return false;
1814     }
1815     if (pc > funcEnd) {
1816       if (log)
1817         fprintf(
1818             stderr,
1819             "\tpc not in table, pc=0x%llX, funcStart=0x%llX, funcEnd=0x%llX\n",
1820             (uint64_t) pc, (uint64_t) funcStart, (uint64_t) funcEnd);
1821       return false;
1822     }
1823   } else if (pageKind == UNWIND_SECOND_LEVEL_COMPRESSED) {
1824     // compressed page
1825     UnwindSectionCompressedPageHeader<A> pageHeader(_addressSpace,
1826                                                     secondLevelAddr);
1827     UnwindSectionCompressedArray<A> pageIndex(
1828         _addressSpace, secondLevelAddr + pageHeader.entryPageOffset());
1829     const uint32_t targetFunctionPageOffset =
1830         (uint32_t)(targetFunctionOffset - firstLevelFunctionOffset);
1831     // binary search looks for entry with e where index[e].offset <= pc <
1832     // index[e+1].offset
1833     if (log)
1834       fprintf(stderr, "\tbinary search of compressed page starting at "
1835                       "secondLevelAddr=0x%llX\n",
1836               (uint64_t) secondLevelAddr);
1837     low = 0;
1838     last = pageHeader.entryCount() - 1;
1839     high = pageHeader.entryCount();
1840     while (low < high) {
1841       uint32_t mid = (low + high) / 2;
1842       if (pageIndex.functionOffset(mid) <= targetFunctionPageOffset) {
1843         if ((mid == last) ||
1844             (pageIndex.functionOffset(mid + 1) > targetFunctionPageOffset)) {
1845           low = mid;
1846           break;
1847         } else {
1848           low = mid + 1;
1849         }
1850       } else {
1851         high = mid;
1852       }
1853     }
1854     funcStart = pageIndex.functionOffset(low) + firstLevelFunctionOffset
1855                                                               + sects.dso_base;
1856     if (low < last)
1857       funcEnd =
1858           pageIndex.functionOffset(low + 1) + firstLevelFunctionOffset
1859                                                               + sects.dso_base;
1860     else
1861       funcEnd = firstLevelNextPageFunctionOffset + sects.dso_base;
1862     if (pc < funcStart) {
1863       _LIBUNWIND_DEBUG_LOG("malformed __unwind_info, pc=0x%llX "
1864                            "not in second level compressed unwind table. "
1865                            "funcStart=0x%llX",
1866                             (uint64_t) pc, (uint64_t) funcStart);
1867       return false;
1868     }
1869     if (pc > funcEnd) {
1870       _LIBUNWIND_DEBUG_LOG("malformed __unwind_info, pc=0x%llX "
1871                            "not in second level compressed unwind table. "
1872                            "funcEnd=0x%llX",
1873                            (uint64_t) pc, (uint64_t) funcEnd);
1874       return false;
1875     }
1876     uint16_t encodingIndex = pageIndex.encodingIndex(low);
1877     if (encodingIndex < sectionHeader.commonEncodingsArrayCount()) {
1878       // encoding is in common table in section header
1879       encoding = _addressSpace.get32(
1880           sects.compact_unwind_section +
1881           sectionHeader.commonEncodingsArraySectionOffset() +
1882           encodingIndex * sizeof(uint32_t));
1883     } else {
1884       // encoding is in page specific table
1885       uint16_t pageEncodingIndex =
1886           encodingIndex - (uint16_t)sectionHeader.commonEncodingsArrayCount();
1887       encoding = _addressSpace.get32(secondLevelAddr +
1888                                      pageHeader.encodingsPageOffset() +
1889                                      pageEncodingIndex * sizeof(uint32_t));
1890     }
1891   } else {
1892     _LIBUNWIND_DEBUG_LOG(
1893         "malformed __unwind_info at 0x%0llX bad second level page",
1894         (uint64_t)sects.compact_unwind_section);
1895     return false;
1896   }
1897 
1898   // look up LSDA, if encoding says function has one
1899   if (encoding & UNWIND_HAS_LSDA) {
1900     UnwindSectionLsdaArray<A> lsdaIndex(_addressSpace, lsdaArrayStartAddr);
1901     uint32_t funcStartOffset = (uint32_t)(funcStart - sects.dso_base);
1902     low = 0;
1903     high = (uint32_t)(lsdaArrayEndAddr - lsdaArrayStartAddr) /
1904                     sizeof(unwind_info_section_header_lsda_index_entry);
1905     // binary search looks for entry with exact match for functionOffset
1906     if (log)
1907       fprintf(stderr,
1908               "\tbinary search of lsda table for targetFunctionOffset=0x%08X\n",
1909               funcStartOffset);
1910     while (low < high) {
1911       uint32_t mid = (low + high) / 2;
1912       if (lsdaIndex.functionOffset(mid) == funcStartOffset) {
1913         lsda = lsdaIndex.lsdaOffset(mid) + sects.dso_base;
1914         break;
1915       } else if (lsdaIndex.functionOffset(mid) < funcStartOffset) {
1916         low = mid + 1;
1917       } else {
1918         high = mid;
1919       }
1920     }
1921     if (lsda == 0) {
1922       _LIBUNWIND_DEBUG_LOG("found encoding 0x%08X with HAS_LSDA bit set for "
1923                     "pc=0x%0llX, but lsda table has no entry",
1924                     encoding, (uint64_t) pc);
1925       return false;
1926     }
1927   }
1928 
1929   // extract personality routine, if encoding says function has one
1930   uint32_t personalityIndex = (encoding & UNWIND_PERSONALITY_MASK) >>
1931                               (__builtin_ctz(UNWIND_PERSONALITY_MASK));
1932   if (personalityIndex != 0) {
1933     --personalityIndex; // change 1-based to zero-based index
1934     if (personalityIndex >= sectionHeader.personalityArrayCount()) {
1935       _LIBUNWIND_DEBUG_LOG("found encoding 0x%08X with personality index %d,  "
1936                             "but personality table has only %d entries",
1937                             encoding, personalityIndex,
1938                             sectionHeader.personalityArrayCount());
1939       return false;
1940     }
1941     int32_t personalityDelta = (int32_t)_addressSpace.get32(
1942         sects.compact_unwind_section +
1943         sectionHeader.personalityArraySectionOffset() +
1944         personalityIndex * sizeof(uint32_t));
1945     pint_t personalityPointer = sects.dso_base + (pint_t)personalityDelta;
1946     personality = _addressSpace.getP(personalityPointer);
1947     if (log)
1948       fprintf(stderr, "getInfoFromCompactEncodingSection(pc=0x%llX), "
1949                       "personalityDelta=0x%08X, personality=0x%08llX\n",
1950               (uint64_t) pc, personalityDelta, (uint64_t) personality);
1951   }
1952 
1953   if (log)
1954     fprintf(stderr, "getInfoFromCompactEncodingSection(pc=0x%llX), "
1955                     "encoding=0x%08X, lsda=0x%08llX for funcStart=0x%llX\n",
1956             (uint64_t) pc, encoding, (uint64_t) lsda, (uint64_t) funcStart);
1957   _info.start_ip = funcStart;
1958   _info.end_ip = funcEnd;
1959   _info.lsda = lsda;
1960   _info.handler = personality;
1961   _info.gp = 0;
1962   _info.flags = 0;
1963   _info.format = encoding;
1964   _info.unwind_info = 0;
1965   _info.unwind_info_size = 0;
1966   _info.extra = sects.dso_base;
1967   return true;
1968 }
1969 #endif // defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
1970 
1971 
1972 #if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
1973 template <typename A, typename R>
1974 bool UnwindCursor<A, R>::getInfoFromSEH(pint_t pc) {
1975   pint_t base;
1976   RUNTIME_FUNCTION *unwindEntry = lookUpSEHUnwindInfo(pc, &base);
1977   if (!unwindEntry) {
1978     _LIBUNWIND_DEBUG_LOG("\tpc not in table, pc=0x%llX", (uint64_t) pc);
1979     return false;
1980   }
1981   _info.gp = 0;
1982   _info.flags = 0;
1983   _info.format = 0;
1984   _info.unwind_info_size = sizeof(RUNTIME_FUNCTION);
1985   _info.unwind_info = reinterpret_cast<unw_word_t>(unwindEntry);
1986   _info.extra = base;
1987   _info.start_ip = base + unwindEntry->BeginAddress;
1988 #ifdef _LIBUNWIND_TARGET_X86_64
1989   _info.end_ip = base + unwindEntry->EndAddress;
1990   // Only fill in the handler and LSDA if they're stale.
1991   if (pc != getLastPC()) {
1992     UNWIND_INFO *xdata = reinterpret_cast<UNWIND_INFO *>(base + unwindEntry->UnwindData);
1993     if (xdata->Flags & (UNW_FLAG_EHANDLER|UNW_FLAG_UHANDLER)) {
1994       // The personality is given in the UNWIND_INFO itself. The LSDA immediately
1995       // follows the UNWIND_INFO. (This follows how both Clang and MSVC emit
1996       // these structures.)
1997       // N.B. UNWIND_INFO structs are DWORD-aligned.
1998       uint32_t lastcode = (xdata->CountOfCodes + 1) & ~1;
1999       const uint32_t *handler = reinterpret_cast<uint32_t *>(&xdata->UnwindCodes[lastcode]);
2000       _info.lsda = reinterpret_cast<unw_word_t>(handler+1);
2001       _dispContext.HandlerData = reinterpret_cast<void *>(_info.lsda);
2002       _dispContext.LanguageHandler =
2003           reinterpret_cast<EXCEPTION_ROUTINE *>(base + *handler);
2004       if (*handler) {
2005         _info.handler = reinterpret_cast<unw_word_t>(__libunwind_seh_personality);
2006       } else
2007         _info.handler = 0;
2008     } else {
2009       _info.lsda = 0;
2010       _info.handler = 0;
2011     }
2012   }
2013 #endif
2014   setLastPC(pc);
2015   return true;
2016 }
2017 #endif
2018 
2019 #if defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND)
2020 // Masks for traceback table field xtbtable.
2021 enum xTBTableMask : uint8_t {
2022   reservedBit = 0x02, // The traceback table was incorrectly generated if set
2023                       // (see comments in function getInfoFromTBTable().
2024   ehInfoBit = 0x08    // Exception handling info is present if set
2025 };
2026 
2027 enum frameType : unw_word_t {
2028   frameWithXLEHStateTable = 0,
2029   frameWithEHInfo = 1
2030 };
2031 
2032 extern "C" {
2033 typedef _Unwind_Reason_Code __xlcxx_personality_v0_t(int, _Unwind_Action,
2034                                                      uint64_t,
2035                                                      _Unwind_Exception *,
2036                                                      struct _Unwind_Context *);
2037 __attribute__((__weak__)) __xlcxx_personality_v0_t __xlcxx_personality_v0;
2038 }
2039 
2040 static __xlcxx_personality_v0_t *xlcPersonalityV0;
2041 static RWMutex xlcPersonalityV0InitLock;
2042 
2043 template <typename A, typename R>
2044 bool UnwindCursor<A, R>::getInfoFromTBTable(pint_t pc, R &registers) {
2045   uint32_t *p = reinterpret_cast<uint32_t *>(pc);
2046 
2047   // Keep looking forward until a word of 0 is found. The traceback
2048   // table starts at the following word.
2049   while (*p)
2050     ++p;
2051   tbtable *TBTable = reinterpret_cast<tbtable *>(p + 1);
2052 
2053   if (_LIBUNWIND_TRACING_UNWINDING) {
2054     char functionBuf[512];
2055     const char *functionName = functionBuf;
2056     unw_word_t offset;
2057     if (!getFunctionName(functionBuf, sizeof(functionBuf), &offset)) {
2058       functionName = ".anonymous.";
2059     }
2060     _LIBUNWIND_TRACE_UNWINDING("%s: Look up traceback table of func=%s at %p",
2061                                __func__, functionName,
2062                                reinterpret_cast<void *>(TBTable));
2063   }
2064 
2065   // If the traceback table does not contain necessary info, bypass this frame.
2066   if (!TBTable->tb.has_tboff)
2067     return false;
2068 
2069   // Structure tbtable_ext contains important data we are looking for.
2070   p = reinterpret_cast<uint32_t *>(&TBTable->tb_ext);
2071 
2072   // Skip field parminfo if it exists.
2073   if (TBTable->tb.fixedparms || TBTable->tb.floatparms)
2074     ++p;
2075 
2076   // p now points to tb_offset, the offset from start of function to TB table.
2077   unw_word_t start_ip =
2078       reinterpret_cast<unw_word_t>(TBTable) - *p - sizeof(uint32_t);
2079   unw_word_t end_ip = reinterpret_cast<unw_word_t>(TBTable);
2080   ++p;
2081 
2082   _LIBUNWIND_TRACE_UNWINDING("start_ip=%p, end_ip=%p\n",
2083                              reinterpret_cast<void *>(start_ip),
2084                              reinterpret_cast<void *>(end_ip));
2085 
2086   // Skip field hand_mask if it exists.
2087   if (TBTable->tb.int_hndl)
2088     ++p;
2089 
2090   unw_word_t lsda = 0;
2091   unw_word_t handler = 0;
2092   unw_word_t flags = frameType::frameWithXLEHStateTable;
2093 
2094   if (TBTable->tb.lang == TB_CPLUSPLUS && TBTable->tb.has_ctl) {
2095     // State table info is available. The ctl_info field indicates the
2096     // number of CTL anchors. There should be only one entry for the C++
2097     // state table.
2098     assert(*p == 1 && "libunwind: there must be only one ctl_info entry");
2099     ++p;
2100     // p points to the offset of the state table into the stack.
2101     pint_t stateTableOffset = *p++;
2102 
2103     int framePointerReg;
2104 
2105     // Skip fields name_len and name if exist.
2106     if (TBTable->tb.name_present) {
2107       const uint16_t name_len = *(reinterpret_cast<uint16_t *>(p));
2108       p = reinterpret_cast<uint32_t *>(reinterpret_cast<char *>(p) + name_len +
2109                                        sizeof(uint16_t));
2110     }
2111 
2112     if (TBTable->tb.uses_alloca)
2113       framePointerReg = *(reinterpret_cast<char *>(p));
2114     else
2115       framePointerReg = 1; // default frame pointer == SP
2116 
2117     _LIBUNWIND_TRACE_UNWINDING(
2118         "framePointerReg=%d, framePointer=%p, "
2119         "stateTableOffset=%#lx\n",
2120         framePointerReg,
2121         reinterpret_cast<void *>(_registers.getRegister(framePointerReg)),
2122         stateTableOffset);
2123     lsda = _registers.getRegister(framePointerReg) + stateTableOffset;
2124 
2125     // Since the traceback table generated by the legacy XLC++ does not
2126     // provide the location of the personality for the state table,
2127     // function __xlcxx_personality_v0(), which is the personality for the state
2128     // table and is exported from libc++abi, is directly assigned as the
2129     // handler here. When a legacy XLC++ frame is encountered, the symbol
2130     // is resolved dynamically using dlopen() to avoid hard dependency from
2131     // libunwind on libc++abi.
2132 
2133     // Resolve the function pointer to the state table personality if it has
2134     // not already.
2135     if (xlcPersonalityV0 == NULL) {
2136       xlcPersonalityV0InitLock.lock();
2137       if (xlcPersonalityV0 == NULL) {
2138         // If libc++abi is statically linked in, symbol __xlcxx_personality_v0
2139         // has been resolved at the link time.
2140         xlcPersonalityV0 = &__xlcxx_personality_v0;
2141         if (xlcPersonalityV0 == NULL) {
2142           // libc++abi is dynamically linked. Resolve __xlcxx_personality_v0
2143           // using dlopen().
2144           const char libcxxabi[] = "libc++abi.a(libc++abi.so.1)";
2145           void *libHandle;
2146           // The AIX dlopen() sets errno to 0 when it is successful, which
2147           // clobbers the value of errno from the user code. This is an AIX
2148           // bug because according to POSIX it should not set errno to 0. To
2149           // workaround before AIX fixes the bug, errno is saved and restored.
2150           int saveErrno = errno;
2151           libHandle = dlopen(libcxxabi, RTLD_MEMBER | RTLD_NOW);
2152           if (libHandle == NULL) {
2153             _LIBUNWIND_TRACE_UNWINDING("dlopen() failed with errno=%d\n",
2154                                        errno);
2155             assert(0 && "dlopen() failed");
2156           }
2157           xlcPersonalityV0 = reinterpret_cast<__xlcxx_personality_v0_t *>(
2158               dlsym(libHandle, "__xlcxx_personality_v0"));
2159           if (xlcPersonalityV0 == NULL) {
2160             _LIBUNWIND_TRACE_UNWINDING("dlsym() failed with errno=%d\n", errno);
2161             assert(0 && "dlsym() failed");
2162           }
2163           dlclose(libHandle);
2164           errno = saveErrno;
2165         }
2166       }
2167       xlcPersonalityV0InitLock.unlock();
2168     }
2169     handler = reinterpret_cast<unw_word_t>(xlcPersonalityV0);
2170     _LIBUNWIND_TRACE_UNWINDING("State table: LSDA=%p, Personality=%p\n",
2171                                reinterpret_cast<void *>(lsda),
2172                                reinterpret_cast<void *>(handler));
2173   } else if (TBTable->tb.longtbtable) {
2174     // This frame has the traceback table extension. Possible cases are
2175     // 1) a C++ frame that has the 'eh_info' structure; 2) a C++ frame that
2176     // is not EH aware; or, 3) a frame of other languages. We need to figure out
2177     // if the traceback table extension contains the 'eh_info' structure.
2178     //
2179     // We also need to deal with the complexity arising from some XL compiler
2180     // versions use the wrong ordering of 'longtbtable' and 'has_vec' bits
2181     // where the 'longtbtable' bit is meant to be the 'has_vec' bit and vice
2182     // versa. For frames of code generated by those compilers, the 'longtbtable'
2183     // bit may be set but there isn't really a traceback table extension.
2184     //
2185     // In </usr/include/sys/debug.h>, there is the following definition of
2186     // 'struct tbtable_ext'. It is not really a structure but a dummy to
2187     // collect the description of optional parts of the traceback table.
2188     //
2189     // struct tbtable_ext {
2190     //   ...
2191     //   char alloca_reg;        /* Register for alloca automatic storage */
2192     //   struct vec_ext vec_ext; /* Vector extension (if has_vec is set) */
2193     //   unsigned char xtbtable; /* More tbtable fields, if longtbtable is set*/
2194     // };
2195     //
2196     // Depending on how the 'has_vec'/'longtbtable' bit is interpreted, the data
2197     // following 'alloca_reg' can be treated either as 'struct vec_ext' or
2198     // 'unsigned char xtbtable'. 'xtbtable' bits are defined in
2199     // </usr/include/sys/debug.h> as flags. The 7th bit '0x02' is currently
2200     // unused and should not be set. 'struct vec_ext' is defined in
2201     // </usr/include/sys/debug.h> as follows:
2202     //
2203     // struct vec_ext {
2204     //   unsigned vr_saved:6;      /* Number of non-volatile vector regs saved
2205     //   */
2206     //                             /* first register saved is assumed to be */
2207     //                             /* 32 - vr_saved                         */
2208     //   unsigned saves_vrsave:1;  /* Set if vrsave is saved on the stack */
2209     //   unsigned has_varargs:1;
2210     //   ...
2211     // };
2212     //
2213     // Here, the 7th bit is used as 'saves_vrsave'. To determine whether it
2214     // is 'struct vec_ext' or 'xtbtable' that follows 'alloca_reg',
2215     // we checks if the 7th bit is set or not because 'xtbtable' should
2216     // never have the 7th bit set. The 7th bit of 'xtbtable' will be reserved
2217     // in the future to make sure the mitigation works. This mitigation
2218     // is not 100% bullet proof because 'struct vec_ext' may not always have
2219     // 'saves_vrsave' bit set.
2220     //
2221     // 'reservedBit' is defined in enum 'xTBTableMask' above as the mask for
2222     // checking the 7th bit.
2223 
2224     // p points to field name len.
2225     uint8_t *charPtr = reinterpret_cast<uint8_t *>(p);
2226 
2227     // Skip fields name_len and name if they exist.
2228     if (TBTable->tb.name_present) {
2229       const uint16_t name_len = *(reinterpret_cast<uint16_t *>(charPtr));
2230       charPtr = charPtr + name_len + sizeof(uint16_t);
2231     }
2232 
2233     // Skip field alloc_reg if it exists.
2234     if (TBTable->tb.uses_alloca)
2235       ++charPtr;
2236 
2237     // Check traceback table bit has_vec. Skip struct vec_ext if it exists.
2238     if (TBTable->tb.has_vec)
2239       // Note struct vec_ext does exist at this point because whether the
2240       // ordering of longtbtable and has_vec bits is correct or not, both
2241       // are set.
2242       charPtr += sizeof(struct vec_ext);
2243 
2244     // charPtr points to field 'xtbtable'. Check if the EH info is available.
2245     // Also check if the reserved bit of the extended traceback table field
2246     // 'xtbtable' is set. If it is, the traceback table was incorrectly
2247     // generated by an XL compiler that uses the wrong ordering of 'longtbtable'
2248     // and 'has_vec' bits and this is in fact 'struct vec_ext'. So skip the
2249     // frame.
2250     if ((*charPtr & xTBTableMask::ehInfoBit) &&
2251         !(*charPtr & xTBTableMask::reservedBit)) {
2252       // Mark this frame has the new EH info.
2253       flags = frameType::frameWithEHInfo;
2254 
2255       // eh_info is available.
2256       charPtr++;
2257       // The pointer is 4-byte aligned.
2258       if (reinterpret_cast<uintptr_t>(charPtr) % 4)
2259         charPtr += 4 - reinterpret_cast<uintptr_t>(charPtr) % 4;
2260       uintptr_t *ehInfo =
2261           reinterpret_cast<uintptr_t *>(*(reinterpret_cast<uintptr_t *>(
2262               registers.getRegister(2) +
2263               *(reinterpret_cast<uintptr_t *>(charPtr)))));
2264 
2265       // ehInfo points to structure en_info. The first member is version.
2266       // Only version 0 is currently supported.
2267       assert(*(reinterpret_cast<uint32_t *>(ehInfo)) == 0 &&
2268              "libunwind: ehInfo version other than 0 is not supported");
2269 
2270       // Increment ehInfo to point to member lsda.
2271       ++ehInfo;
2272       lsda = *ehInfo++;
2273 
2274       // enInfo now points to member personality.
2275       handler = *ehInfo;
2276 
2277       _LIBUNWIND_TRACE_UNWINDING("Range table: LSDA=%#lx, Personality=%#lx\n",
2278                                  lsda, handler);
2279     }
2280   }
2281 
2282   _info.start_ip = start_ip;
2283   _info.end_ip = end_ip;
2284   _info.lsda = lsda;
2285   _info.handler = handler;
2286   _info.gp = 0;
2287   _info.flags = flags;
2288   _info.format = 0;
2289   _info.unwind_info = reinterpret_cast<unw_word_t>(TBTable);
2290   _info.unwind_info_size = 0;
2291   _info.extra = registers.getRegister(2);
2292 
2293   return true;
2294 }
2295 
2296 // Step back up the stack following the frame back link.
2297 template <typename A, typename R>
2298 int UnwindCursor<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable,
2299                                         R &registers, bool &isSignalFrame) {
2300   if (_LIBUNWIND_TRACING_UNWINDING) {
2301     char functionBuf[512];
2302     const char *functionName = functionBuf;
2303     unw_word_t offset;
2304     if (!getFunctionName(functionBuf, sizeof(functionBuf), &offset)) {
2305       functionName = ".anonymous.";
2306     }
2307     _LIBUNWIND_TRACE_UNWINDING(
2308         "%s: Look up traceback table of func=%s at %p, pc=%p, "
2309         "SP=%p, saves_lr=%d, stores_bc=%d",
2310         __func__, functionName, reinterpret_cast<void *>(TBTable),
2311         reinterpret_cast<void *>(pc),
2312         reinterpret_cast<void *>(registers.getSP()), TBTable->tb.saves_lr,
2313         TBTable->tb.stores_bc);
2314   }
2315 
2316 #if defined(__powerpc64__)
2317   // Instruction to reload TOC register "ld r2,40(r1)"
2318   const uint32_t loadTOCRegInst = 0xe8410028;
2319   const int32_t unwPPCF0Index = UNW_PPC64_F0;
2320   const int32_t unwPPCV0Index = UNW_PPC64_V0;
2321 #else
2322   // Instruction to reload TOC register "lwz r2,20(r1)"
2323   const uint32_t loadTOCRegInst = 0x80410014;
2324   const int32_t unwPPCF0Index = UNW_PPC_F0;
2325   const int32_t unwPPCV0Index = UNW_PPC_V0;
2326 #endif
2327 
2328   // lastStack points to the stack frame of the next routine up.
2329   pint_t curStack = static_cast<pint_t>(registers.getSP());
2330   pint_t lastStack = *reinterpret_cast<pint_t *>(curStack);
2331 
2332   if (lastStack == 0)
2333     return UNW_STEP_END;
2334 
2335   R newRegisters = registers;
2336 
2337   // If backchain is not stored, use the current stack frame.
2338   if (!TBTable->tb.stores_bc)
2339     lastStack = curStack;
2340 
2341   // Return address is the address after call site instruction.
2342   pint_t returnAddress;
2343 
2344   if (isSignalFrame) {
2345     _LIBUNWIND_TRACE_UNWINDING("Possible signal handler frame: lastStack=%p",
2346                                reinterpret_cast<void *>(lastStack));
2347 
2348     sigcontext *sigContext = reinterpret_cast<sigcontext *>(
2349         reinterpret_cast<char *>(lastStack) + STKMINALIGN);
2350     returnAddress = sigContext->sc_jmpbuf.jmp_context.iar;
2351 
2352     bool useSTKMIN = false;
2353     if (returnAddress < 0x10000000) {
2354       // Try again using STKMIN.
2355       sigContext = reinterpret_cast<sigcontext *>(
2356           reinterpret_cast<char *>(lastStack) + STKMIN);
2357       returnAddress = sigContext->sc_jmpbuf.jmp_context.iar;
2358       if (returnAddress < 0x10000000) {
2359         _LIBUNWIND_TRACE_UNWINDING("Bad returnAddress=%p from sigcontext=%p",
2360                                    reinterpret_cast<void *>(returnAddress),
2361                                    reinterpret_cast<void *>(sigContext));
2362         return UNW_EBADFRAME;
2363       }
2364       useSTKMIN = true;
2365     }
2366     _LIBUNWIND_TRACE_UNWINDING("Returning from a signal handler %s: "
2367                                "sigContext=%p, returnAddress=%p. "
2368                                "Seems to be a valid address",
2369                                useSTKMIN ? "STKMIN" : "STKMINALIGN",
2370                                reinterpret_cast<void *>(sigContext),
2371                                reinterpret_cast<void *>(returnAddress));
2372 
2373     // Restore the condition register from sigcontext.
2374     newRegisters.setCR(sigContext->sc_jmpbuf.jmp_context.cr);
2375 
2376     // Save the LR in sigcontext for stepping up when the function that
2377     // raised the signal is a leaf function. This LR has the return address
2378     // to the caller of the leaf function.
2379     newRegisters.setLR(sigContext->sc_jmpbuf.jmp_context.lr);
2380     _LIBUNWIND_TRACE_UNWINDING(
2381         "Save LR=%p from sigcontext",
2382         reinterpret_cast<void *>(sigContext->sc_jmpbuf.jmp_context.lr));
2383 
2384     // Restore GPRs from sigcontext.
2385     for (int i = 0; i < 32; ++i)
2386       newRegisters.setRegister(i, sigContext->sc_jmpbuf.jmp_context.gpr[i]);
2387 
2388     // Restore FPRs from sigcontext.
2389     for (int i = 0; i < 32; ++i)
2390       newRegisters.setFloatRegister(i + unwPPCF0Index,
2391                                     sigContext->sc_jmpbuf.jmp_context.fpr[i]);
2392 
2393     // Restore vector registers if there is an associated extended context
2394     // structure.
2395     if (sigContext->sc_jmpbuf.jmp_context.msr & __EXTCTX) {
2396       ucontext_t *uContext = reinterpret_cast<ucontext_t *>(sigContext);
2397       if (uContext->__extctx->__extctx_magic == __EXTCTX_MAGIC) {
2398         for (int i = 0; i < 32; ++i)
2399           newRegisters.setVectorRegister(
2400               i + unwPPCV0Index, *(reinterpret_cast<v128 *>(
2401                                      &(uContext->__extctx->__vmx.__vr[i]))));
2402       }
2403     }
2404   } else {
2405     // Step up a normal frame.
2406 
2407     if (!TBTable->tb.saves_lr && registers.getLR()) {
2408       // This case should only occur if we were called from a signal handler
2409       // and the signal occurred in a function that doesn't save the LR.
2410       returnAddress = static_cast<pint_t>(registers.getLR());
2411       _LIBUNWIND_TRACE_UNWINDING("Use saved LR=%p",
2412                                  reinterpret_cast<void *>(returnAddress));
2413     } else {
2414       // Otherwise, use the LR value in the stack link area.
2415       returnAddress = reinterpret_cast<pint_t *>(lastStack)[2];
2416     }
2417 
2418     // Reset LR in the current context.
2419     newRegisters.setLR(NULL);
2420 
2421     _LIBUNWIND_TRACE_UNWINDING(
2422         "Extract info from lastStack=%p, returnAddress=%p",
2423         reinterpret_cast<void *>(lastStack),
2424         reinterpret_cast<void *>(returnAddress));
2425     _LIBUNWIND_TRACE_UNWINDING("fpr_regs=%d, gpr_regs=%d, saves_cr=%d",
2426                                TBTable->tb.fpr_saved, TBTable->tb.gpr_saved,
2427                                TBTable->tb.saves_cr);
2428 
2429     // Restore FP registers.
2430     char *ptrToRegs = reinterpret_cast<char *>(lastStack);
2431     double *FPRegs = reinterpret_cast<double *>(
2432         ptrToRegs - (TBTable->tb.fpr_saved * sizeof(double)));
2433     for (int i = 0; i < TBTable->tb.fpr_saved; ++i)
2434       newRegisters.setFloatRegister(
2435           32 - TBTable->tb.fpr_saved + i + unwPPCF0Index, FPRegs[i]);
2436 
2437     // Restore GP registers.
2438     ptrToRegs = reinterpret_cast<char *>(FPRegs);
2439     uintptr_t *GPRegs = reinterpret_cast<uintptr_t *>(
2440         ptrToRegs - (TBTable->tb.gpr_saved * sizeof(uintptr_t)));
2441     for (int i = 0; i < TBTable->tb.gpr_saved; ++i)
2442       newRegisters.setRegister(32 - TBTable->tb.gpr_saved + i, GPRegs[i]);
2443 
2444     // Restore Vector registers.
2445     ptrToRegs = reinterpret_cast<char *>(GPRegs);
2446 
2447     // Restore vector registers only if this is a Clang frame. Also
2448     // check if traceback table bit has_vec is set. If it is, structure
2449     // vec_ext is available.
2450     if (_info.flags == frameType::frameWithEHInfo && TBTable->tb.has_vec) {
2451 
2452       // Get to the vec_ext structure to check if vector registers are saved.
2453       uint32_t *p = reinterpret_cast<uint32_t *>(&TBTable->tb_ext);
2454 
2455       // Skip field parminfo if exists.
2456       if (TBTable->tb.fixedparms || TBTable->tb.floatparms)
2457         ++p;
2458 
2459       // Skip field tb_offset if exists.
2460       if (TBTable->tb.has_tboff)
2461         ++p;
2462 
2463       // Skip field hand_mask if exists.
2464       if (TBTable->tb.int_hndl)
2465         ++p;
2466 
2467       // Skip fields ctl_info and ctl_info_disp if exist.
2468       if (TBTable->tb.has_ctl) {
2469         // Skip field ctl_info.
2470         ++p;
2471         // Skip field ctl_info_disp.
2472         ++p;
2473       }
2474 
2475       // Skip fields name_len and name if exist.
2476       // p is supposed to point to field name_len now.
2477       uint8_t *charPtr = reinterpret_cast<uint8_t *>(p);
2478       if (TBTable->tb.name_present) {
2479         const uint16_t name_len = *(reinterpret_cast<uint16_t *>(charPtr));
2480         charPtr = charPtr + name_len + sizeof(uint16_t);
2481       }
2482 
2483       // Skip field alloc_reg if it exists.
2484       if (TBTable->tb.uses_alloca)
2485         ++charPtr;
2486 
2487       struct vec_ext *vec_ext = reinterpret_cast<struct vec_ext *>(charPtr);
2488 
2489       _LIBUNWIND_TRACE_UNWINDING("vr_saved=%d", vec_ext->vr_saved);
2490 
2491       // Restore vector register(s) if saved on the stack.
2492       if (vec_ext->vr_saved) {
2493         // Saved vector registers are 16-byte aligned.
2494         if (reinterpret_cast<uintptr_t>(ptrToRegs) % 16)
2495           ptrToRegs -= reinterpret_cast<uintptr_t>(ptrToRegs) % 16;
2496         v128 *VecRegs = reinterpret_cast<v128 *>(ptrToRegs - vec_ext->vr_saved *
2497                                                                  sizeof(v128));
2498         for (int i = 0; i < vec_ext->vr_saved; ++i) {
2499           newRegisters.setVectorRegister(
2500               32 - vec_ext->vr_saved + i + unwPPCV0Index, VecRegs[i]);
2501         }
2502       }
2503     }
2504     if (TBTable->tb.saves_cr) {
2505       // Get the saved condition register. The condition register is only
2506       // a single word.
2507       newRegisters.setCR(
2508           *(reinterpret_cast<uint32_t *>(lastStack + sizeof(uintptr_t))));
2509     }
2510 
2511     // Restore the SP.
2512     newRegisters.setSP(lastStack);
2513 
2514     // The first instruction after return.
2515     uint32_t firstInstruction = *(reinterpret_cast<uint32_t *>(returnAddress));
2516 
2517     // Do we need to set the TOC register?
2518     _LIBUNWIND_TRACE_UNWINDING(
2519         "Current gpr2=%p",
2520         reinterpret_cast<void *>(newRegisters.getRegister(2)));
2521     if (firstInstruction == loadTOCRegInst) {
2522       _LIBUNWIND_TRACE_UNWINDING(
2523           "Set gpr2=%p from frame",
2524           reinterpret_cast<void *>(reinterpret_cast<pint_t *>(lastStack)[5]));
2525       newRegisters.setRegister(2, reinterpret_cast<pint_t *>(lastStack)[5]);
2526     }
2527   }
2528   _LIBUNWIND_TRACE_UNWINDING("lastStack=%p, returnAddress=%p, pc=%p\n",
2529                              reinterpret_cast<void *>(lastStack),
2530                              reinterpret_cast<void *>(returnAddress),
2531                              reinterpret_cast<void *>(pc));
2532 
2533   // The return address is the address after call site instruction, so
2534   // setting IP to that simulates a return.
2535   newRegisters.setIP(reinterpret_cast<uintptr_t>(returnAddress));
2536 
2537   // Simulate the step by replacing the register set with the new ones.
2538   registers = newRegisters;
2539 
2540   // Check if the next frame is a signal frame.
2541   pint_t nextStack = *(reinterpret_cast<pint_t *>(registers.getSP()));
2542 
2543   // Return address is the address after call site instruction.
2544   pint_t nextReturnAddress = reinterpret_cast<pint_t *>(nextStack)[2];
2545 
2546   if (nextReturnAddress > 0x01 && nextReturnAddress < 0x10000) {
2547     _LIBUNWIND_TRACE_UNWINDING("The next is a signal handler frame: "
2548                                "nextStack=%p, next return address=%p\n",
2549                                reinterpret_cast<void *>(nextStack),
2550                                reinterpret_cast<void *>(nextReturnAddress));
2551     isSignalFrame = true;
2552   } else {
2553     isSignalFrame = false;
2554   }
2555   return UNW_STEP_SUCCESS;
2556 }
2557 #endif // defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND)
2558 
2559 template <typename A, typename R>
2560 void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {
2561 #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN)
2562   _isSigReturn = false;
2563 #endif
2564 
2565   pint_t pc = static_cast<pint_t>(this->getReg(UNW_REG_IP));
2566 #if defined(_LIBUNWIND_ARM_EHABI)
2567   // Remove the thumb bit so the IP represents the actual instruction address.
2568   // This matches the behaviour of _Unwind_GetIP on arm.
2569   pc &= (pint_t)~0x1;
2570 #endif
2571 
2572   // Exit early if at the top of the stack.
2573   if (pc == 0) {
2574     _unwindInfoMissing = true;
2575     return;
2576   }
2577 
2578   // If the last line of a function is a "throw" the compiler sometimes
2579   // emits no instructions after the call to __cxa_throw.  This means
2580   // the return address is actually the start of the next function.
2581   // To disambiguate this, back up the pc when we know it is a return
2582   // address.
2583   if (isReturnAddress)
2584 #if defined(_AIX)
2585     // PC needs to be a 4-byte aligned address to be able to look for a
2586     // word of 0 that indicates the start of the traceback table at the end
2587     // of a function on AIX.
2588     pc -= 4;
2589 #else
2590     --pc;
2591 #endif
2592 
2593   // Ask address space object to find unwind sections for this pc.
2594   UnwindInfoSections sects;
2595   if (_addressSpace.findUnwindSections(pc, sects)) {
2596 #if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
2597     // If there is a compact unwind encoding table, look there first.
2598     if (sects.compact_unwind_section != 0) {
2599       if (this->getInfoFromCompactEncodingSection(pc, sects)) {
2600   #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
2601         // Found info in table, done unless encoding says to use dwarf.
2602         uint32_t dwarfOffset;
2603         if ((sects.dwarf_section != 0) && compactSaysUseDwarf(&dwarfOffset)) {
2604           if (this->getInfoFromDwarfSection(pc, sects, dwarfOffset)) {
2605             // found info in dwarf, done
2606             return;
2607           }
2608         }
2609   #endif
2610         // If unwind table has entry, but entry says there is no unwind info,
2611         // record that we have no unwind info.
2612         if (_info.format == 0)
2613           _unwindInfoMissing = true;
2614         return;
2615       }
2616     }
2617 #endif // defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
2618 
2619 #if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
2620     // If there is SEH unwind info, look there next.
2621     if (this->getInfoFromSEH(pc))
2622       return;
2623 #endif
2624 
2625 #if defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND)
2626     // If there is unwind info in the traceback table, look there next.
2627     if (this->getInfoFromTBTable(pc, _registers))
2628       return;
2629 #endif
2630 
2631 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
2632     // If there is dwarf unwind info, look there next.
2633     if (sects.dwarf_section != 0) {
2634       if (this->getInfoFromDwarfSection(pc, sects)) {
2635         // found info in dwarf, done
2636         return;
2637       }
2638     }
2639 #endif
2640 
2641 #if defined(_LIBUNWIND_ARM_EHABI)
2642     // If there is ARM EHABI unwind info, look there next.
2643     if (sects.arm_section != 0 && this->getInfoFromEHABISection(pc, sects))
2644       return;
2645 #endif
2646   }
2647 
2648 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
2649   // There is no static unwind info for this pc. Look to see if an FDE was
2650   // dynamically registered for it.
2651   pint_t cachedFDE = DwarfFDECache<A>::findFDE(DwarfFDECache<A>::kSearchAll,
2652                                                pc);
2653   if (cachedFDE != 0) {
2654     typename CFI_Parser<A>::FDE_Info fdeInfo;
2655     typename CFI_Parser<A>::CIE_Info cieInfo;
2656     if (!CFI_Parser<A>::decodeFDE(_addressSpace, cachedFDE, &fdeInfo, &cieInfo))
2657       if (getInfoFromFdeCie(fdeInfo, cieInfo, pc, 0))
2658         return;
2659   }
2660 
2661   // Lastly, ask AddressSpace object about platform specific ways to locate
2662   // other FDEs.
2663   pint_t fde;
2664   if (_addressSpace.findOtherFDE(pc, fde)) {
2665     typename CFI_Parser<A>::FDE_Info fdeInfo;
2666     typename CFI_Parser<A>::CIE_Info cieInfo;
2667     if (!CFI_Parser<A>::decodeFDE(_addressSpace, fde, &fdeInfo, &cieInfo)) {
2668       // Double check this FDE is for a function that includes the pc.
2669       if ((fdeInfo.pcStart <= pc) && (pc < fdeInfo.pcEnd))
2670         if (getInfoFromFdeCie(fdeInfo, cieInfo, pc, 0))
2671           return;
2672     }
2673   }
2674 #endif // #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
2675 
2676 #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN)
2677   if (setInfoForSigReturn())
2678     return;
2679 #endif
2680 
2681   // no unwind info, flag that we can't reliably unwind
2682   _unwindInfoMissing = true;
2683 }
2684 
2685 #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&                               \
2686     defined(_LIBUNWIND_TARGET_AARCH64)
2687 template <typename A, typename R>
2688 bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_arm64 &) {
2689   // Look for the sigreturn trampoline. The trampoline's body is two
2690   // specific instructions (see below). Typically the trampoline comes from the
2691   // vDSO[1] (i.e. the __kernel_rt_sigreturn function). A libc might provide its
2692   // own restorer function, though, or user-mode QEMU might write a trampoline
2693   // onto the stack.
2694   //
2695   // This special code path is a fallback that is only used if the trampoline
2696   // lacks proper (e.g. DWARF) unwind info. On AArch64, a new DWARF register
2697   // constant for the PC needs to be defined before DWARF can handle a signal
2698   // trampoline. This code may segfault if the target PC is unreadable, e.g.:
2699   //  - The PC points at a function compiled without unwind info, and which is
2700   //    part of an execute-only mapping (e.g. using -Wl,--execute-only).
2701   //  - The PC is invalid and happens to point to unreadable or unmapped memory.
2702   //
2703   // [1] https://github.com/torvalds/linux/blob/master/arch/arm64/kernel/vdso/sigreturn.S
2704   const pint_t pc = static_cast<pint_t>(this->getReg(UNW_REG_IP));
2705   // The PC might contain an invalid address if the unwind info is bad, so
2706   // directly accessing it could cause a SIGSEGV.
2707   if (!isReadableAddr(pc))
2708     return false;
2709   auto *instructions = reinterpret_cast<const uint32_t *>(pc);
2710   // Look for instructions: mov x8, #0x8b; svc #0x0
2711   if (instructions[0] != 0xd2801168 || instructions[1] != 0xd4000001)
2712     return false;
2713 
2714   _info = {};
2715   _info.start_ip = pc;
2716   _info.end_ip = pc + 4;
2717   _isSigReturn = true;
2718   return true;
2719 }
2720 
2721 template <typename A, typename R>
2722 int UnwindCursor<A, R>::stepThroughSigReturn(Registers_arm64 &) {
2723   // In the signal trampoline frame, sp points to an rt_sigframe[1], which is:
2724   //  - 128-byte siginfo struct
2725   //  - ucontext struct:
2726   //     - 8-byte long (uc_flags)
2727   //     - 8-byte pointer (uc_link)
2728   //     - 24-byte stack_t
2729   //     - 128-byte signal set
2730   //     - 8 bytes of padding because sigcontext has 16-byte alignment
2731   //     - sigcontext/mcontext_t
2732   // [1] https://github.com/torvalds/linux/blob/master/arch/arm64/kernel/signal.c
2733   const pint_t kOffsetSpToSigcontext = (128 + 8 + 8 + 24 + 128 + 8); // 304
2734 
2735   // Offsets from sigcontext to each register.
2736   const pint_t kOffsetGprs = 8; // offset to "__u64 regs[31]" field
2737   const pint_t kOffsetSp = 256; // offset to "__u64 sp" field
2738   const pint_t kOffsetPc = 264; // offset to "__u64 pc" field
2739 
2740   pint_t sigctx = _registers.getSP() + kOffsetSpToSigcontext;
2741 
2742   for (int i = 0; i <= 30; ++i) {
2743     uint64_t value = _addressSpace.get64(sigctx + kOffsetGprs +
2744                                          static_cast<pint_t>(i * 8));
2745     _registers.setRegister(UNW_AARCH64_X0 + i, value);
2746   }
2747   _registers.setSP(_addressSpace.get64(sigctx + kOffsetSp));
2748   _registers.setIP(_addressSpace.get64(sigctx + kOffsetPc));
2749   _isSignalFrame = true;
2750   return UNW_STEP_SUCCESS;
2751 }
2752 #endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&
2753        // defined(_LIBUNWIND_TARGET_AARCH64)
2754 
2755 #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&                               \
2756     defined(_LIBUNWIND_TARGET_RISCV)
2757 template <typename A, typename R>
2758 bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_riscv &) {
2759   const pint_t pc = static_cast<pint_t>(getReg(UNW_REG_IP));
2760   // The PC might contain an invalid address if the unwind info is bad, so
2761   // directly accessing it could cause a SIGSEGV.
2762   if (!isReadableAddr(pc))
2763     return false;
2764   const auto *instructions = reinterpret_cast<const uint32_t *>(pc);
2765   // Look for the two instructions used in the sigreturn trampoline
2766   // __vdso_rt_sigreturn:
2767   //
2768   // 0x08b00893 li a7,0x8b
2769   // 0x00000073 ecall
2770   if (instructions[0] != 0x08b00893 || instructions[1] != 0x00000073)
2771     return false;
2772 
2773   _info = {};
2774   _info.start_ip = pc;
2775   _info.end_ip = pc + 4;
2776   _isSigReturn = true;
2777   return true;
2778 }
2779 
2780 template <typename A, typename R>
2781 int UnwindCursor<A, R>::stepThroughSigReturn(Registers_riscv &) {
2782   // In the signal trampoline frame, sp points to an rt_sigframe[1], which is:
2783   //  - 128-byte siginfo struct
2784   //  - ucontext_t struct:
2785   //     - 8-byte long (__uc_flags)
2786   //     - 8-byte pointer (*uc_link)
2787   //     - 24-byte uc_stack
2788   //     - 8-byte uc_sigmask
2789   //     - 120-byte of padding to allow sigset_t to be expanded in the future
2790   //     - 8 bytes of padding because sigcontext has 16-byte alignment
2791   //     - struct sigcontext uc_mcontext
2792   // [1]
2793   // https://github.com/torvalds/linux/blob/master/arch/riscv/kernel/signal.c
2794   const pint_t kOffsetSpToSigcontext = 128 + 8 + 8 + 24 + 8 + 128;
2795 
2796   const pint_t sigctx = _registers.getSP() + kOffsetSpToSigcontext;
2797   _registers.setIP(_addressSpace.get64(sigctx));
2798   for (int i = UNW_RISCV_X1; i <= UNW_RISCV_X31; ++i) {
2799     uint64_t value = _addressSpace.get64(sigctx + static_cast<pint_t>(i * 8));
2800     _registers.setRegister(i, value);
2801   }
2802   _isSignalFrame = true;
2803   return UNW_STEP_SUCCESS;
2804 }
2805 #endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&
2806        // defined(_LIBUNWIND_TARGET_RISCV)
2807 
2808 #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&                               \
2809     defined(_LIBUNWIND_TARGET_S390X)
2810 template <typename A, typename R>
2811 bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_s390x &) {
2812   // Look for the sigreturn trampoline. The trampoline's body is a
2813   // specific instruction (see below). Typically the trampoline comes from the
2814   // vDSO (i.e. the __kernel_[rt_]sigreturn function). A libc might provide its
2815   // own restorer function, though, or user-mode QEMU might write a trampoline
2816   // onto the stack.
2817   const pint_t pc = static_cast<pint_t>(this->getReg(UNW_REG_IP));
2818   // The PC might contain an invalid address if the unwind info is bad, so
2819   // directly accessing it could cause a SIGSEGV.
2820   if (!isReadableAddr(pc))
2821     return false;
2822   const auto inst = *reinterpret_cast<const uint16_t *>(pc);
2823   if (inst == 0x0a77 || inst == 0x0aad) {
2824     _info = {};
2825     _info.start_ip = pc;
2826     _info.end_ip = pc + 2;
2827     _isSigReturn = true;
2828     return true;
2829   }
2830   return false;
2831 }
2832 
2833 template <typename A, typename R>
2834 int UnwindCursor<A, R>::stepThroughSigReturn(Registers_s390x &) {
2835   // Determine current SP.
2836   const pint_t sp = static_cast<pint_t>(this->getReg(UNW_REG_SP));
2837   // According to the s390x ABI, the CFA is at (incoming) SP + 160.
2838   const pint_t cfa = sp + 160;
2839 
2840   // Determine current PC and instruction there (this must be either
2841   // a "svc __NR_sigreturn" or "svc __NR_rt_sigreturn").
2842   const pint_t pc = static_cast<pint_t>(this->getReg(UNW_REG_IP));
2843   const uint16_t inst = _addressSpace.get16(pc);
2844 
2845   // Find the addresses of the signo and sigcontext in the frame.
2846   pint_t pSigctx = 0;
2847   pint_t pSigno = 0;
2848 
2849   // "svc __NR_sigreturn" uses a non-RT signal trampoline frame.
2850   if (inst == 0x0a77) {
2851     // Layout of a non-RT signal trampoline frame, starting at the CFA:
2852     //  - 8-byte signal mask
2853     //  - 8-byte pointer to sigcontext, followed by signo
2854     //  - 4-byte signo
2855     pSigctx = _addressSpace.get64(cfa + 8);
2856     pSigno = pSigctx + 344;
2857   }
2858 
2859   // "svc __NR_rt_sigreturn" uses a RT signal trampoline frame.
2860   if (inst == 0x0aad) {
2861     // Layout of a RT signal trampoline frame, starting at the CFA:
2862     //  - 8-byte retcode (+ alignment)
2863     //  - 128-byte siginfo struct (starts with signo)
2864     //  - ucontext struct:
2865     //     - 8-byte long (uc_flags)
2866     //     - 8-byte pointer (uc_link)
2867     //     - 24-byte stack_t
2868     //     - 8 bytes of padding because sigcontext has 16-byte alignment
2869     //     - sigcontext/mcontext_t
2870     pSigctx = cfa + 8 + 128 + 8 + 8 + 24 + 8;
2871     pSigno = cfa + 8;
2872   }
2873 
2874   assert(pSigctx != 0);
2875   assert(pSigno != 0);
2876 
2877   // Offsets from sigcontext to each register.
2878   const pint_t kOffsetPc = 8;
2879   const pint_t kOffsetGprs = 16;
2880   const pint_t kOffsetFprs = 216;
2881 
2882   // Restore all registers.
2883   for (int i = 0; i < 16; ++i) {
2884     uint64_t value = _addressSpace.get64(pSigctx + kOffsetGprs +
2885                                          static_cast<pint_t>(i * 8));
2886     _registers.setRegister(UNW_S390X_R0 + i, value);
2887   }
2888   for (int i = 0; i < 16; ++i) {
2889     static const int fpr[16] = {
2890       UNW_S390X_F0, UNW_S390X_F1, UNW_S390X_F2, UNW_S390X_F3,
2891       UNW_S390X_F4, UNW_S390X_F5, UNW_S390X_F6, UNW_S390X_F7,
2892       UNW_S390X_F8, UNW_S390X_F9, UNW_S390X_F10, UNW_S390X_F11,
2893       UNW_S390X_F12, UNW_S390X_F13, UNW_S390X_F14, UNW_S390X_F15
2894     };
2895     double value = _addressSpace.getDouble(pSigctx + kOffsetFprs +
2896                                            static_cast<pint_t>(i * 8));
2897     _registers.setFloatRegister(fpr[i], value);
2898   }
2899   _registers.setIP(_addressSpace.get64(pSigctx + kOffsetPc));
2900 
2901   // SIGILL, SIGFPE and SIGTRAP are delivered with psw_addr
2902   // after the faulting instruction rather than before it.
2903   // Do not set _isSignalFrame in that case.
2904   uint32_t signo = _addressSpace.get32(pSigno);
2905   _isSignalFrame = (signo != 4 && signo != 5 && signo != 8);
2906 
2907   return UNW_STEP_SUCCESS;
2908 }
2909 #endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) &&
2910        // defined(_LIBUNWIND_TARGET_S390X)
2911 
2912 template <typename A, typename R> int UnwindCursor<A, R>::step(bool stage2) {
2913   (void)stage2;
2914   // Bottom of stack is defined is when unwind info cannot be found.
2915   if (_unwindInfoMissing)
2916     return UNW_STEP_END;
2917 
2918   // Use unwinding info to modify register set as if function returned.
2919   int result;
2920 #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN)
2921   if (_isSigReturn) {
2922     result = this->stepThroughSigReturn();
2923   } else
2924 #endif
2925   {
2926 #if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
2927     result = this->stepWithCompactEncoding(stage2);
2928 #elif defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
2929     result = this->stepWithSEHData();
2930 #elif defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND)
2931     result = this->stepWithTBTableData();
2932 #elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
2933     result = this->stepWithDwarfFDE(stage2);
2934 #elif defined(_LIBUNWIND_ARM_EHABI)
2935     result = this->stepWithEHABI();
2936 #else
2937   #error Need _LIBUNWIND_SUPPORT_COMPACT_UNWIND or \
2938               _LIBUNWIND_SUPPORT_SEH_UNWIND or \
2939               _LIBUNWIND_SUPPORT_DWARF_UNWIND or \
2940               _LIBUNWIND_ARM_EHABI
2941 #endif
2942   }
2943 
2944   // update info based on new PC
2945   if (result == UNW_STEP_SUCCESS) {
2946     this->setInfoBasedOnIPRegister(true);
2947     if (_unwindInfoMissing)
2948       return UNW_STEP_END;
2949   }
2950 
2951   return result;
2952 }
2953 
2954 template <typename A, typename R>
2955 void UnwindCursor<A, R>::getInfo(unw_proc_info_t *info) {
2956   if (_unwindInfoMissing)
2957     memset(info, 0, sizeof(*info));
2958   else
2959     *info = _info;
2960 }
2961 
2962 template <typename A, typename R>
2963 bool UnwindCursor<A, R>::getFunctionName(char *buf, size_t bufLen,
2964                                                            unw_word_t *offset) {
2965   return _addressSpace.findFunctionName((pint_t)this->getReg(UNW_REG_IP),
2966                                          buf, bufLen, offset);
2967 }
2968 
2969 #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN)
2970 template <typename A, typename R>
2971 bool UnwindCursor<A, R>::isReadableAddr(const pint_t addr) const {
2972   // We use SYS_rt_sigprocmask, inspired by Abseil's AddressIsReadable.
2973 
2974   const auto sigsetAddr = reinterpret_cast<sigset_t *>(addr);
2975   // We have to check that addr is nullptr because sigprocmask allows that
2976   // as an argument without failure.
2977   if (!sigsetAddr)
2978     return false;
2979   const auto saveErrno = errno;
2980   // We MUST use a raw syscall here, as wrappers may try to access
2981   // sigsetAddr which may cause a SIGSEGV. A raw syscall however is
2982   // safe. Additionally, we need to pass the kernel_sigset_size, which is
2983   // different from libc sizeof(sigset_t). For the majority of architectures,
2984   // it's 64 bits (_NSIG), and libc NSIG is _NSIG + 1.
2985   const auto kernelSigsetSize = NSIG / 8;
2986   [[maybe_unused]] const int Result = syscall(
2987       SYS_rt_sigprocmask, /*how=*/~0, sigsetAddr, nullptr, kernelSigsetSize);
2988   // Because our "how" is invalid, this syscall should always fail, and our
2989   // errno should always be EINVAL or an EFAULT. This relies on the Linux
2990   // kernel to check copy_from_user before checking if the "how" argument is
2991   // invalid.
2992   assert(Result == -1);
2993   assert(errno == EFAULT || errno == EINVAL);
2994   const auto readable = errno != EFAULT;
2995   errno = saveErrno;
2996   return readable;
2997 }
2998 #endif
2999 
3000 #if defined(_LIBUNWIND_USE_CET)
3001 extern "C" void *__libunwind_cet_get_registers(unw_cursor_t *cursor) {
3002   AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
3003   return co->get_registers();
3004 }
3005 #endif
3006 } // namespace libunwind
3007 
3008 #endif // __UNWINDCURSOR_HPP__
3009