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