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