[libunwind] 87ca040 - [libunwind] [SEH] Sync LSDA and handler between unw_proc_info_t and DISPATCHER_CONTEXT

Martin Storsjö via cfe-commits cfe-commits at lists.llvm.org
Mon Apr 10 14:03:42 PDT 2023


Author: Martin Storsjö
Date: 2023-04-11T00:00:30+03:00
New Revision: 87ca04033c1bf79f4de964505dd8818cbbc2bdf4

URL: https://github.com/llvm/llvm-project/commit/87ca04033c1bf79f4de964505dd8818cbbc2bdf4
DIFF: https://github.com/llvm/llvm-project/commit/87ca04033c1bf79f4de964505dd8818cbbc2bdf4.diff

LOG: [libunwind] [SEH] Sync LSDA and handler between unw_proc_info_t and DISPATCHER_CONTEXT

For normal C++ unwinding, we get _dispContext initialized by the
prepopulated DISPATCHER_CONTEXT in _GCC_specific_handler, which
we set with __unw_seh_set_disp_ctx.

When doing force unwinding, we step and populate the unw_proc_info_t
struct _info with getInfoFromSEH, but when we execute the handler
via the __libunwind_seh_personality wrapper function, we execute
the handler set in DISPATCHER_CONTEXT.

Whenever updating these fields in either _info or _dispContext,
sync them to the other one too.

This fixes one aspect of the libcxxabi force_unwind*.pass.cpp tests on
x86_64.

Differential Revision: https://reviews.llvm.org/D147637

Added: 
    

Modified: 
    libunwind/src/UnwindCursor.hpp

Removed: 
    


################################################################################
diff  --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp
index 0c6cda3604a23..ac690badc2618 100644
--- a/libunwind/src/UnwindCursor.hpp
+++ b/libunwind/src/UnwindCursor.hpp
@@ -506,7 +506,14 @@ class UnwindCursor : public AbstractUnwindCursor {
 #endif
 
   DISPATCHER_CONTEXT *getDispatcherContext() { return &_dispContext; }
-  void setDispatcherContext(DISPATCHER_CONTEXT *disp) { _dispContext = *disp; }
+  void setDispatcherContext(DISPATCHER_CONTEXT *disp) {
+    _dispContext = *disp;
+    _info.lsda = reinterpret_cast<unw_word_t>(_dispContext.HandlerData);
+    if (_dispContext.LanguageHandler) {
+      _info.handler = reinterpret_cast<unw_word_t>(__libunwind_seh_personality);
+    } else
+      _info.handler = 0;
+  }
 
   // libunwind does not and should not depend on C++ library which means that we
   // need our own definition of inline placement new.
@@ -1978,6 +1985,9 @@ bool UnwindCursor<A, R>::getInfoFromSEH(pint_t pc) {
       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);
+      _dispContext.HandlerData = reinterpret_cast<void *>(_info.lsda);
+      _dispContext.LanguageHandler =
+          reinterpret_cast<EXCEPTION_ROUTINE *>(base + *handler);
       if (*handler) {
         _info.handler = reinterpret_cast<unw_word_t>(__libunwind_seh_personality);
       } else


        


More information about the cfe-commits mailing list