summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clr.coreclr.props2
-rw-r--r--clrdefinitions.cmake2
-rw-r--r--src/inc/corinfo.h15
-rw-r--r--src/jit/codegenlegacy.cpp9
-rw-r--r--src/jit/gentree.h5
-rw-r--r--src/jit/importer.cpp5
-rw-r--r--src/vm/comdelegate.cpp44
-rw-r--r--src/vm/dllimport.h2
-rw-r--r--src/vm/ilstubcache.cpp6
-rw-r--r--src/vm/ilstubresolver.cpp1
-rw-r--r--src/vm/ilstubresolver.h1
-rw-r--r--src/vm/jitinterface.cpp17
-rw-r--r--src/vm/method.hpp6
13 files changed, 102 insertions, 13 deletions
diff --git a/clr.coreclr.props b/clr.coreclr.props
index f1c2b129cb..23a16524c1 100644
--- a/clr.coreclr.props
+++ b/clr.coreclr.props
@@ -82,7 +82,7 @@
<FeaturePal>true</FeaturePal>
<FeatureXplatEventSource>true</FeatureXplatEventSource>
- <FeatureStubsAsIL Condition="'$(TargetArch)' != 'arm'">true</FeatureStubsAsIL>
+ <FeatureStubsAsIL>true</FeatureStubsAsIL>
<!-- Windows specific features -->
<FeatureWin32Registry>false</FeatureWin32Registry>
diff --git a/clrdefinitions.cmake b/clrdefinitions.cmake
index 20040b75a9..3520795a55 100644
--- a/clrdefinitions.cmake
+++ b/clrdefinitions.cmake
@@ -160,7 +160,7 @@ endif(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_I386)
add_definitions(-DFEATURE_STANDALONE_SN)
add_definitions(-DFEATURE_STRONGNAME_DELAY_SIGNING_ALLOWED)
add_definitions(-DFEATURE_STRONGNAME_MIGRATION)
-if ((CLR_CMAKE_PLATFORM_UNIX OR CLR_CMAKE_TARGET_ARCH_ARM64) AND NOT CLR_CMAKE_TARGET_ARCH_ARM)
+if (CLR_CMAKE_PLATFORM_UNIX OR CLR_CMAKE_TARGET_ARCH_ARM64)
add_definitions(-DFEATURE_STUBS_AS_IL)
endif ()
add_definitions(-DFEATURE_SVR_GC)
diff --git a/src/inc/corinfo.h b/src/inc/corinfo.h
index 7302f4a5e7..6e41d8e035 100644
--- a/src/inc/corinfo.h
+++ b/src/inc/corinfo.h
@@ -231,11 +231,11 @@ TODO: Talk about initializing strutures before use
#if COR_JIT_EE_VERSION > 460
// Update this one
-SELECTANY const GUID JITEEVersionIdentifier = { /* 718c4238-2a85-45de-88ad-9b1fed806547 */
- 0x718c4238,
- 0x2a85,
- 0x45de,
- { 0x88, 0xad, 0x9b, 0x1f, 0xed, 0x80, 0x65, 0x47 }
+SELECTANY const GUID JITEEVersionIdentifier = { /* 0b17dfeb-1ead-4e06-b025-d60d3a493b53 */
+ 0x0b17dfeb,
+ 0x1ead,
+ 0x4e06,
+ { 0xb0, 0x25, 0xd6, 0x0d, 0x3a, 0x49, 0x3b, 0x53 }
};
#else
@@ -1686,6 +1686,8 @@ struct CORINFO_CALL_INFO
};
CORINFO_CONST_LOOKUP instParamLookup; // Used by Ready-to-Run
+
+ BOOL secureDelegateInvoke;
};
//----------------------------------------------------------------------------
@@ -1808,6 +1810,9 @@ struct CORINFO_EE_INFO
unsigned offsetOfDelegateInstance;
unsigned offsetOfDelegateFirstTarget;
+ // Secure delegate offsets
+ unsigned offsetOfSecureDelegateIndirectCell;
+
// Remoting offsets
unsigned offsetOfTransparentProxyRP;
unsigned offsetOfRealProxyServer;
diff --git a/src/jit/codegenlegacy.cpp b/src/jit/codegenlegacy.cpp
index feb4540907..0f0ccc7fdf 100644
--- a/src/jit/codegenlegacy.cpp
+++ b/src/jit/codegenlegacy.cpp
@@ -18418,7 +18418,6 @@ regMaskTP CodeGen::genLoadIndirectCallTarget(GenTreePtr call)
* register mask that describes where the result will be found is returned;
* otherwise, RBM_NONE is returned.
*/
-
#ifdef _PREFAST_
#pragma warning(push)
#pragma warning(disable : 21000) // Suppress PREFast warning about overly large function
@@ -18837,6 +18836,14 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
instOffs = pInfo->offsetOfDelegateInstance;
firstTgtOffs = pInfo->offsetOfDelegateFirstTarget;
+#ifdef _TARGET_ARM_
+ if ((call->gtCall.gtCallMoreFlags & GTF_CALL_M_SECURE_DELEGATE_INV))
+ {
+ getEmitter()->emitIns_R_R_I(INS_add, EA_PTRSIZE, REG_VIRTUAL_STUB_PARAM, regThis, pInfo->offsetOfSecureDelegateIndirectCell);
+ regTracker.rsTrackRegTrash(REG_VIRTUAL_STUB_PARAM);
+ }
+#endif // _TARGET_ARM_
+
// Grab an available register to use for the CALL indirection
regNumber indCallReg = regSet.rsGrabReg(RBM_ALLINT);
diff --git a/src/jit/gentree.h b/src/jit/gentree.h
index bf114f4fc3..89d88393be 100644
--- a/src/jit/gentree.h
+++ b/src/jit/gentree.h
@@ -2929,8 +2929,9 @@ struct GenTreeCall final : public GenTree
// a Pinvoke but not as an unmanaged call. See impCheckForPInvokeCall() to
// know when these flags are set.
-#define GTF_CALL_M_R2R_REL_INDIRECT 0x2000 // GT_CALL -- ready to run call is indirected through a relative address
-#define GTF_CALL_M_DOES_NOT_RETURN 0x4000 // GT_CALL -- call does not return
+#define GTF_CALL_M_R2R_REL_INDIRECT 0x2000 // GT_CALL -- ready to run call is indirected through a relative address
+#define GTF_CALL_M_DOES_NOT_RETURN 0x4000 // GT_CALL -- call does not return
+#define GTF_CALL_M_SECURE_DELEGATE_INV 0x8000 // GT_CALL -- call is in secure delegate
bool IsUnmanaged() const
{
diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp
index 73026bd00f..6157611aad 100644
--- a/src/jit/importer.cpp
+++ b/src/jit/importer.cpp
@@ -6586,6 +6586,11 @@ var_types Compiler::impImportCall(OPCODE opcode,
/* Set the delegate flag */
call->gtCall.gtCallMoreFlags |= GTF_CALL_M_DELEGATE_INV;
+ if (callInfo->secureDelegateInvoke)
+ {
+ call->gtCall.gtCallMoreFlags |= GTF_CALL_M_SECURE_DELEGATE_INV;
+ }
+
if (opcode == CEE_CALLVIRT)
{
assert(mflags & CORINFO_FLG_FINAL);
diff --git a/src/vm/comdelegate.cpp b/src/vm/comdelegate.cpp
index c400fc36ab..9ba1bdb328 100644
--- a/src/vm/comdelegate.cpp
+++ b/src/vm/comdelegate.cpp
@@ -2596,7 +2596,7 @@ BOOL COMDelegate::NeedsWrapperDelegate(MethodDesc* pTargetMD)
#ifdef _TARGET_ARM_
// For arm VSD expects r4 to contain the indirection cell. However r4 is a non-volatile register
// and its value must be preserved. So we need to erect a frame and store indirection cell in r4 before calling
- // virtual stub dispatch. Erecting frame is already done by secure delegates so the secureDelegate infrastructure
+ // virtual stub dispatch. Erecting frame is already done by secure delegates so the secureDelegate infrastructure
// can easliy be used for our purpose.
// set needsSecureDelegate flag in order to erect a frame. (Secure Delegate stub also loads the right value in r4)
if (!pTargetMD->IsStatic() && pTargetMD->IsVirtual() && !pTargetMD->GetMethodTable()->IsValueType())
@@ -2931,7 +2931,47 @@ PCODE COMDelegate::GetSecureInvoke(MethodDesc* pMD)
#ifdef FEATURE_CAS_POLICY
#error GetSecureInvoke not implemented
#else
- UNREACHABLE();
+ GCX_PREEMP();
+
+ MetaSig sig(pMD);
+
+ BOOL fReturnVal = !sig.IsReturnTypeVoid();
+
+ SigTypeContext emptyContext;
+ ILStubLinker sl(pMD->GetModule(), pMD->GetSignature(), &emptyContext, pMD, TRUE, TRUE, FALSE);
+
+ ILCodeStream *pCode = sl.NewCodeStream(ILStubLinker::kDispatch);
+
+ // Load the "real" delegate
+ pCode->EmitLoadThis();
+ pCode->EmitLDFLD(pCode->GetToken(MscorlibBinder::GetField(FIELD__MULTICAST_DELEGATE__INVOCATION_LIST)));
+
+ // Load the arguments
+ UINT paramCount = 0;
+ while(paramCount < sig.NumFixedArgs())
+ pCode->EmitLDARG(paramCount++);
+
+ // Call the delegate
+ pCode->EmitCALL(pCode->GetToken(pMD), sig.NumFixedArgs(), fReturnVal);
+
+ // Return
+ pCode->EmitRET();
+
+ PCCOR_SIGNATURE pSig;
+ DWORD cbSig;
+
+ pMD->GetSig(&pSig,&cbSig);
+
+ MethodDesc* pStubMD =
+ ILStubCache::CreateAndLinkNewILStubMethodDesc(pMD->GetLoaderAllocator(),
+ pMD->GetMethodTable(),
+ ILSTUB_SECUREDELEGATE_INVOKE,
+ pMD->GetModule(),
+ pSig, cbSig,
+ NULL,
+ &sl);
+
+ return Stub::NewStub(JitILStub(pStubMD))->GetEntryPoint();
#endif
}
#else // FEATURE_STUBS_AS_IL
diff --git a/src/vm/dllimport.h b/src/vm/dllimport.h
index 3785385d04..b393bf6cdd 100644
--- a/src/vm/dllimport.h
+++ b/src/vm/dllimport.h
@@ -215,6 +215,7 @@ enum ILStubTypes
ILSTUB_MULTICASTDELEGATE_INVOKE = 0x80000010,
ILSTUB_UNBOXINGILSTUB = 0x80000020,
ILSTUB_INSTANTIATINGSTUB = 0x80000040,
+ ILSTUB_SECUREDELEGATE_INVOKE = 0x80000080,
#endif
};
@@ -245,6 +246,7 @@ inline bool SF_IsArrayOpStub (DWORD dwStubFlags) { LIMITED_METHOD_CONT
#endif
#ifdef FEATURE_STUBS_AS_IL
+inline bool SF_IsSecureDelegateStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags == ILSTUB_SECUREDELEGATE_INVOKE); }
inline bool SF_IsMulticastDelegateStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags == ILSTUB_MULTICASTDELEGATE_INVOKE); }
inline bool SF_IsUnboxingILStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags == ILSTUB_UNBOXINGILSTUB); }
inline bool SF_IsInstantiatingStub (DWORD dwStubFlags) { LIMITED_METHOD_CONTRACT; return (dwStubFlags == ILSTUB_INSTANTIATINGSTUB); }
diff --git a/src/vm/ilstubcache.cpp b/src/vm/ilstubcache.cpp
index 426976a344..4343ba819f 100644
--- a/src/vm/ilstubcache.cpp
+++ b/src/vm/ilstubcache.cpp
@@ -217,6 +217,12 @@ MethodDesc* ILStubCache::CreateNewMethodDesc(LoaderHeap* pCreationHeap, MethodTa
else
#endif
#ifdef FEATURE_STUBS_AS_IL
+ if (SF_IsSecureDelegateStub(dwStubFlags))
+ {
+ pMD->m_dwExtendedFlags |= DynamicMethodDesc::nomdSecureDelegateStub;
+ pMD->GetILStubResolver()->SetStubType(ILStubResolver::SecureDelegateStub);
+ }
+ else
if (SF_IsMulticastDelegateStub(dwStubFlags))
{
pMD->m_dwExtendedFlags |= DynamicMethodDesc::nomdMulticastStub;
diff --git a/src/vm/ilstubresolver.cpp b/src/vm/ilstubresolver.cpp
index aea5c69487..64ff99f67e 100644
--- a/src/vm/ilstubresolver.cpp
+++ b/src/vm/ilstubresolver.cpp
@@ -91,6 +91,7 @@ LPCUTF8 ILStubResolver::GetStubMethodName()
case MulticastDelegateStub: return "IL_STUB_MulticastDelegate_Invoke";
case UnboxingILStub: return "IL_STUB_UnboxingStub";
case InstantiatingStub: return "IL_STUB_InstantiatingStub";
+ case SecureDelegateStub: return "IL_STUB_SecureDelegate_Invoke";
#endif
default:
UNREACHABLE_MSG("Unknown stub type");
diff --git a/src/vm/ilstubresolver.h b/src/vm/ilstubresolver.h
index 5113b55ef9..b100931107 100644
--- a/src/vm/ilstubresolver.h
+++ b/src/vm/ilstubresolver.h
@@ -83,6 +83,7 @@ protected:
ArrayOpStub,
#endif
#ifdef FEATURE_STUBS_AS_IL
+ SecureDelegateStub,
MulticastDelegateStub,
UnboxingILStub,
InstantiatingStub,
diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp
index b016d20804..76d4568adb 100644
--- a/src/vm/jitinterface.cpp
+++ b/src/vm/jitinterface.cpp
@@ -5169,7 +5169,6 @@ void CEEInfo::getCallInfo(
bool resolvedCallVirt = false;
bool callVirtCrossingVersionBubble = false;
-
// Delegate targets are always treated as direct calls here. (It would be nice to clean it up...).
if (flags & CORINFO_CALLINFO_LDFTN)
{
@@ -5686,6 +5685,19 @@ void CEEInfo::getCallInfo(
}
}
+ pResult->secureDelegateInvoke = FALSE;
+
+#ifdef FEATURE_STUBS_AS_IL
+ if (m_pMethodBeingCompiled->IsDynamicMethod())
+ {
+ auto pMD = m_pMethodBeingCompiled->AsDynamicMethodDesc();
+ if (pMD->IsILStub() && pMD->IsSecureDelegateStub())
+ {
+ pResult->secureDelegateInvoke = TRUE;
+ }
+ }
+#endif
+
EE_TO_JIT_TRANSITION();
}
@@ -9630,6 +9642,9 @@ void CEEInfo::getEEInfo(CORINFO_EE_INFO *pEEInfoOut)
pEEInfoOut->offsetOfDelegateInstance = DelegateObject::GetOffsetOfTarget();
pEEInfoOut->offsetOfDelegateFirstTarget = DelegateObject::GetOffsetOfMethodPtr();
+ // Secure delegate offsets
+ pEEInfoOut->offsetOfSecureDelegateIndirectCell = DelegateObject::GetOffsetOfMethodPtrAux();
+
// Remoting offsets
pEEInfoOut->offsetOfTransparentProxyRP = TransparentProxyObject::GetOffsetOfRP();
pEEInfoOut->offsetOfRealProxyServer = RealProxyObject::GetOffsetOfServerObject();
diff --git a/src/vm/method.hpp b/src/vm/method.hpp
index 5c73827a61..3cdd794f08 100644
--- a/src/vm/method.hpp
+++ b/src/vm/method.hpp
@@ -2304,6 +2304,7 @@ protected:
nomdStubNeedsCOMStarted = 0x0800, // EnsureComStarted must be called before executing the method
nomdMulticastStub = 0x1000,
nomdUnboxingILStub = 0x2000,
+ nomdSecureDelegateStub = 0x4000,
nomdILStub = 0x00010000,
nomdLCGMethod = 0x00020000,
@@ -2412,6 +2413,11 @@ public:
bool IsSignatureNeedsRestore() { LIMITED_METHOD_CONTRACT; _ASSERTE(IsILStub()); return (0 != (m_dwExtendedFlags & nomdSignatureNeedsRestore)); }
bool IsStubNeedsCOMStarted() { LIMITED_METHOD_CONTRACT; _ASSERTE(IsILStub()); return (0 != (m_dwExtendedFlags & nomdStubNeedsCOMStarted)); }
#ifdef FEATURE_STUBS_AS_IL
+ bool IsSecureDelegateStub() {
+ LIMITED_METHOD_DAC_CONTRACT;
+ _ASSERTE(IsILStub());
+ return !!(m_dwExtendedFlags & nomdSecureDelegateStub);
+ }
bool IsMulticastStub() {
LIMITED_METHOD_DAC_CONTRACT;
_ASSERTE(IsILStub());