diff options
-rw-r--r-- | clr.coreclr.props | 2 | ||||
-rw-r--r-- | clrdefinitions.cmake | 2 | ||||
-rw-r--r-- | src/inc/corinfo.h | 15 | ||||
-rw-r--r-- | src/jit/codegenlegacy.cpp | 9 | ||||
-rw-r--r-- | src/jit/gentree.h | 5 | ||||
-rw-r--r-- | src/jit/importer.cpp | 5 | ||||
-rw-r--r-- | src/vm/comdelegate.cpp | 44 | ||||
-rw-r--r-- | src/vm/dllimport.h | 2 | ||||
-rw-r--r-- | src/vm/ilstubcache.cpp | 6 | ||||
-rw-r--r-- | src/vm/ilstubresolver.cpp | 1 | ||||
-rw-r--r-- | src/vm/ilstubresolver.h | 1 | ||||
-rw-r--r-- | src/vm/jitinterface.cpp | 17 | ||||
-rw-r--r-- | src/vm/method.hpp | 6 |
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()); |