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