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