https://github.com/safocl updated https://github.com/llvm/llvm-project/pull/189209
>From c24f954692a77c5ce7697ccfcccee632a6664cb2 Mon Sep 17 00:00:00 2001 From: Safocl Stollmannovic <[email protected]> Date: Sun, 29 Mar 2026 05:40:54 +0400 Subject: [PATCH 1/2] libunwind: fix some invalid `reinterpret_cast`s Some `reinterpret_cast`s were invalid. https://eel.is/c++draft/basic.compound#5 https://eel.is/c++draft/basic.compound#6 https://eel.is/c++draft/basic.lval#11 https://eel.is/c++draft/expr.static.cast#12 https://eel.is/c++draft/expr.reinterpret.cast#7 https://en.cppreference.com/w/cpp/utility/launder.html --- libunwind/include/libunwind.h | 8 +++++++- libunwind/src/Unwind-seh.cpp | 21 +++++++++------------ libunwind/src/UnwindCursor.hpp | 23 +++++++++++++++++------ libunwind/src/libunwind.cpp | 33 ++++++++++++++++----------------- 4 files changed, 49 insertions(+), 36 deletions(-) diff --git a/libunwind/include/libunwind.h b/libunwind/include/libunwind.h index 6c2dfe58e53bf..5a3e0c4e2f7bd 100644 --- a/libunwind/include/libunwind.h +++ b/libunwind/include/libunwind.h @@ -176,7 +176,13 @@ struct unw_context_t { typedef struct unw_context_t unw_context_t; struct unw_cursor_t { - uint64_t data[_LIBUNWIND_CURSOR_SIZE]; + /* Only the “array of N unsigned char” or of type “array of N std::byte” types can used as + storage (https://eel.is/c++draft/intro.object#3) */ + union { + unsigned char data[_LIBUNWIND_CURSOR_SIZE * sizeof(uint64_t)]; + /* `aligner` exists only for alignment */ + uint64_t aligner__[_LIBUNWIND_CURSOR_SIZE]; + } u; } LIBUNWIND_CURSOR_ALIGNMENT_ATTR; typedef struct unw_cursor_t unw_cursor_t; diff --git a/libunwind/src/Unwind-seh.cpp b/libunwind/src/Unwind-seh.cpp index 0b1930b44d1c6..3435e8b81396e 100644 --- a/libunwind/src/Unwind-seh.cpp +++ b/libunwind/src/Unwind-seh.cpp @@ -498,24 +498,21 @@ _Unwind_GetRegionStart(struct _Unwind_Context *context) { static int __unw_init_seh(unw_cursor_t *cursor, CONTEXT *context) { #ifdef _LIBUNWIND_TARGET_X86_64 - new (reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_x86_64> *>(cursor)) + auto *co = new (reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_x86_64> *>(cursor->u.data)) UnwindCursor<LocalAddressSpace, Registers_x86_64>( context, LocalAddressSpace::sThisAddressSpace); - auto *co = reinterpret_cast<AbstractUnwindCursor *>(cursor); co->setInfoBasedOnIPRegister(); return UNW_ESUCCESS; #elif defined(_LIBUNWIND_TARGET_ARM) - new (reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm> *>(cursor)) + auto *co = new (reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm> *>(cursor->u.data)) UnwindCursor<LocalAddressSpace, Registers_arm>( context, LocalAddressSpace::sThisAddressSpace); - auto *co = reinterpret_cast<AbstractUnwindCursor *>(cursor); co->setInfoBasedOnIPRegister(); return UNW_ESUCCESS; #elif defined(_LIBUNWIND_TARGET_AARCH64) - new (reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm64> *>(cursor)) + auto *co = new (reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm64> *>(cursor->u.data)) UnwindCursor<LocalAddressSpace, Registers_arm64>( context, LocalAddressSpace::sThisAddressSpace); - auto *co = reinterpret_cast<AbstractUnwindCursor *>(cursor); co->setInfoBasedOnIPRegister(); return UNW_ESUCCESS; #else @@ -525,11 +522,11 @@ static int __unw_init_seh(unw_cursor_t *cursor, CONTEXT *context) { static DISPATCHER_CONTEXT *__unw_seh_get_disp_ctx(unw_cursor_t *cursor) { #ifdef _LIBUNWIND_TARGET_X86_64 - return reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_x86_64> *>(cursor)->getDispatcherContext(); + return reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_x86_64> *>(cursor->u.data)->getDispatcherContext(); #elif defined(_LIBUNWIND_TARGET_ARM) - return reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm> *>(cursor)->getDispatcherContext(); + return reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm> *>(cursor->u.data)->getDispatcherContext(); #elif defined(_LIBUNWIND_TARGET_AARCH64) - return reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm64> *>(cursor)->getDispatcherContext(); + return reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm64> *>(cursor->u.data)->getDispatcherContext(); #else return nullptr; #endif @@ -538,11 +535,11 @@ static DISPATCHER_CONTEXT *__unw_seh_get_disp_ctx(unw_cursor_t *cursor) { static void __unw_seh_set_disp_ctx(unw_cursor_t *cursor, DISPATCHER_CONTEXT *disp) { #ifdef _LIBUNWIND_TARGET_X86_64 - reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_x86_64> *>(cursor)->setDispatcherContext(disp); + reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_x86_64> *>(cursor->u.data)->setDispatcherContext(disp); #elif defined(_LIBUNWIND_TARGET_ARM) - reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm> *>(cursor)->setDispatcherContext(disp); + reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm> *>(cursor->u.data)->setDispatcherContext(disp); #elif defined(_LIBUNWIND_TARGET_AARCH64) - reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm64> *>(cursor)->setDispatcherContext(disp); + reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm64> *>(cursor->u.data)->setDispatcherContext(disp); #endif } diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp index ff92c9e0a844a..2e207d692f184 100644 --- a/libunwind/src/UnwindCursor.hpp +++ b/libunwind/src/UnwindCursor.hpp @@ -2114,13 +2114,24 @@ bool UnwindCursor<A, R>::getInfoFromSEH(pint_t pc) { // follows the UNWIND_INFO. (This follows how both Clang and MSVC emit // these structures.) // N.B. UNWIND_INFO structs are DWORD-aligned. - uint32_t lastcode = (xdata->CountOfCodes + 1) & ~1; - const uint32_t *handler = reinterpret_cast<uint32_t *>(&xdata->UnwindCodes[lastcode]); - _info.lsda = reinterpret_cast<unw_word_t>(handler+1); + + // uint32_t lastcode = (xdata->CountOfCodes + 1) & ~1; + // NOTE: lastcode can be equal to or greater than 2, then accessing UnwindCodes[lastcode] is + // out of bound (i.e. undefined behavior). The external memory outside the class object + // cannot be reached from a pointer to a subobject. The only valid case is when CountOfCodes + // is 0, and then lastcode will be equal 0. + // However, `reinterpret_cast` from a pointer to uint16[2] to a pointer to uint32 is not + // allowed in any case (https://eel.is/c++draft/basic.compound#5, + // https://eel.is/c++draft/basic.lval#11). (https://godbolt.org/z/vY1zKEvo6) + uint32_t handler; + memcpy(&handler, xdata->UnwindCodes, sizeof(uint32_t)); + // FIXME: Does `xdata` actually point to an array of UNWIND_INFO? + // https://github.com/cplusplus/CWG/issues/874 + _info.lsda = reinterpret_cast<unw_word_t>(xdata+1); _dispContext.HandlerData = reinterpret_cast<void *>(_info.lsda); _dispContext.LanguageHandler = - reinterpret_cast<EXCEPTION_ROUTINE *>(base + *handler); - if (*handler) { + reinterpret_cast<EXCEPTION_ROUTINE *>(base + handler); + if (handler) { _info.handler = reinterpret_cast<unw_word_t>(__libunwind_seh_personality); } else _info.handler = 0; @@ -3351,7 +3362,7 @@ bool UnwindCursor<A, R>::isReadableAddr(const pint_t addr) const { #if defined(_LIBUNWIND_USE_CET) || defined(_LIBUNWIND_USE_GCS) extern "C" void *__libunwind_shstk_get_registers(unw_cursor_t *cursor) { - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; + AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); return co->get_registers(); } #endif diff --git a/libunwind/src/libunwind.cpp b/libunwind/src/libunwind.cpp index 0b9d56ec805bc..152b0cfceb5be 100644 --- a/libunwind/src/libunwind.cpp +++ b/libunwind/src/libunwind.cpp @@ -83,11 +83,10 @@ _LIBUNWIND_HIDDEN int __unw_init_local(unw_cursor_t *cursor, # error Architecture not supported #endif // Use "placement new" to allocate UnwindCursor in the cursor buffer. - new (reinterpret_cast<UnwindCursor<LocalAddressSpace, REGISTER_KIND> *>(cursor)) + auto *co = new (reinterpret_cast<UnwindCursor<LocalAddressSpace, REGISTER_KIND> *>(cursor->u.data)) UnwindCursor<LocalAddressSpace, REGISTER_KIND>( context, LocalAddressSpace::sThisAddressSpace); #undef REGISTER_KIND - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; co->setInfoBasedOnIPRegister(); return UNW_ESUCCESS; @@ -100,7 +99,7 @@ _LIBUNWIND_HIDDEN int __unw_get_reg(unw_cursor_t *cursor, unw_regnum_t regNum, _LIBUNWIND_TRACE_API("__unw_get_reg(cursor=%p, regNum=%d, &value=%p)", static_cast<void *>(cursor), regNum, static_cast<void *>(value)); - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; + AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); if (co->validReg(regNum)) { *value = co->getReg(regNum); return UNW_ESUCCESS; @@ -116,7 +115,7 @@ _LIBUNWIND_HIDDEN int __unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum, ")", static_cast<void *>(cursor), regNum, value); typedef LocalAddressSpace::pint_t pint_t; - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; + AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); if (co->validReg(regNum)) { // special case altering IP to re-find info (being called by personality // function) @@ -188,7 +187,7 @@ _LIBUNWIND_HIDDEN int __unw_get_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum, _LIBUNWIND_TRACE_API("__unw_get_fpreg(cursor=%p, regNum=%d, &value=%p)", static_cast<void *>(cursor), regNum, static_cast<void *>(value)); - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; + AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); if (co->validFloatReg(regNum)) { *value = co->getFloatReg(regNum); return UNW_ESUCCESS; @@ -207,7 +206,7 @@ _LIBUNWIND_HIDDEN int __unw_set_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum, _LIBUNWIND_TRACE_API("__unw_set_fpreg(cursor=%p, regNum=%d, value=%g)", static_cast<void *>(cursor), regNum, value); #endif - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; + AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); if (co->validFloatReg(regNum)) { co->setFloatReg(regNum, value); return UNW_ESUCCESS; @@ -219,7 +218,7 @@ _LIBUNWIND_WEAK_ALIAS(__unw_set_fpreg, unw_set_fpreg) /// Move cursor to next frame. _LIBUNWIND_HIDDEN int __unw_step(unw_cursor_t *cursor) { _LIBUNWIND_TRACE_API("__unw_step(cursor=%p)", static_cast<void *>(cursor)); - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; + AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); return co->step(); } _LIBUNWIND_WEAK_ALIAS(__unw_step, unw_step) @@ -229,7 +228,7 @@ _LIBUNWIND_WEAK_ALIAS(__unw_step, unw_step) extern "C" _LIBUNWIND_HIDDEN int __unw_step_stage2(unw_cursor_t *cursor) { _LIBUNWIND_TRACE_API("__unw_step_stage2(cursor=%p)", static_cast<void *>(cursor)); - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; + AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); return co->step(true); } @@ -238,7 +237,7 @@ _LIBUNWIND_HIDDEN int __unw_get_proc_info(unw_cursor_t *cursor, unw_proc_info_t *info) { _LIBUNWIND_TRACE_API("__unw_get_proc_info(cursor=%p, &info=%p)", static_cast<void *>(cursor), static_cast<void *>(info)); - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; + AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); co->getInfo(info); if (info->end_ip == 0) return UNW_ENOINFO; @@ -258,7 +257,7 @@ _LIBUNWIND_HIDDEN int __unw_resume_with_frames_walked(unw_cursor_t *cursor, __asan_handle_no_return(); #endif #ifdef _LIBUNWIND_TRACE_RET_INJECT - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; + AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); co->setWalkedFrames(walkedFrames); #endif return __unw_resume(cursor); @@ -273,7 +272,7 @@ _LIBUNWIND_HIDDEN int __unw_resume(unw_cursor_t *cursor) { // Inform the ASan runtime that now might be a good time to clean stuff up. __asan_handle_no_return(); #endif - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; + AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); co->jumpto(); return UNW_EUNSPEC; } @@ -285,7 +284,7 @@ _LIBUNWIND_HIDDEN int __unw_get_proc_name(unw_cursor_t *cursor, char *buf, _LIBUNWIND_TRACE_API("__unw_get_proc_name(cursor=%p, &buf=%p, bufLen=%lu)", static_cast<void *>(cursor), static_cast<void *>(buf), static_cast<unsigned long>(bufLen)); - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; + AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); if (co->getFunctionName(buf, bufLen, offset)) return UNW_ESUCCESS; return UNW_EUNSPEC; @@ -297,7 +296,7 @@ _LIBUNWIND_HIDDEN int __unw_is_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum) { _LIBUNWIND_TRACE_API("__unw_is_fpreg(cursor=%p, regNum=%d)", static_cast<void *>(cursor), regNum); - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; + AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); return co->validFloatReg(regNum); } _LIBUNWIND_WEAK_ALIAS(__unw_is_fpreg, unw_is_fpreg) @@ -307,7 +306,7 @@ _LIBUNWIND_HIDDEN const char *__unw_regname(unw_cursor_t *cursor, unw_regnum_t regNum) { _LIBUNWIND_TRACE_API("__unw_regname(cursor=%p, regNum=%d)", static_cast<void *>(cursor), regNum); - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; + AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); return co->getRegisterName(regNum); } _LIBUNWIND_WEAK_ALIAS(__unw_regname, unw_regname) @@ -316,7 +315,7 @@ _LIBUNWIND_WEAK_ALIAS(__unw_regname, unw_regname) _LIBUNWIND_HIDDEN int __unw_is_signal_frame(unw_cursor_t *cursor) { _LIBUNWIND_TRACE_API("__unw_is_signal_frame(cursor=%p)", static_cast<void *>(cursor)); - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; + AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); return co->isSignalFrame(); } _LIBUNWIND_WEAK_ALIAS(__unw_is_signal_frame, unw_is_signal_frame) @@ -325,7 +324,7 @@ _LIBUNWIND_WEAK_ALIAS(__unw_is_signal_frame, unw_is_signal_frame) _LIBUNWIND_EXPORT uintptr_t __unw_get_data_rel_base(unw_cursor_t *cursor) { _LIBUNWIND_TRACE_API("unw_get_data_rel_base(cursor=%p)", static_cast<void *>(cursor)); - AbstractUnwindCursor *co = reinterpret_cast<AbstractUnwindCursor *>(cursor); + AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); return co->getDataRelBase(); } _LIBUNWIND_WEAK_ALIAS(__unw_get_data_rel_base, unw_get_data_rel_base) @@ -336,7 +335,7 @@ _LIBUNWIND_WEAK_ALIAS(__unw_get_data_rel_base, unw_get_data_rel_base) _LIBUNWIND_HIDDEN void __unw_save_vfp_as_X(unw_cursor_t *cursor) { _LIBUNWIND_TRACE_API("__unw_get_fpreg_save_vfp_as_X(cursor=%p)", static_cast<void *>(cursor)); - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; + AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); return co->saveVFPAsX(); } _LIBUNWIND_WEAK_ALIAS(__unw_save_vfp_as_X, unw_save_vfp_as_X) >From 0d610d75b098783c54187c044457770e9bca881e Mon Sep 17 00:00:00 2001 From: Safocl Stollmannovic <[email protected]> Date: Mon, 30 Mar 2026 18:08:19 +0400 Subject: [PATCH 2/2] make UnwindCursor easier to use Rename UnwindCursor to BasicUnwindCursorType__ Rename AbstractUnwindCursor to AbstractBasicUnwindCursorType__ Add `using UnwindCursor`, which has a target type of registers-arch. --- libunwind/src/Unwind-seh.cpp | 24 ++-- libunwind/src/UnwindCursor.hpp | 193 ++++++++++++++++++++------------- libunwind/src/libunwind.cpp | 72 +++--------- 3 files changed, 147 insertions(+), 142 deletions(-) diff --git a/libunwind/src/Unwind-seh.cpp b/libunwind/src/Unwind-seh.cpp index 3435e8b81396e..e45313b92df51 100644 --- a/libunwind/src/Unwind-seh.cpp +++ b/libunwind/src/Unwind-seh.cpp @@ -498,20 +498,20 @@ _Unwind_GetRegionStart(struct _Unwind_Context *context) { static int __unw_init_seh(unw_cursor_t *cursor, CONTEXT *context) { #ifdef _LIBUNWIND_TARGET_X86_64 - auto *co = new (reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_x86_64> *>(cursor->u.data)) - UnwindCursor<LocalAddressSpace, Registers_x86_64>( + auto *co = new (reinterpret_cast<UnwindCursor *>(cursor->u.data)) + UnwindCursor( context, LocalAddressSpace::sThisAddressSpace); co->setInfoBasedOnIPRegister(); return UNW_ESUCCESS; #elif defined(_LIBUNWIND_TARGET_ARM) - auto *co = new (reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm> *>(cursor->u.data)) - UnwindCursor<LocalAddressSpace, Registers_arm>( + auto *co = new (reinterpret_cast<UnwindCursor *>(cursor->u.data)) + UnwindCursor( context, LocalAddressSpace::sThisAddressSpace); co->setInfoBasedOnIPRegister(); return UNW_ESUCCESS; #elif defined(_LIBUNWIND_TARGET_AARCH64) - auto *co = new (reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm64> *>(cursor->u.data)) - UnwindCursor<LocalAddressSpace, Registers_arm64>( + auto *co = new (reinterpret_cast<UnwindCursor *>(cursor->u.data)) + UnwindCursor( context, LocalAddressSpace::sThisAddressSpace); co->setInfoBasedOnIPRegister(); return UNW_ESUCCESS; @@ -522,11 +522,11 @@ static int __unw_init_seh(unw_cursor_t *cursor, CONTEXT *context) { static DISPATCHER_CONTEXT *__unw_seh_get_disp_ctx(unw_cursor_t *cursor) { #ifdef _LIBUNWIND_TARGET_X86_64 - return reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_x86_64> *>(cursor->u.data)->getDispatcherContext(); + return reinterpret_cast<UnwindCursor *>(cursor->u.data)->getDispatcherContext(); #elif defined(_LIBUNWIND_TARGET_ARM) - return reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm> *>(cursor->u.data)->getDispatcherContext(); + return reinterpret_cast<UnwindCursor *>(cursor->u.data)->getDispatcherContext(); #elif defined(_LIBUNWIND_TARGET_AARCH64) - return reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm64> *>(cursor->u.data)->getDispatcherContext(); + return reinterpret_cast<UnwindCursor *>(cursor->u.data)->getDispatcherContext(); #else return nullptr; #endif @@ -535,11 +535,11 @@ static DISPATCHER_CONTEXT *__unw_seh_get_disp_ctx(unw_cursor_t *cursor) { static void __unw_seh_set_disp_ctx(unw_cursor_t *cursor, DISPATCHER_CONTEXT *disp) { #ifdef _LIBUNWIND_TARGET_X86_64 - reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_x86_64> *>(cursor->u.data)->setDispatcherContext(disp); + reinterpret_cast<UnwindCursor *>(cursor->u.data)->setDispatcherContext(disp); #elif defined(_LIBUNWIND_TARGET_ARM) - reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm> *>(cursor->u.data)->setDispatcherContext(disp); + reinterpret_cast<UnwindCursor *>(cursor->u.data)->setDispatcherContext(disp); #elif defined(_LIBUNWIND_TARGET_AARCH64) - reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm64> *>(cursor->u.data)->setDispatcherContext(disp); + reinterpret_cast<UnwindCursor *>(cursor->u.data)->setDispatcherContext(disp); #endif } diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp index 2e207d692f184..a22971aa0d84c 100644 --- a/libunwind/src/UnwindCursor.hpp +++ b/libunwind/src/UnwindCursor.hpp @@ -451,13 +451,13 @@ template <typename A> class UnwindSectionLsdaArray { }; #endif // defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) -class _LIBUNWIND_HIDDEN AbstractUnwindCursor { +class _LIBUNWIND_HIDDEN AbstractBasicUnwindCursorType__ { public: // NOTE: provide a class specific placement deallocation function (S5.3.4 p20) // This avoids an unnecessary dependency to libc++abi. void operator delete(void *, size_t) {} - virtual ~AbstractUnwindCursor() {} + virtual ~AbstractBasicUnwindCursorType__() {} virtual bool validReg(int) { _LIBUNWIND_ABORT("validReg not implemented"); } virtual unw_word_t getReg(int) { _LIBUNWIND_ABORT("getReg not implemented"); } virtual void setReg(int, unw_word_t) { @@ -516,16 +516,16 @@ class _LIBUNWIND_HIDDEN AbstractUnwindCursor { #if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) && defined(_WIN32) -/// \c UnwindCursor contains all state (including all register values) during +/// \c BasicUnwindCursorType__ contains all state (including all register values) during /// an unwind. This is normally stack-allocated inside a unw_cursor_t. template <typename A, typename R> -class UnwindCursor : public AbstractUnwindCursor { +class BasicUnwindCursorType__ : public AbstractBasicUnwindCursorType__ { typedef typename A::pint_t pint_t; public: - UnwindCursor(unw_context_t *context, A &as); - UnwindCursor(CONTEXT *context, A &as); - UnwindCursor(A &as, void *threadArg); - virtual ~UnwindCursor() {} + BasicUnwindCursorType__(unw_context_t *context, A &as); + BasicUnwindCursorType__(CONTEXT *context, A &as); + BasicUnwindCursorType__(A &as, void *threadArg); + virtual ~BasicUnwindCursorType__() {} virtual bool validReg(int); virtual unw_word_t getReg(int); virtual void setReg(int, unw_word_t); @@ -555,7 +555,7 @@ class UnwindCursor : public AbstractUnwindCursor { // libunwind does not and should not depend on C++ library which means that we // need our own definition of inline placement new. - static void *operator new(size_t, UnwindCursor<A, R> *p) { return p; } + static void *operator new(size_t, BasicUnwindCursorType__<A, R> *p) { return p; } private: @@ -605,12 +605,12 @@ class UnwindCursor : public AbstractUnwindCursor { template <typename A, typename R> -UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as) +BasicUnwindCursorType__<A, R>::BasicUnwindCursorType__(unw_context_t *context, A &as) : _addressSpace(as), _unwindInfoMissing(false) { - static_assert((check_fit<UnwindCursor<A, R>, unw_cursor_t>::does_fit), - "UnwindCursor<> does not fit in unw_cursor_t"); - static_assert((alignof(UnwindCursor<A, R>) <= alignof(unw_cursor_t)), - "UnwindCursor<> requires more alignment than unw_cursor_t"); + static_assert((check_fit<BasicUnwindCursorType__<A, R>, unw_cursor_t>::does_fit), + "BasicUnwindCursorType__<> does not fit in unw_cursor_t"); + static_assert((alignof(BasicUnwindCursorType__<A, R>) <= alignof(unw_cursor_t)), + "BasicUnwindCursorType__<> requires more alignment than unw_cursor_t"); memset(&_info, 0, sizeof(_info)); memset(&_histTable, 0, sizeof(_histTable)); memset(&_dispContext, 0, sizeof(_dispContext)); @@ -710,10 +710,10 @@ UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as) } template <typename A, typename R> -UnwindCursor<A, R>::UnwindCursor(CONTEXT *context, A &as) +BasicUnwindCursorType__<A, R>::BasicUnwindCursorType__(CONTEXT *context, A &as) : _addressSpace(as), _unwindInfoMissing(false) { - static_assert((check_fit<UnwindCursor<A, R>, unw_cursor_t>::does_fit), - "UnwindCursor<> does not fit in unw_cursor_t"); + static_assert((check_fit<BasicUnwindCursorType__<A, R>, unw_cursor_t>::does_fit), + "BasicUnwindCursorType__<> does not fit in unw_cursor_t"); memset(&_info, 0, sizeof(_info)); memset(&_histTable, 0, sizeof(_histTable)); memset(&_dispContext, 0, sizeof(_dispContext)); @@ -724,7 +724,7 @@ UnwindCursor<A, R>::UnwindCursor(CONTEXT *context, A &as) template <typename A, typename R> -bool UnwindCursor<A, R>::validReg(int regNum) { +bool BasicUnwindCursorType__<A, R>::validReg(int regNum) { if (regNum == UNW_REG_IP || regNum == UNW_REG_SP) return true; #if defined(_LIBUNWIND_TARGET_X86_64) if (regNum >= UNW_X86_64_RAX && regNum <= UNW_X86_64_RIP) return true; @@ -739,7 +739,7 @@ bool UnwindCursor<A, R>::validReg(int regNum) { } template <typename A, typename R> -unw_word_t UnwindCursor<A, R>::getReg(int regNum) { +unw_word_t BasicUnwindCursorType__<A, R>::getReg(int regNum) { switch (regNum) { #if defined(_LIBUNWIND_TARGET_X86_64) case UNW_X86_64_RIP: @@ -790,7 +790,7 @@ unw_word_t UnwindCursor<A, R>::getReg(int regNum) { } template <typename A, typename R> -void UnwindCursor<A, R>::setReg(int regNum, unw_word_t value) { +void BasicUnwindCursorType__<A, R>::setReg(int regNum, unw_word_t value) { switch (regNum) { #if defined(_LIBUNWIND_TARGET_X86_64) case UNW_X86_64_RIP: @@ -872,7 +872,7 @@ void UnwindCursor<A, R>::setReg(int regNum, unw_word_t value) { } template <typename A, typename R> -bool UnwindCursor<A, R>::validFloatReg(int regNum) { +bool BasicUnwindCursorType__<A, R>::validFloatReg(int regNum) { #if defined(_LIBUNWIND_TARGET_ARM) if (regNum >= UNW_ARM_S0 && regNum <= UNW_ARM_S31) return true; if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D31) return true; @@ -885,7 +885,7 @@ bool UnwindCursor<A, R>::validFloatReg(int regNum) { } template <typename A, typename R> -unw_fpreg_t UnwindCursor<A, R>::getFloatReg(int regNum) { +unw_fpreg_t BasicUnwindCursorType__<A, R>::getFloatReg(int regNum) { #if defined(_LIBUNWIND_TARGET_ARM) if (regNum >= UNW_ARM_S0 && regNum <= UNW_ARM_S31) { union { @@ -913,7 +913,7 @@ unw_fpreg_t UnwindCursor<A, R>::getFloatReg(int regNum) { } template <typename A, typename R> -void UnwindCursor<A, R>::setFloatReg(int regNum, unw_fpreg_t value) { +void BasicUnwindCursorType__<A, R>::setFloatReg(int regNum, unw_fpreg_t value) { #if defined(_LIBUNWIND_TARGET_ARM) if (regNum >= UNW_ARM_S0 && regNum <= UNW_ARM_S31) { union { @@ -941,34 +941,34 @@ void UnwindCursor<A, R>::setFloatReg(int regNum, unw_fpreg_t value) { #endif } -template <typename A, typename R> void UnwindCursor<A, R>::jumpto() { +template <typename A, typename R> void BasicUnwindCursorType__<A, R>::jumpto() { RtlRestoreContext(&_msContext, nullptr); } #ifdef __arm__ -template <typename A, typename R> void UnwindCursor<A, R>::saveVFPAsX() {} +template <typename A, typename R> void BasicUnwindCursorType__<A, R>::saveVFPAsX() {} #endif template <typename A, typename R> -const char *UnwindCursor<A, R>::getRegisterName(int regNum) { +const char *BasicUnwindCursorType__<A, R>::getRegisterName(int regNum) { return R::getRegisterName(regNum); } -template <typename A, typename R> bool UnwindCursor<A, R>::isSignalFrame() { +template <typename A, typename R> bool BasicUnwindCursorType__<A, R>::isSignalFrame() { return false; } #else // !defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) || !defined(_WIN32) -/// UnwindCursor contains all state (including all register values) during +/// BasicUnwindCursorType__ contains all state (including all register values) during /// an unwind. This is normally stack allocated inside a unw_cursor_t. template <typename A, typename R> -class UnwindCursor : public AbstractUnwindCursor { +class BasicUnwindCursorType__ : public AbstractBasicUnwindCursorType__ { typedef typename A::pint_t pint_t; public: - UnwindCursor(unw_context_t *context, A &as); - UnwindCursor(A &as, void *threadArg); - virtual ~UnwindCursor() {} + BasicUnwindCursorType__(unw_context_t *context, A &as); + BasicUnwindCursorType__(A &as, void *threadArg); + virtual ~BasicUnwindCursorType__() {} virtual bool validReg(int); virtual unw_word_t getReg(int); virtual void setReg(int, unw_word_t); @@ -1001,7 +1001,7 @@ class UnwindCursor : public AbstractUnwindCursor { // libunwind does not and should not depend on C++ library which means that we // need our own definition of inline placement new. - static void *operator new(size_t, UnwindCursor<A, R> *p) { return p; } + static void *operator new(size_t, BasicUnwindCursorType__<A, R> *p) { return p; } private: @@ -1381,18 +1381,18 @@ class UnwindCursor : public AbstractUnwindCursor { template <typename A, typename R> -UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as) +BasicUnwindCursorType__<A, R>::BasicUnwindCursorType__(unw_context_t *context, A &as) : _addressSpace(as), _registers(context), _unwindInfoMissing(false), _isSignalFrame(false) { - static_assert((check_fit<UnwindCursor<A, R>, unw_cursor_t>::does_fit), - "UnwindCursor<> does not fit in unw_cursor_t"); - static_assert((alignof(UnwindCursor<A, R>) <= alignof(unw_cursor_t)), - "UnwindCursor<> requires more alignment than unw_cursor_t"); + static_assert((check_fit<BasicUnwindCursorType__<A, R>, unw_cursor_t>::does_fit), + "BasicUnwindCursorType__<> does not fit in unw_cursor_t"); + static_assert((alignof(BasicUnwindCursorType__<A, R>) <= alignof(unw_cursor_t)), + "BasicUnwindCursorType__<> requires more alignment than unw_cursor_t"); memset(static_cast<void *>(&_info), 0, sizeof(_info)); } template <typename A, typename R> -UnwindCursor<A, R>::UnwindCursor(A &as, void *) +BasicUnwindCursorType__<A, R>::BasicUnwindCursorType__(A &as, void *) : _addressSpace(as), _unwindInfoMissing(false), _isSignalFrame(false) { memset(static_cast<void *>(&_info), 0, sizeof(_info)); // FIXME @@ -1401,36 +1401,36 @@ UnwindCursor<A, R>::UnwindCursor(A &as, void *) template <typename A, typename R> -bool UnwindCursor<A, R>::validReg(int regNum) { +bool BasicUnwindCursorType__<A, R>::validReg(int regNum) { return _registers.validRegister(regNum); } template <typename A, typename R> -unw_word_t UnwindCursor<A, R>::getReg(int regNum) { +unw_word_t BasicUnwindCursorType__<A, R>::getReg(int regNum) { return _registers.getRegister(regNum); } template <typename A, typename R> -void UnwindCursor<A, R>::setReg(int regNum, unw_word_t value) { +void BasicUnwindCursorType__<A, R>::setReg(int regNum, unw_word_t value) { _registers.setRegister(regNum, (typename A::pint_t)value); } template <typename A, typename R> -bool UnwindCursor<A, R>::validFloatReg(int regNum) { +bool BasicUnwindCursorType__<A, R>::validFloatReg(int regNum) { return _registers.validFloatRegister(regNum); } template <typename A, typename R> -unw_fpreg_t UnwindCursor<A, R>::getFloatReg(int regNum) { +unw_fpreg_t BasicUnwindCursorType__<A, R>::getFloatReg(int regNum) { return _registers.getFloatRegister(regNum); } template <typename A, typename R> -void UnwindCursor<A, R>::setFloatReg(int regNum, unw_fpreg_t value) { +void BasicUnwindCursorType__<A, R>::setFloatReg(int regNum, unw_fpreg_t value) { _registers.setFloatRegister(regNum, value); } -template <typename A, typename R> void UnwindCursor<A, R>::jumpto() { +template <typename A, typename R> void BasicUnwindCursorType__<A, R>::jumpto() { #ifdef _LIBUNWIND_TRACE_RET_INJECT /* @@ -1450,7 +1450,7 @@ template <typename A, typename R> void UnwindCursor<A, R>::jumpto() { ``` frame #0: libunwind.1.dylib`__libunwind_Registers_arm64_jumpto at UnwindRegistersRestore.S:646 frame #1: libunwind.1.dylib`libunwind::Registers_arm64::returnto at Registers.hpp:2291:3 - frame #2: libunwind.1.dylib`libunwind::UnwindCursor<libunwind::LocalAddressSpace, libunwind::Registers_arm64>::jumpto at UnwindCursor.hpp:1474:14 + frame #2: libunwind.1.dylib`libunwind::BasicUnwindCursorType__<libunwind::LocalAddressSpace, libunwind::Registers_arm64>::jumpto at BasicUnwindCursorType__.hpp:1474:14 frame #3: libunwind.1.dylib`__unw_resume at libunwind.cpp:375:7 frame #4: libunwind.1.dylib`__unw_resume_with_frames_walked at libunwind.cpp:363:10 frame #5: libunwind.1.dylib`unwind_phase2 at UnwindLevel1.c:328:9 @@ -1474,31 +1474,31 @@ template <typename A, typename R> void UnwindCursor<A, R>::jumpto() { } #ifdef __arm__ -template <typename A, typename R> void UnwindCursor<A, R>::saveVFPAsX() { +template <typename A, typename R> void BasicUnwindCursorType__<A, R>::saveVFPAsX() { _registers.saveVFPAsX(); } #endif #ifdef _LIBUNWIND_TRACE_RET_INJECT template <typename A, typename R> -void UnwindCursor<A, R>::setWalkedFrames(unsigned walkedFrames) { +void BasicUnwindCursorType__<A, R>::setWalkedFrames(unsigned walkedFrames) { _walkedFrames = walkedFrames; } #endif #ifdef _AIX template <typename A, typename R> -uintptr_t UnwindCursor<A, R>::getDataRelBase() { +uintptr_t BasicUnwindCursorType__<A, R>::getDataRelBase() { return reinterpret_cast<uintptr_t>(_info.extra); } #endif template <typename A, typename R> -const char *UnwindCursor<A, R>::getRegisterName(int regNum) { +const char *BasicUnwindCursorType__<A, R>::getRegisterName(int regNum) { return _registers.getRegisterName(regNum); } -template <typename A, typename R> bool UnwindCursor<A, R>::isSignalFrame() { +template <typename A, typename R> bool BasicUnwindCursorType__<A, R>::isSignalFrame() { return _isSignalFrame; } @@ -1592,7 +1592,7 @@ EHABISectionIterator<A> EHABISectionUpperBound( } template <typename A, typename R> -bool UnwindCursor<A, R>::getInfoFromEHABISection( +bool BasicUnwindCursorType__<A, R>::getInfoFromEHABISection( pint_t pc, const UnwindInfoSections §s) { EHABISectionIterator<A> begin = @@ -1732,7 +1732,7 @@ bool UnwindCursor<A, R>::getInfoFromEHABISection( #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) template <typename A, typename R> -bool UnwindCursor<A, R>::getInfoFromFdeCie( +bool BasicUnwindCursorType__<A, R>::getInfoFromFdeCie( const typename CFI_Parser<A>::FDE_Info &fdeInfo, const typename CFI_Parser<A>::CIE_Info &cieInfo, typename R::link_hardened_reg_arg_t pc, uintptr_t dso_base) { @@ -1758,7 +1758,7 @@ bool UnwindCursor<A, R>::getInfoFromFdeCie( } template <typename A, typename R> -bool UnwindCursor<A, R>::getInfoFromDwarfSection( +bool BasicUnwindCursorType__<A, R>::getInfoFromDwarfSection( typename R::link_hardened_reg_arg_t pc, const UnwindInfoSections §s, uint32_t fdeSectionOffsetHint) { typename CFI_Parser<A>::FDE_Info fdeInfo; @@ -1817,7 +1817,7 @@ bool UnwindCursor<A, R>::getInfoFromDwarfSection( #if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) template <typename A, typename R> -bool UnwindCursor<A, R>::getInfoFromCompactEncodingSection( +bool BasicUnwindCursorType__<A, R>::getInfoFromCompactEncodingSection( typename R::link_hardened_reg_arg_t pc, const UnwindInfoSections §s) { const bool log = false; if (log) @@ -2090,7 +2090,7 @@ bool UnwindCursor<A, R>::getInfoFromCompactEncodingSection( #if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) template <typename A, typename R> -bool UnwindCursor<A, R>::getInfoFromSEH(pint_t pc) { +bool BasicUnwindCursorType__<A, R>::getInfoFromSEH(pint_t pc) { pint_t base; RUNTIME_FUNCTION *unwindEntry = lookUpSEHUnwindInfo(pc, &base); if (!unwindEntry) { @@ -2225,7 +2225,7 @@ static __xlcxx_personality_v0_t *xlcPersonalityV0; static RWMutex xlcPersonalityV0InitLock; template <typename A, typename R> -bool UnwindCursor<A, R>::getInfoFromTBTable(pint_t pc, R ®isters) { +bool BasicUnwindCursorType__<A, R>::getInfoFromTBTable(pint_t pc, R ®isters) { uint32_t *p = reinterpret_cast<uint32_t *>(pc); // Keep looking forward until a word of 0 is found. The traceback @@ -2472,7 +2472,7 @@ bool UnwindCursor<A, R>::getInfoFromTBTable(pint_t pc, R ®isters) { // Step back up the stack following the frame back link. template <typename A, typename R> -int UnwindCursor<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable, +int BasicUnwindCursorType__<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable, R ®isters, bool &isSignalFrame) { if (_LIBUNWIND_TRACING_UNWINDING) { char functionBuf[512]; @@ -2734,7 +2734,7 @@ int UnwindCursor<A, R>::stepWithTBTable(pint_t pc, tbtable *TBTable, #endif // defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND) template <typename A, typename R> -void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) { +void BasicUnwindCursorType__<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) { #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \ defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) _isSigReturn = false; @@ -2896,7 +2896,7 @@ void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) { #endif template <typename A, typename R> -bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_arm64 &) { +bool BasicUnwindCursorType__<A, R>::setInfoForSigReturn(Registers_arm64 &) { // Look for the sigreturn trampoline. The trampoline's body is two // specific instructions (see below). Typically the trampoline comes from the // vDSO[1] (i.e. the __kernel_rt_sigreturn function). A libc might provide its @@ -2930,7 +2930,7 @@ bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_arm64 &) { } template <typename A, typename R> -int UnwindCursor<A, R>::stepThroughSigReturn(Registers_arm64 &) { +int BasicUnwindCursorType__<A, R>::stepThroughSigReturn(Registers_arm64 &) { // In the signal trampoline frame, sp points to an rt_sigframe[1], which is: // - 128-byte siginfo struct // - ucontext struct: @@ -2966,7 +2966,7 @@ int UnwindCursor<A, R>::stepThroughSigReturn(Registers_arm64 &) { #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && \ defined(_LIBUNWIND_TARGET_LOONGARCH) template <typename A, typename R> -bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_loongarch &) { +bool BasicUnwindCursorType__<A, R>::setInfoForSigReturn(Registers_loongarch &) { const pint_t pc = static_cast<pint_t>(getReg(UNW_REG_IP)); // The PC might contain an invalid address if the unwind info is bad, so // directly accessing it could cause a SIGSEGV. @@ -2989,7 +2989,7 @@ bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_loongarch &) { } template <typename A, typename R> -int UnwindCursor<A, R>::stepThroughSigReturn(Registers_loongarch &) { +int BasicUnwindCursorType__<A, R>::stepThroughSigReturn(Registers_loongarch &) { // In the signal trampoline frame, sp points to an rt_sigframe[1], which is: // - 128-byte siginfo struct // - ucontext_t struct: @@ -3021,7 +3021,7 @@ int UnwindCursor<A, R>::stepThroughSigReturn(Registers_loongarch &) { #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && \ defined(_LIBUNWIND_TARGET_RISCV) template <typename A, typename R> -bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_riscv &) { +bool BasicUnwindCursorType__<A, R>::setInfoForSigReturn(Registers_riscv &) { const pint_t pc = static_cast<pint_t>(getReg(UNW_REG_IP)); // The PC might contain an invalid address if the unwind info is bad, so // directly accessing it could cause a SIGSEGV. @@ -3044,7 +3044,7 @@ bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_riscv &) { } template <typename A, typename R> -int UnwindCursor<A, R>::stepThroughSigReturn(Registers_riscv &) { +int BasicUnwindCursorType__<A, R>::stepThroughSigReturn(Registers_riscv &) { // In the signal trampoline frame, sp points to an rt_sigframe[1], which is: // - 128-byte siginfo struct // - ucontext_t struct: @@ -3074,7 +3074,7 @@ int UnwindCursor<A, R>::stepThroughSigReturn(Registers_riscv &) { #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && \ defined(_LIBUNWIND_TARGET_S390X) template <typename A, typename R> -bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_s390x &) { +bool BasicUnwindCursorType__<A, R>::setInfoForSigReturn(Registers_s390x &) { // Look for the sigreturn trampoline. The trampoline's body is a // specific instruction (see below). Typically the trampoline comes from the // vDSO (i.e. the __kernel_[rt_]sigreturn function). A libc might provide its @@ -3097,7 +3097,7 @@ bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_s390x &) { } template <typename A, typename R> -int UnwindCursor<A, R>::stepThroughSigReturn(Registers_s390x &) { +int BasicUnwindCursorType__<A, R>::stepThroughSigReturn(Registers_s390x &) { // Determine current SP. const pint_t sp = static_cast<pint_t>(this->getReg(UNW_REG_SP)); // According to the s390x ABI, the CFA is at (incoming) SP + 160. @@ -3177,7 +3177,7 @@ int UnwindCursor<A, R>::stepThroughSigReturn(Registers_s390x &) { #if defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) template <typename A, typename R> -bool UnwindCursor<A, R>::setInfoForSigReturn() { +bool BasicUnwindCursorType__<A, R>::setInfoForSigReturn() { Dl_info dlinfo; const auto isSignalHandler = [&](pint_t addr) { if (!dladdr(reinterpret_cast<void *>(addr), &dlinfo)) @@ -3226,7 +3226,7 @@ bool UnwindCursor<A, R>::setInfoForSigReturn() { } template <typename A, typename R> -int UnwindCursor<A, R>::stepThroughSigReturn() { +int BasicUnwindCursorType__<A, R>::stepThroughSigReturn() { _isSignalFrame = true; #if defined(_LIBUNWIND_TARGET_X86_64) @@ -3265,7 +3265,7 @@ int UnwindCursor<A, R>::stepThroughSigReturn() { } #endif // defined(_LIBUNWIND_CHECK_HAIKU_SIGRETURN) -template <typename A, typename R> int UnwindCursor<A, R>::step(bool stage2) { +template <typename A, typename R> int BasicUnwindCursorType__<A, R>::step(bool stage2) { (void)stage2; // Bottom of stack is defined when unwind info cannot be found. if (_unwindInfoMissing) @@ -3309,7 +3309,7 @@ template <typename A, typename R> int UnwindCursor<A, R>::step(bool stage2) { } template <typename A, typename R> -void UnwindCursor<A, R>::getInfo(unw_proc_info_t *info) { +void BasicUnwindCursorType__<A, R>::getInfo(unw_proc_info_t *info) { if (_unwindInfoMissing) memset(static_cast<void *>(info), 0, sizeof(*info)); else @@ -3317,7 +3317,7 @@ void UnwindCursor<A, R>::getInfo(unw_proc_info_t *info) { } template <typename A, typename R> -bool UnwindCursor<A, R>::getFunctionName(char *buf, size_t bufLen, +bool BasicUnwindCursorType__<A, R>::getFunctionName(char *buf, size_t bufLen, unw_word_t *offset) { #if defined(_LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING) typename R::reg_t rawPC = this->getReg(UNW_REG_IP); @@ -3331,7 +3331,7 @@ bool UnwindCursor<A, R>::getFunctionName(char *buf, size_t bufLen, #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) template <typename A, typename R> -bool UnwindCursor<A, R>::isReadableAddr(const pint_t addr) const { +bool BasicUnwindCursorType__<A, R>::isReadableAddr(const pint_t addr) const { // We use SYS_rt_sigprocmask, inspired by Abseil's AddressIsReadable. const auto sigsetAddr = reinterpret_cast<sigset_t *>(addr); @@ -3360,12 +3360,55 @@ bool UnwindCursor<A, R>::isReadableAddr(const pint_t addr) const { } #endif +#if defined(__i386__) +# define REGISTER_KIND Registers_x86 +#elif defined(__x86_64__) +# define REGISTER_KIND Registers_x86_64 +#elif defined(__powerpc64__) +# define REGISTER_KIND Registers_ppc64 +#elif defined(__powerpc__) +# define REGISTER_KIND Registers_ppc +#elif defined(__aarch64__) +# define REGISTER_KIND Registers_arm64 +#elif defined(__arm__) +# define REGISTER_KIND Registers_arm +#elif defined(__or1k__) +# define REGISTER_KIND Registers_or1k +#elif defined(__hexagon__) +# define REGISTER_KIND Registers_hexagon +#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 +# define REGISTER_KIND Registers_mips_o32 +#elif defined(__mips64) +# define REGISTER_KIND Registers_mips_newabi +#elif defined(__mips__) +# warning The MIPS architecture is not supported with this ABI and environment! +#elif defined(__sparc__) && defined(__arch64__) +#define REGISTER_KIND Registers_sparc64 +#elif defined(__sparc__) +# define REGISTER_KIND Registers_sparc +#elif defined(__riscv) +# define REGISTER_KIND Registers_riscv +#elif defined(__ve__) +# define REGISTER_KIND Registers_ve +#elif defined(__s390x__) +# define REGISTER_KIND Registers_s390x +#elif defined(__loongarch__) && __loongarch_grlen == 64 +#define REGISTER_KIND Registers_loongarch +#else +# error Architecture not supported +#endif + +using UnwindCursor = BasicUnwindCursorType__<LocalAddressSpace, REGISTER_KIND>; + +#undef REGISTER_KIND + #if defined(_LIBUNWIND_USE_CET) || defined(_LIBUNWIND_USE_GCS) extern "C" void *__libunwind_shstk_get_registers(unw_cursor_t *cursor) { - AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); + auto *co = reinterpret_cast<UnwindCursor *>(cursor->u.data); return co->get_registers(); } #endif + } // namespace libunwind #endif // __UNWINDCURSOR_HPP__ diff --git a/libunwind/src/libunwind.cpp b/libunwind/src/libunwind.cpp index 152b0cfceb5be..ccb25b9fb41ae 100644 --- a/libunwind/src/libunwind.cpp +++ b/libunwind/src/libunwind.cpp @@ -45,48 +45,10 @@ _LIBUNWIND_HIDDEN int __unw_init_local(unw_cursor_t *cursor, _LIBUNWIND_TRACE_API("__unw_init_local(cursor=%p, context=%p)", static_cast<void *>(cursor), static_cast<void *>(context)); -#if defined(__i386__) -# define REGISTER_KIND Registers_x86 -#elif defined(__x86_64__) -# define REGISTER_KIND Registers_x86_64 -#elif defined(__powerpc64__) -# define REGISTER_KIND Registers_ppc64 -#elif defined(__powerpc__) -# define REGISTER_KIND Registers_ppc -#elif defined(__aarch64__) -# define REGISTER_KIND Registers_arm64 -#elif defined(__arm__) -# define REGISTER_KIND Registers_arm -#elif defined(__or1k__) -# define REGISTER_KIND Registers_or1k -#elif defined(__hexagon__) -# define REGISTER_KIND Registers_hexagon -#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 -# define REGISTER_KIND Registers_mips_o32 -#elif defined(__mips64) -# define REGISTER_KIND Registers_mips_newabi -#elif defined(__mips__) -# warning The MIPS architecture is not supported with this ABI and environment! -#elif defined(__sparc__) && defined(__arch64__) -#define REGISTER_KIND Registers_sparc64 -#elif defined(__sparc__) -# define REGISTER_KIND Registers_sparc -#elif defined(__riscv) -# define REGISTER_KIND Registers_riscv -#elif defined(__ve__) -# define REGISTER_KIND Registers_ve -#elif defined(__s390x__) -# define REGISTER_KIND Registers_s390x -#elif defined(__loongarch__) && __loongarch_grlen == 64 -#define REGISTER_KIND Registers_loongarch -#else -# error Architecture not supported -#endif // Use "placement new" to allocate UnwindCursor in the cursor buffer. - auto *co = new (reinterpret_cast<UnwindCursor<LocalAddressSpace, REGISTER_KIND> *>(cursor->u.data)) - UnwindCursor<LocalAddressSpace, REGISTER_KIND>( + auto *co = new (reinterpret_cast<UnwindCursor *>(cursor->u.data)) + UnwindCursor( context, LocalAddressSpace::sThisAddressSpace); -#undef REGISTER_KIND co->setInfoBasedOnIPRegister(); return UNW_ESUCCESS; @@ -99,7 +61,7 @@ _LIBUNWIND_HIDDEN int __unw_get_reg(unw_cursor_t *cursor, unw_regnum_t regNum, _LIBUNWIND_TRACE_API("__unw_get_reg(cursor=%p, regNum=%d, &value=%p)", static_cast<void *>(cursor), regNum, static_cast<void *>(value)); - AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); + auto *co = reinterpret_cast<UnwindCursor *>(cursor->u.data); if (co->validReg(regNum)) { *value = co->getReg(regNum); return UNW_ESUCCESS; @@ -115,7 +77,7 @@ _LIBUNWIND_HIDDEN int __unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum, ")", static_cast<void *>(cursor), regNum, value); typedef LocalAddressSpace::pint_t pint_t; - AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); + auto *co = reinterpret_cast<UnwindCursor *>(cursor->u.data); if (co->validReg(regNum)) { // special case altering IP to re-find info (being called by personality // function) @@ -187,7 +149,7 @@ _LIBUNWIND_HIDDEN int __unw_get_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum, _LIBUNWIND_TRACE_API("__unw_get_fpreg(cursor=%p, regNum=%d, &value=%p)", static_cast<void *>(cursor), regNum, static_cast<void *>(value)); - AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); + auto *co = reinterpret_cast<UnwindCursor *>(cursor->u.data); if (co->validFloatReg(regNum)) { *value = co->getFloatReg(regNum); return UNW_ESUCCESS; @@ -206,7 +168,7 @@ _LIBUNWIND_HIDDEN int __unw_set_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum, _LIBUNWIND_TRACE_API("__unw_set_fpreg(cursor=%p, regNum=%d, value=%g)", static_cast<void *>(cursor), regNum, value); #endif - AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); + auto *co = reinterpret_cast<UnwindCursor *>(cursor->u.data); if (co->validFloatReg(regNum)) { co->setFloatReg(regNum, value); return UNW_ESUCCESS; @@ -218,7 +180,7 @@ _LIBUNWIND_WEAK_ALIAS(__unw_set_fpreg, unw_set_fpreg) /// Move cursor to next frame. _LIBUNWIND_HIDDEN int __unw_step(unw_cursor_t *cursor) { _LIBUNWIND_TRACE_API("__unw_step(cursor=%p)", static_cast<void *>(cursor)); - AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); + auto *co = reinterpret_cast<UnwindCursor *>(cursor->u.data); return co->step(); } _LIBUNWIND_WEAK_ALIAS(__unw_step, unw_step) @@ -228,7 +190,7 @@ _LIBUNWIND_WEAK_ALIAS(__unw_step, unw_step) extern "C" _LIBUNWIND_HIDDEN int __unw_step_stage2(unw_cursor_t *cursor) { _LIBUNWIND_TRACE_API("__unw_step_stage2(cursor=%p)", static_cast<void *>(cursor)); - AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); + auto *co = reinterpret_cast<UnwindCursor *>(cursor->u.data); return co->step(true); } @@ -237,7 +199,7 @@ _LIBUNWIND_HIDDEN int __unw_get_proc_info(unw_cursor_t *cursor, unw_proc_info_t *info) { _LIBUNWIND_TRACE_API("__unw_get_proc_info(cursor=%p, &info=%p)", static_cast<void *>(cursor), static_cast<void *>(info)); - AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); + auto *co = reinterpret_cast<UnwindCursor *>(cursor->u.data); co->getInfo(info); if (info->end_ip == 0) return UNW_ENOINFO; @@ -257,7 +219,7 @@ _LIBUNWIND_HIDDEN int __unw_resume_with_frames_walked(unw_cursor_t *cursor, __asan_handle_no_return(); #endif #ifdef _LIBUNWIND_TRACE_RET_INJECT - AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); + auto *co = reinterpret_cast<UnwindCursor *>(cursor->u.data); co->setWalkedFrames(walkedFrames); #endif return __unw_resume(cursor); @@ -272,7 +234,7 @@ _LIBUNWIND_HIDDEN int __unw_resume(unw_cursor_t *cursor) { // Inform the ASan runtime that now might be a good time to clean stuff up. __asan_handle_no_return(); #endif - AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); + auto *co = reinterpret_cast<UnwindCursor *>(cursor->u.data); co->jumpto(); return UNW_EUNSPEC; } @@ -284,7 +246,7 @@ _LIBUNWIND_HIDDEN int __unw_get_proc_name(unw_cursor_t *cursor, char *buf, _LIBUNWIND_TRACE_API("__unw_get_proc_name(cursor=%p, &buf=%p, bufLen=%lu)", static_cast<void *>(cursor), static_cast<void *>(buf), static_cast<unsigned long>(bufLen)); - AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); + auto *co = reinterpret_cast<UnwindCursor *>(cursor->u.data); if (co->getFunctionName(buf, bufLen, offset)) return UNW_ESUCCESS; return UNW_EUNSPEC; @@ -296,7 +258,7 @@ _LIBUNWIND_HIDDEN int __unw_is_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum) { _LIBUNWIND_TRACE_API("__unw_is_fpreg(cursor=%p, regNum=%d)", static_cast<void *>(cursor), regNum); - AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); + auto *co = reinterpret_cast<UnwindCursor *>(cursor->u.data); return co->validFloatReg(regNum); } _LIBUNWIND_WEAK_ALIAS(__unw_is_fpreg, unw_is_fpreg) @@ -306,7 +268,7 @@ _LIBUNWIND_HIDDEN const char *__unw_regname(unw_cursor_t *cursor, unw_regnum_t regNum) { _LIBUNWIND_TRACE_API("__unw_regname(cursor=%p, regNum=%d)", static_cast<void *>(cursor), regNum); - AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); + auto *co = reinterpret_cast<UnwindCursor *>(cursor->u.data); return co->getRegisterName(regNum); } _LIBUNWIND_WEAK_ALIAS(__unw_regname, unw_regname) @@ -315,7 +277,7 @@ _LIBUNWIND_WEAK_ALIAS(__unw_regname, unw_regname) _LIBUNWIND_HIDDEN int __unw_is_signal_frame(unw_cursor_t *cursor) { _LIBUNWIND_TRACE_API("__unw_is_signal_frame(cursor=%p)", static_cast<void *>(cursor)); - AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); + auto *co = reinterpret_cast<UnwindCursor *>(cursor->u.data); return co->isSignalFrame(); } _LIBUNWIND_WEAK_ALIAS(__unw_is_signal_frame, unw_is_signal_frame) @@ -324,7 +286,7 @@ _LIBUNWIND_WEAK_ALIAS(__unw_is_signal_frame, unw_is_signal_frame) _LIBUNWIND_EXPORT uintptr_t __unw_get_data_rel_base(unw_cursor_t *cursor) { _LIBUNWIND_TRACE_API("unw_get_data_rel_base(cursor=%p)", static_cast<void *>(cursor)); - AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); + auto *co = reinterpret_cast<UnwindCursor *>(cursor->u.data); return co->getDataRelBase(); } _LIBUNWIND_WEAK_ALIAS(__unw_get_data_rel_base, unw_get_data_rel_base) @@ -335,7 +297,7 @@ _LIBUNWIND_WEAK_ALIAS(__unw_get_data_rel_base, unw_get_data_rel_base) _LIBUNWIND_HIDDEN void __unw_save_vfp_as_X(unw_cursor_t *cursor) { _LIBUNWIND_TRACE_API("__unw_get_fpreg_save_vfp_as_X(cursor=%p)", static_cast<void *>(cursor)); - AbstractUnwindCursor *co = dynamic_cast<AbstractUnwindCursor *>(reinterpret_cast<AbstractUnwindCursor *>(cursor->u.data)); + auto *co = reinterpret_cast<UnwindCursor *>(cursor->u.data); return co->saveVFPAsX(); } _LIBUNWIND_WEAK_ALIAS(__unw_save_vfp_as_X, unw_save_vfp_as_X) _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
