| 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,9 +196,9 @@ |
| 196 | # define _LIBUNWIND_TARGET_RISCV 1 | 196 | # define _LIBUNWIND_TARGET_RISCV 1 |
| 197 | # define _LIBUNWIND_TARGET_VE 1 | 197 | # define _LIBUNWIND_TARGET_VE 1 |
| 198 | # define _LIBUNWIND_TARGET_S390X 1 | 198 | # define _LIBUNWIND_TARGET_S390X 1 |
| 199 | #define _LIBUNWIND_TARGET_LOONGARCH 1 | 199 | #define _LIBUNWIND_TARGET_LOONGARCH 1 |
| 200 | # define _LIBUNWIND_CONTEXT_SIZE 167 | 200 | # define _LIBUNWIND_CONTEXT_SIZE 167 |
| 201 | # define _LIBUNWIND_CURSOR_SIZE 179 | 201 | # define _LIBUNWIND_CURSOR_SIZE 204 |
| 202 | # define _LIBUNWIND_HIGHEST_DWARF_REGISTER 287 | 202 | # define _LIBUNWIND_HIGHEST_DWARF_REGISTER 287 |
| 203 | #endif // _LIBUNWIND_IS_NATIVE_ONLY | 203 | #endif // _LIBUNWIND_IS_NATIVE_ONLY |
| 204 | 204 |
lib/libunwind/include/unwind.h+2-2| ... | @@ -56,9 +56,9 @@ typedef enum { | ... | @@ -56,9 +56,9 @@ typedef enum { |
| 56 | typedef struct _Unwind_Context _Unwind_Context; // opaque | 56 | typedef struct _Unwind_Context _Unwind_Context; // opaque |
| 57 | 57 | ||
| 58 | #if defined(_LIBUNWIND_ARM_EHABI) | 58 | #if defined(_LIBUNWIND_ARM_EHABI) |
| 59 | #include "unwind_arm_ehabi.h" | 59 | #include <unwind_arm_ehabi.h> |
| 60 | #else | 60 | #else |
| 61 | #include "unwind_itanium.h" | 61 | #include <unwind_itanium.h> |
| 62 | #endif | 62 | #endif |
| 63 | 63 | ||
| 64 | typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) | 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,6 +66,10 @@ char *getFuncNameFromTBTable(uintptr_t pc, uint16_t &NameLen, |
| 66 | // In 10.7.0 or later, libSystem.dylib implements this function. | 66 | // In 10.7.0 or later, libSystem.dylib implements this function. |
| 67 | extern "C" bool _dyld_find_unwind_sections(void *, dyld_unwind_sections *); | 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 | #elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL) | 73 | #elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL) |
| 70 | 74 | ||
| 71 | // When statically linked on bare-metal, the symbols for the EH table are looked | 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,6 +501,22 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr, |
| 497 | info.compact_unwind_section_length = (size_t)dyldInfo.compact_unwind_section_length; | 501 | info.compact_unwind_section_length = (size_t)dyldInfo.compact_unwind_section_length; |
| 498 | return true; | 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 | #elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL) | 520 | #elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL) |
| 501 | info.dso_base = 0; | 521 | info.dso_base = 0; |
| 502 | // Bare metal is statically linked, so no need to ask the dynamic loader | 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,7 +224,8 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc, |
| 224 | p &= ~0xfULL; | 224 | p &= ~0xfULL; |
| 225 | // CFA is the bottom of the current stack frame. | 225 | // CFA is the bottom of the current stack frame. |
| 226 | for (; p < cfa; p += 16) { | 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 | "stg %[Ptr], [%[Ptr]]\n" | 229 | "stg %[Ptr], [%[Ptr]]\n" |
| 229 | : | 230 | : |
| 230 | : [Ptr] "r"(p) | 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,7 +709,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, |
| 709 | // Update info about this frame. | 709 | // Update info about this frame. |
| 710 | unw_proc_info_t frameInfo; | 710 | unw_proc_info_t frameInfo; |
| 711 | if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) { | 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 | "failed => _URC_END_OF_STACK", | 713 | "failed => _URC_END_OF_STACK", |
| 714 | (void *)exception_object); | 714 | (void *)exception_object); |
| 715 | return _URC_FATAL_PHASE2_ERROR; | 715 | return _URC_FATAL_PHASE2_ERROR; |
| ... | @@ -885,8 +885,11 @@ _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) { | ... | @@ -885,8 +885,11 @@ _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) { |
| 885 | return result; | 885 | return result; |
| 886 | } | 886 | } |
| 887 | 887 | ||
| 888 | static uint64_t ValueAsBitPattern(_Unwind_VRS_DataRepresentation representation, | 888 | // Only used in _LIBUNWIND_TRACE_API, which is a no-op when assertions are |
| 889 | void* valuep) { | 889 | // disabled. |
| 890 | [[gnu::unused]] static uint64_t | ||
| 891 | ValueAsBitPattern(_Unwind_VRS_DataRepresentation representation, | ||
| 892 | const void *valuep) { | ||
| 890 | uint64_t value = 0; | 893 | uint64_t value = 0; |
| 891 | switch (representation) { | 894 | switch (representation) { |
| 892 | case _UVRSD_UINT32: | 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,11 +212,20 @@ __libunwind_seh_personality(int version, _Unwind_Action state, |
| 212 | ms_exc.ExceptionInformation[2] = state; | 212 | ms_exc.ExceptionInformation[2] = state; |
| 213 | DISPATCHER_CONTEXT *disp_ctx = | 213 | DISPATCHER_CONTEXT *disp_ctx = |
| 214 | __unw_seh_get_disp_ctx((unw_cursor_t *)context); | 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 | EXCEPTION_DISPOSITION ms_act = disp_ctx->LanguageHandler(&ms_exc, | 220 | EXCEPTION_DISPOSITION ms_act = disp_ctx->LanguageHandler(&ms_exc, |
| 216 | (PVOID)disp_ctx->EstablisherFrame, | 221 | (PVOID)disp_ctx->EstablisherFrame, |
| 217 | disp_ctx->ContextRecord, | 222 | disp_ctx->ContextRecord, |
| 218 | disp_ctx); | 223 | disp_ctx); |
| 224 | _LIBUNWIND_TRACE_UNWINDING("__libunwind_seh_personality() LanguageHandler " | ||
| 225 | "returned %d", | ||
| 226 | (int)ms_act); | ||
| 219 | switch (ms_act) { | 227 | switch (ms_act) { |
| 228 | case ExceptionContinueExecution: return _URC_END_OF_STACK; | ||
| 220 | case ExceptionContinueSearch: return _URC_CONTINUE_UNWIND; | 229 | case ExceptionContinueSearch: return _URC_CONTINUE_UNWIND; |
| 221 | case 4 /*ExceptionExecuteHandler*/: | 230 | case 4 /*ExceptionExecuteHandler*/: |
| 222 | return phase2 ? _URC_INSTALL_CONTEXT : _URC_HANDLER_FOUND; | 231 | return phase2 ? _URC_INSTALL_CONTEXT : _URC_HANDLER_FOUND; |
| ... | @@ -238,7 +247,7 @@ unwind_phase2_forced(unw_context_t *uc, | ... | @@ -238,7 +247,7 @@ unwind_phase2_forced(unw_context_t *uc, |
| 238 | // Update info about this frame. | 247 | // Update info about this frame. |
| 239 | unw_proc_info_t frameInfo; | 248 | unw_proc_info_t frameInfo; |
| 240 | if (__unw_get_proc_info(&cursor2, &frameInfo) != UNW_ESUCCESS) { | 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 | "failed => _URC_END_OF_STACK", | 251 | "failed => _URC_END_OF_STACK", |
| 243 | (void *)exception_object); | 252 | (void *)exception_object); |
| 244 | return _URC_FATAL_PHASE2_ERROR; | 253 | return _URC_FATAL_PHASE2_ERROR; |
| ... | @@ -304,6 +313,12 @@ unwind_phase2_forced(unw_context_t *uc, | ... | @@ -304,6 +313,12 @@ unwind_phase2_forced(unw_context_t *uc, |
| 304 | // We may get control back if landing pad calls _Unwind_Resume(). | 313 | // We may get control back if landing pad calls _Unwind_Resume(). |
| 305 | __unw_resume(&cursor2); | 314 | __unw_resume(&cursor2); |
| 306 | break; | 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 | default: | 322 | default: |
| 308 | // Personality routine returned an unknown result code. | 323 | // Personality routine returned an unknown result code. |
| 309 | _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " | 324 | _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " |
| ... | @@ -312,6 +327,8 @@ unwind_phase2_forced(unw_context_t *uc, | ... | @@ -312,6 +327,8 @@ unwind_phase2_forced(unw_context_t *uc, |
| 312 | (void *)exception_object, personalityResult); | 327 | (void *)exception_object, personalityResult); |
| 313 | return _URC_FATAL_PHASE2_ERROR; | 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,7 +31,8 @@ |
| 31 | #endif | 31 | #endif |
| 32 | 32 | ||
| 33 | #if defined(_LIBUNWIND_TARGET_LINUX) && \ | 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 | #include <sys/syscall.h> | 36 | #include <sys/syscall.h> |
| 36 | #include <sys/uio.h> | 37 | #include <sys/uio.h> |
| 37 | #include <unistd.h> | 38 | #include <unistd.h> |
| ... | @@ -506,7 +507,14 @@ public: | ... | @@ -506,7 +507,14 @@ public: |
| 506 | #endif | 507 | #endif |
| 507 | 508 | ||
| 508 | DISPATCHER_CONTEXT *getDispatcherContext() { return &_dispContext; } | 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 | // libunwind does not and should not depend on C++ library which means that we | 519 | // libunwind does not and should not depend on C++ library which means that we |
| 512 | // need our own definition of inline placement new. | 520 | // need our own definition of inline placement new. |
| ... | @@ -568,10 +576,12 @@ UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as) | ... | @@ -568,10 +576,12 @@ UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as) |
| 568 | "UnwindCursor<> requires more alignment than unw_cursor_t"); | 576 | "UnwindCursor<> requires more alignment than unw_cursor_t"); |
| 569 | memset(&_info, 0, sizeof(_info)); | 577 | memset(&_info, 0, sizeof(_info)); |
| 570 | memset(&_histTable, 0, sizeof(_histTable)); | 578 | memset(&_histTable, 0, sizeof(_histTable)); |
| 579 | memset(&_dispContext, 0, sizeof(_dispContext)); | ||
| 571 | _dispContext.ContextRecord = &_msContext; | 580 | _dispContext.ContextRecord = &_msContext; |
| 572 | _dispContext.HistoryTable = &_histTable; | 581 | _dispContext.HistoryTable = &_histTable; |
| 573 | // Initialize MS context from ours. | 582 | // Initialize MS context from ours. |
| 574 | R r(context); | 583 | R r(context); |
| 584 | RtlCaptureContext(&_msContext); | ||
| 575 | _msContext.ContextFlags = CONTEXT_CONTROL|CONTEXT_INTEGER|CONTEXT_FLOATING_POINT; | 585 | _msContext.ContextFlags = CONTEXT_CONTROL|CONTEXT_INTEGER|CONTEXT_FLOATING_POINT; |
| 576 | #if defined(_LIBUNWIND_TARGET_X86_64) | 586 | #if defined(_LIBUNWIND_TARGET_X86_64) |
| 577 | _msContext.Rax = r.getRegister(UNW_X86_64_RAX); | 587 | _msContext.Rax = r.getRegister(UNW_X86_64_RAX); |
| ... | @@ -669,6 +679,7 @@ UnwindCursor<A, R>::UnwindCursor(CONTEXT *context, A &as) | ... | @@ -669,6 +679,7 @@ UnwindCursor<A, R>::UnwindCursor(CONTEXT *context, A &as) |
| 669 | "UnwindCursor<> does not fit in unw_cursor_t"); | 679 | "UnwindCursor<> does not fit in unw_cursor_t"); |
| 670 | memset(&_info, 0, sizeof(_info)); | 680 | memset(&_info, 0, sizeof(_info)); |
| 671 | memset(&_histTable, 0, sizeof(_histTable)); | 681 | memset(&_histTable, 0, sizeof(_histTable)); |
| 682 | memset(&_dispContext, 0, sizeof(_dispContext)); | ||
| 672 | _dispContext.ContextRecord = &_msContext; | 683 | _dispContext.ContextRecord = &_msContext; |
| 673 | _dispContext.HistoryTable = &_histTable; | 684 | _dispContext.HistoryTable = &_histTable; |
| 674 | _msContext = *context; | 685 | _msContext = *context; |
| ... | @@ -679,7 +690,7 @@ template <typename A, typename R> | ... | @@ -679,7 +690,7 @@ template <typename A, typename R> |
| 679 | bool UnwindCursor<A, R>::validReg(int regNum) { | 690 | bool UnwindCursor<A, R>::validReg(int regNum) { |
| 680 | if (regNum == UNW_REG_IP || regNum == UNW_REG_SP) return true; | 691 | if (regNum == UNW_REG_IP || regNum == UNW_REG_SP) return true; |
| 681 | #if defined(_LIBUNWIND_TARGET_X86_64) | 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 | #elif defined(_LIBUNWIND_TARGET_ARM) | 694 | #elif defined(_LIBUNWIND_TARGET_ARM) |
| 684 | if ((regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15) || | 695 | if ((regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15) || |
| 685 | regNum == UNW_ARM_RA_AUTH_CODE) | 696 | regNum == UNW_ARM_RA_AUTH_CODE) |
| ... | @@ -694,6 +705,7 @@ template <typename A, typename R> | ... | @@ -694,6 +705,7 @@ template <typename A, typename R> |
| 694 | unw_word_t UnwindCursor<A, R>::getReg(int regNum) { | 705 | unw_word_t UnwindCursor<A, R>::getReg(int regNum) { |
| 695 | switch (regNum) { | 706 | switch (regNum) { |
| 696 | #if defined(_LIBUNWIND_TARGET_X86_64) | 707 | #if defined(_LIBUNWIND_TARGET_X86_64) |
| 708 | case UNW_X86_64_RIP: | ||
| 697 | case UNW_REG_IP: return _msContext.Rip; | 709 | case UNW_REG_IP: return _msContext.Rip; |
| 698 | case UNW_X86_64_RAX: return _msContext.Rax; | 710 | case UNW_X86_64_RAX: return _msContext.Rax; |
| 699 | case UNW_X86_64_RDX: return _msContext.Rdx; | 711 | case UNW_X86_64_RDX: return _msContext.Rdx; |
| ... | @@ -744,6 +756,7 @@ template <typename A, typename R> | ... | @@ -744,6 +756,7 @@ template <typename A, typename R> |
| 744 | void UnwindCursor<A, R>::setReg(int regNum, unw_word_t value) { | 756 | void UnwindCursor<A, R>::setReg(int regNum, unw_word_t value) { |
| 745 | switch (regNum) { | 757 | switch (regNum) { |
| 746 | #if defined(_LIBUNWIND_TARGET_X86_64) | 758 | #if defined(_LIBUNWIND_TARGET_X86_64) |
| 759 | case UNW_X86_64_RIP: | ||
| 747 | case UNW_REG_IP: _msContext.Rip = value; break; | 760 | case UNW_REG_IP: _msContext.Rip = value; break; |
| 748 | case UNW_X86_64_RAX: _msContext.Rax = value; break; | 761 | case UNW_X86_64_RAX: _msContext.Rax = value; break; |
| 749 | case UNW_X86_64_RDX: _msContext.Rdx = value; break; | 762 | case UNW_X86_64_RDX: _msContext.Rdx = value; break; |
| ... | @@ -981,6 +994,10 @@ private: | ... | @@ -981,6 +994,10 @@ private: |
| 981 | bool setInfoForSigReturn(Registers_arm64 &); | 994 | bool setInfoForSigReturn(Registers_arm64 &); |
| 982 | int stepThroughSigReturn(Registers_arm64 &); | 995 | int stepThroughSigReturn(Registers_arm64 &); |
| 983 | #endif | 996 | #endif |
| 997 | #if defined(_LIBUNWIND_TARGET_RISCV) | ||
| 998 | bool setInfoForSigReturn(Registers_riscv &); | ||
| 999 | int stepThroughSigReturn(Registers_riscv &); | ||
| 1000 | #endif | ||
| 984 | #if defined(_LIBUNWIND_TARGET_S390X) | 1001 | #if defined(_LIBUNWIND_TARGET_S390X) |
| 985 | bool setInfoForSigReturn(Registers_s390x &); | 1002 | bool setInfoForSigReturn(Registers_s390x &); |
| 986 | int stepThroughSigReturn(Registers_s390x &); | 1003 | int stepThroughSigReturn(Registers_s390x &); |
| ... | @@ -1978,6 +1995,9 @@ bool UnwindCursor<A, R>::getInfoFromSEH(pint_t pc) { | ... | @@ -1978,6 +1995,9 @@ bool UnwindCursor<A, R>::getInfoFromSEH(pint_t pc) { |
| 1978 | uint32_t lastcode = (xdata->CountOfCodes + 1) & ~1; | 1995 | uint32_t lastcode = (xdata->CountOfCodes + 1) & ~1; |
| 1979 | const uint32_t *handler = reinterpret_cast<uint32_t *>(&xdata->UnwindCodes[lastcode]); | 1996 | const uint32_t *handler = reinterpret_cast<uint32_t *>(&xdata->UnwindCodes[lastcode]); |
| 1980 | _info.lsda = reinterpret_cast<unw_word_t>(handler+1); | 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 | if (*handler) { | 2001 | if (*handler) { |
| 1982 | _info.handler = reinterpret_cast<unw_word_t>(__libunwind_seh_personality); | 2002 | _info.handler = reinterpret_cast<unw_word_t>(__libunwind_seh_personality); |
| 1983 | } else | 2003 | } else |
| ... | @@ -2705,6 +2725,60 @@ int UnwindCursor<A, R>::stepThroughSigReturn(Registers_arm64 &) { | ... | @@ -2705,6 +2725,60 @@ int UnwindCursor<A, R>::stepThroughSigReturn(Registers_arm64 &) { |
| 2705 | #endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && | 2725 | #endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && |
| 2706 | // defined(_LIBUNWIND_TARGET_AARCH64) | 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 | #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && \ | 2782 | #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && \ |
| 2709 | defined(_LIBUNWIND_TARGET_S390X) | 2783 | defined(_LIBUNWIND_TARGET_S390X) |
| 2710 | template <typename A, typename R> | 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,7 +167,7 @@ _Unwind_Backtrace(_Unwind_Trace_Fn callback, void *ref) { |
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | // Update the pr_cache in the mock exception object. | 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 | ex.pr_cache.fnstart = frameInfo.start_ip; | 171 | ex.pr_cache.fnstart = frameInfo.start_ip; |
| 172 | ex.pr_cache.ehtp = (_Unwind_EHT_Header *) unwindInfo; | 172 | ex.pr_cache.ehtp = (_Unwind_EHT_Header *) unwindInfo; |
| 173 | ex.pr_cache.additional= frameInfo.flags; | 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,7 +321,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, |
| 321 | unw_proc_info_t frameInfo; | 321 | unw_proc_info_t frameInfo; |
| 322 | if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) { | 322 | if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) { |
| 323 | _LIBUNWIND_TRACE_UNWINDING( | 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 | "failed => _URC_END_OF_STACK", | 325 | "failed => _URC_END_OF_STACK", |
| 326 | (void *)exception_object); | 326 | (void *)exception_object); |
| 327 | return _URC_FATAL_PHASE2_ERROR; | 327 | return _URC_FATAL_PHASE2_ERROR; |
lib/libunwind/src/UnwindRegistersRestore.S+20-2| ... | @@ -194,9 +194,20 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv) | ... | @@ -194,9 +194,20 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv) |
| 194 | addi 4, 3, PPC64_OFFS_FP | 194 | addi 4, 3, PPC64_OFFS_FP |
| 195 | 195 | ||
| 196 | // load VS register | 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 | #define PPC64_LVS(n) \ | 202 | #define PPC64_LVS(n) \ |
| 198 | lxvd2x n, 0, 4 ;\ | 203 | lxvd2x n, 0, 4 ;\ |
| 204 | xxswapd n, n ;\ | ||
| 199 | addi 4, 4, 16 | 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 | // restore the first 32 VS regs (and also all floating point regs) | 212 | // restore the first 32 VS regs (and also all floating point regs) |
| 202 | PPC64_LVS(0) | 213 | PPC64_LVS(0) |
| ... | @@ -232,9 +243,16 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv) | ... | @@ -232,9 +243,16 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv) |
| 232 | PPC64_LVS(30) | 243 | PPC64_LVS(30) |
| 233 | PPC64_LVS(31) | 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 | #define PPC64_CLVS_RESTORE(n) \ | 252 | #define PPC64_CLVS_RESTORE(n) \ |
| 236 | addi 4, 3, PPC64_OFFS_FP + n * 16 ;\ | 253 | addi 4, 3, PPC64_OFFS_FP + n * 16 ;\ |
| 237 | lxvd2x n, 0, 4 | 254 | lxvd2x n, 0, 4 |
| 255 | #endif | ||
| 238 | 256 | ||
| 239 | #if !defined(_AIX) | 257 | #if !defined(_AIX) |
| 240 | // use VRSAVE to conditionally restore the remaining VS regs, that are | 258 | // use VRSAVE to conditionally restore the remaining VS regs, that are |
| ... | @@ -1203,8 +1221,8 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind19Registers_loongarch6jumptoEv) | ... | @@ -1203,8 +1221,8 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind19Registers_loongarch6jumptoEv) |
| 1203 | ld.d $r\i, $a0, (8 * \i) | 1221 | ld.d $r\i, $a0, (8 * \i) |
| 1204 | .endr | 1222 | .endr |
| 1205 | 1223 | ||
| 1206 | ld.d $r4, $a0, (8 * 4) // restore $a0 last | 1224 | ld.d $ra, $a0, (8 * 32) // load new pc into $ra |
| 1207 | ld.d $r1, $a0, (8 * 32) // load new pc into $ra | 1225 | ld.d $a0, $a0, (8 * 4) // restore $a0 last |
| 1208 | 1226 | ||
| 1209 | jr $ra | 1227 | jr $ra |
| 1210 | 1228 |
lib/libunwind/src/UnwindRegistersSave.S+11| ... | @@ -351,9 +351,20 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) | ... | @@ -351,9 +351,20 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) |
| 351 | addi 4, 3, PPC64_OFFS_FP | 351 | addi 4, 3, PPC64_OFFS_FP |
| 352 | 352 | ||
| 353 | // store VS register | 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 | #define PPC64_STVS(n) \ | 359 | #define PPC64_STVS(n) \ |
| 360 | xxswapd n, n ;\ | ||
| 355 | stxvd2x n, 0, 4 ;\ | 361 | stxvd2x n, 0, 4 ;\ |
| 356 | addi 4, 4, 16 | 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 | PPC64_STVS(0) | 369 | PPC64_STVS(0) |
| 359 | PPC64_STVS(1) | 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,10 +162,14 @@ |
| 162 | #define _LIBUNWIND_LOG0(msg) | 162 | #define _LIBUNWIND_LOG0(msg) |
| 163 | #define _LIBUNWIND_LOG(msg, ...) | 163 | #define _LIBUNWIND_LOG(msg, ...) |
| 164 | #else | 164 | #else |
| 165 | #define _LIBUNWIND_LOG0(msg) \ | 165 | #define _LIBUNWIND_LOG0(msg) do { \ |
| 166 | fprintf(stderr, "libunwind: " msg "\n") | 166 | fprintf(stderr, "libunwind: " msg "\n"); \ |
| 167 | #define _LIBUNWIND_LOG(msg, ...) \ | 167 | fflush(stderr); \ |
| 168 | fprintf(stderr, "libunwind: " msg "\n", __VA_ARGS__) | 168 | } while (0) |
| 169 | #define _LIBUNWIND_LOG(msg, ...) do { \ | ||
| 170 | fprintf(stderr, "libunwind: " msg "\n", __VA_ARGS__); \ | ||
| 171 | fflush(stderr); \ | ||
| 172 | } while (0) | ||
| 169 | #endif | 173 | #endif |
| 170 | 174 | ||
| 171 | #if defined(NDEBUG) | 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,7 +349,87 @@ void __unw_remove_dynamic_eh_frame_section(unw_word_t eh_frame_start) { |
| 349 | #endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) | 349 | #endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) |
| 350 | #endif // !defined(__USING_SJLJ_EXCEPTIONS__) | 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 | // Add logging hooks in Debug builds only | 434 | // Add logging hooks in Debug builds only |
| 355 | #ifndef NDEBUG | 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,6 +58,71 @@ extern void __unw_remove_dynamic_fde(unw_word_t fde); |
| 58 | extern void __unw_add_dynamic_eh_frame_section(unw_word_t eh_frame_start); | 58 | extern void __unw_add_dynamic_eh_frame_section(unw_word_t eh_frame_start); |
| 59 | extern void __unw_remove_dynamic_eh_frame_section(unw_word_t eh_frame_start); | 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 | #if defined(_LIBUNWIND_ARM_EHABI) | 126 | #if defined(_LIBUNWIND_ARM_EHABI) |
| 62 | extern const uint32_t* decode_eht_entry(const uint32_t*, size_t*, size_t*); | 127 | extern const uint32_t* decode_eht_entry(const uint32_t*, size_t*, size_t*); |
| 63 | extern _Unwind_Reason_Code _Unwind_VRS_Interpret(_Unwind_Context *context, | 128 | extern _Unwind_Reason_Code _Unwind_VRS_Interpret(_Unwind_Context *context, |