Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,17 @@ class AsmOffsets
public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0x132;
#elif TARGET_X86
public const int OFFSETOF__REGDISPLAY__m_pCurrentContext = 0x4;
public const int SIZEOF__StackFrameIterator = 0x3d4;
public const int SIZEOF__StackFrameIterator = 0x3d0;
public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0x3c2;
public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0x3d0;
public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0x3cc;
#else // TARGET_64BIT
public const int OFFSETOF__REGDISPLAY__m_pCurrentContext = 0x4;
#if FEATURE_INTERPRETER
public const int SIZEOF__StackFrameIterator = 0xdc;
public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0xd8;
public const int SIZEOF__StackFrameIterator = 0xd8;
public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0xd4;
#else
public const int SIZEOF__StackFrameIterator = 0xcc;
public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0xc8;
public const int SIZEOF__StackFrameIterator = 0xc8;
public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0xc4;
#endif
public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0xba;
#endif // TARGET_64BIT
Expand Down Expand Up @@ -139,17 +139,17 @@ class AsmOffsets
public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0x12a;
#elif TARGET_X86
public const int OFFSETOF__REGDISPLAY__m_pCurrentContext = 0x4;
public const int SIZEOF__StackFrameIterator = 0x3cc;
public const int SIZEOF__StackFrameIterator = 0x3c8;
public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0x3ba;
public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0x3c8;
public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0x3c4;
#else // TARGET_64BIT
public const int OFFSETOF__REGDISPLAY__m_pCurrentContext = 0x4;
#if FEATURE_INTERPRETER
public const int SIZEOF__StackFrameIterator = 0xd4;
public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0xd0;
public const int SIZEOF__StackFrameIterator = 0xd0;
public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0xcc;
#else
public const int SIZEOF__StackFrameIterator = 0xc4;
public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0xc0;
public const int SIZEOF__StackFrameIterator = 0xc0;
public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0xbc;
#endif
public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0xb2;
#endif // TARGET_64BIT
Expand Down Expand Up @@ -217,6 +217,23 @@ class AsmOffsets
public const int OFFSETOF__ExInfo__m_idxCurClause = 0xbc;
public const int OFFSETOF__ExInfo__m_frameIter = 0xc0;
public const int OFFSETOF__ExInfo__m_notifyDebuggerSP = OFFSETOF__ExInfo__m_frameIter + SIZEOF__StackFrameIterator;
public const int OFFSETOF__ExInfo__m_pCatchHandler = OFFSETOF__ExInfo__m_frameIter + SIZEOF__StackFrameIterator + 0x48;
public const int OFFSETOF__ExInfo__m_handlingFrameSP = OFFSETOF__ExInfo__m_frameIter + SIZEOF__StackFrameIterator + 0x50;

#if TARGET_ARM64
public const int OFFSETOF__ExInfo__m_handlingFramePC = OFFSETOF__ExInfo__m_frameIter + SIZEOF__StackFrameIterator + 0x58;
#endif

#if TARGET_UNIX
#if TARGET_ARM64
public const int OFFSETOF__ExInfo__m_pReversePInvokePropagationCallback = OFFSETOF__ExInfo__m_frameIter + SIZEOF__StackFrameIterator + 0x68;
public const int OFFSETOF__ExInfo__m_pReversePInvokePropagationContext = OFFSETOF__ExInfo__m_frameIter + SIZEOF__StackFrameIterator + 0x70;
#else // TARGET_ARM64
public const int OFFSETOF__ExInfo__m_pReversePInvokePropagationCallback = OFFSETOF__ExInfo__m_frameIter + SIZEOF__StackFrameIterator + 0x60;
public const int OFFSETOF__ExInfo__m_pReversePInvokePropagationContext = OFFSETOF__ExInfo__m_frameIter + SIZEOF__StackFrameIterator + 0x68;
#endif // TARGET_ARM64
#endif // TARGET_UNIX

