| author | |
| committer | |
| log | 571a4c86c39d83b28a0c6f413f3fc259b48cf422 |
| tree | 4084e777e8d7cd3e305622f3631bc5ff72c0c756 |
| parent | 6a07b7024a33211f158f0c332267050955896918 |
release/17.x branch, commit 8f4dd44097c9ae25dd203d5ac87f3b48f854bba815 files changed, 313 insertions(+), 133 deletions(-)
lib/libunwind/include/__libunwind_config.h+2-2| ... | ... | @@ -196,9 +196,9 @@ |
| 196 | 196 | # define _LIBUNWIND_TARGET_RISCV 1 |
| 197 | 197 | # define _LIBUNWIND_TARGET_VE 1 |
| 198 | 198 | # define _LIBUNWIND_TARGET_S390X 1 |
| 199 | #define _LIBUNWIND_TARGET_LOONGARCH 1 | |
| 199 | #define _LIBUNWIND_TARGET_LOONGARCH 1 | |
| 200 | 200 | # define _LIBUNWIND_CONTEXT_SIZE 167 |
| 201 | # define _LIBUNWIND_CURSOR_SIZE 179 | |
| 201 | # define _LIBUNWIND_CURSOR_SIZE 204 | |
| 202 | 202 | # define _LIBUNWIND_HIGHEST_DWARF_REGISTER 287 |
| 203 | 203 | #endif // _LIBUNWIND_IS_NATIVE_ONLY |
| 204 | 204 |
lib/libunwind/include/unwind.h+2-2| ... | ... | @@ -56,9 +56,9 @@ typedef enum { |
| 56 | 56 | typedef struct _Unwind_Context _Unwind_Context; // opaque |
| 57 | 57 | |
| 58 | 58 | #if defined(_LIBUNWIND_ARM_EHABI) |
| 59 | #include "unwind_arm_ehabi.h" | |
| 59 | #include <unwind_arm_ehabi.h> | |
| 60 | 60 | #else |
| 61 | #include "unwind_itanium.h" | |
| 61 | #include <unwind_itanium.h> | |
| 62 | 62 | #endif |
| 63 | 63 | |
| 64 | 64 | typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) |
lib/libunwind/src/AddressSpace.hpp+20| ... | ... | @@ -66,6 +66,10 @@ char *getFuncNameFromTBTable(uintptr_t pc, uint16_t &NameLen, |
| 66 | 66 | // In 10.7.0 or later, libSystem.dylib implements this function. |
| 67 | 67 | extern "C" bool _dyld_find_unwind_sections(void *, dyld_unwind_sections *); |
| 68 | 68 | |
| 69 | namespace libunwind { | |
| 70 | bool findDynamicUnwindSections(void *, unw_dynamic_unwind_sections *); | |
| 71 | } | |
| 72 | ||
| 69 | 73 | #elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL) |
| 70 | 74 | |
| 71 | 75 | // When statically linked on bare-metal, the symbols for the EH table are looked |
| ... | ... | @@ -497,6 +501,22 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr, |
| 497 | 501 | info.compact_unwind_section_length = (size_t)dyldInfo.compact_unwind_section_length; |
| 498 | 502 | return true; |
| 499 | 503 | } |
| 504 | ||
| 505 | unw_dynamic_unwind_sections dynamicUnwindSectionInfo; | |
| 506 | if (findDynamicUnwindSections((void *)targetAddr, | |
| 507 | &dynamicUnwindSectionInfo)) { | |
| 508 | info.dso_base = dynamicUnwindSectionInfo.dso_base; | |
| 509 | #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) | |
| 510 | info.dwarf_section = (uintptr_t)dynamicUnwindSectionInfo.dwarf_section; | |
| 511 | info.dwarf_section_length = dynamicUnwindSectionInfo.dwarf_section_length; | |
| 512 | #endif | |
| 513 | info.compact_unwind_section = | |
| 514 | (uintptr_t)dynamicUnwindSectionInfo.compact_unwind_section; | |
| 515 | info.compact_unwind_section_length = | |
| 516 | dynamicUnwindSectionInfo.compact_unwind_section_length; | |
| 517 | return true; | |
| 518 | } | |
| 519 | ||
| 500 | 520 | #elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL) |
| 501 | 521 | info.dso_base = 0; |
| 502 | 522 | // Bare metal is statically linked, so no need to ask the dynamic loader |
lib/libunwind/src/DwarfInstructions.hpp+2-1| ... | ... | @@ -224,7 +224,8 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc, |
| 224 | 224 | p &= ~0xfULL; |
| 225 | 225 | // CFA is the bottom of the current stack frame. |
| 226 | 226 | for (; p < cfa; p += 16) { |
| 227 | __asm__ __volatile__(".arch_extension memtag\n" | |
| 227 | __asm__ __volatile__(".arch armv8.5-a\n" | |
| 228 | ".arch_extension memtag\n" | |
| 228 | 229 | "stg %[Ptr], [%[Ptr]]\n" |
| 229 | 230 | : |
| 230 | 231 | : [Ptr] "r"(p) |
lib/libunwind/src/Unwind-EHABI.cpp+6-3| ... | ... | @@ -709,7 +709,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, |
| 709 | 709 | // Update info about this frame. |
| 710 | 710 | unw_proc_info_t frameInfo; |
| 711 | 711 | if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) { |
| 712 | _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): __unw_step " | |
| 712 | _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): __unw_get_proc_info " | |
| 713 | 713 | "failed => _URC_END_OF_STACK", |
| 714 | 714 | (void *)exception_object); |
| 715 | 715 | return _URC_FATAL_PHASE2_ERROR; |
| ... | ... | @@ -885,8 +885,11 @@ _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) { |
| 885 | 885 | return result; |
| 886 | 886 | } |
| 887 | 887 | |
| 888 | static uint64_t ValueAsBitPattern(_Unwind_VRS_DataRepresentation representation, | |
| 889 | void* valuep) { | |
| 888 | // Only used in _LIBUNWIND_TRACE_API, which is a no-op when assertions are | |
| 889 | // disabled. | |
| 890 | [[gnu::unused]] static uint64_t | |
| 891 | ValueAsBitPattern(_Unwind_VRS_DataRepresentation representation, | |
| 892 | const void *valuep) { | |
| 890 | 893 | uint64_t value = 0; |
| 891 | 894 | switch (representation) { |
| 892 | 895 | case _UVRSD_UINT32: |
lib/libunwind/src/Unwind-seh.cpp+18-1| ... | ... | @@ -212,11 +212,20 @@ __libunwind_seh_personality(int version, _Unwind_Action state, |
| 212 | 212 | ms_exc.ExceptionInformation[2] = state; |
| 213 | 213 | DISPATCHER_CONTEXT *disp_ctx = |
| 214 | 214 | __unw_seh_get_disp_ctx((unw_cursor_t *)context); |
| 215 | _LIBUNWIND_TRACE_UNWINDING("__libunwind_seh_personality() calling " | |
| 216 | "LanguageHandler %p(%p, %p, %p, %p)", | |
| 217 | (void *)disp_ctx->LanguageHandler, (void *)&ms_exc, | |
| 218 | (void *)disp_ctx->EstablisherFrame, | |
| 219 | (void *)disp_ctx->ContextRecord, (void *)disp_ctx); | |
| 215 | 220 | EXCEPTION_DISPOSITION ms_act = disp_ctx->LanguageHandler(&ms_exc, |
| 216 | 221 | (PVOID)disp_ctx->EstablisherFrame, |
| 217 | 222 | disp_ctx->ContextRecord, |
| 218 | 223 | disp_ctx); |
| 224 | _LIBUNWIND_TRACE_UNWINDING("__libunwind_seh_personality() LanguageHandler " | |
| 225 | "returned %d", | |
| 226 | (int)ms_act); | |
| 219 | 227 | switch (ms_act) { |
| 228 | case ExceptionContinueExecution: return _URC_END_OF_STACK; | |
| 220 | 229 | case ExceptionContinueSearch: return _URC_CONTINUE_UNWIND; |
| 221 | 230 | case 4 /*ExceptionExecuteHandler*/: |
| 222 | 231 | return phase2 ? _URC_INSTALL_CONTEXT : _URC_HANDLER_FOUND; |
| ... | ... | @@ -238,7 +247,7 @@ unwind_phase2_forced(unw_context_t *uc, |
| 238 | 247 | // Update info about this frame. |
| 239 | 248 | unw_proc_info_t frameInfo; |
| 240 | 249 | if (__unw_get_proc_info(&cursor2, &frameInfo) != UNW_ESUCCESS) { |
| 241 | _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): __unw_step " | |
| 250 | _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): __unw_get_proc_info " | |
| 242 | 251 | "failed => _URC_END_OF_STACK", |
| 243 | 252 | (void *)exception_object); |
| 244 | 253 | return _URC_FATAL_PHASE2_ERROR; |
| ... | ... | @@ -304,6 +313,12 @@ unwind_phase2_forced(unw_context_t *uc, |
| 304 | 313 | // We may get control back if landing pad calls _Unwind_Resume(). |
| 305 | 314 | __unw_resume(&cursor2); |
| 306 | 315 | break; |
| 316 | case _URC_END_OF_STACK: | |
| 317 | _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " | |
| 318 | "personality returned " | |
| 319 | "_URC_END_OF_STACK", | |
| 320 | (void *)exception_object); | |
| 321 | break; | |
| 307 | 322 | default: |
| 308 | 323 | // Personality routine returned an unknown result code. |
| 309 | 324 | _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " |
| ... | ... | @@ -312,6 +327,8 @@ unwind_phase2_forced(unw_context_t *uc, |
| 312 | 327 | (void *)exception_object, personalityResult); |
| 313 | 328 | return _URC_FATAL_PHASE2_ERROR; |
| 314 | 329 | } |
| 330 | if (personalityResult == _URC_END_OF_STACK) | |
| 331 | break; | |
| 315 | 332 | } |
| 316 | 333 | } |
| 317 | 334 |
lib/libunwind/src/UnwindCursor.hpp+77-3| ... | ... | @@ -31,7 +31,8 @@ |
| 31 | 31 | #endif |
| 32 | 32 | |
| 33 | 33 | #if defined(_LIBUNWIND_TARGET_LINUX) && \ |
| 34 | (defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_S390X)) | |
| 34 | (defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_RISCV) || \ | |
| 35 | defined(_LIBUNWIND_TARGET_S390X)) | |
| 35 | 36 | #include <sys/syscall.h> |
| 36 | 37 | #include <sys/uio.h> |
| 37 | 38 | #include <unistd.h> |
| ... | ... | @@ -506,7 +507,14 @@ public: |
| 506 | 507 | #endif |
| 507 | 508 | |
| 508 | 509 | DISPATCHER_CONTEXT *getDispatcherContext() { return &_dispContext; } |
| 509 | void setDispatcherContext(DISPATCHER_CONTEXT *disp) { _dispContext = *disp; } | |
| 510 | void setDispatcherContext(DISPATCHER_CONTEXT *disp) { | |
| 511 | _dispContext = *disp; | |
| 512 | _info.lsda = reinterpret_cast<unw_word_t>(_dispContext.HandlerData); | |
| 513 | if (_dispContext.LanguageHandler) { | |
| 514 | _info.handler = reinterpret_cast<unw_word_t>(__libunwind_seh_personality); | |
| 515 | } else | |
| 516 | _info.handler = 0; | |
| 517 | } | |
| 510 | 518 | |
| 511 | 519 | // libunwind does not and should not depend on C++ library which means that we |
| 512 | 520 | // need our own definition of inline placement new. |
| ... | ... | @@ -568,10 +576,12 @@ UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as) |
| 568 | 576 | "UnwindCursor<> requires more alignment than unw_cursor_t"); |
| 569 | 577 | memset(&_info, 0, sizeof(_info)); |
| 570 | 578 | memset(&_histTable, 0, sizeof(_histTable)); |
| 579 | memset(&_dispContext, 0, sizeof(_dispContext)); | |
| 571 | 580 | _dispContext.ContextRecord = &_msContext; |
| 572 | 581 | _dispContext.HistoryTable = &_histTable; |
| 573 | 582 | // Initialize MS context from ours. |
| 574 | 583 | R r(context); |
| 584 | RtlCaptureContext(&_msContext); | |
| 575 | 585 | _msContext.ContextFlags = CONTEXT_CONTROL|CONTEXT_INTEGER|CONTEXT_FLOATING_POINT; |
| 576 | 586 | #if defined(_LIBUNWIND_TARGET_X86_64) |
| 577 | 587 | _msContext.Rax = r.getRegister(UNW_X86_64_RAX); |
| ... | ... | @@ -669,6 +679,7 @@ UnwindCursor<A, R>::UnwindCursor(CONTEXT *context, A &as) |
| 669 | 679 | "UnwindCursor<> does not fit in unw_cursor_t"); |
| 670 | 680 | memset(&_info, 0, sizeof(_info)); |
| 671 | 681 | memset(&_histTable, 0, sizeof(_histTable)); |
| 682 | memset(&_dispContext, 0, sizeof(_dispContext)); | |
| 672 | 683 | _dispContext.ContextRecord = &_msContext; |
| 673 | 684 | _dispContext.HistoryTable = &_histTable; |
| 674 | 685 | _msContext = *context; |
| ... | ... | @@ -679,7 +690,7 @@ template <typename A, typename R> |
| 679 | 690 | bool UnwindCursor<A, R>::validReg(int regNum) { |
| 680 | 691 | if (regNum == UNW_REG_IP || regNum == UNW_REG_SP) return true; |
| 681 | 692 | #if defined(_LIBUNWIND_TARGET_X86_64) |
| 682 | if (regNum >= UNW_X86_64_RAX && regNum <= UNW_X86_64_R15) return true; | |
| 693 | if (regNum >= UNW_X86_64_RAX && regNum <= UNW_X86_64_RIP) return true; | |
| 683 | 694 | #elif defined(_LIBUNWIND_TARGET_ARM) |
| 684 | 695 | if ((regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15) || |
| 685 | 696 | regNum == UNW_ARM_RA_AUTH_CODE) |
| ... | ... | @@ -694,6 +705,7 @@ template <typename A, typename R> |
| 694 | 705 | unw_word_t UnwindCursor<A, R>::getReg(int regNum) { |
| 695 | 706 | switch (regNum) { |
| 696 | 707 | #if defined(_LIBUNWIND_TARGET_X86_64) |
| 708 | case UNW_X86_64_RIP: | |
| 697 | 709 | case UNW_REG_IP: return _msContext.Rip; |
| 698 | 710 | case UNW_X86_64_RAX: return _msContext.Rax; |
| 699 | 711 | case UNW_X86_64_RDX: return _msContext.Rdx; |
| ... | ... | @@ -744,6 +756,7 @@ template <typename A, typename R> |
| 744 | 756 | void UnwindCursor<A, R>::setReg(int regNum, unw_word_t value) { |
| 745 | 757 | switch (regNum) { |
| 746 | 758 | #if defined(_LIBUNWIND_TARGET_X86_64) |
| 759 | case UNW_X86_64_RIP: | |
| 747 | 760 | case UNW_REG_IP: _msContext.Rip = value; break; |
| 748 | 761 | case UNW_X86_64_RAX: _msContext.Rax = value; break; |
| 749 | 762 | case UNW_X86_64_RDX: _msContext.Rdx = value; break; |
| ... | ... | @@ -981,6 +994,10 @@ private: |
| 981 | 994 | bool setInfoForSigReturn(Registers_arm64 &); |
| 982 | 995 | int stepThroughSigReturn(Registers_arm64 &); |
| 983 | 996 | #endif |
| 997 | #if defined(_LIBUNWIND_TARGET_RISCV) | |
| 998 | bool setInfoForSigReturn(Registers_riscv &); | |
| 999 | int stepThroughSigReturn(Registers_riscv &); | |
| 1000 | #endif | |
| 984 | 1001 | #if defined(_LIBUNWIND_TARGET_S390X) |
| 985 | 1002 | bool setInfoForSigReturn(Registers_s390x &); |
| 986 | 1003 | int stepThroughSigReturn(Registers_s390x &); |
| ... | ... | @@ -1978,6 +1995,9 @@ bool UnwindCursor<A, R>::getInfoFromSEH(pint_t pc) { |
| 1978 | 1995 | uint32_t lastcode = (xdata->CountOfCodes + 1) & ~1; |
| 1979 | 1996 | const uint32_t *handler = reinterpret_cast<uint32_t *>(&xdata->UnwindCodes[lastcode]); |
| 1980 | 1997 | _info.lsda = reinterpret_cast<unw_word_t>(handler+1); |
| 1998 | _dispContext.HandlerData = reinterpret_cast<void *>(_info.lsda); | |
| 1999 | _dispContext.LanguageHandler = | |
| 2000 | reinterpret_cast<EXCEPTION_ROUTINE *>(base + *handler); | |
| 1981 | 2001 | if (*handler) { |
| 1982 | 2002 | _info.handler = reinterpret_cast<unw_word_t>(__libunwind_seh_personality); |
| 1983 | 2003 | } else |
| ... | ... | @@ -2705,6 +2725,60 @@ int UnwindCursor<A, R>::stepThroughSigReturn(Registers_arm64 &) { |
| 2705 | 2725 | #endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && |
| 2706 | 2726 | // defined(_LIBUNWIND_TARGET_AARCH64) |
| 2707 | 2727 | |
| 2728 | #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && \ | |
| 2729 | defined(_LIBUNWIND_TARGET_RISCV) | |
| 2730 | template <typename A, typename R> | |
| 2731 | bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_riscv &) { | |
| 2732 | const pint_t pc = static_cast<pint_t>(getReg(UNW_REG_IP)); | |
| 2733 | uint32_t instructions[2]; | |
| 2734 | struct iovec local_iov = {&instructions, sizeof instructions}; | |
| 2735 | struct iovec remote_iov = {reinterpret_cast<void *>(pc), sizeof instructions}; | |
| 2736 | long bytesRead = | |
| 2737 | syscall(SYS_process_vm_readv, getpid(), &local_iov, 1, &remote_iov, 1, 0); | |
| 2738 | // Look for the two instructions used in the sigreturn trampoline | |
| 2739 | // __vdso_rt_sigreturn: | |
| 2740 | // | |
| 2741 | // 0x08b00893 li a7,0x8b | |
| 2742 | // 0x00000073 ecall | |
| 2743 | if (bytesRead != sizeof instructions || instructions[0] != 0x08b00893 || | |
| 2744 | instructions[1] != 0x00000073) | |
| 2745 | return false; | |
| 2746 | ||
| 2747 | _info = {}; | |
| 2748 | _info.start_ip = pc; | |
| 2749 | _info.end_ip = pc + 4; | |
| 2750 | _isSigReturn = true; | |
| 2751 | return true; | |
| 2752 | } | |
| 2753 | ||
| 2754 | template <typename A, typename R> | |
| 2755 | int UnwindCursor<A, R>::stepThroughSigReturn(Registers_riscv &) { | |
| 2756 | // In the signal trampoline frame, sp points to an rt_sigframe[1], which is: | |
| 2757 | // - 128-byte siginfo struct | |
| 2758 | // - ucontext_t struct: | |
| 2759 | // - 8-byte long (__uc_flags) | |
| 2760 | // - 8-byte pointer (*uc_link) | |
| 2761 | // - 24-byte uc_stack | |
| 2762 | // - 8-byte uc_sigmask | |
| 2763 | // - 120-byte of padding to allow sigset_t to be expanded in the future | |
| 2764 | // - 8 bytes of padding because sigcontext has 16-byte alignment | |
| 2765 | // - struct sigcontext uc_mcontext | |
| 2766 | // [1] | |
| 2767 | // https://github.com/torvalds/linux/blob/master/arch/riscv/kernel/signal.c | |
| 2768 | const pint_t kOffsetSpToSigcontext = 128 + 8 + 8 + 24 + 8 + 128; | |
| 2769 | ||
| 2770 | const pint_t sigctx = _registers.getSP() + kOffsetSpToSigcontext; | |
| 2771 | _registers.setIP(_addressSpace.get64(sigctx)); | |
| 2772 | for (int i = UNW_RISCV_X1; i <= UNW_RISCV_X31; ++i) { | |
| 2773 | uint64_t value = _addressSpace.get64(sigctx + static_cast<pint_t>(i * 8)); | |
| 2774 | _registers.setRegister(i, value); | |
| 2775 | } | |
| 2776 | _isSignalFrame = true; | |
| 2777 | return UNW_STEP_SUCCESS; | |
| 2778 | } | |
| 2779 | #endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && | |
| 2780 | // defined(_LIBUNWIND_TARGET_RISCV) | |
| 2781 | ||
| 2708 | 2782 | #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && \ |
| 2709 | 2783 | defined(_LIBUNWIND_TARGET_S390X) |
| 2710 | 2784 | template <typename A, typename R> |
lib/libunwind/src/UnwindLevel1-gcc-ext.c+1-1| ... | ... | @@ -167,7 +167,7 @@ _Unwind_Backtrace(_Unwind_Trace_Fn callback, void *ref) { |
| 167 | 167 | } |
| 168 | 168 | |
| 169 | 169 | // Update the pr_cache in the mock exception object. |
| 170 | const uint32_t* unwindInfo = (uint32_t *) frameInfo.unwind_info; | |
| 170 | uint32_t *unwindInfo = (uint32_t *)frameInfo.unwind_info; | |
| 171 | 171 | ex.pr_cache.fnstart = frameInfo.start_ip; |
| 172 | 172 | ex.pr_cache.ehtp = (_Unwind_EHT_Header *) unwindInfo; |
| 173 | 173 | ex.pr_cache.additional= frameInfo.flags; |
lib/libunwind/src/UnwindLevel1.c+1-1| ... | ... | @@ -321,7 +321,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, |
| 321 | 321 | unw_proc_info_t frameInfo; |
| 322 | 322 | if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) { |
| 323 | 323 | _LIBUNWIND_TRACE_UNWINDING( |
| 324 | "unwind_phase2_forced(ex_obj=%p): __unw_step_stage2 " | |
| 324 | "unwind_phase2_forced(ex_obj=%p): __unw_get_proc_info " | |
| 325 | 325 | "failed => _URC_END_OF_STACK", |
| 326 | 326 | (void *)exception_object); |
| 327 | 327 | return _URC_FATAL_PHASE2_ERROR; |
lib/libunwind/src/UnwindRegistersRestore.S+20-2| ... | ... | @@ -194,9 +194,20 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv) |
| 194 | 194 | addi 4, 3, PPC64_OFFS_FP |
| 195 | 195 | |
| 196 | 196 | // load VS register |
| 197 | #ifdef __LITTLE_ENDIAN__ | |
| 198 | // For little-endian targets, we need a swap since lxvd2x will load the register | |
| 199 | // in the incorrect doubleword order. | |
| 200 | // FIXME: when supporting targets older than Power9 on LE is no longer required, | |
| 201 | // this can be changed to simply `lxv n, (16 * n)(4)`. | |
| 197 | 202 | #define PPC64_LVS(n) \ |
| 198 | 203 | lxvd2x n, 0, 4 ;\ |
| 204 | xxswapd n, n ;\ | |
| 199 | 205 | addi 4, 4, 16 |
| 206 | #else | |
| 207 | #define PPC64_LVS(n) \ | |
| 208 | lxvd2x n, 0, 4 ;\ | |
| 209 | addi 4, 4, 16 | |
| 210 | #endif | |
| 200 | 211 | |
| 201 | 212 | // restore the first 32 VS regs (and also all floating point regs) |
| 202 | 213 | PPC64_LVS(0) |
| ... | ... | @@ -232,9 +243,16 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv) |
| 232 | 243 | PPC64_LVS(30) |
| 233 | 244 | PPC64_LVS(31) |
| 234 | 245 | |
| 246 | #ifdef __LITTLE_ENDIAN__ | |
| 247 | #define PPC64_CLVS_RESTORE(n) \ | |
| 248 | addi 4, 3, PPC64_OFFS_FP + n * 16 ;\ | |
| 249 | lxvd2x n, 0, 4 ;\ | |
| 250 | xxswapd n, n | |
| 251 | #else | |
| 235 | 252 | #define PPC64_CLVS_RESTORE(n) \ |
| 236 | 253 | addi 4, 3, PPC64_OFFS_FP + n * 16 ;\ |
| 237 | 254 | lxvd2x n, 0, 4 |
| 255 | #endif | |
| 238 | 256 | |
| 239 | 257 | #if !defined(_AIX) |
| 240 | 258 | // use VRSAVE to conditionally restore the remaining VS regs, that are |
| ... | ... | @@ -1203,8 +1221,8 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind19Registers_loongarch6jumptoEv) |
| 1203 | 1221 | ld.d $r\i, $a0, (8 * \i) |
| 1204 | 1222 | .endr |
| 1205 | 1223 | |
| 1206 | ld.d $r4, $a0, (8 * 4) // restore $a0 last | |
| 1207 | ld.d $r1, $a0, (8 * 32) // load new pc into $ra | |
| 1224 | ld.d $ra, $a0, (8 * 32) // load new pc into $ra | |
| 1225 | ld.d $a0, $a0, (8 * 4) // restore $a0 last | |
| 1208 | 1226 | |
| 1209 | 1227 | jr $ra |
| 1210 | 1228 |
lib/libunwind/src/UnwindRegistersSave.S+11| ... | ... | @@ -351,9 +351,20 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) |
| 351 | 351 | addi 4, 3, PPC64_OFFS_FP |
| 352 | 352 | |
| 353 | 353 | // store VS register |
| 354 | #ifdef __LITTLE_ENDIAN__ | |
| 355 | // For little-endian targets, we need a swap since stxvd2x will store the | |
| 356 | // register in the incorrect doubleword order. | |
| 357 | // FIXME: when supporting targets older than Power9 on LE is no longer required | |
| 358 | // this can be changed to simply `stxv n, 16 * n(4)`. | |
| 354 | 359 | #define PPC64_STVS(n) \ |
| 360 | xxswapd n, n ;\ | |
| 355 | 361 | stxvd2x n, 0, 4 ;\ |
| 356 | 362 | addi 4, 4, 16 |
| 363 | #else | |
| 364 | #define PPC64_STVS(n) \ | |
| 365 | stxvd2x n, 0, 4 ;\ | |
| 366 | addi 4, 4, 16 | |
| 367 | #endif | |
| 357 | 368 | |
| 358 | 369 | PPC64_STVS(0) |
| 359 | 370 | PPC64_STVS(1) |
lib/libunwind/src/Unwind_AppleExtras.cpp deleted-113| ... | ... | @@ -1,113 +0,0 @@ |
| 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 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #include "config.h" | |
| 11 | ||
| 12 | ||
| 13 | // static linker symbols to prevent wrong two level namespace for _Unwind symbols | |
| 14 | #if defined(__arm__) | |
| 15 | #define NOT_HERE_BEFORE_5_0(sym) \ | |
| 16 | extern const char sym##_tmp30 __asm("$ld$hide$os3.0$_" #sym ); \ | |
| 17 | __attribute__((visibility("default"))) const char sym##_tmp30 = 0; \ | |
| 18 | extern const char sym##_tmp31 __asm("$ld$hide$os3.1$_" #sym ); \ | |
| 19 | __attribute__((visibility("default"))) const char sym##_tmp31 = 0; \ | |
| 20 | extern const char sym##_tmp32 __asm("$ld$hide$os3.2$_" #sym );\ | |
| 21 | __attribute__((visibility("default"))) const char sym##_tmp32 = 0; \ | |
| 22 | extern const char sym##_tmp40 __asm("$ld$hide$os4.0$_" #sym ); \ | |
| 23 | __attribute__((visibility("default"))) const char sym##_tmp40 = 0; \ | |
| 24 | extern const char sym##_tmp41 __asm("$ld$hide$os4.1$_" #sym ); \ | |
| 25 | __attribute__((visibility("default"))) const char sym##_tmp41 = 0; \ | |
| 26 | extern const char sym##_tmp42 __asm("$ld$hide$os4.2$_" #sym ); \ | |
| 27 | __attribute__((visibility("default"))) const char sym##_tmp42 = 0; \ | |
| 28 | extern const char sym##_tmp43 __asm("$ld$hide$os4.3$_" #sym ); \ | |
| 29 | __attribute__((visibility("default"))) const char sym##_tmp43 = 0; | |
| 30 | #elif defined(__aarch64__) | |
| 31 | #define NOT_HERE_BEFORE_10_6(sym) | |
| 32 | #define NEVER_HERE(sym) | |
| 33 | #else | |
| 34 | #define NOT_HERE_BEFORE_10_6(sym) \ | |
| 35 | extern const char sym##_tmp4 __asm("$ld$hide$os10.4$_" #sym ); \ | |
| 36 | __attribute__((visibility("default"))) const char sym##_tmp4 = 0; \ | |
| 37 | extern const char sym##_tmp5 __asm("$ld$hide$os10.5$_" #sym ); \ | |
| 38 | __attribute__((visibility("default"))) const char sym##_tmp5 = 0; | |
| 39 | #define NEVER_HERE(sym) \ | |
| 40 | extern const char sym##_tmp4 __asm("$ld$hide$os10.4$_" #sym ); \ | |
| 41 | __attribute__((visibility("default"))) const char sym##_tmp4 = 0; \ | |
| 42 | extern const char sym##_tmp5 __asm("$ld$hide$os10.5$_" #sym ); \ | |
| 43 | __attribute__((visibility("default"))) const char sym##_tmp5 = 0; \ | |
| 44 | extern const char sym##_tmp6 __asm("$ld$hide$os10.6$_" #sym ); \ | |
| 45 | __attribute__((visibility("default"))) const char sym##_tmp6 = 0; | |
| 46 | #endif | |
| 47 | ||
| 48 | ||
| 49 | #if defined(_LIBUNWIND_BUILD_ZERO_COST_APIS) | |
| 50 | ||
| 51 | // | |
| 52 | // symbols in libSystem.dylib in 10.6 and later, but are in libgcc_s.dylib in | |
| 53 | // earlier versions | |
| 54 | // | |
| 55 | NOT_HERE_BEFORE_10_6(_Unwind_DeleteException) | |
| 56 | NOT_HERE_BEFORE_10_6(_Unwind_Find_FDE) | |
| 57 | NOT_HERE_BEFORE_10_6(_Unwind_ForcedUnwind) | |
| 58 | NOT_HERE_BEFORE_10_6(_Unwind_GetGR) | |
| 59 | NOT_HERE_BEFORE_10_6(_Unwind_GetIP) | |
| 60 | NOT_HERE_BEFORE_10_6(_Unwind_GetLanguageSpecificData) | |
| 61 | NOT_HERE_BEFORE_10_6(_Unwind_GetRegionStart) | |
| 62 | NOT_HERE_BEFORE_10_6(_Unwind_RaiseException) | |
| 63 | NOT_HERE_BEFORE_10_6(_Unwind_Resume) | |
| 64 | NOT_HERE_BEFORE_10_6(_Unwind_SetGR) | |
| 65 | NOT_HERE_BEFORE_10_6(_Unwind_SetIP) | |
| 66 | NOT_HERE_BEFORE_10_6(_Unwind_Backtrace) | |
| 67 | NOT_HERE_BEFORE_10_6(_Unwind_FindEnclosingFunction) | |
| 68 | NOT_HERE_BEFORE_10_6(_Unwind_GetCFA) | |
| 69 | NOT_HERE_BEFORE_10_6(_Unwind_GetDataRelBase) | |
| 70 | NOT_HERE_BEFORE_10_6(_Unwind_GetTextRelBase) | |
| 71 | NOT_HERE_BEFORE_10_6(_Unwind_Resume_or_Rethrow) | |
| 72 | NOT_HERE_BEFORE_10_6(_Unwind_GetIPInfo) | |
| 73 | NOT_HERE_BEFORE_10_6(__register_frame) | |
| 74 | NOT_HERE_BEFORE_10_6(__deregister_frame) | |
| 75 | ||
| 76 | // | |
| 77 | // symbols in libSystem.dylib for compatibility, but we don't want any new code | |
| 78 | // using them | |
| 79 | // | |
| 80 | NEVER_HERE(__register_frame_info_bases) | |
| 81 | NEVER_HERE(__register_frame_info) | |
| 82 | NEVER_HERE(__register_frame_info_table_bases) | |
| 83 | NEVER_HERE(__register_frame_info_table) | |
| 84 | NEVER_HERE(__register_frame_table) | |
| 85 | NEVER_HERE(__deregister_frame_info) | |
| 86 | NEVER_HERE(__deregister_frame_info_bases) | |
| 87 | ||
| 88 | #endif // defined(_LIBUNWIND_BUILD_ZERO_COST_APIS) | |
| 89 | ||
| 90 | ||
| 91 | ||
| 92 | ||
| 93 | #if defined(_LIBUNWIND_BUILD_SJLJ_APIS) | |
| 94 | // | |
| 95 | // symbols in libSystem.dylib in iOS 5.0 and later, but are in libgcc_s.dylib in | |
| 96 | // earlier versions | |
| 97 | // | |
| 98 | NOT_HERE_BEFORE_5_0(_Unwind_GetLanguageSpecificData) | |
| 99 | NOT_HERE_BEFORE_5_0(_Unwind_GetRegionStart) | |
| 100 | NOT_HERE_BEFORE_5_0(_Unwind_GetIP) | |
| 101 | NOT_HERE_BEFORE_5_0(_Unwind_SetGR) | |
| 102 | NOT_HERE_BEFORE_5_0(_Unwind_SetIP) | |
| 103 | NOT_HERE_BEFORE_5_0(_Unwind_DeleteException) | |
| 104 | NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Register) | |
| 105 | NOT_HERE_BEFORE_5_0(_Unwind_GetGR) | |
| 106 | NOT_HERE_BEFORE_5_0(_Unwind_GetIPInfo) | |
| 107 | NOT_HERE_BEFORE_5_0(_Unwind_GetCFA) | |
| 108 | NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Resume) | |
| 109 | NOT_HERE_BEFORE_5_0(_Unwind_SjLj_RaiseException) | |
| 110 | NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Resume_or_Rethrow) | |
| 111 | NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Unregister) | |
| 112 | ||
| 113 | #endif // defined(_LIBUNWIND_BUILD_SJLJ_APIS) |
lib/libunwind/src/config.h+8-4| ... | ... | @@ -162,10 +162,14 @@ |
| 162 | 162 | #define _LIBUNWIND_LOG0(msg) |
| 163 | 163 | #define _LIBUNWIND_LOG(msg, ...) |
| 164 | 164 | #else |
| 165 | #define _LIBUNWIND_LOG0(msg) \ | |
| 166 | fprintf(stderr, "libunwind: " msg "\n") | |
| 167 | #define _LIBUNWIND_LOG(msg, ...) \ | |
| 168 | fprintf(stderr, "libunwind: " msg "\n", __VA_ARGS__) | |
| 165 | #define _LIBUNWIND_LOG0(msg) do { \ | |
| 166 | fprintf(stderr, "libunwind: " msg "\n"); \ | |
| 167 | fflush(stderr); \ | |
| 168 | } while (0) | |
| 169 | #define _LIBUNWIND_LOG(msg, ...) do { \ | |
| 170 | fprintf(stderr, "libunwind: " msg "\n", __VA_ARGS__); \ | |
| 171 | fflush(stderr); \ | |
| 172 | } while (0) | |
| 169 | 173 | #endif |
| 170 | 174 | |
| 171 | 175 | #if defined(NDEBUG) |
lib/libunwind/src/libunwind.cpp+80| ... | ... | @@ -349,7 +349,87 @@ void __unw_remove_dynamic_eh_frame_section(unw_word_t eh_frame_start) { |
| 349 | 349 | #endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) |
| 350 | 350 | #endif // !defined(__USING_SJLJ_EXCEPTIONS__) |
| 351 | 351 | |
| 352 | #ifdef __APPLE__ | |
| 352 | 353 | |
| 354 | namespace libunwind { | |
| 355 | ||
| 356 | static constexpr size_t MAX_DYNAMIC_UNWIND_SECTIONS_FINDERS = 8; | |
| 357 | ||
| 358 | static RWMutex findDynamicUnwindSectionsLock; | |
| 359 | static size_t numDynamicUnwindSectionsFinders = 0; | |
| 360 | static unw_find_dynamic_unwind_sections | |
| 361 | dynamicUnwindSectionsFinders[MAX_DYNAMIC_UNWIND_SECTIONS_FINDERS] = {0}; | |
| 362 | ||
| 363 | bool findDynamicUnwindSections(void *addr, unw_dynamic_unwind_sections *info) { | |
| 364 | bool found = false; | |
| 365 | findDynamicUnwindSectionsLock.lock_shared(); | |
| 366 | for (size_t i = 0; i != numDynamicUnwindSectionsFinders; ++i) { | |
| 367 | if (dynamicUnwindSectionsFinders[i]((unw_word_t)addr, info)) { | |
| 368 | found = true; | |
| 369 | break; | |
| 370 | } | |
| 371 | } | |
| 372 | findDynamicUnwindSectionsLock.unlock_shared(); | |
| 373 | return found; | |
| 374 | } | |
| 375 | ||
| 376 | } // namespace libunwind | |
| 377 | ||
| 378 | int __unw_add_find_dynamic_unwind_sections( | |
| 379 | unw_find_dynamic_unwind_sections find_dynamic_unwind_sections) { | |
| 380 | findDynamicUnwindSectionsLock.lock(); | |
| 381 | ||
| 382 | // Check that we have enough space... | |
| 383 | if (numDynamicUnwindSectionsFinders == MAX_DYNAMIC_UNWIND_SECTIONS_FINDERS) { | |
| 384 | findDynamicUnwindSectionsLock.unlock(); | |
| 385 | return UNW_ENOMEM; | |
| 386 | } | |
| 387 | ||
| 388 | // Check for value already present... | |
| 389 | for (size_t i = 0; i != numDynamicUnwindSectionsFinders; ++i) { | |
| 390 | if (dynamicUnwindSectionsFinders[i] == find_dynamic_unwind_sections) { | |
| 391 | findDynamicUnwindSectionsLock.unlock(); | |
| 392 | return UNW_EINVAL; | |
| 393 | } | |
| 394 | } | |
| 395 | ||
| 396 | // Success -- add callback entry. | |
| 397 | dynamicUnwindSectionsFinders[numDynamicUnwindSectionsFinders++] = | |
| 398 | find_dynamic_unwind_sections; | |
| 399 | findDynamicUnwindSectionsLock.unlock(); | |
| 400 | ||
| 401 | return UNW_ESUCCESS; | |
| 402 | } | |
| 403 | ||
| 404 | int __unw_remove_find_dynamic_unwind_sections( | |
| 405 | unw_find_dynamic_unwind_sections find_dynamic_unwind_sections) { | |
| 406 | findDynamicUnwindSectionsLock.lock(); | |
| 407 | ||
| 408 | // Find index to remove. | |
| 409 | size_t finderIdx = numDynamicUnwindSectionsFinders; | |
| 410 | for (size_t i = 0; i != numDynamicUnwindSectionsFinders; ++i) { | |
| 411 | if (dynamicUnwindSectionsFinders[i] == find_dynamic_unwind_sections) { | |
| 412 | finderIdx = i; | |
| 413 | break; | |
| 414 | } | |
| 415 | } | |
| 416 | ||
| 417 | // If no such registration is present then error out. | |
| 418 | if (finderIdx == numDynamicUnwindSectionsFinders) { | |
| 419 | findDynamicUnwindSectionsLock.unlock(); | |
| 420 | return UNW_EINVAL; | |
| 421 | } | |
| 422 | ||
| 423 | // Remove entry. | |
| 424 | for (size_t i = finderIdx; i != numDynamicUnwindSectionsFinders - 1; ++i) | |
| 425 | dynamicUnwindSectionsFinders[i] = dynamicUnwindSectionsFinders[i + 1]; | |
| 426 | dynamicUnwindSectionsFinders[--numDynamicUnwindSectionsFinders] = nullptr; | |
| 427 | ||
| 428 | findDynamicUnwindSectionsLock.unlock(); | |
| 429 | return UNW_ESUCCESS; | |
| 430 | } | |
| 431 | ||
| 432 | #endif // __APPLE__ | |
| 353 | 433 | |
| 354 | 434 | // Add logging hooks in Debug builds only |
| 355 | 435 | #ifndef NDEBUG |
lib/libunwind/src/libunwind_ext.h+65| ... | ... | @@ -58,6 +58,71 @@ extern void __unw_remove_dynamic_fde(unw_word_t fde); |
| 58 | 58 | extern void __unw_add_dynamic_eh_frame_section(unw_word_t eh_frame_start); |
| 59 | 59 | extern void __unw_remove_dynamic_eh_frame_section(unw_word_t eh_frame_start); |
| 60 | 60 | |
| 61 | #ifdef __APPLE__ | |
| 62 | ||
| 63 | // Holds a description of the object-format-header (if any) and unwind info | |
| 64 | // sections for a given address: | |
| 65 | // | |
| 66 | // * dso_base should point to a header for the JIT'd object containing the | |
| 67 | // given address. The header's type should match the format type that | |
| 68 | // libunwind was compiled for (so a mach_header or mach_header_64 on Darwin). | |
| 69 | // A value of zero indicates that no such header exists. | |
| 70 | // | |
| 71 | // * dwarf_section and dwarf_section_length hold the address range of a DWARF | |
| 72 | // eh-frame section associated with the given address, if any. If the | |
| 73 | // dwarf_section_length field is zero it indicates that no such section | |
| 74 | // exists (and in this case dwarf_section should also be set to zero). | |
| 75 | // | |
| 76 | // * compact_unwind_section and compact_unwind_section_length hold the address | |
| 77 | // range of a compact-unwind info section associated with the given address, | |
| 78 | // if any. If the compact_unwind_section_length field is zero it indicates | |
| 79 | // that no such section exists (and in this case compact_unwind_section | |
| 80 | // should also be set to zero). | |
| 81 | // | |
| 82 | // See the unw_find_dynamic_unwind_sections type below for more details. | |
| 83 | struct unw_dynamic_unwind_sections { | |
| 84 | unw_word_t dso_base; | |
| 85 | unw_word_t dwarf_section; | |
| 86 | size_t dwarf_section_length; | |
| 87 | unw_word_t compact_unwind_section; | |
| 88 | size_t compact_unwind_section_length; | |
| 89 | }; | |
| 90 | ||
| 91 | // Typedef for unwind-info lookup callbacks. Functions of this type can be | |
| 92 | // registered and deregistered using __unw_add_find_dynamic_unwind_sections | |
| 93 | // and __unw_remove_find_dynamic_unwind_sections respectively. | |
| 94 | // | |
| 95 | // An unwind-info lookup callback should return 1 to indicate that it found | |
| 96 | // unwind-info for the given address, or 0 to indicate that it did not find | |
| 97 | // unwind-info for the given address. If found, the callback should populate | |
| 98 | // some or all of the fields of the info argument (which is guaranteed to be | |
| 99 | // non-null with all fields zero-initialized): | |
| 100 | typedef int (*unw_find_dynamic_unwind_sections)( | |
| 101 | unw_word_t addr, struct unw_dynamic_unwind_sections *info); | |
| 102 | ||
| 103 | // Register a dynamic unwind-info lookup callback. If libunwind does not find | |
| 104 | // unwind info for a given frame in the executable program or normal dynamic | |
| 105 | // shared objects then it will call all registered dynamic lookup functions | |
| 106 | // in registration order until either one of them returns true, or the end | |
| 107 | // of the list is reached. This lookup will happen before libunwind searches | |
| 108 | // any eh-frames registered via __register_frame or | |
| 109 | // __unw_add_dynamic_eh_frame_section. | |
| 110 | // | |
| 111 | // Returns UNW_ESUCCESS for successful registrations. If the given callback | |
| 112 | // has already been registered then UNW_EINVAL will be returned. If all | |
| 113 | // available callback entries are in use then UNW_ENOMEM will be returned. | |
| 114 | extern int __unw_add_find_dynamic_unwind_sections( | |
| 115 | unw_find_dynamic_unwind_sections find_dynamic_unwind_sections); | |
| 116 | ||
| 117 | // Deregister a dynacim unwind-info lookup callback. | |
| 118 | // | |
| 119 | // Returns UNW_ESUCCESS for successful deregistrations. If the given callback | |
| 120 | // has already been registered then UNW_EINVAL will be returned. | |
| 121 | extern int __unw_remove_find_dynamic_unwind_sections( | |
| 122 | unw_find_dynamic_unwind_sections find_dynamic_unwind_sections); | |
| 123 | ||
| 124 | #endif | |
| 125 | ||
| 61 | 126 | #if defined(_LIBUNWIND_ARM_EHABI) |
| 62 | 127 | extern const uint32_t* decode_eht_entry(const uint32_t*, size_t*, size_t*); |
| 63 | 128 | extern _Unwind_Reason_Code _Unwind_VRS_Interpret(_Unwind_Context *context, |