From 7bc637d41033ccb1a0d881f719654e59fe0319a0 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Fri, 2 Jul 2021 10:49:49 -0700 Subject: [PATCH] Do not setup both an inlined call frame and perform a reverse pinvoke in the same function - Pushing/popping the frame chain requires that the thread be in cooperative mode - Before the reverse pinvoke logic engages, the thread is in preemptive mode - The current implementation of InlinedCallFrame and reverse p/invoke sets up the InlinedCallFrame before the reverse p/invoke transition, which is unsafe - A reverse pinvoke function directly calling back into native code is fairly rare, and so optimizing the situation is of marginal utility. - The fix is to use the pinvoke helpers logic to setup the pinvoke instead of relying on the InlinedCallFrame logic. This avoid the problem of incorrect ordering in the prolog/epilog, but moving inlined call frame handling to point of use. Fix bug #45326 --- src/coreclr/jit/compiler.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index fbafd6e9a844d9..d27b5e9736246c 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -9218,10 +9218,14 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX #endif // true if we should use the PINVOKE_{BEGIN,END} helpers instead of generating - // PInvoke transitions inline. + // PInvoke transitions inline. Normally used by R2R, but also used when generating a reverse pinvoke frame, as + // the current logic for frame setup initializes and pushes + // the InlinedCallFrame before performing the Reverse PInvoke transition, which is invalid (as frames cannot + // safely be pushed/popped while the thread is in a preemptive state.). bool ShouldUsePInvokeHelpers() { - return jitFlags->IsSet(JitFlags::JIT_FLAG_USE_PINVOKE_HELPERS); + return jitFlags->IsSet(JitFlags::JIT_FLAG_USE_PINVOKE_HELPERS) || + jitFlags->IsSet(JitFlags::JIT_FLAG_REVERSE_PINVOKE); } // true if we should use insert the REVERSE_PINVOKE_{ENTER,EXIT} helpers in the method