#else // TARGET_64BIT
public const int SIZEOF__EHEnum = 0x10;
public const int OFFSETOF__StackFrameIterator__m_pRegDisplay = 0x14;
Expand All @@ -228,6 +245,14 @@ class AsmOffsets
public const int OFFSETOF__ExInfo__m_idxCurClause = 0x68;
public const int OFFSETOF__ExInfo__m_frameIter = 0x6c;
public const int OFFSETOF__ExInfo__m_notifyDebuggerSP = OFFSETOF__ExInfo__m_frameIter + SIZEOF__StackFrameIterator;
public const int OFFSETOF__ExInfo__m_pCatchHandler = OFFSETOF__ExInfo__m_frameIter + SIZEOF__StackFrameIterator + 0x2c;
public const int OFFSETOF__ExInfo__m_handlingFrameSP = OFFSETOF__ExInfo__m_frameIter + SIZEOF__StackFrameIterator + 0x30;

#if TARGET_UNIX
public const int OFFSETOF__ExInfo__m_pReversePInvokePropagationCallback = OFFSETOF__ExInfo__m_frameIter + SIZEOF__StackFrameIterator + 0x38;
public const int OFFSETOF__ExInfo__m_pReversePInvokePropagationContext = OFFSETOF__ExInfo__m_frameIter + SIZEOF__StackFrameIterator + 0x3c;
#endif

#endif // TARGET_64BIT

#if __cplusplus
Expand Down Expand Up @@ -268,8 +293,18 @@ class AsmOffsets
static_assert_no_msg(offsetof(ExInfo, m_idxCurClause) == OFFSETOF__ExInfo__m_idxCurClause);
static_assert_no_msg(offsetof(ExInfo, m_frameIter) == OFFSETOF__ExInfo__m_frameIter);
static_assert_no_msg(offsetof(ExInfo, m_notifyDebuggerSP) == OFFSETOF__ExInfo__m_notifyDebuggerSP);
static_assert_no_msg(offsetof(ExInfo, m_pCatchHandler) == OFFSETOF__ExInfo__m_pCatchHandler);
static_assert_no_msg(offsetof(ExInfo, m_handlingFrameSP) == OFFSETOF__ExInfo__m_handlingFrameSP);
#if TARGET_ARM64
static_assert_no_msg(offsetof(ExInfo, m_handlingFramePC) == OFFSETOF__ExInfo__m_handlingFramePC);
#endif

#if TARGET_UNIX
static_assert_no_msg(offsetof(ExInfo, m_propagateExceptionCallback) == OFFSETOF__ExInfo__m_pReversePInvokePropagationCallback);
static_assert_no_msg(offsetof(ExInfo, m_propagateExceptionContext) == OFFSETOF__ExInfo__m_pReversePInvokePropagationContext);
#endif

#endif
}
#if __cplusplus
;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,6 @@ internal static partial class InternalCalls
[return: MarshalAs(UnmanagedType.U1)]
internal static unsafe partial bool RhpSfiNext(ref StackFrameIterator pThis, uint* uExCollideClauseIdx, bool* fUnwoundReversePInvoke, bool* fIsExceptionIntercepted);

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ResumeAtInterceptionLocation")]
internal static unsafe partial void ResumeAtInterceptionLocation(void* pvRegDisplay);

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "CallCatchFunclet")]
internal static unsafe partial IntPtr RhpCallCatchFunclet(
ObjectHandleOnStack exceptionObj, byte* pHandlerIP, void* pvRegDisplay, EH.ExInfo* exInfo);

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "CallFinallyFunclet")]
internal static unsafe partial void RhpCallFinallyFunclet(byte* pHandlerIP, void* pvRegDisplay, EH.ExInfo* exInfo);

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "CallFilterFunclet")]
[return: MarshalAs(UnmanagedType.U1)]
internal static unsafe partial bool RhpCallFilterFunclet(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,30 @@ internal object ThrownException

[FieldOffset(AsmOffsets.OFFSETOF__ExInfo__m_notifyDebuggerSP)]
internal volatile UIntPtr _notifyDebuggerSP;
#if !NATIVEAOT
[FieldOffset(AsmOffsets.OFFSETOF__ExInfo__m_pCatchHandler)]
internal volatile byte* _pCatchHandler;

[FieldOffset(AsmOffsets.OFFSETOF__ExInfo__m_handlingFrameSP)]
internal volatile UIntPtr _handlingFrameSP;

#if TARGET_ARM64
// On ARM64, two frames can have the same SP, when a leaf function
// doesn't use any stack. So to distinguish between the caller frame
// and the leaf one, we also need to know the PC of the handling frame.
[FieldOffset(AsmOffsets.OFFSETOF__ExInfo__m_handlingFramePC)]
internal volatile byte* _handlingFramePC;
#endif

#if TARGET_UNIX
[FieldOffset(AsmOffsets.OFFSETOF__ExInfo__m_pReversePInvokePropagationCallback)]
internal volatile IntPtr _pReversePInvokePropagationCallback;

[FieldOffset(AsmOffsets.OFFSETOF__ExInfo__m_pReversePInvokePropagationContext)]
internal volatile IntPtr _pReversePInvokePropagationContext;
#endif // TARGET_UNIX

#endif // !NATIVEAOT
}

