summaryrefslogtreecommitdiff
path: root/libunwind
diff options
context:
space:
mode:
authorMartin Storsjö <martin@martin.st>2023-04-04 20:26:20 +0000
committerMartin Storsjö <martin@martin.st>2023-04-11 00:00:30 +0300
commit87ca04033c1bf79f4de964505dd8818cbbc2bdf4 (patch)
treebda6f875b4e3e67dc1b43228e4cf35982ad4e312 /libunwind
parent55abdef3dac681866503ab286c3be6b4e8be3a9a (diff)
downloadllvm-87ca04033c1bf79f4de964505dd8818cbbc2bdf4.tar.gz
[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
Diffstat (limited to 'libunwind')
-rw-r--r--libunwind/src/UnwindCursor.hpp12
1 files changed, 11 insertions, 1 deletions
diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp
index 0c6cda3604a2..ac690badc261 100644
--- a/libunwind/src/UnwindCursor.hpp
+++ b/libunwind/src/UnwindCursor.hpp
@@ -506,7 +506,14 @@ public:
#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