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