summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/pal/inc/pal.h9
-rw-r--r--src/pal/inc/rt/palrt.h1
-rw-r--r--src/pal/src/exception/seh-unwind.cpp4
-rw-r--r--src/unwinder/i386/unwinder_i386.cpp2
-rw-r--r--src/vm/exceptionhandling.cpp11
5 files changed, 21 insertions, 6 deletions
diff --git a/src/pal/inc/pal.h b/src/pal/inc/pal.h
index 6e88553b85..fdcec58c24 100644
--- a/src/pal/inc/pal.h
+++ b/src/pal/inc/pal.h
@@ -1726,6 +1726,15 @@ QueueUserAPC(
#define CONTEXT_EXCEPTION_REQUEST 0x40000000L
#define CONTEXT_EXCEPTION_REPORTING 0x80000000L
+//
+// This flag is set by the unwinder if it has unwound to a call
+// site, and cleared whenever it unwinds through a trap frame.
+// It is used by language-specific exception handlers to help
+// differentiate exception scopes during dispatching.
+//
+
+#define CONTEXT_UNWOUND_TO_CALL 0x20000000
+
typedef struct _FLOATING_SAVE_AREA {
DWORD ControlWord;
DWORD StatusWord;
diff --git a/src/pal/inc/rt/palrt.h b/src/pal/inc/rt/palrt.h
index 6811666e0d..059d3a68a5 100644
--- a/src/pal/inc/rt/palrt.h
+++ b/src/pal/inc/rt/palrt.h
@@ -1506,6 +1506,7 @@ typedef struct _DISPATCHER_CONTEXT {
PEXCEPTION_ROUTINE LanguageHandler;
PVOID HandlerData;
PUNWIND_HISTORY_TABLE HistoryTable;
+ BOOLEAN ControlPcIsUnwound;
} DISPATCHER_CONTEXT, *PDISPATCHER_CONTEXT;
#else
diff --git a/src/pal/src/exception/seh-unwind.cpp b/src/pal/src/exception/seh-unwind.cpp
index fa2f109875..e3fa09f7c8 100644
--- a/src/pal/src/exception/seh-unwind.cpp
+++ b/src/pal/src/exception/seh-unwind.cpp
@@ -322,14 +322,14 @@ BOOL PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextP
if (unw_is_signal_frame(&cursor) > 0)
{
context->ContextFlags |= CONTEXT_EXCEPTION_ACTIVE;
-#if defined(_ARM_) || defined(_ARM64_)
+#if defined(_ARM_) || defined(_ARM64_) || defined(_X86_)
context->ContextFlags &= ~CONTEXT_UNWOUND_TO_CALL;
#endif // _ARM_ || _ARM64_
}
else
{
context->ContextFlags &= ~CONTEXT_EXCEPTION_ACTIVE;
-#if defined(_ARM_) || defined(_ARM64_)
+#if defined(_ARM_) || defined(_ARM64_) || defined(_X86_)
context->ContextFlags |= CONTEXT_UNWOUND_TO_CALL;
#endif // _ARM_ || _ARM64_
}
diff --git a/src/unwinder/i386/unwinder_i386.cpp b/src/unwinder/i386/unwinder_i386.cpp
index 05fa4a1540..f4490ace7e 100644
--- a/src/unwinder/i386/unwinder_i386.cpp
+++ b/src/unwinder/i386/unwinder_i386.cpp
@@ -118,6 +118,8 @@ OOPStackUnwinderX86::VirtualUnwind(
#undef CALLEE_SAVED_REGISTER
}
+ ContextRecord->ContextFlags |= CONTEXT_UNWOUND_TO_CALL;
+
ContextRecord->Esp = rd.SP;
ContextRecord->Eip = rd.ControlPC;
ContextRecord->Ebp = *rd.pEbp;
diff --git a/src/vm/exceptionhandling.cpp b/src/vm/exceptionhandling.cpp
index 5fe8a26ecd..d3485e3671 100644
--- a/src/vm/exceptionhandling.cpp
+++ b/src/vm/exceptionhandling.cpp
@@ -1376,6 +1376,8 @@ void ExceptionTracker::InitializeCrawlFrame(CrawlFrame* pcfThisFrame, Thread* pT
// </ARM and ARM64>
pThread->InitRegDisplay(pcfThisFrame->pRD, pDispatcherContext->ContextRecord, true);
+ bool fAdjustRegdisplayControlPC = false;
+
// The "if" check below is trying to determine when we have a valid current context in DC->ContextRecord and whether, or not,
// RegDisplay needs to be fixed up to set SP and ControlPC to have the values for the current frame for which personality routine
// is invoked.
@@ -1421,7 +1423,6 @@ void ExceptionTracker::InitializeCrawlFrame(CrawlFrame* pcfThisFrame, Thread* pT
// However, we do this *only* when "ControlPCForEHSearch" is the same as "DispatcherContext->ControlPC",
// indicating we are not using the thread-abort reraise loop prevention logic.
//
- bool fAdjustRegdisplayControlPC = false;
if (pDispatcherContext->ControlPc == ControlPCForEHSearch)
{
// Since DispatcherContext->ControlPc is used to initialize the
@@ -1437,7 +1438,9 @@ void ExceptionTracker::InitializeCrawlFrame(CrawlFrame* pcfThisFrame, Thread* pT
// Remove the Thumb bit
ControlPCForEHSearch = ThumbCodeToDataPointer<DWORD_PTR, DWORD_PTR>(ControlPCForEHSearch);
#endif
+#endif // _TARGET_ARM_ || _TARGET_ARM64_
+#if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_) || defined(_TARGET_X86_)
// If the OS indicated that the IP is a callsite, then adjust the ControlPC by decrementing it
// by two. This is done because unwinding at callsite will make ControlPC point to the
// instruction post the callsite. If a protected region ends "at" the callsite, then
@@ -1460,7 +1463,7 @@ void ExceptionTracker::InitializeCrawlFrame(CrawlFrame* pcfThisFrame, Thread* pT
pcfThisFrame->isIPadjusted = true;
}
}
-#endif // _TARGET_ARM_ || _TARGET_ARM64_
+#endif // _TARGET_ARM_ || _TARGET_ARM64_ || _TARGET_X86_
pcfThisFrame->codeInfo.Init(ControlPCForEHSearch);
@@ -4337,7 +4340,7 @@ VOID UnwindManagedExceptionPass2(PAL_SEHException& ex, CONTEXT* unwindStartConte
dispatcherContext.FunctionEntry = codeInfo.GetFunctionEntry();
dispatcherContext.ControlPc = controlPc;
dispatcherContext.ImageBase = codeInfo.GetModuleBase();
-#if defined(_TARGET_ARM_)
+#if defined(_TARGET_ARM_) || defined(_TARGET_X86_)
dispatcherContext.ControlPcIsUnwound = !!(currentFrameContext->ContextFlags & CONTEXT_UNWOUND_TO_CALL);
#endif
// Check whether we have a function table entry for the current controlPC.
@@ -4488,7 +4491,7 @@ VOID DECLSPEC_NORETURN UnwindManagedExceptionPass1(PAL_SEHException& ex, CONTEXT
dispatcherContext.FunctionEntry = codeInfo.GetFunctionEntry();
dispatcherContext.ControlPc = controlPc;
dispatcherContext.ImageBase = codeInfo.GetModuleBase();
-#if defined(_TARGET_ARM_)
+#if defined(_TARGET_ARM_) || defined(_TARGET_X86_)
dispatcherContext.ControlPcIsUnwound = !!(frameContext->ContextFlags & CONTEXT_UNWOUND_TO_CALL);
#endif