//
Expand Down Expand Up @@ -637,7 +661,9 @@ public static void RhThrowHwEx(uint exceptionCode, ref ExInfo exInfo)

exInfo.Init(exceptionToThrow!, instructionFault);
DispatchEx(ref exInfo._frameIter, ref exInfo);
#if NATIVEAOT
FallbackFailFast(RhFailFastReason.InternalError, null);
#endif
}

private const uint MaxTryRegionIdx = 0xFFFFFFFFu;
Expand Down Expand Up @@ -670,68 +696,11 @@ public static void RhThrowEx(object exceptionObj, ref ExInfo exInfo)

exInfo.Init(exceptionObj);
DispatchEx(ref exInfo._frameIter, ref exInfo);
#if NATIVEAOT
FallbackFailFast(RhFailFastReason.InternalError, null);
#endif
}

#if !NATIVEAOT
public static void RhUnwindAndIntercept(ref ExInfo exInfo, UIntPtr interceptStackFrameSP)
{
exInfo._passNumber = 2;
exInfo._idxCurClause = MaxTryRegionIdx;
uint startIdx = MaxTryRegionIdx;
bool unwoundReversePInvoke = false;
bool isExceptionIntercepted = false;
bool isValid = exInfo._frameIter.Init(exInfo._pExContext, (exInfo._kind & ExKind.InstructionFaultFlag) != 0, &isExceptionIntercepted);
for (; isValid && !isExceptionIntercepted && ((byte*)exInfo._frameIter.SP <= (byte*)interceptStackFrameSP); isValid = exInfo._frameIter.Next(&startIdx, &unwoundReversePInvoke, &isExceptionIntercepted))
{
Debug.Assert(isValid, "Unwind and intercept failed unexpectedly");
DebugScanCallFrame(exInfo._passNumber, exInfo._frameIter.ControlPC, exInfo._frameIter.SP);

if (unwoundReversePInvoke)
{
// Found the native frame that called the reverse P/invoke.
// It is not possible to run managed second pass handlers on a native frame.
break;
}

if (exInfo._frameIter.SP == interceptStackFrameSP)
{
break;
}

InvokeSecondPass(ref exInfo, startIdx);
if (isExceptionIntercepted)
{
Debug.Assert(false);
break;
}
}

// ------------------------------------------------
//
// Call the interception code
//
// ------------------------------------------------
if (unwoundReversePInvoke)
{
object exceptionObj = exInfo.ThrownException;
fixed (EH.ExInfo* pExInfo = &exInfo)
{
InternalCalls.RhpCallCatchFunclet(
ObjectHandleOnStack.Create(ref exceptionObj), null, exInfo._frameIter.RegisterSet, pExInfo);
}
}
else
{
InternalCalls.ResumeAtInterceptionLocation(exInfo._frameIter.RegisterSet);
}

Debug.Fail("unreachable");
FallbackFailFast(RhFailFastReason.InternalError, null);
}
#endif // !NATIVEAOT


