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 &sects) {
   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 &sects,
     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 &sects) {
   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 &registers) {
+bool BasicUnwindCursorType__<A, R>::getInfoFromTBTable(pint_t pc, R 
&registers) {
   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 
&registers) {
 
 // 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 &registers, 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

Reply via email to