diff options
Diffstat (limited to 'src/vm/jitinterface.cpp')
-rw-r--r-- | src/vm/jitinterface.cpp | 291 |
1 files changed, 11 insertions, 280 deletions
diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp index ff3010d12c..97fe3e8262 100644 --- a/src/vm/jitinterface.cpp +++ b/src/vm/jitinterface.cpp @@ -24,7 +24,6 @@ #include "excep.h" #include "float.h" // for isnan #include "dbginterface.h" -#include "security.h" #include "dllimport.h" #include "gcheaputilities.h" #include "comdelegate.h" @@ -47,7 +46,6 @@ #include "genericdict.h" #include "array.h" #include "debuginfostore.h" -#include "security.h" #include "safemath.h" #include "runtimehandles.h" #include "sigbuilder.h" @@ -1787,9 +1785,7 @@ void CEEInfo::getFieldInfo (CORINFO_RESOLVED_TOKEN * pResolvedToken, fieldAttribs, NULL, (flags & CORINFO_ACCESS_INIT_ARRAY) ? NULL : pField, // For InitializeArray, we don't need tocheck the type of the field. - accessCheckOptions, - FALSE /*checkTargetMethodTransparency*/, - TRUE /*checkTargetTypeTransparency*/); + accessCheckOptions); if (!canAccess) { @@ -1928,14 +1924,6 @@ CEEInfo::findCallSiteSig( if (TypeFromToken(sigMethTok) == mdtMemberRef) { IfFailThrow(module->GetMDImport()->GetNameAndSigOfMemberRef(sigMethTok, &pSig, &cbSig, &szName)); - - // Defs have already been checked by the loader for validity - // However refs need to be checked. - if (!Security::CanSkipVerification(module->GetDomainAssembly())) - { - // Can pass 0 for the flags, since it is only used for defs. - IfFailThrow(validateTokenSig(sigMethTok, pSig, cbSig, 0, module->GetMDImport())); - } } else if (TypeFromToken(sigMethTok) == mdtMethodDef) { @@ -5559,9 +5547,7 @@ void CEEInfo::getCallInfo( pCalleeForSecurity->GetAttrs(), pCalleeForSecurity, NULL, - accessCheckOptions, - FALSE, - TRUE + accessCheckOptions ); // If we were allowed access to the exact method, but it is on a type that has a type parameter @@ -5581,11 +5567,10 @@ void CEEInfo::getCallInfo( // No accees check is need for Var, MVar, or FnPtr. if (pTypeParamMT != NULL) - canAccessMethod = ClassLoader::CanAccessClassForExtraChecks(&accessContext, - pTypeParamMT, - typeParam.GetAssembly(), - accessCheckOptions, - TRUE); + canAccessMethod = ClassLoader::CanAccessClass(&accessContext, + pTypeParamMT, + typeParam.GetAssembly(), + accessCheckOptions); } pResult->accessAllowed = canAccessMethod ? CORINFO_ACCESS_ALLOWED : CORINFO_ACCESS_ILLEGAL; @@ -6499,13 +6484,10 @@ DWORD CEEInfo::getMethodAttribsInternal (CORINFO_METHOD_HANDLE ftn) if (pMD->IsLCGMethod()) { -#ifndef CROSSGEN_COMPILE -#endif // !CROSSGEN_COMPILE - return CORINFO_FLG_STATIC | CORINFO_FLG_DONT_INLINE | CORINFO_FLG_NOSECURITYWRAP; } - DWORD result = 0; + DWORD result = CORINFO_FLG_NOSECURITYWRAP; // <REVISIT_TODO>@todo: can we git rid of CORINFO_FLG_ stuff and just include cor.h?</REVISIT_TODO> @@ -6559,11 +6541,6 @@ DWORD CEEInfo::getMethodAttribsInternal (CORINFO_METHOD_HANDLE ftn) result |= CORINFO_FLG_PINVOKE; } - if (!pMD->IsInterceptedForDeclSecurity()) - { - result |= CORINFO_FLG_NOSECURITYWRAP; - } - if (IsMdRequireSecObject(attribs)) { // Assume all methods marked as DynamicSecurity are @@ -6645,15 +6622,6 @@ void CEEInfo::setMethodAttribs ( } } - // Both CORINFO_FLG_UNVERIFIABLE and CORINFO_FLG_VERIFIABLE cannot be set - _ASSERTE(!(attribs & CORINFO_FLG_UNVERIFIABLE) || - !(attribs & CORINFO_FLG_VERIFIABLE )); - - if (attribs & CORINFO_FLG_VERIFIABLE) - ftn->SetIsVerified(TRUE); - else if (attribs & CORINFO_FLG_UNVERIFIABLE) - ftn->SetIsVerified(FALSE); - EE_TO_JIT_TRANSITION(); } @@ -7389,12 +7357,6 @@ CEEInfo::getMethodInfo( else { /* Get the IL header */ - /* <REVISIT_TODO>TODO: canInline already did validation, however, we do it again - here because NGEN uses this function without calling canInline - It would be nice to avoid this redundancy </REVISIT_TODO>*/ - Module* pModule = ftn->GetModule(); - - bool verify = !Security::CanSkipVerification(ftn); if (ftn->IsDynamicMethod()) { @@ -7402,28 +7364,7 @@ CEEInfo::getMethodInfo( } else { - COR_ILMETHOD_DECODER::DecoderStatus status = COR_ILMETHOD_DECODER::SUCCESS; - COR_ILMETHOD_DECODER header(ftn->GetILHeader(TRUE), ftn->GetMDImport(), verify ? &status : NULL); - - // If we get a verification error then we try to demand SkipVerification for the module - if (status == COR_ILMETHOD_DECODER::VERIFICATION_ERROR && - Security::CanSkipVerification(pModule->GetDomainAssembly())) - { - status = COR_ILMETHOD_DECODER::SUCCESS; - } - - if (status != COR_ILMETHOD_DECODER::SUCCESS) - { - if (status == COR_ILMETHOD_DECODER::VERIFICATION_ERROR) - { - // Throw a verification HR - COMPlusThrowHR(COR_E_VERIFICATION); - } - else - { - COMPlusThrowHR(COR_E_BADIMAGEFORMAT, BFA_BAD_IL); - } - } + COR_ILMETHOD_DECODER header(ftn->GetILHeader(TRUE), ftn->GetMDImport(), NULL); getMethodInfoHelper(ftn, ftnHnd, &header, methInfo); } @@ -7550,25 +7491,6 @@ CorInfoInline CEEInfo::canInline (CORINFO_METHOD_HANDLE hCaller, Module * pOrigCallerModule; pOrigCallerModule = pOrigCaller->GetLoaderModule(); - // Prevent recursive compiling/inlining/verifying - if (pOrigCaller != pCallee) - { - // The Inliner may not do code verification. - // So never inline anything that is unverifiable / bad code. - if (!Security::CanSkipVerification(pCallee)) - { - // Inlinee needs to be verifiable - if (!pCallee->IsVerifiable()) - { - result = INLINE_NEVER; - szFailReason = "Inlinee is not verifiable"; - goto exit; - } - } - } - - // We check this here as the call to MethodDesc::IsVerifiable() - // may set CORINFO_FLG_DONT_INLINE. if (pCallee->IsNotInline()) { result = INLINE_NEVER; @@ -7969,8 +7891,7 @@ CorInfoInstantiationVerification goto exit; } - result = pMethod->IsVerifiable() ? INSTVER_GENERIC_PASSED_VERIFICATION - : INSTVER_GENERIC_FAILED_VERIFICATION; + result = INSTVER_GENERIC_PASSED_VERIFICATION; exit: ; @@ -8025,16 +7946,6 @@ bool CEEInfo::canTailCall (CORINFO_METHOD_HANDLE hCaller, goto exit; } - // TailCalls will throw off security stackwalking logic when there is a declarative Assert - // Note that this check will also include declarative demands. It's OK to do a tailcall in - // those cases, but we currently don't have a way to check only for declarative Asserts. - if (pCaller->IsInterceptedForDeclSecurity()) - { - result = false; - szFailReason = "Caller has declarative security"; - goto exit; - } - if (!fIsTailPrefix) { mdMethodDef callerToken = pCaller->GetMemberDef(); @@ -11881,13 +11792,6 @@ CorJitResult invokeCompileMethod(EEJitManager *jitMgr, return ret; } -CORJIT_FLAGS GetCompileFlagsIfGenericInstantiation( - CORINFO_METHOD_HANDLE method, - CORJIT_FLAGS compileFlags, - ICorJitInfo * pCorJitInfo, - BOOL * raiseVerificationException, - BOOL * unverifiableGenericCode); - CorJitResult CallCompileMethodWithSEHWrapper(EEJitManager *jitMgr, CEEInfo *comp, struct CORINFO_METHOD_INFO *info, @@ -12137,22 +12041,10 @@ CORJIT_FLAGS GetCompileFlags(MethodDesc * ftn, CORJIT_FLAGS flags, CORINFO_METHO } } - // - // Verification flags - // - -#ifdef _DEBUG - if (g_pConfig->IsJitVerificationDisabled()) - flags.Set(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION); -#endif // _DEBUG - - if (!flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY) && Security::CanSkipVerification(ftn)) - flags.Set(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION); + flags.Set(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION); if (ftn->IsILStub()) { - flags.Set(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION); - // no debug info available for IL stubs flags.Clear(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_INFO); } @@ -12160,148 +12052,6 @@ CORJIT_FLAGS GetCompileFlags(MethodDesc * ftn, CORJIT_FLAGS flags, CORINFO_METHO return flags; } -#if defined(_WIN64) -//The implementation of Jit64 prevents it from both inlining and verifying at the same time. This causes a -//perf problem for code that adopts Transparency. This code attempts to enable inlining in spite of that -//limitation in that scenario. -// -//This only works for real methods. If the method isn't IsIL, then IsVerifiable will AV. That would be a -//bad thing (TM). -BOOL IsTransparentMethodSafeToSkipVerification(CORJIT_FLAGS flags, MethodDesc * ftn) -{ - STANDARD_VM_CONTRACT; - - BOOL ret = FALSE; - if (!flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY) && !flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION) - && Security::IsMethodTransparent(ftn) && - ((ftn->IsIL() && !ftn->IsUnboxingStub()) || - (ftn->IsDynamicMethod() && !ftn->IsILStub()))) - { - EX_TRY - { - //Verify the method - ret = ftn->IsVerifiable(); - } - EX_CATCH - { - //If the jit throws an exception, do not let it leak out of here. For example, we can sometimes - //get an IPE that we could recover from in the Jit (i.e. invalid local in a method with skip - //verification). - } - EX_END_CATCH(RethrowTerminalExceptions) - } - return ret; -} -#else -#define IsTransparentMethodSafeToSkipVerification(flags,ftn) (FALSE) -#endif //_WIN64 - -/*********************************************************************/ -// We verify generic code once and for all using the typical open type, -// and then no instantiations need to be verified. If verification -// failed, then we need to throw an exception whenever we try -// to compile a real instantiation - -CORJIT_FLAGS GetCompileFlagsIfGenericInstantiation( - CORINFO_METHOD_HANDLE method, - CORJIT_FLAGS compileFlags, - ICorJitInfo * pCorJitInfo, - BOOL * raiseVerificationException, - BOOL * unverifiableGenericCode) -{ - STANDARD_VM_CONTRACT; - - *raiseVerificationException = FALSE; - *unverifiableGenericCode = FALSE; - - // If we have already decided to skip verification, keep on going. - if (compileFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION)) - return compileFlags; - - CorInfoInstantiationVerification ver = pCorJitInfo->isInstantiationOfVerifiedGeneric(method); - - switch(ver) - { - case INSTVER_NOT_INSTANTIATION: - // Non-generic, or open instantiation of a generic type/method - if (IsTransparentMethodSafeToSkipVerification(compileFlags, (MethodDesc*)method)) - compileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION); - return compileFlags; - - case INSTVER_GENERIC_PASSED_VERIFICATION: - // If the typical instantiation is verifiable, there is no need - // to verify the concrete instantiations - compileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION); - return compileFlags; - - case INSTVER_GENERIC_FAILED_VERIFICATION: - - *unverifiableGenericCode = TRUE; - - // The generic method is not verifiable. - // Check if it has SkipVerification permission - MethodDesc * pGenMethod = GetMethod(method)->LoadTypicalMethodDefinition(); - - CORINFO_METHOD_HANDLE genMethodHandle = CORINFO_METHOD_HANDLE(pGenMethod); - - CorInfoCanSkipVerificationResult canSkipVer; - canSkipVer = pCorJitInfo->canSkipMethodVerification(genMethodHandle); - - switch(canSkipVer) - { - -#ifdef FEATURE_PREJIT - case CORINFO_VERIFICATION_DONT_JIT: - { - // Transparent code could be partial trust, but we don't know at NGEN time. - // This is the flag that NGEN passes to the JIT to tell it to give-up if it - // hits unverifiable code. Since we've already hit unverifiable code, - // there's no point in starting the JIT, just to have it give up, so we - // give up here. - _ASSERTE(compileFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_PREJIT)); - *raiseVerificationException = TRUE; - return CORJIT_FLAGS(); // This value will not be used - } -#else // FEATURE_PREJIT - // Need to have this case here to keep the MAC build happy - case CORINFO_VERIFICATION_DONT_JIT: - { - _ASSERTE(!"We should never get here"); - return compileFlags; - } -#endif // FEATURE_PREJIT - - case CORINFO_VERIFICATION_CANNOT_SKIP: - { - // For unverifiable generic code without SkipVerification permission, - // we cannot ask the compiler to emit CORINFO_HELP_VERIFICATION in - // unverifiable branches as the compiler cannot determine the unverifiable - // branches while compiling the concrete instantiation. Instead, - // just throw a VerificationException right away. - *raiseVerificationException = TRUE; - return CORJIT_FLAGS(); // This value will not be used - } - - case CORINFO_VERIFICATION_CAN_SKIP: - { - compileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION); - return compileFlags; - } - - case CORINFO_VERIFICATION_RUNTIME_CHECK: - { - // Compile the method without CORJIT_FLAG_SKIP_VERIFICATION. - // The compiler will know to add a call to - // CORINFO_HELP_VERIFICATION_RUNTIME_CHECK, and then to skip verification. - return compileFlags; - } - } - } - - _ASSERTE(!"We should never get here"); - return compileFlags; -} - // ******************************************************************** // Throw the right type of exception for the given JIT result @@ -12560,26 +12310,12 @@ PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* ILHeader, CORJIT_ pMethodForSecurity->GetAttrs(), pMethodForSecurity, NULL, - accessCheckOptions, - TRUE /*Check method transparency*/, - TRUE /*Check type transparency*/)) + accessCheckOptions)) { EX_THROW(EEMethodException, (pMethodForSecurity)); } } - BOOL raiseVerificationException, unverifiableGenericCode; - - flags = GetCompileFlagsIfGenericInstantiation( - ftnHnd, - flags, - &jitInfo, - &raiseVerificationException, - &unverifiableGenericCode); - - if (raiseVerificationException) - COMPlusThrow(kVerificationException); - CorJitResult res; PBYTE nativeEntry; ULONG sizeOfCode; @@ -12676,11 +12412,6 @@ PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* ILHeader, CORJIT_ if (flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY)) { - // The method must been processed by the verifier. Note that it may - // either have been marked as verifiable or unverifiable. - // ie. IsVerified() does not imply IsVerifiable() - _ASSERTE(ftn->IsVerified()); - // We are done break; } |