#if NATIVEAOT
[RuntimeExport("RhRethrow")]
#endif
Expand All @@ -757,7 +726,9 @@ public static void RhRethrow(ref ExInfo activeExInfo, ref ExInfo exInfo)

exInfo.Init(rethrownException, ref activeExInfo);
DispatchEx(ref exInfo._frameIter, ref exInfo);
#if NATIVEAOT
FallbackFailFast(RhFailFastReason.InternalError, null);
#endif
}

[StackTraceHidden]
Expand Down Expand Up @@ -877,6 +848,21 @@ private static void DispatchEx(scoped ref StackFrameIterator frameIter, ref ExIn
Debug.Assert(pCatchHandler != null || pReversePInvokePropagationCallback != IntPtr.Zero || unwoundReversePInvoke || isExceptionIntercepted, "We should have a handler if we're starting the second pass");
Debug.Assert(!isExceptionIntercepted || (pCatchHandler == null), "No catch handler should be returned for intercepted exceptions in the first pass");

#if !NATIVEAOT
exInfo._pCatchHandler = pCatchHandler;
exInfo._handlingFrameSP = handlingFrameSP;
#if TARGET_ARM64
exInfo._handlingFramePC = prevOriginalPC;
#endif
#if TARGET_UNIX
exInfo._pReversePInvokePropagationCallback = pReversePInvokePropagationCallback;
exInfo._pReversePInvokePropagationContext = pReversePInvokePropagationContext;
#endif // TARGET_UNIX
exInfo._idxCurClause = catchingTryRegionIdx;

return;

#else // !NATIVEAOT
// ------------------------------------------------
//
// Second pass
Expand All @@ -888,9 +874,10 @@ private static void DispatchEx(scoped ref StackFrameIterator frameIter, ref ExIn
// 'collapse' funclets which gets confused when we walk out of the dispatch code and encounter the
// 'main body' without first encountering the funclet. The thunks used to invoke 2nd-pass
// funclets will always toggle this mode off before invoking them.
#if NATIVEAOT

InternalCalls.RhpSetThreadDoNotTriggerGC();
#endif


exInfo._passNumber = 2;
exInfo._idxCurClause = catchingTryRegionIdx;
startIdx = MaxTryRegionIdx;
Expand All @@ -910,10 +897,8 @@ private static void DispatchEx(scoped ref StackFrameIterator frameIter, ref ExIn

if (unwoundReversePInvoke)
{
#if NATIVEAOT
Debug.Assert(pReversePInvokePropagationCallback != IntPtr.Zero, "Unwound to a reverse P/Invoke in the second pass. We should have a propagation handler.");
Debug.Assert(frameIter.PreviousTransitionFrame != IntPtr.Zero, "Should have a transition frame for reverse P/Invoke.");
#endif
Debug.Assert(frameIter.SP == handlingFrameSP, "Encountered a different reverse P/Invoke frame in the second pass.");
// Found the native frame that called the reverse P/invoke.
// It is not possible to run managed second pass handlers on a native frame.
Expand All @@ -937,36 +922,26 @@ private static void DispatchEx(scoped ref StackFrameIterator frameIter, ref ExIn
#if FEATURE_OBJCMARSHAL
if (pReversePInvokePropagationCallback != IntPtr.Zero)
{
#if NATIVEAOT
InternalCalls.RhpCallPropagateExceptionCallback(
pReversePInvokePropagationContext, pReversePInvokePropagationCallback, frameIter.RegisterSet, ref exInfo, frameIter.PreviousTransitionFrame);
// the helper should jump to propagation handler and not return
#endif
Debug.Fail("unreachable");
FallbackFailFast(RhFailFastReason.InternalError, null);
}
#endif // FEATURE_OBJCMARSHAL


// ------------------------------------------------
//
// Call the handler and resume execution
//
// ------------------------------------------------
exInfo._idxCurClause = catchingTryRegionIdx;
#if NATIVEAOT
InternalCalls.RhpCallCatchFunclet(
exceptionObj, pCatchHandler, frameIter.RegisterSet, ref exInfo);
#else // NATIVEAOT
fixed (EH.ExInfo* pExInfo = &exInfo)
{
InternalCalls.RhpCallCatchFunclet(
ObjectHandleOnStack.Create(ref exceptionObj), pCatchHandler, frameIter.RegisterSet, pExInfo);
}
#endif // NATIVEAOT
// currently, RhpCallCatchFunclet will resume after the catch
Debug.Fail("unreachable");
FallbackFailFast(RhFailFastReason.InternalError, null);
#endif // !NATIVEAOT
}

[System.Diagnostics.Conditional("DEBUG")]
Expand Down Expand Up @@ -1170,6 +1145,7 @@ private static bool ShouldTypedClauseCatchThisException(object exception, Method
#endif
}

#if NATIVEAOT
private static void InvokeSecondPass(ref ExInfo exInfo, uint idxStart)
{
InvokeSecondPass(ref exInfo, idxStart, MaxTryRegionIdx);
Expand Down Expand Up @@ -1207,11 +1183,7 @@ private static void InvokeSecondPass(ref ExInfo exInfo, uint idxStart, uint idxL

// Now, we continue skipping while the try region is identical to the one that invoked the
// previous dispatch.
if ((ehClause._tryStartOffset == lastTryStart) && (ehClause._tryEndOffset == lastTryEnd)
#if !NATIVEAOT
&& (ehClause._isSameTry)
#endif
)
if ((ehClause._tryStartOffset == lastTryStart) && (ehClause._tryEndOffset == lastTryEnd))
continue;

// We are done skipping. This is required to handle empty finally block markers that are used
Expand Down Expand Up @@ -1242,19 +1214,11 @@ private static void InvokeSecondPass(ref ExInfo exInfo, uint idxStart, uint idxL

byte* pFinallyHandler = ehClause._handlerAddress;
exInfo._idxCurClause = curIdx;
#if NATIVEAOT
InternalCalls.RhpCallFinallyFunclet(pFinallyHandler, exInfo._frameIter.RegisterSet);
#else // NATIVEAOT
fixed (EH.ExInfo* pExInfo = &exInfo)
{
InternalCalls.RhpCallFinallyFunclet(pFinallyHandler, exInfo._frameIter.RegisterSet, pExInfo);
}
#endif // NATIVEAOT
exInfo._idxCurClause = MaxTryRegionIdx;
}
}

#if NATIVEAOT
#pragma warning disable IDE0060
[UnmanagedCallersOnly(EntryPoint = "RhpFailFastForPInvokeExceptionPreemp")]
public static void RhpFailFastForPInvokeExceptionPreemp(IntPtr PInvokeCallsiteReturnAddr, void* pExceptionRecord, void* pContextRecord)
Expand Down
1 change: 0 additions & 1 deletion src/coreclr/vm/corelib.h
Original file line number Diff line number Diff line change
Expand Up @@ -1357,7 +1357,6 @@ DEFINE_CLASS(EH, Runtime, EH)
DEFINE_METHOD(EH, RH_THROW_EX, RhThrowEx, SM_Obj_RefExInfo_RetVoid)
DEFINE_METHOD(EH, RH_THROWHW_EX, RhThrowHwEx, SM_UInt_RefExInfo_RetVoid)
DEFINE_METHOD(EH, RH_RETHROW, RhRethrow, SM_RefExInfo_RefExInfo_RetVoid)
DEFINE_METHOD(EH, UNWIND_AND_INTERCEPT, RhUnwindAndIntercept, SM_RefExInfo_UIntPtr_RetVoid)
DEFINE_CLASS(EXCEPTIONSERVICES_INTERNALCALLS, ExceptionServices, InternalCalls)
DEFINE_CLASS(STACKFRAMEITERATOR, Runtime, StackFrameIterator)
#endif // FEATURE_EH_FUNCLETS
Expand Down
Loading