diff options
author | danmosemsft <danmose@microsoft.com> | 2017-02-14 21:07:49 -0800 |
---|---|---|
committer | danmosemsft <danmose@microsoft.com> | 2017-02-14 21:24:05 -0800 |
commit | 16eb7551d9f5ea8ec593dc86b789df4db2198a4b (patch) | |
tree | efec4968d631de26b785b962770e50c5874a83e8 | |
parent | 1c1cc23cddad0eb765752d774a48dc686ae1d61f (diff) | |
download | coreclr-16eb7551d9f5ea8ec593dc86b789df4db2198a4b.tar.gz coreclr-16eb7551d9f5ea8ec593dc86b789df4db2198a4b.tar.bz2 coreclr-16eb7551d9f5ea8ec593dc86b789df4db2198a4b.zip |
Remove never defined FEATURE_MIXEDMODE
36 files changed, 2 insertions, 3248 deletions
diff --git a/src/debug/daccess/nidump.cpp b/src/debug/daccess/nidump.cpp index c300e6fa01..3ba3d9778c 100644 --- a/src/debug/daccess/nidump.cpp +++ b/src/debug/daccess/nidump.cpp @@ -4020,12 +4020,6 @@ void NativeImageDumper::DumpModule( PTR_Module module ) DisplayWriteFieldPointer( m_pNgenStats, DataPtrToDisplay((TADDR)module->m_pNgenStats), Module, MODULE ); -#if defined(FEATURE_MIXEDMODE) - DisplayWriteFieldPointer( m_pThunkHeap, - DataPtrToDisplay(dac_cast<TADDR>(module->m_pThunkHeap)), - Module, MODULE ); - _ASSERTE(module->m_pThunkHeap == NULL); -#endif DisplayWriteFieldAddress(m_propertyNameSet, DPtrToPreferredAddr(module->m_propertyNameSet), diff --git a/src/debug/daccess/request.cpp b/src/debug/daccess/request.cpp index 5caf54585a..1f90c5e428 100644 --- a/src/debug/daccess/request.cpp +++ b/src/debug/daccess/request.cpp @@ -1580,9 +1580,6 @@ ClrDataAccess::GetModuleData(CLRDATA_ADDRESS addr, struct DacpModuleData *Module ModuleData->FileReferencesMap = PTR_CDADDR(pModule->m_FileReferencesMap.pTable); ModuleData->ManifestModuleReferencesMap = PTR_CDADDR(pModule->m_ManifestModuleReferencesMap.pTable); -#ifdef FEATURE_MIXEDMODE // IJW - ModuleData->pThunkHeap = HOST_CDADDR(pModule->m_pThunkHeap); -#endif // FEATURE_MIXEDMODE // IJW } EX_CATCH { diff --git a/src/inc/jithelpers.h b/src/inc/jithelpers.h index f84db9142d..854d2059f0 100644 --- a/src/inc/jithelpers.h +++ b/src/inc/jithelpers.h @@ -216,12 +216,7 @@ #endif #if COR_JIT_EE_VERSION > 460 -#ifdef FEATURE_MIXEDMODE - // TLS - JITHELPER(CORINFO_HELP_GETSTATICFIELDADDR_TLS, JIT_GetStaticFieldAddr_Tls,CORINFO_HELP_SIG_REG_ONLY) -#else // FEATURE_MIXEDMODE JITHELPER(CORINFO_HELP_GETSTATICFIELDADDR_TLS, NULL, CORINFO_HELP_SIG_CANNOT_USE_ALIGN_STUB) -#endif // FEATURE_MIXEDMODE #else // COR_JIT_EE_VERSION JITHELPER(CORINFO_HELP_GETSTATICFIELDADDR_TLS, JIT_GetStaticFieldAddr_Tls,CORINFO_HELP_SIG_REG_ONLY) #endif // COR_JIT_EE_VERSION diff --git a/src/utilcode/pedecoder.cpp b/src/utilcode/pedecoder.cpp index 0ab1cf3563..e4fc465888 100644 --- a/src/utilcode/pedecoder.cpp +++ b/src/utilcode/pedecoder.cpp @@ -34,7 +34,7 @@ CHECK PEDecoder::CheckFormat() const { CHECK(CheckCorHeader()); -#if !defined(FEATURE_MIXEDMODE) && !defined(FEATURE_PREJIT) +#if !defined(FEATURE_PREJIT) CHECK(IsILOnly()); #endif diff --git a/src/vm/amd64/UMThunkStub.asm b/src/vm/amd64/UMThunkStub.asm index 16bc5368c6..8a612be71f 100644 --- a/src/vm/amd64/UMThunkStub.asm +++ b/src/vm/amd64/UMThunkStub.asm @@ -11,18 +11,11 @@ include <AsmMacros.inc> include AsmConstants.inc -ifdef FEATURE_MIXEDMODE -IJWNOADThunk__MakeCall equ ?MakeCall@IJWNOADThunk@@KAXXZ -IJWNOADThunk__FindThunkTarget equ ?FindThunkTarget@IJWNOADThunk@@QEAAPEBXXZ -endif gfHostConfig equ ?g_fHostConfig@@3KA NDirect__IsHostHookEnabled equ ?IsHostHookEnabled@NDirect@@SAHXZ extern CreateThreadBlockThrow:proc extern TheUMEntryPrestubWorker:proc -ifdef FEATURE_MIXEDMODE -extern IJWNOADThunk__FindThunkTarget:proc -endif extern UMEntryPrestubUnwindFrameChainHandler:proc extern UMThunkStubUnwindFrameChainHandler:proc extern g_TrapReturningThreads:dword @@ -464,41 +457,5 @@ CopyStackArgs: NESTED_END UM2MThunk_WrapperHelper, _TEXT -ifdef FEATURE_MIXEDMODE -NESTED_ENTRY IJWNOADThunk__MakeCall, _TEXT - ; METHODDESC_REGISTER = IJWNOADThunk* - - alloc_stack 68h - - save_reg_postrsp rcx, 70h - save_reg_postrsp rdx, 78h - save_reg_postrsp r8, 80h - save_reg_postrsp r9, 88h - - save_xmm128_postrsp xmm0, 20h - save_xmm128_postrsp xmm1, 30h - save_xmm128_postrsp xmm2, 40h - save_xmm128_postrsp xmm3, 50h - END_PROLOGUE - - mov rcx, METHODDESC_REGISTER - call IJWNOADThunk__FindThunkTarget - - movdqa xmm0, xmmword ptr [rsp + 20h] - movdqa xmm1, xmmword ptr [rsp + 30h] - movdqa xmm2, xmmword ptr [rsp + 40h] - movdqa xmm3, xmmword ptr [rsp + 50h] - - mov rcx, [rsp + 70h] - mov rdx, [rsp + 78h] - mov r8, [rsp + 80h] - mov r9 , [rsp + 88h] - - ; The target is in rax - add rsp, 68h - TAILJMP_RAX -NESTED_END IJWNOADThunk__MakeCall, _TEXT -endif ; FEATURE_MIXEDMODE - end diff --git a/src/vm/appdomain.cpp b/src/vm/appdomain.cpp index 975751e440..c28af7ce9e 100644 --- a/src/vm/appdomain.cpp +++ b/src/vm/appdomain.cpp @@ -3400,120 +3400,6 @@ Volatile<LONG> g_fInExecuteMainMethod = 0; -#ifdef FEATURE_MIXEDMODE -static HRESULT RunDllMainHelper(HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved, Thread* pThread, bool bReenablePreemptive) -{ - STATIC_CONTRACT_NOTHROW; - STATIC_CONTRACT_GC_TRIGGERS; - STATIC_CONTRACT_MODE_COOPERATIVE; - STATIC_CONTRACT_FAULT; - - MethodDesc *pMD; - AppDomain *pDomain; - Module *pModule; - HRESULT hr = S_FALSE; // Assume no entry point. - - // Setup the thread state to cooperative to run managed code. - - // Get the old domain from the thread. Legacy dll entry points must always - // be run from the default domain. - // - // We cannot support legacy dlls getting loaded into all domains!! - EX_TRY - { - ENTER_DOMAIN_PTR(SystemDomain::System()->DefaultDomain(),ADV_DEFAULTAD) - { - pDomain = pThread->GetDomain(); - - // The module needs to be in the current list if you are coming here. - pModule = pDomain->GetIJWModule(hInst); - if (!pModule) - goto ErrExit; - - // See if there even is an entry point. - pMD = pModule->GetDllEntryPoint(); - if (!pMD) - goto ErrExit; - - // We're actually going to run some managed code. There may be a customer - // debug probe enabled, that prevents execution in the loader lock. - CanRunManagedCode(hInst); - - { - // Enter cooperative mode - GCX_COOP_NO_DTOR(); - } - - // Run through the helper which will do exception handling for us. - hr = ::RunDllMain(pMD, hInst, dwReason, lpReserved); - - { - // Update thread state for the case where we are returning to unmanaged code. - GCX_MAYBE_PREEMP_NO_DTOR(bReenablePreemptive); - } - -ErrExit: ; - // does not throw exception - } - END_DOMAIN_TRANSITION; - - } - EX_CATCH - { - hr = GetExceptionHResult(GET_THROWABLE()); - } - EX_END_CATCH(SwallowAllExceptions) - - return (hr); -} - -//***************************************************************************** -// This guy will set up the proper thread state, look for the module given -// the hinstance, and then run the entry point if there is one. -//***************************************************************************** -HRESULT SystemDomain::RunDllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved) -{ - - CONTRACTL - { - NOTHROW; - if (GetThread() && !lpReserved) {MODE_PREEMPTIVE;} else {DISABLED(MODE_PREEMPTIVE);}; - if(GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}; - } - CONTRACTL_END; - - - Thread *pThread = NULL; - BOOL fEnterCoop = FALSE; - HRESULT hr = S_FALSE; // Assume no entry point. - - pThread = GetThread(); - if ((!pThread && (dwReason == DLL_PROCESS_DETACH || dwReason == DLL_THREAD_DETACH)) || - g_fEEShutDown) - return S_OK; - - // ExitProcess is called while a thread is doing GC. - if (dwReason == DLL_PROCESS_DETACH && GCHeapUtilities::IsGCInProgress()) - return S_OK; - - // ExitProcess is called on a thread that we don't know about - if (dwReason == DLL_PROCESS_DETACH && GetThread() == NULL) - return S_OK; - - // Need to setup the thread since this might be the first time the EE has - // seen it if the thread was created in unmanaged code and this is a thread - // attach event. - if (pThread) - fEnterCoop = pThread->PreemptiveGCDisabled(); - else { - pThread = SetupThreadNoThrow(&hr); - if (pThread == NULL) - return hr; - } - - return RunDllMainHelper(hInst, dwReason, lpReserved, pThread, !fEnterCoop); -} -#endif // FEATURE_MIXEDMODE #endif // CROSSGEN_COMPILE @@ -6791,64 +6677,6 @@ DomainAssembly * AppDomain::FindAssembly(PEAssembly * pFile, FindAssemblyOptions static const AssemblyIterationFlags STANDARD_IJW_ITERATOR_FLAGS = (AssemblyIterationFlags)(kIncludeLoaded | kIncludeLoading | kIncludeExecution | kExcludeCollectible); -#ifdef FEATURE_MIXEDMODE -Module * AppDomain::GetIJWModule(HMODULE hMod) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM();); - } - CONTRACTL_END; - - AssemblyIterator i = IterateAssembliesEx(STANDARD_IJW_ITERATOR_FLAGS); - CollectibleAssemblyHolder<DomainAssembly *> pDomainAssembly; - - while (i.Next(pDomainAssembly.This())) - { - _ASSERTE(!pDomainAssembly->IsCollectible()); - DomainFile * result = pDomainAssembly->FindIJWModule(hMod); - - if (result == NULL) - continue; - result->EnsureAllocated(); - return result->GetLoadedModule(); - } - - return NULL; -} - -DomainFile * AppDomain::FindIJWDomainFile(HMODULE hMod, const SString & path) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM();); - } - CONTRACTL_END; - - AssemblyIterator i = IterateAssembliesEx(STANDARD_IJW_ITERATOR_FLAGS); - CollectibleAssemblyHolder<DomainAssembly *> pDomainAssembly; - - while (i.Next(pDomainAssembly.This())) - { - _ASSERTE(!pDomainAssembly->IsCollectible()); - if (pDomainAssembly->GetCurrentAssembly() == NULL) - continue; - - DomainFile * result = pDomainAssembly->GetCurrentAssembly()->FindIJWDomainFile(hMod, path); - - if (result != NULL) - return result; - } - - return NULL; -} -#endif // FEATURE_MIXEDMODE void AppDomain::SetFriendlyName(LPCWSTR pwzFriendlyName, BOOL fDebuggerCares/*=TRUE*/) { diff --git a/src/vm/appdomain.hpp b/src/vm/appdomain.hpp index 9bf43b8ffe..9ecb820ae0 100644 --- a/src/vm/appdomain.hpp +++ b/src/vm/appdomain.hpp @@ -2334,12 +2334,6 @@ public: DomainAssembly * FindAssembly(PEAssembly * pFile, FindAssemblyOptions options = FindAssemblyOptions_None) DAC_EMPTY_RET(NULL); -#ifdef FEATURE_MIXEDMODE - // Finds only loaded modules, elevates level if needed - Module* GetIJWModule(HMODULE hMod) DAC_EMPTY_RET(NULL); - // Finds loading modules - DomainFile* FindIJWDomainFile(HMODULE hMod, const SString &path) DAC_EMPTY_RET(NULL); -#endif // FEATURE_MIXEDMODE Assembly *LoadAssembly(AssemblySpec* pIdentity, PEAssembly *pFile, @@ -4281,9 +4275,6 @@ public: #endif static BOOL SetGlobalSharePolicyUsingAttribute(IMDInternalImport* pScope, mdMethodDef mdMethod); -#ifdef FEATURE_MIXEDMODE - static HRESULT RunDllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved); -#endif // FEATURE_MIXEDMODE //**************************************************************************************** // diff --git a/src/vm/arm/asmhelpers.asm b/src/vm/arm/asmhelpers.asm index 796c1d14c5..002477d1a4 100644 --- a/src/vm/arm/asmhelpers.asm +++ b/src/vm/arm/asmhelpers.asm @@ -64,11 +64,6 @@ IMPORT GetCurrentSavedRedirectContext -#ifdef FEATURE_MIXEDMODE - SETALIAS IJWNOADThunk__FindThunkTarget, ?FindThunkTarget@IJWNOADThunk@@QAAPBXXZ - IMPORT $IJWNOADThunk__FindThunkTarget -#endif - ;; Imports to support virtual import fixup for ngen images IMPORT VirtualMethodFixupWorker ;; Import to support cross-moodule external method invocation in ngen images @@ -562,41 +557,6 @@ UM2MThunk_WrapperHelper_ArgumentsSetup NESTED_END -; ------------------------------------------------------------------ -; -; IJWNOADThunk::MakeCall -; -; On entry: -; r12 : IJWNOADThunk * -; -; On exit: -; Tail calls to real managed target -; - -#ifdef FEATURE_MIXEDMODE - NESTED_ENTRY IJWNOADThunk__MakeCall - - ; Can't pass C++ mangled names to NESTED_ENTRY and my attempts to use EQU to define an alternate name - ; for a symbol didn't work. Just define a label for the decorated name of the method and export it - ; manually. -|?MakeCall@IJWNOADThunk@@KAXXZ| - EXPORT |?MakeCall@IJWNOADThunk@@KAXXZ| - - PROLOG_PUSH {r0-r4,lr} - PROLOG_VPUSH {d0-d7} - - CHECK_STACK_ALIGNMENT - - mov r0, r12 ; IJWNOADThunk * is this pointer for IJWNOADThunk::FindThunkTarget - bl $IJWNOADThunk__FindThunkTarget - mov r12, r0 ; Returns real jump target in r0, save this in r12 - - EPILOG_VPOP {d0-d7} - EPILOG_POP {r0-r4,lr} - EPILOG_BRANCH_REG r12 - - NESTED_END -#endif ; ------------------------------------------------------------------ diff --git a/src/vm/assembly.cpp b/src/vm/assembly.cpp index fc9ce7189c..3d05368317 100644 --- a/src/vm/assembly.cpp +++ b/src/vm/assembly.cpp @@ -1834,37 +1834,6 @@ Module* Assembly::FindModule(PEFile *pFile, BOOL includeLoading) } #endif // FEATURE_MULTIMODULE_ASSEMBLIES -#ifdef FEATURE_MIXEDMODE -DomainFile* Assembly::FindIJWDomainFile(HMODULE hMod, const SString &path) -{ - CONTRACT (DomainFile*) - { - INSTANCE_CHECK; - THROWS; - GC_TRIGGERS; - MODE_ANY; - PRECONDITION(CheckPointer(GetManifestModule())); - POSTCONDITION(CheckPointer(RETVAL, NULL_OK)); - } - CONTRACT_END; - - ModuleIterator i = IterateModules(); - while (i.Next()) - { - PEFile *pFile = i.GetModule()->GetFile(); - - if ( !pFile->IsResource() - && !pFile->IsDynamic() - && !pFile->IsILOnly()) - { - if ( (pFile->GetLoadedIL()!= NULL && pFile->GetIJWBase() == hMod) - || PEImage::PathEquals(pFile->GetPath(), path)) - RETURN i.GetModule()->GetDomainFile(); - } - } - RETURN NULL; -} -#endif // FEATURE_MIXEDMODE //***************************************************************************** // Set up the list of names of any friend assemblies diff --git a/src/vm/assembly.hpp b/src/vm/assembly.hpp index da82001b32..e3f647c461 100644 --- a/src/vm/assembly.hpp +++ b/src/vm/assembly.hpp @@ -244,10 +244,6 @@ public: Module* FindModule(PEFile *pFile, BOOL includeLoading = FALSE); #endif // FEATURE_MULTIMODULE_ASSEMBLIES -#ifdef FEATURE_MIXEDMODE - // Finds loading modules as well - DomainFile* FindIJWDomainFile(HMODULE hMod, const SString &path); -#endif //**************************************************************************************** // // Get the domain the assembly lives in. diff --git a/src/vm/assemblyspec.cpp b/src/vm/assemblyspec.cpp index 13b1992b4a..b60f95724b 100644 --- a/src/vm/assemblyspec.cpp +++ b/src/vm/assemblyspec.cpp @@ -252,46 +252,6 @@ HRESULT AssemblySpec::InitializeSpecInternal(mdToken kAssemblyToken, } // AssemblySpec::InitializeSpecInternal -#ifdef FEATURE_MIXEDMODE -void AssemblySpec::InitializeSpec(HMODULE hMod, - BOOL fIntrospectionOnly /*=FALSE*/) -{ - CONTRACTL - { - INSTANCE_CHECK; - GC_TRIGGERS; - THROWS; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM();); - } - CONTRACTL_END; - - // Normalize this boolean as it tends to be used for comparisons - m_fIntrospectionOnly = !!fIntrospectionOnly; - - PEDecoder pe(hMod); - - if (!pe.CheckILFormat()) - { - StackSString path; - PEImage::GetPathFromDll(hMod, path); - EEFileLoadException::Throw(path, COR_E_BADIMAGEFORMAT); - } - - COUNT_T size; - const void *data = pe.GetMetadata(&size); - SafeComHolder<IMDInternalImport> pImport; - IfFailThrow(GetMetaDataInternalInterface((void *) data, size, ofRead, - IID_IMDInternalImport, - (void **) &pImport)); - - mdAssembly a; - if (FAILED(pImport->GetAssemblyFromScope(&a))) - ThrowHR(COR_E_ASSEMBLYEXPECTED); - - InitializeSpec(a, pImport, NULL, fIntrospectionOnly); -} -#endif //FEATURE_MIXEDMODE void AssemblySpec::InitializeSpec(PEAssembly * pFile) { diff --git a/src/vm/assemblyspec.hpp b/src/vm/assemblyspec.hpp index 48a6b459e2..ae02f20ccf 100644 --- a/src/vm/assemblyspec.hpp +++ b/src/vm/assemblyspec.hpp @@ -122,9 +122,6 @@ class AssemblySpec : public BaseAssemblySpec void AssemblyNameInit(ASSEMBLYNAMEREF* pName, PEImage* pImageInfo); //[in,out], [in] -#ifdef FEATURE_MIXEDMODE - void InitializeSpec(HINSTANCE hMod, BOOL fIntrospectionOnly = FALSE); -#endif // FEATURE_MIXEDMODE void SetCodeBase(LPCWSTR szCodeBase) { diff --git a/src/vm/ceeload.cpp b/src/vm/ceeload.cpp index 9739952fab..fafb8efa3c 100644 --- a/src/vm/ceeload.cpp +++ b/src/vm/ceeload.cpp @@ -214,283 +214,6 @@ COUNT_T Module::GetInliners(PTR_Module inlineeOwnerMod, mdMethodDef inlineeTkn, #ifndef DACCESS_COMPILE -#ifdef FEATURE_MIXEDMODE - -#include <pshpack1.h> -struct MUThunk -{ - VASigCookie *m_pCookie; - PCCOR_SIGNATURE m_pSig; - LPVOID m_pTarget; -#ifdef _TARGET_X86_ - LPVOID GetCode() - { - LIMITED_METHOD_CONTRACT; - return &m_op1; - } - - BYTE m_op1; //0x58 POP eax ;;pop return address - - BYTE m_op2; //0x68 PUSH cookie - UINT32 m_opcookie;// - - BYTE m_op3; //0x50 PUSH eax ;;repush return address - - BYTE m_op4; //0xb8 MOV eax,target - UINT32 m_optarget;// - BYTE m_jmp; //0xe9 JMP PInvokeCalliStub - UINT32 m_jmptarg; -#else // !_TARGET_X86_ - LPVOID GetCode() - { - LIMITED_METHOD_CONTRACT; - PORTABILITY_ASSERT("MUThunk not implemented on this platform"); - return NULL; - } -#endif // !_TARGET_X86_ -}; -#include <poppack.h> - - -// -// A hashtable for u->m thunks not represented in the fixup tables. -// -class MUThunkHash : public CClosedHashBase { - private: - //---------------------------------------------------- - // Hash key for CClosedHashBase - //---------------------------------------------------- - struct UTHKey { - LPVOID m_pTarget; - PCCOR_SIGNATURE m_pSig; - DWORD m_cSig; - }; - - //---------------------------------------------------- - // Hash entry for CClosedHashBase - //---------------------------------------------------- - struct UTHEntry { - UTHKey m_key; - ELEMENTSTATUS m_status; - MUThunk *m_pMUThunk; - }; - - public: - MUThunkHash(Module *pModule) : - CClosedHashBase( -#ifdef _DEBUG - 3, -#else // !_DEBUG - 17, // CClosedHashTable will grow as necessary -#endif // !_DEBUG - - sizeof(UTHEntry), - FALSE - ), - m_crst(CrstMUThunkHash) - - { - WRAPPER_NO_CONTRACT; - m_pModule = pModule; - } - - ~MUThunkHash() - { - CONTRACT_VOID - { - NOTHROW; - DESTRUCTOR_CHECK; - GC_NOTRIGGER; - FORBID_FAULT; - MODE_ANY; - } - CONTRACT_END - - UTHEntry *phe = (UTHEntry*)GetFirst(); - while (phe) { - delete (BYTE*)phe->m_pMUThunk->m_pSig; - DeleteExecutable(phe->m_pMUThunk); - phe = (UTHEntry*)GetNext((BYTE*)phe); - } - - RETURN; - } - - -#ifdef FEATURE_MIXEDMODE - public: - LPVOID GetMUThunk(LPVOID pTarget, PCCOR_SIGNATURE pSig0, DWORD cSig) - { - STATIC_CONTRACT_THROWS; - - // A persistent copy of the sig - NewArrayHolder<COR_SIGNATURE> sigHolder = new COR_SIGNATURE[cSig]; - - memcpyNoGCRefs(sigHolder.GetValue(), pSig0, cSig); - sigHolder[0] = IMAGE_CEE_CS_CALLCONV_STDCALL; - - // Have to lookup cookie eagerly because once we've added a blank - // entry to the hashtable, it's not easy to tolerate failure. - VASigCookie *pCookie = m_pModule->GetVASigCookie(Signature(sigHolder, cSig)); - - if (pCookie == NULL) - { - return NULL; - } - sigHolder.SuppressRelease(); - return GetMUThunkHelper(pTarget, sigHolder, cSig, pCookie); - } -private: - LPVOID GetMUThunkHelper(LPVOID pTarget, PCCOR_SIGNATURE pSig, DWORD cSig, VASigCookie *pCookie) - { - CONTRACT (LPVOID) - { - INSTANCE_CHECK; - THROWS; - GC_TRIGGERS; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM()); - POSTCONDITION(CheckPointer(RETVAL, NULL_OK)); - } - CONTRACT_END - - UTHEntry *phe; - CrstHolder ch(&m_crst); - - UTHKey key; - key.m_pTarget = pTarget; - key.m_pSig = pSig; - key.m_cSig = cSig; - - bool bNew; - phe = (UTHEntry*)FindOrAdd((LPVOID)&key, /*modifies*/bNew); - - if (phe) - { - if (bNew) - { - phe->m_pMUThunk = new (executable) MUThunk; - phe->m_pMUThunk->m_pCookie = pCookie; - phe->m_pMUThunk->m_pSig = pSig; - phe->m_pMUThunk->m_pTarget = pTarget; -#ifdef _TARGET_X86_ - phe->m_pMUThunk->m_op1 = 0x58; //POP EAX - phe->m_pMUThunk->m_op2 = 0x68; //PUSH - phe->m_pMUThunk->m_opcookie = (UINT32)(size_t)pCookie; - phe->m_pMUThunk->m_op3 = 0x50; //POP EAX - phe->m_pMUThunk->m_op4 = 0xb8; //mov eax - phe->m_pMUThunk->m_optarget = (UINT32)(size_t)pTarget; - phe->m_pMUThunk->m_jmp = 0xe9; //jmp - phe->m_pMUThunk->m_jmptarg = (UINT32)(GetEEFuncEntryPoint(GenericPInvokeCalliHelper) - ((size_t)( 1 + &(phe->m_pMUThunk->m_jmptarg)))); -#else // !_TARGET_X86_ - PORTABILITY_ASSERT("MUThunkHash not implemented on this platform"); -#endif // !_TARGET_X86_ - - phe->m_key = key; - phe->m_status = USED; - } - else - { - delete[] (BYTE*)pSig; - } - } - else - { - delete[] (BYTE*)pSig; - } - - if (phe) - RETURN (LPVOID)(phe->m_pMUThunk->GetCode()); - else - RETURN NULL; - } -#endif // FEATURE_MIXEDMODE - -public: - - // *** OVERRIDES FOR CClosedHashBase ***/ - - //***************************************************************************** - // Hash is called with a pointer to an element in the table. You must override - // this method and provide a hash algorithm for your element type. - //***************************************************************************** - virtual unsigned int Hash( // The key value. - void const *pData) // Raw data to hash. - { - LIMITED_METHOD_CONTRACT; - - UTHKey *pKey = (UTHKey*)pData; - return (ULONG)(size_t)(pKey->m_pTarget); - } - - - //***************************************************************************** - // Compare is used in the typical memcmp way, 0 is eqaulity, -1/1 indicate - // direction of miscompare. In this system everything is always equal or not. - //***************************************************************************** - unsigned int Compare( // 0, -1, or 1. - void const *pData, // Raw key data on lookup. - BYTE *pElement) // The element to compare data against. - { - CONTRACTL - { - NOTHROW; - GC_TRIGGERS; - MODE_ANY; - } - CONTRACTL_END; - - UTHKey *pkey1 = (UTHKey*)pData; - UTHKey *pkey2 = &( ((UTHEntry*)pElement)->m_key ); - - if (pkey1->m_pTarget != pkey2->m_pTarget) - return 1; - - if (S_OK != MetaSig::CompareMethodSigsNT(pkey1->m_pSig, pkey1->m_cSig, m_pModule, NULL, pkey2->m_pSig, pkey2->m_cSig, m_pModule, NULL)) - return 1; - - return 0; - } - - //***************************************************************************** - // Return true if the element is free to be used. - //***************************************************************************** - virtual ELEMENTSTATUS Status( // The status of the entry. - BYTE *pElement) // The element to check. - { - LIMITED_METHOD_CONTRACT; - - return ((UTHEntry*)pElement)->m_status; - } - - //***************************************************************************** - // Sets the status of the given element. - //***************************************************************************** - virtual void SetStatus( - BYTE *pElement, // The element to set status for. - ELEMENTSTATUS eStatus) // New status. - { - LIMITED_METHOD_CONTRACT; - - ((UTHEntry*)pElement)->m_status = eStatus; - } - - //***************************************************************************** - // Returns the internal key value for an element. - //***************************************************************************** - virtual void *GetKey( // The data to hash on. - BYTE *pElement) // The element to return data ptr for. - { - LIMITED_METHOD_CONTRACT; - return (BYTE*) &(((UTHEntry*)pElement)->m_key); - } - - - - Module *m_pModule; - Crst m_crst; -}; -#endif // FEATURE_MIXEDMODE // =========================================================================== @@ -1634,10 +1357,6 @@ void Module::Destruct() delete m_pILStubCache; } -#ifdef FEATURE_MIXEDMODE // IJW - delete m_pMUThunkHash; - delete m_pThunkHeap; -#endif // FEATURE_MIXEDMODE // IJW #ifdef PROFILING_SUPPORTED @@ -7328,619 +7047,6 @@ void Module::NotifyDebuggerUnload(AppDomain *pDomain) g_pDebugInterface->UnloadModule(this, pDomain); } -#if defined(FEATURE_MIXEDMODE) && !defined(CROSSGEN_COMPILE) - -//====================================================================================== -// These are used to call back to the shim to get the information about -// thunks, and to set the new targets. -typedef mdToken STDMETHODCALLTYPE GetTokenForVTableEntry_t(HINSTANCE hInst, BYTE **ppVTEntry); -typedef void STDMETHODCALLTYPE SetTargetForVTableEntry_t(HINSTANCE hInst, BYTE **ppVTEntry, BYTE *pTarget); -typedef BYTE * STDMETHODCALLTYPE GetTargetForVTableEntry_t(HINSTANCE hInst, BYTE **ppVTEntry); - -GetTokenForVTableEntry_t *g_pGetTokenForVTableEntry = NULL; -SetTargetForVTableEntry_t *g_pSetTargetForVTableEntry = NULL; -GetTargetForVTableEntry_t *g_pGetTargetForVTableEntry = NULL; - -//====================================================================================== -void InitThunkCallbackFunctions(HINSTANCE hInstShim) -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - } CONTRACTL_END; - - typedef enum { - e_UNINITIALIZED, - e_INITIALIZED_SUCCESS, - } InitState_t; - - static InitState_t s_state = e_UNINITIALIZED; - if (s_state == e_UNINITIALIZED) { - g_pGetTokenForVTableEntry = (GetTokenForVTableEntry_t *)GetProcAddress(hInstShim, "GetTokenForVTableEntry"); - if (g_pGetTokenForVTableEntry == NULL) { - COMPlusThrow(kMissingMethodException, IDS_EE_MSCOREE_MISSING_ENTRYPOINT, W("GetTokenForVTableEntry")); - } - g_pSetTargetForVTableEntry = (SetTargetForVTableEntry_t *)GetProcAddress(hInstShim, "SetTargetForVTableEntry"); - if (g_pSetTargetForVTableEntry == NULL) { - COMPlusThrow(kMissingMethodException, IDS_EE_MSCOREE_MISSING_ENTRYPOINT, W("SetTargetForVTableEntry")); - } - g_pGetTargetForVTableEntry = (GetTargetForVTableEntry_t *)GetProcAddress(hInstShim, "GetTargetForVTableEntry"); - if (g_pGetTargetForVTableEntry == NULL) { - COMPlusThrow(kMissingMethodException, IDS_EE_MSCOREE_MISSING_ENTRYPOINT, W("GetTargetForVTableEntry")); - } - s_state = e_INITIALIZED_SUCCESS; - } - CONSISTENCY_CHECK(s_state != e_UNINITIALIZED); -} - -//====================================================================================== -void InitShimHINSTANCE() -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - } CONTRACTL_END; - - if (g_hInstShim == NULL) { - g_hInstShim = WszLoadLibrary(MSCOREE_SHIM_W); - if (g_hInstShim == NULL) { - InlineSString<80> ssErrorFormat; - if(!ssErrorFormat.LoadResource(CCompRC::Optional, IDS_EE_MSCOREE_MISSING)) - { - // Keep this in sync with the actual message - ssErrorFormat.Set(W("MSCOREE is not loaded.")); - } - EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE(COR_E_EXECUTIONENGINE, ssErrorFormat.GetUnicode()); - } - } -} - -//====================================================================================== -HINSTANCE GetShimHINSTANCE() // dead code? -{ - WRAPPER_NO_CONTRACT; - InitShimHINSTANCE(); - return g_hInstShim; -} - -//====================================================================================== -// Fixup vtables stored in the header to contain pointers to method desc -// prestubs rather than metadata method tokens. -void Module::FixupVTables() -{ - CONTRACTL { - INSTANCE_CHECK; - STANDARD_VM_CHECK; - } CONTRACTL_END; - - - // If we've already fixed up, or this is not an IJW module, just return. - // NOTE: This relies on ILOnly files not having fixups. If this changes, - // we need to change this conditional. - if (IsIJWFixedUp() || m_file->IsILOnly() || IsIntrospectionOnly()) { - return; - } - - // An EEException will be thrown if either MSCOREE or any of the required - // entrypoints cannot be found. - InitShimHINSTANCE(); - InitThunkCallbackFunctions(g_hInstShim); - - HINSTANCE hInstThis = GetFile()->GetIJWBase(); - - // <REVISIT_TODO>@todo: workaround!</REVISIT_TODO> - // If we are compiling in-process, we don't want to fixup the vtables - as it - // will have side effects on the other copy of the module! - if (SystemDomain::GetCurrentDomain()->IsPassiveDomain()) { - return; - } - -#ifdef FEATURE_PREJIT - // We delayed filling in this value until the LoadLibrary occurred - if (HasTls() && HasNativeImage()) { - CORCOMPILE_EE_INFO_TABLE *pEEInfo = GetNativeImage()->GetNativeEEInfoTable(); - pEEInfo->rvaStaticTlsIndex = GetTlsIndex(); - } -#endif - // Get vtable fixup data - COUNT_T cFixupRecords; - IMAGE_COR_VTABLEFIXUP *pFixupTable = m_file->GetVTableFixups(&cFixupRecords); - - // No records then return - if (cFixupRecords == 0) { - return; - } - - // Now, we need to take a lock to serialize fixup. - PEImage::IJWFixupData *pData = PEImage::GetIJWData(m_file->GetIJWBase()); - - // If it's already been fixed (in some other appdomain), record the fact and return - if (pData->IsFixedUp()) { - SetIsIJWFixedUp(); - return; - } - - ////////////////////////////////////////////////////// - // - // This is done in three stages: - // 1. We enumerate the types we'll need to load - // 2. We load the types - // 3. We create and install the thunks - // - - COUNT_T cVtableThunks = 0; - struct MethodLoadData - { - mdToken token; - MethodDesc *pMD; - }; - MethodLoadData *rgMethodsToLoad = NULL; - COUNT_T cMethodsToLoad = 0; - - // - // Stage 1 - // - - // Each fixup entry describes a vtable, so iterate the vtables and sum their counts - { - DWORD iFixup; - for (iFixup = 0; iFixup < cFixupRecords; iFixup++) - cVtableThunks += pFixupTable[iFixup].Count; - } - - Thread *pThread = GetThread(); - StackingAllocator *pAlloc = &pThread->m_MarshalAlloc; - CheckPointHolder cph(pAlloc->GetCheckpoint()); - - // Allocate the working array of tokens. - cMethodsToLoad = cVtableThunks; - - rgMethodsToLoad = new (pAlloc) MethodLoadData[cMethodsToLoad]; - memset(rgMethodsToLoad, 0, cMethodsToLoad*sizeof(MethodLoadData)); - - // Now take the IJW module lock and get all the tokens - { - // Take the lock - CrstHolder lockHolder(pData->GetLock()); - - // If someone has beaten us, just return - if (pData->IsFixedUp()) - { - SetIsIJWFixedUp(); - return; - } - - COUNT_T iCurMethod = 0; - - if (cFixupRecords != 0) - { - for (COUNT_T iFixup = 0; iFixup < cFixupRecords; iFixup++) - { - // Vtables can be 32 or 64 bit. - if ((pFixupTable[iFixup].Type == (COR_VTABLE_PTRSIZED)) || - (pFixupTable[iFixup].Type == (COR_VTABLE_PTRSIZED|COR_VTABLE_FROM_UNMANAGED)) || - (pFixupTable[iFixup].Type == (COR_VTABLE_PTRSIZED|COR_VTABLE_FROM_UNMANAGED_RETAIN_APPDOMAIN))) - { - const BYTE** pPointers = (const BYTE **) m_file->GetVTable(pFixupTable[iFixup].RVA); - for (int iMethod = 0; iMethod < pFixupTable[iFixup].Count; iMethod++) - { - if (pData->IsMethodFixedUp(iFixup,iMethod)) - continue; - mdToken mdTok = (*g_pGetTokenForVTableEntry)(hInstThis, (BYTE **)(pPointers + iMethod)); - CONSISTENCY_CHECK(mdTok != mdTokenNil); - rgMethodsToLoad[iCurMethod++].token = mdTok; - } - } - } - } - - } - - // - // Stage 2 - Load the types - // - - { - for (COUNT_T iCurMethod = 0; iCurMethod < cMethodsToLoad; iCurMethod++) - { - mdToken curTok = rgMethodsToLoad[iCurMethod].token; - if(!GetMDImport()->IsValidToken(curTok)) - { - _ASSERTE(!"Invalid token in v-table fix-up table"); - ThrowHR(COR_E_BADIMAGEFORMAT); - } - - - // Find the method desc - MethodDesc *pMD; - - { - CONTRACT_VIOLATION(LoadsTypeViolation); - pMD = FindMethodThrowing(curTok); - } - - CONSISTENCY_CHECK(CheckPointer(pMD)); - - rgMethodsToLoad[iCurMethod].pMD = pMD; - } - } - - // - // Stage 3 - Create the thunk data - // - { - // Take the lock - CrstHolder lockHolder(pData->GetLock()); - - // If someone has beaten us, just return - if (pData->IsFixedUp()) - { - SetIsIJWFixedUp(); - return; - } - - // This is the app domain which all of our U->M thunks for this module will have - // affinity with. Note that if the module is shared between multiple domains, all thunks will marshal back - // to the original domain, so some of the thunks may cause a surprising domain switch to occur. - // (And furthermore note that if the original domain is unloaded, all the thunks will simply throw an - // exception.) - // - // (The essential problem is that these thunks are shared via the global process address space - // rather than per domain, thus there is no context to figure out our domain from. We could - // use the current thread's domain, but that is effectively undefined in unmanaged space.) - // - // The bottom line is that the IJW model just doesn't fit with multiple app domain design very well, so - // better to have well defined limitations than flaky behavior. - // - // - - AppDomain *pAppDomain = GetAppDomain(); - - // Used to index into rgMethodsToLoad - COUNT_T iCurMethod = 0; - - - // Each fixup entry describes a vtable (each slot contains a metadata token - // at this stage). - DWORD iFixup; - for (iFixup = 0; iFixup < cFixupRecords; iFixup++) - cVtableThunks += pFixupTable[iFixup].Count; - - DWORD dwIndex=0; - DWORD dwThunkIndex = 0; - - // Now to fill in the thunk table. - for (iFixup = 0; iFixup < cFixupRecords; iFixup++) - { - const BYTE** pPointers = (const BYTE **) - m_file->GetVTable(pFixupTable[iFixup].RVA); - - // Vtables can be 32 or 64 bit. - if (pFixupTable[iFixup].Type == COR_VTABLE_PTRSIZED) - { - for (int iMethod = 0; iMethod < pFixupTable[iFixup].Count; iMethod++) - { - if (pData->IsMethodFixedUp(iFixup,iMethod)) - continue; - - mdToken mdTok = rgMethodsToLoad[iCurMethod].token; - MethodDesc *pMD = rgMethodsToLoad[iCurMethod].pMD; - iCurMethod++; - -#ifdef _DEBUG - if (pMD->IsNDirect()) - { - LOG((LF_IJW, LL_INFO10, "[0x%lx] <-- PINV thunk for \"%s\" (target = 0x%lx)\n", - (size_t)&(pPointers[iMethod]), pMD->m_pszDebugMethodName, - (size_t) (((NDirectMethodDesc*)pMD)->GetNDirectTarget()))); - } -#endif // _DEBUG - - CONSISTENCY_CHECK(dwThunkIndex < cVtableThunks); - - // Point the local vtable slot to the thunk we created - (*g_pSetTargetForVTableEntry)(hInstThis, (BYTE **)&pPointers[iMethod], (BYTE *)pMD->GetMultiCallableAddrOfCode()); - - pData->MarkMethodFixedUp(iFixup,iMethod); - - dwThunkIndex++; - } - - } - else if (pFixupTable[iFixup].Type == (COR_VTABLE_PTRSIZED|COR_VTABLE_FROM_UNMANAGED)) - { - - for (int iMethod = 0; iMethod < pFixupTable[iFixup].Count; iMethod++) - { - if (pData->IsMethodFixedUp(iFixup,iMethod)) - continue; - - mdToken mdTok = rgMethodsToLoad[iCurMethod].token; - MethodDesc *pMD = rgMethodsToLoad[iCurMethod].pMD; - iCurMethod++; - LOG((LF_IJW, LL_INFO10, "[0x%p] <-- VTable thunk for \"%s\" (pMD = 0x%p)\n", - (UINT_PTR)&(pPointers[iMethod]), pMD->m_pszDebugMethodName, pMD)); - - UMEntryThunk *pUMEntryThunk = (UMEntryThunk*)(void*)(GetDllThunkHeap()->AllocAlignedMem(sizeof(UMEntryThunk), CODE_SIZE_ALIGN)); // UMEntryThunk contains code - FillMemory(pUMEntryThunk, sizeof(*pUMEntryThunk), 0); - - UMThunkMarshInfo *pUMThunkMarshInfo = (UMThunkMarshInfo*)(void*)(GetThunkHeap()->AllocAlignedMem(sizeof(UMThunkMarshInfo), CODE_SIZE_ALIGN)); - FillMemory(pUMThunkMarshInfo, sizeof(*pUMThunkMarshInfo), 0); - - pUMThunkMarshInfo->LoadTimeInit(pMD); - pUMEntryThunk->LoadTimeInit(NULL, NULL, pUMThunkMarshInfo, pMD, pAppDomain->GetId()); - (*g_pSetTargetForVTableEntry)(hInstThis, (BYTE **)&pPointers[iMethod], (BYTE *)pUMEntryThunk->GetCode()); - - pData->MarkMethodFixedUp(iFixup,iMethod); - } - } - else if (pFixupTable[iFixup].Type == (COR_VTABLE_PTRSIZED|COR_VTABLE_FROM_UNMANAGED_RETAIN_APPDOMAIN)) - { - - for (int iMethod = 0; iMethod < pFixupTable[iFixup].Count; iMethod++) - { - if (pData->IsMethodFixedUp(iFixup,iMethod)) - continue; - - mdToken mdTok = rgMethodsToLoad[iCurMethod].token; - iCurMethod++; - - IJWNOADThunk* pThunkLocal = new(GetDllThunkHeap()->AllocAlignedMem(sizeof(IJWNOADThunk), CODE_SIZE_ALIGN)) IJWNOADThunk(GetFile()->GetIJWBase(),dwIndex++,mdTok); - (*g_pSetTargetForVTableEntry)(hInstThis, (BYTE **)&pPointers[iMethod], (BYTE *)pThunkLocal->GetCode()); - - pData->MarkMethodFixedUp(iFixup,iMethod); - } - } - else if ((pFixupTable[iFixup].Type & COR_VTABLE_NOT_PTRSIZED) == COR_VTABLE_NOT_PTRSIZED) - { - // fixup type doesn't match the platform - THROW_BAD_FORMAT(BFA_FIXUP_WRONG_PLATFORM, this); - } - else - { - _ASSERTE(!"Unknown vtable fixup type"); - } - } - - - if(!GetAssembly()->IsDomainNeutral()) - CreateDomainThunks(); - - SetDomainIdOfIJWFixups(pAppDomain->GetId()); -#ifdef FEATURE_PREJIT - if (HasNativeImage()) { - CORCOMPILE_EE_INFO_TABLE *pEEInfo = GetNativeImage()->GetNativeEEInfoTable(); - - if (pEEInfo->nativeEntryPointStart != 0) { - PTR_PEImageLayout pIJWLayout = m_file->GetLoadedIL(); - SIZE_T base = (SIZE_T)pIJWLayout->GetBase(); - - _ASSERTE(pIJWLayout->CheckRva((RVA)pEEInfo->nativeEntryPointStart)); - _ASSERTE(pIJWLayout->CheckRva((RVA)pEEInfo->nativeEntryPointEnd)); - - pEEInfo->nativeEntryPointStart += base; - pEEInfo->nativeEntryPointEnd += base; - } - else { - _ASSERTE(pEEInfo->nativeEntryPointEnd == 0); - } - } -#endif - // Indicate that this module has been fixed before releasing the lock - pData->SetIsFixedUp(); // On the data - SetIsIJWFixedUp(); // On the module - } // End of Stage 3 -} - -// Self-initializing accessor for m_pThunkHeap -LoaderHeap *Module::GetDllThunkHeap() -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - } - CONTRACTL_END; - return PEImage::GetDllThunkHeap(GetFile()->GetIJWBase()); - -} -LoaderHeap *Module::GetThunkHeap() -{ - CONTRACT (LoaderHeap *) - { - INSTANCE_CHECK; - THROWS; - GC_NOTRIGGER; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM()); - POSTCONDITION(CheckPointer(RETVAL)); - } - CONTRACT_END - - if (!m_pThunkHeap) - { - size_t * pPrivatePCLBytes = NULL; - size_t * pGlobalPCLBytes = NULL; - -#ifdef PROFILING_SUPPORTED - pPrivatePCLBytes = &(GetPerfCounters().m_Loading.cbLoaderHeapSize); -#endif - - LoaderHeap *pNewHeap = new LoaderHeap(VIRTUAL_ALLOC_RESERVE_GRANULARITY, // DWORD dwReserveBlockSize - 0, // DWORD dwCommitBlockSize - pPrivatePCLBytes, - ThunkHeapStubManager::g_pManager->GetRangeList(), - TRUE); // BOOL fMakeExecutable - - if (FastInterlockCompareExchangePointer(&m_pThunkHeap, pNewHeap, 0) != 0) - { - delete pNewHeap; - } - } - - RETURN m_pThunkHeap; -} - -void Module::SetADThunkTable(UMEntryThunk* pTable) -{ - CONTRACTL - { - INSTANCE_CHECK; - THROWS; - GC_TRIGGERS; - MODE_ANY; - } - CONTRACTL_END; - - GetDomainLocalModule()->SetADThunkTable(pTable); -} - -UMEntryThunk* Module::GetADThunkTable() -{ - CONTRACT(UMEntryThunk*) - { - INSTANCE_CHECK; - THROWS; - GC_TRIGGERS; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM()); - POSTCONDITION(CheckPointer(RETVAL)); - } - CONTRACT_END - - DomainLocalModule* pMod=GetDomainLocalModule(); - _ASSERTE(pMod); - UMEntryThunk * pADThunkTable = pMod->GetADThunkTable(); - if (pADThunkTable == NULL) - { - CreateDomainThunks(); - pADThunkTable = pMod->GetADThunkTable(); - _ASSERTE(pADThunkTable != NULL); - } - - RETURN (UMEntryThunk*)pADThunkTable; -}; - -void Module::CreateDomainThunks() -{ - CONTRACTL - { - INSTANCE_CHECK; - THROWS; - GC_TRIGGERS; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM()); - } - CONTRACTL_END; - - AppDomain *pAppDomain = GetAppDomain(); - if(!pAppDomain) - { - _ASSERTE(!"No appdomain"); - return; - } - - UINT32 cFixupRecords; - IMAGE_COR_VTABLEFIXUP *pFixupTable = m_file->GetVTableFixups(&cFixupRecords); - - DWORD iFixup; - DWORD cVtableThunks=0; - for (iFixup = 0; iFixup < cFixupRecords; iFixup++) - { - if (pFixupTable[iFixup].Type==(COR_VTABLE_FROM_UNMANAGED_RETAIN_APPDOMAIN|COR_VTABLE_PTRSIZED)) - { - cVtableThunks += pFixupTable[iFixup].Count; - } - } - - if (cVtableThunks==0) - { - return; - } - - AllocMemTracker amTracker; - AllocMemTracker *pamTracker = &amTracker; - - UMEntryThunk* pTable=((UMEntryThunk*)pamTracker->Track(pAppDomain->GetStubHeap()->AllocAlignedMem(sizeof(UMEntryThunk)*cVtableThunks, CODE_SIZE_ALIGN))); - DWORD dwCurrIndex=0; - for (iFixup = 0; iFixup < cFixupRecords; iFixup++) - { - if (pFixupTable[iFixup].Type == (COR_VTABLE_FROM_UNMANAGED_RETAIN_APPDOMAIN|COR_VTABLE_PTRSIZED)) - { - const BYTE **pPointers = (const BYTE **) m_file->GetVTable(pFixupTable[iFixup].RVA); - for (int iMethod = 0; iMethod < pFixupTable[iFixup].Count; iMethod++) - { - PCODE pCode = (PCODE) - (*g_pGetTargetForVTableEntry)((HINSTANCE)GetFile()->GetIJWBase(), (BYTE **)&pPointers[iMethod]); - IJWNOADThunk* pThnk = IJWNOADThunk::FromCode(pCode); - mdToken tok=pThnk->GetToken(); //!! - if(!GetMDImport()->IsValidToken(tok)) - { - ThrowHR(COR_E_BADIMAGEFORMAT, BFA_INVALID_TOKEN); - return; - } - - MethodDesc *pMD = FindMethodThrowing(tok); - - // @TODO: Check for out of memory - UMThunkMarshInfo *pUMThunkMarshInfo = (UMThunkMarshInfo*)pamTracker->Track(pAppDomain->GetStubHeap()->AllocAlignedMem(sizeof(UMThunkMarshInfo), CODE_SIZE_ALIGN)); - _ASSERTE(pUMThunkMarshInfo != NULL); - - pUMThunkMarshInfo->LoadTimeInit(pMD); - pTable[dwCurrIndex].LoadTimeInit(NULL, NULL, pUMThunkMarshInfo, pMD, pAppDomain->GetId()); - - // If we're setting up a domain that is cached, update the code pointer in the cache - if (pThnk->IsCachedAppDomainID(pAppDomain->GetId())) - pThnk->SetCachedInfo(pAppDomain->GetId(), (LPVOID)GetEEFuncEntryPoint((LPVOID)pTable[dwCurrIndex].GetCode())); - - dwCurrIndex++; - } - } - } - - pamTracker->SuppressRelease(); - SetADThunkTable(pTable); -} - -LPVOID Module::GetUMThunk(LPVOID pManagedIp, PCCOR_SIGNATURE pSig, ULONG cSig) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - CAN_TAKE_LOCK; - } - CONTRACTL_END; - - return GetDomainFile()->GetUMThunk(pManagedIp, pSig, cSig); -} - - -void *Module::GetMUThunk(LPVOID pUnmanagedIp, PCCOR_SIGNATURE pSig, ULONG cSig) -{ - CONTRACT (void*) - { - INSTANCE_CHECK; - THROWS; - GC_TRIGGERS; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM()); - POSTCONDITION(CheckPointer(RETVAL, NULL_OK)); - } - CONTRACT_END - - if (m_pMUThunkHash == NULL) - { - MUThunkHash *pMUThunkHash = new MUThunkHash(this); - if (FastInterlockCompareExchangePointer(&m_pMUThunkHash, pMUThunkHash, NULL) != NULL) - delete pMUThunkHash; - } - RETURN m_pMUThunkHash->GetMUThunk(pUnmanagedIp, pSig, cSig); -} - -#endif //FEATURE_MIXEDMODE && !CROSSGEN_COMPILE #ifdef FEATURE_NATIVE_IMAGE_GENERATION @@ -13727,13 +12833,6 @@ void Module::DeleteProfilingData() } #endif //FEATURE_PREJIT -#ifdef FEATURE_MIXEDMODE -void Module::SetIsIJWFixedUp() -{ - LIMITED_METHOD_CONTRACT; - FastInterlockOr(&m_dwTransientFlags, IS_IJW_FIXED_UP); -} -#endif #ifdef FEATURE_PREJIT @@ -15165,12 +14264,6 @@ void Module::EnumMemoryRegions(CLRDataEnumMemoryFlags flags, m_pStubMethodHashTable->EnumMemoryRegions(flags); } #endif // FEATURE_PREJIT -#ifdef FEATURE_MIXEDMODE - if (m_pThunkHeap.IsValid()) - { - m_pThunkHeap->EnumMemoryRegions(flags); - } -#endif // FEATURE_MIXEDMODE if (m_pBinder.IsValid()) { m_pBinder->EnumMemoryRegions(flags); diff --git a/src/vm/ceeload.h b/src/vm/ceeload.h index de92900b2e..ba95b2da62 100644 --- a/src/vm/ceeload.h +++ b/src/vm/ceeload.h @@ -1779,40 +1779,6 @@ private: NgenStats *m_pNgenStats; #endif // FEATURE_PREJIT -#ifdef FEATURE_MIXEDMODE - // LoaderHeap for storing thunks - PTR_LoaderHeap m_pThunkHeap; - - // Self-initializing accessor for thunk heap - LoaderHeap *GetThunkHeap(); - // Self-initializing accessor for domain-independent thunk heap - LoaderHeap *GetDllThunkHeap(); - - -public: - UMEntryThunk* GetADThunkTable(); - void SetADThunkTable(UMEntryThunk* pTable); - -protected: - // Domain that the IJW fixups were applied in - ADID m_DomainIdOfIJWFixups; - -public: - ADID GetDomainIdOfIJWFixups() - { - LIMITED_METHOD_CONTRACT; - _ASSERT(m_DomainIdOfIJWFixups != ADID()); - return m_DomainIdOfIJWFixups; - } - - void SetDomainIdOfIJWFixups(ADID id) - { - LIMITED_METHOD_CONTRACT; - _ASSERT(id != ADID()); - m_DomainIdOfIJWFixups = id; - } - -#endif // FEATURE_MIXEDMODE protected: @@ -1862,9 +1828,6 @@ protected: void ApplyMetaData(); -#ifdef FEATURE_MIXEDMODE - void FixupVTables(); -#endif void FreeClassTables(); @@ -2698,10 +2661,6 @@ public: BOOL CanExecuteCode(); -#ifdef FEATURE_MIXEDMODE - LPVOID GetUMThunk(LPVOID pManagedIp, PCCOR_SIGNATURE pSig, ULONG cSig); - LPVOID GetMUThunk(LPVOID pUnmanagedIp, PCCOR_SIGNATURE pSig, ULONG cSig); -#endif // FEATURE_MIXEDMODE // This data is only valid for NGEN'd modules, and for modules we're creating at NGEN time. ModuleCtorInfo* GetZapModuleCtorInfo() @@ -2713,9 +2672,6 @@ public: private: -#ifdef FEATURE_MIXEDMODE - class MUThunkHash *m_pMUThunkHash; -#endif // FEATURE_MIXEDMODE public: #ifndef DACCESS_COMPILE diff --git a/src/vm/ceemain.cpp b/src/vm/ceemain.cpp index 365daf5e34..cbe3659248 100644 --- a/src/vm/ceemain.cpp +++ b/src/vm/ceemain.cpp @@ -270,11 +270,6 @@ static HRESULT GetThreadUICultureNames(__inout StringArrayList* pCultureNames); HRESULT EEStartup(COINITIEE fFlags); -#ifdef FEATURE_MIXEDMODE -HRESULT PrepareExecuteDLLForThunk(HINSTANCE hInst, - DWORD dwReason, - LPVOID lpReserved); -#endif // FEATURE_MIXEDMODE BOOL STDMETHODCALLTYPE ExecuteEXE(HMODULE hMod); BOOL STDMETHODCALLTYPE ExecuteEXE(__in LPWSTR pImageNameIn); @@ -2414,375 +2409,9 @@ void STDMETHODCALLTYPE CoUninitializeEE(BOOL fIsDllUnloading) } -#ifdef FEATURE_MIXEDMODE -//***************************************************************************** -void STDMETHODCALLTYPE CorDllMainForThunk(HINSTANCE hInst, HINSTANCE hInstShim) -{ - - STATIC_CONTRACT_THROWS; - STATIC_CONTRACT_GC_TRIGGERS; - - - g_fEEIJWStartup = TRUE; - - { - - // If no managed thread exists, then we need to call the prepare method - // to try and startup the runtime and/or create a managed thread object - // so that installing an unwind and continue handler below is possible. - // If we fail to startup or create a thread, we'll raise the basic - // EXCEPTION_COMPLUS exception. - if (GetThread() == NULL) - { - HRESULT hr; - // Since this method is only called if a bootstrap thunk is invoked, we - // know that passing TRUE for fFromThunk is the correct value. - if (FAILED(hr = PrepareExecuteDLLForThunk(hInst, 0, NULL))) - { - RaiseComPlusException(); - } - } - - } - - INSTALL_UNWIND_AND_CONTINUE_HANDLER; - - // We're actually going to run some managed code and we're inside the loader lock. - // There may be a customer debug probe enabled that prevents this. - CanRunManagedCode(hInst); - - // Since this method is only called if a bootstrap thunk is invoked, we - // know that passing TRUE for fFromThunk is the correct value. - ExecuteDLL(hInst, 0, NULL, TRUE); - - UNINSTALL_UNWIND_AND_CONTINUE_HANDLER; - -} -#endif // FEATURE_MIXEDMODE - - - -#ifdef FEATURE_MIXEDMODE - -LONG RunDllMainFilter(EXCEPTION_POINTERS* ep, LPVOID pv) -{ - CONTRACTL - { - NOTHROW; - GC_TRIGGERS; - MODE_ANY; - } - CONTRACTL_END; - - BOOL useLastThrownObject = UpdateCurrentThrowable(ep->ExceptionRecord); - DefaultCatchHandler(ep, NULL, useLastThrownObject, FALSE); - - DefaultCatchFilterParam param(COMPLUS_EXCEPTION_EXECUTE_HANDLER); - return DefaultCatchFilter(ep, ¶m); -} - -// <TODO>@Todo: For M10, this only runs unmanaged native classic entry points for -// the IJW mc++ case.</TODO> -HRESULT RunDllMain(MethodDesc *pMD, HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved) -{ - STATIC_CONTRACT_NOTHROW; - - _ASSERTE(!GetAppDomain()->IsPassiveDomain()); - - if (!pMD) { - _ASSERTE(!"Must have a valid function to call!"); - return E_INVALIDARG; - } - - if (pMD->IsIntrospectionOnly()) - return S_OK; - - struct Param - { - MethodDesc *pMD; - HINSTANCE hInst; - DWORD dwReason; - LPVOID lpReserved; - HRESULT hr; - }; Param param; - param.pMD = pMD; - param.hInst = hInst; - param.dwReason = dwReason; - param.lpReserved = lpReserved; - param.hr = S_OK; - - PAL_TRY(Param *, pParamOuter, ¶m) - { - EX_TRY_NOCATCH(Param *, pParam, pParamOuter) - { - HRESULT hr; - - // This call is inherently unverifiable entry point. - if (!Security::CanSkipVerification(pParam->pMD)) { - hr = SECURITY_E_UNVERIFIABLE; - goto Done; - } - - { - SigPointer sig(pParam->pMD->GetSigPointer()); - - ULONG data = 0; - CorElementType eType = ELEMENT_TYPE_END; - CorElementType eType2 = ELEMENT_TYPE_END; - - IfFailGoto(sig.GetData(&data), Done); - if (data != IMAGE_CEE_CS_CALLCONV_DEFAULT) { - hr = COR_E_METHODACCESS; - goto Done; - } - - IfFailGoto(sig.GetData(&data), Done); - if (data != 3) { - hr = COR_E_METHODACCESS; - goto Done; - } - - IfFailGoto(sig.GetElemType(&eType), Done); - if (eType != ELEMENT_TYPE_I4) { // return type = int32 - hr = COR_E_METHODACCESS; - goto Done; - } - - IfFailGoto(sig.GetElemType(&eType), Done); - if (eType == ELEMENT_TYPE_PTR) - IfFailGoto(sig.GetElemType(&eType2), Done); - - if (eType!= ELEMENT_TYPE_PTR || eType2 != ELEMENT_TYPE_VOID) { // arg1 = void* - hr = COR_E_METHODACCESS; - goto Done; - } - - IfFailGoto(sig.GetElemType(&eType), Done); - if (eType != ELEMENT_TYPE_U4) { // arg2 = uint32 - hr = COR_E_METHODACCESS; - goto Done; - } - - IfFailGoto(sig.GetElemType(&eType), Done); - if (eType == ELEMENT_TYPE_PTR) - IfFailGoto(sig.GetElemType(&eType2), Done); - - if (eType != ELEMENT_TYPE_PTR || eType2 != ELEMENT_TYPE_VOID) { // arg3 = void* - hr = COR_E_METHODACCESS; - goto Done; - } - } - - { - MethodDescCallSite dllMain(pParam->pMD); - - // Set up a callstack with the values from the OS in the argument array - ARG_SLOT stackVar[3]; - stackVar[0] = PtrToArgSlot(pParam->hInst); - stackVar[1] = (ARG_SLOT) pParam->dwReason; - stackVar[2] = PtrToArgSlot(pParam->lpReserved); - - // Call the method in question with the arguments. - if((dllMain.Call_RetI4(&stackVar[0]) == 0) - &&(pParam->dwReason==DLL_PROCESS_ATTACH) - && (CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_IgnoreDllMainReturn) != 1)) - { - hr = COR_E_INVALIDPROGRAM; -#ifdef MDA_SUPPORTED - MdaDllMainReturnsFalse* pProbe = MDA_GET_ASSISTANT(DllMainReturnsFalse); - if(pProbe != NULL) pProbe->ReportError(); -#endif - } - } -Done: - pParam->hr = hr; - } - EX_END_NOCATCH - } - //@TODO: Revisit why this is here, and if it's still necessary. - PAL_EXCEPT_FILTER(RunDllMainFilter) - { - // switch to COOPERATIVE - GCX_COOP_NO_DTOR(); - // don't do anything - just want to catch it - } - PAL_ENDTRY - - return param.hr; -} - -//***************************************************************************** -// fFromThunk indicates that a dependency is calling through the Import Export table, -// and calling indirect through the IJW vtfixup slot. -// -// fFromThunk=FALSE means that we are running DllMain during LoadLibrary while -// holding the loader lock. -// -HRESULT ExecuteDLLForAttach(HINSTANCE hInst, - DWORD dwReason, - LPVOID lpReserved, - BOOL fFromThunk) -{ - CONTRACTL{ - THROWS; - GC_TRIGGERS; - MODE_ANY; - PRECONDITION(CheckPointer(lpReserved, NULL_OK)); - } CONTRACTL_END; - PEDecoder pe(hInst); - // Note that ILOnly DLLs can have a managed entry point. This will - // be called when the assembly is activated by the CLR loader, - // and it need not be run here. - if (pe.IsILOnly()) - { - _ASSERTE(!fFromThunk); - return S_OK; - } - - if (!pe.HasManagedEntryPoint() && !fFromThunk) - return S_OK; - - // We need to prep the managed assembly for execution. - - AppDomain *pDomain = GetAppDomain(); - - // First we must find the DomainFile associated with this HMODULE. There are basically 3 - // interesting cases: - // - // 1. The file is being loaded. In this case we have a DomainFile in existence but - // (very inconveniently) it does not have its HMODULE set yet. Most likely if we - // were to look at the state of this thread up the stack, we'd see that file is - // currently being loaded right above us. However, we cannot rely on this because - // A. We may be in case 2 (e.g. a static DLL dependency is being loaded first) - // B. _CorDllMain may have been called on a different thread. - // - // 2. The file has never been seen before. In this case we are basically in the dark; we - // simply attempt to load the file as an assembly. (If it is not an assembly we will - // fail.) - // - // 3. The file has been loaded but we are getting called anyway in a race. (This should not - // happen in the loader lock case, only when we are getting called from thunks). - // - // So, we: - // A. Use the current thread's LoadingFile as a hint. We will rely on this only if it has - // the same path as the HMOD. - // B. Search the app domain for a DomainFile with a matching base address, or failing that, path. - // C. We have no information, so assume it is a new assembly being loaded. - - // A: check the loading file - - StackSString path; - PEImage::GetPathFromDll(hInst, path); - - DomainFile *pLoadingFile = GetThread()->GetLoadingFile(); - GetThread()->ClearLoadingFile(); - - if (pLoadingFile != NULL) - { - if (!PEImage::PathEquals(pLoadingFile->GetFile()->GetPath(), path)) - { - pLoadingFile = NULL; - } - else - { - pLoadingFile->GetFile()->SetLoadedHMODULE(hInst); - } - } - - // B: look for a loading IJW module - - if (pLoadingFile == NULL) - { - pLoadingFile = pDomain->FindIJWDomainFile(hInst, path); - } - - // C: nothing else worked, we require it is an assembly with a manifest in this situation - if (pLoadingFile == NULL) - { - pLoadingFile = pDomain->LoadExplicitAssembly(hInst, FALSE)->GetDomainAssembly(); - } - - // There are two cases here, loading from thunks emitted from the shim, and being called - // inside the loader lock for the legacy IJW dll case. - - if (fFromThunk) - { - pLoadingFile->EnsureActive(); - return S_OK; - } - - _ASSERTE(!pe.IsILOnly() && pe.HasManagedEntryPoint()); - // Get the entry point for the IJW module - Module *pModule = pLoadingFile->GetCurrentModule(); - mdMethodDef tkEntry = pModule->GetEntryPointToken(); - - BOOL hasEntryPoint = (TypeFromToken(tkEntry) == mdtMethodDef && - !IsNilToken(tkEntry)); - - if (!hasEntryPoint) - { - return S_OK; - } - - if (pDomain->IsPassiveDomain()) - { - // Running managed code while holding the loader lock can cause deadlocks. - // These deadlocks might happen when this assembly gets executed. However, - // we should avoid those deadlocks if we are in a passive AppDomain. - // Also, managed entry point is now legacy, and has should be replaced - // with Module .cctor. - // - // We also rely on Module::CanExecuteCode() to prevent - // any further code from being executed from this assembly. - _ASSERTE(pLoadingFile && pLoadingFile->GetFile() && pLoadingFile->GetFile()->GetILimage()); - pLoadingFile->GetFile()->GetILimage()->SetPassiveDomainOnly(); - return S_OK; - } - - // We're actually going to run some managed code and we're inside the loader lock. - // There may be a customer debug probe enabled that prevents this. - CanRunManagedCode(hInst); - - // If we are not being called from thunks, we are inside the loader lock - // & have this single opportunity to run our dll main. - // Since we are in deadlock danger anyway (note this is the problematic legacy - // case only!) we disable our file loading and type loading reentrancy protection & allow - // loads to fully proceed. - - // class level override is needed for the entire operation, not just EnsureActive - OVERRIDE_TYPE_LOAD_LEVEL_LIMIT(CLASS_LOADED); - - { - OVERRIDE_LOAD_LEVEL_LIMIT(FILE_ACTIVE); - - // Complete the load as necessary - pLoadingFile->EnsureActive(); - } - - MethodDesc *pMD = pModule->FindMethodThrowing(tkEntry); - CONSISTENCY_CHECK(CheckPointer(pMD)); - - pModule->SetDllEntryPoint(pMD); - - GCX_COOP(); - - // pModule may be for a different domain. - PEFile *pPEFile = pMD->GetModule()->GetFile(); - if (!pPEFile->CheckLoaded()) - { - pPEFile->SetLoadedHMODULE(hInst); - } - - // Call the managed entry point - HRESULT hr = RunDllMain(pMD, hInst, dwReason, lpReserved); - - return hr; -} - -#endif // FEATURE_MIXEDMODE //***************************************************************************** BOOL ExecuteDLL_ReturnOrThrow(HRESULT hr, BOOL fFromThunk) @@ -2804,50 +2433,6 @@ BOOL ExecuteDLL_ReturnOrThrow(HRESULT hr, BOOL fFromThunk) } -#ifdef FEATURE_MIXEDMODE -//***************************************************************************** -// This ensure that the runtime is started and an EEThread object is created -// for the current thread. This functionality is duplicated in ExecuteDLL, -// except that this code will not throw. -//***************************************************************************** -HRESULT PrepareExecuteDLLForThunk(HINSTANCE hInst, - DWORD dwReason, - LPVOID lpReserved) -{ - CONTRACTL { - NOTHROW; - WRAPPER(GC_TRIGGERS); - MODE_ANY; - PRECONDITION(CheckPointer(lpReserved, NULL_OK)); - PRECONDITION(CheckPointer(hInst)); - } CONTRACTL_END; - - - HRESULT hr = S_OK; - Thread *pThread = GetThread(); - - INDEBUG(EnsureManagedThreadExistsForHostedThread();) - - if (pThread == NULL) - { - // If necessary, start the runtime and create a managed thread object. - hr = EnsureEEStarted(COINITEE_DLL); - if (FAILED(hr)) - { - return hr; - } - if ((pThread = SetupThreadNoThrow(&hr)) == NULL) - { - return hr; - } - } - - CONSISTENCY_CHECK(CheckPointer(pThread)); - - return S_OK; -} - -#endif // FEATURE_MIXEDMODE diff --git a/src/vm/common.h b/src/vm/common.h index 45f2d62d61..b81bab73e9 100644 --- a/src/vm/common.h +++ b/src/vm/common.h @@ -384,7 +384,6 @@ namespace Loader #include "interoputil.h" #include "wrappers.h" #include "dynamicmethod.h" -#include "mixedmode.hpp" #include "gcstress.h" diff --git a/src/vm/dllimport.cpp b/src/vm/dllimport.cpp index 444189387d..30b23eafcb 100644 --- a/src/vm/dllimport.cpp +++ b/src/vm/dllimport.cpp @@ -2909,15 +2909,6 @@ void PInvokeStaticSigInfo::DllImportInit(MethodDesc* pMD, LPCUTF8 *ppLibName, LP mdModuleRef modref = mdModuleRefNil; if (FAILED(pInternalImport->GetPinvokeMap(pMD->GetMemberDef(), (DWORD*)&mappingFlags, ppEntryPointName, &modref))) { -#if defined(FEATURE_MIXEDMODE) && !defined(CROSSGEN_COMPILE) // IJW - // The guessing heuristic has been broken with NGen for a long time since we stopped loading - // images at NGen time using full LoadLibrary. The DLL references are not resolved correctly - // without full LoadLibrary. - // - // Disable the heuristic consistently during NGen so that it does not kick in by accident. - if (!IsCompilationProcess()) - BestGuessNDirectDefaults(pMD); -#endif InitCallConv((CorPinvokeMap)0, pMD->IsVarArg()); return; } @@ -2981,235 +2972,6 @@ void PInvokeStaticSigInfo::DllImportInit(MethodDesc* pMD, LPCUTF8 *ppLibName, LP } -#if defined(FEATURE_MIXEDMODE) && !defined(CROSSGEN_COMPILE) // IJW - -// This attempts to guess whether a target is an API call that uses SetLastError to communicate errors. -static BOOL HeuristicDoesThisLooksLikeAnApiCallHelper(LPBYTE pTarget) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - // This code is not that useful anymore since this functionality is already embedded in the VC linker. - // The linker will emit the lasterror flag by default for functions residing in modules that are - // a superset of the list below. - // Look for bug VSWhidbey 241895. - - static struct SysDllInfo - { - LPCWSTR pName; - LPBYTE pImageBase; - DWORD dwImageSize; - } gSysDllInfo[] = {{WINDOWS_KERNEL32_DLLNAME_W, 0, 0}, - {W("GDI32"), 0, 0}, - {W("USER32"), 0, 0}, - {W("ADVAPI32"), 0, 0} - }; - - - for (int i = 0; i < sizeof(gSysDllInfo)/sizeof(*gSysDllInfo); i++) - { - if (gSysDllInfo[i].pImageBase == 0) - { - IMAGE_DOS_HEADER *pDos = (IMAGE_DOS_HEADER*)CLRGetModuleHandle(gSysDllInfo[i].pName); - if (pDos) - { - if (pDos->e_magic == VAL16(IMAGE_DOS_SIGNATURE)) - { - IMAGE_NT_HEADERS *pNT = (IMAGE_NT_HEADERS*) (((LPBYTE)pDos) + VAL32(pDos->e_lfanew)); - if (pNT->Signature == VAL32(IMAGE_NT_SIGNATURE) && - pNT->FileHeader.SizeOfOptionalHeader == -#ifdef _WIN64 - VAL16(sizeof(IMAGE_OPTIONAL_HEADER64)) -#else - VAL16(sizeof(IMAGE_OPTIONAL_HEADER32)) -#endif - && pNT->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR_MAGIC)) - { - gSysDllInfo[i].dwImageSize = VAL32(pNT->OptionalHeader.SizeOfImage); - } - } - - gSysDllInfo[i].pImageBase = (LPBYTE)pDos; - } - } - if (gSysDllInfo[i].pImageBase != 0 && - pTarget >= gSysDllInfo[i].pImageBase && - pTarget < gSysDllInfo[i].pImageBase + gSysDllInfo[i].dwImageSize) - { - return TRUE; - } - } - - return FALSE; -} - -LPBYTE FollowIndirect(LPBYTE pTarget) -{ - CONTRACT (LPBYTE) - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - POSTCONDITION(CheckPointer(RETVAL, NULL_OK)); - } - CONTRACT_END; - - LPBYTE pRet = NULL; - - EX_TRY - { - AVInRuntimeImplOkayHolder AVOkay; - -#ifdef _TARGET_X86_ - if (pTarget != NULL && !(pTarget[0] != 0xff || pTarget[1] != 0x25)) - { - pRet = **(LPBYTE**)(pTarget + 2); - } -#elif defined(_TARGET_AMD64_) - if (pTarget != NULL && !(pTarget[0] != 0xff || pTarget[1] != 0x25)) - { - INT64 rva = *(INT32*)(pTarget + 2); - pRet = *(LPBYTE*)(pTarget + 6 + rva); - } -#endif - } - EX_CATCH - { - // Catch AVs here. - } - EX_END_CATCH(SwallowAllExceptions); - - RETURN pRet; -} - -// This attempts to guess whether a target is an API call that uses SetLastError to communicate errors. -BOOL HeuristicDoesThisLooksLikeAnApiCall(LPBYTE pTarget) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - if (pTarget == NULL) - return FALSE; - - if (HeuristicDoesThisLooksLikeAnApiCallHelper(pTarget)) - return TRUE; - - LPBYTE pTarget2 = FollowIndirect(pTarget); - if (pTarget2) - { - // jmp [xxxx] - could be an import thunk - return HeuristicDoesThisLooksLikeAnApiCallHelper( pTarget2 ); - } - - return FALSE; -} - -BOOL HeuristicDoesThisLookLikeAGetLastErrorCall(LPBYTE pTarget) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - static LPBYTE pGetLastError = NULL; - if (!pGetLastError) - { - // No need to use a holder here, since no cleanup is necessary. - HMODULE hMod = CLRGetModuleHandle(WINDOWS_KERNEL32_DLLNAME_W); - if (hMod) - { - pGetLastError = (LPBYTE)GetProcAddress(hMod, "GetLastError"); - if (!pGetLastError) - { - // This should never happen but better to be cautious. - pGetLastError = (LPBYTE)-1; - } - } - else - { - // We failed to get the module handle for kernel32.dll. This is almost impossible - // however better to err on the side of caution. - pGetLastError = (LPBYTE)-1; - } - } - - if (pTarget == pGetLastError) - return TRUE; - - if (pTarget == NULL) - return FALSE; - - LPBYTE pTarget2 = FollowIndirect(pTarget); - if (pTarget2) - { - // jmp [xxxx] - could be an import thunk - return pTarget2 == pGetLastError; - } - - return FALSE; -} - -DWORD __stdcall FalseGetLastError() -{ - WRAPPER_NO_CONTRACT; - - return GetThread()->m_dwLastError; -} - -void PInvokeStaticSigInfo::BestGuessNDirectDefaults(MethodDesc* pMD) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - if (!pMD->IsNDirect()) - return; - - NDirectMethodDesc* pMDD = (NDirectMethodDesc*)pMD; - - if (!pMDD->IsEarlyBound()) - return; - - LPVOID pTarget = NULL; - - // NOTE: If we get inside this block, and this is a call to GetLastError, - // then InitEarlyBoundNDirectTarget has not been run yet. - if (pMDD->NDirectTargetIsImportThunk()) - { - // Get the unmanaged callsite. - pTarget = (LPVOID)pMDD->GetModule()->GetInternalPInvokeTarget(pMDD->GetRVA()); - - // If this is a call to GetLastError, then we haven't overwritten m_pNativeNDirectTarget yet. - if (HeuristicDoesThisLookLikeAGetLastErrorCall((LPBYTE)pTarget)) - pTarget = (BYTE*) FalseGetLastError; - } - else - { - pTarget = pMDD->GetNativeNDirectTarget(); - } - - if (HeuristicDoesThisLooksLikeAnApiCall((LPBYTE) pTarget)) - SetLinkFlags ((CorNativeLinkFlags)(GetLinkFlags() | nlfLastError)); -} - -#endif // FEATURE_MIXEDMODE && !CROSSGEN_COMPILE void PInvokeStaticSigInfo::InitCallConv(CorPinvokeMap callConv, BOOL bIsVarArg) @@ -5585,13 +5347,6 @@ PCODE NDirect::GetStubForILStub(NDirectMethodDesc* pNMD, MethodDesc** ppStubMD, pStub = TheVarargNDirectStub(pNMD->HasRetBuffArg()); } -#ifdef FEATURE_MIXEDMODE // IJW - if (pNMD->IsEarlyBound()) - { - pNMD->InitEarlyBoundNDirectTarget(); - } - else -#endif { NDirectLink(pNMD); } @@ -6698,21 +6453,6 @@ EXTERN_C LPVOID STDCALL NDirectImportWorker(NDirectMethodDesc* pMD) // any of our internal exceptions into managed exceptions. INSTALL_UNWIND_AND_CONTINUE_HANDLER; -#ifdef FEATURE_MIXEDMODE // IJW - if (pMD->IsEarlyBound()) - { - if (!pMD->IsZapped()) - { - // we need the MD to be populated in case we decide to build an intercept - // stub to wrap the target in InitEarlyBoundNDirectTarget - PInvokeStaticSigInfo sigInfo; - NDirect::PopulateNDirectMethodDesc(pMD, &sigInfo); - } - - pMD->InitEarlyBoundNDirectTarget(); - } - else -#endif // FEATURE_MIXEDMODE { // // Otherwise we're in an inlined pinvoke late bound MD diff --git a/src/vm/dllimport.h b/src/vm/dllimport.h index 0caea6bcfd..8d14aff9c7 100644 --- a/src/vm/dllimport.h +++ b/src/vm/dllimport.h @@ -347,9 +347,6 @@ private: void PreInit(Module* pModule, MethodTable *pClass); void PreInit(MethodDesc* pMD); void SetError(WORD error) { if (!m_error) m_error = error; } -#ifdef FEATURE_MIXEDMODE - void BestGuessNDirectDefaults(MethodDesc* pMD); -#endif public: DWORD GetStubFlags() @@ -580,12 +577,6 @@ protected: EXTERN_C void PInvokeStubForHost(void); #endif -#ifdef FEATURE_MIXEDMODE // IJW -// This attempts to guess whether a target is an API call that uses SetLastError to communicate errors. -BOOL HeuristicDoesThisLooksLikeAnApiCall(LPBYTE pTarget); -BOOL HeuristicDoesThisLookLikeAGetLastErrorCall(LPBYTE pTarget); -DWORD __stdcall FalseGetLastError(); -#endif // FEATURE_MIXEDMODE class NDirectStubParameters { diff --git a/src/vm/domainfile.cpp b/src/vm/domainfile.cpp index c50c3c4d86..e280cb1898 100644 --- a/src/vm/domainfile.cpp +++ b/src/vm/domainfile.cpp @@ -30,7 +30,7 @@ #include "compile.h" #endif // FEATURE_PREJIT -#include "umthunkhash.h" +#include "dllimportcallback.h" #include "peimagelayout.inl" #include "winrthelpers.h" @@ -102,10 +102,6 @@ DomainFile::~DomainFile() m_pOriginalFile->Release(); if (m_pDynamicMethodTable) m_pDynamicMethodTable->Destroy(); -#if defined(FEATURE_MIXEDMODE) && !defined(CROSSGEN_COMPILE) - if (m_pUMThunkHash) - delete m_pUMThunkHash; -#endif delete m_pError; } @@ -1169,10 +1165,6 @@ void DomainFile::VtableFixups() { WRAPPER_NO_CONTRACT; -#if defined(FEATURE_MIXEDMODE) && !defined(CROSSGEN_COMPILE) - if (!GetCurrentModule()->IsResource()) - GetCurrentModule()->FixupVTables(); -#endif } void DomainFile::FinishLoad() @@ -3534,29 +3526,3 @@ DomainModule::EnumMemoryRegions(CLRDataEnumMemoryFlags flags) #endif // #ifdef DACCESS_COMPILE -#if defined(FEATURE_MIXEDMODE) && !defined(CROSSGEN_COMPILE) -LPVOID DomainFile::GetUMThunk(LPVOID pManagedIp, PCCOR_SIGNATURE pSig, ULONG cSig) -{ - CONTRACT (LPVOID) - { - INSTANCE_CHECK; - THROWS; - GC_TRIGGERS; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM()); - POSTCONDITION(CheckPointer(RETVAL, NULL_OK)); - } - CONTRACT_END - - - if (m_pUMThunkHash == NULL) - { - UMThunkHash *pUMThunkHash = new UMThunkHash(GetModule(), this->GetAppDomain()); - if (FastInterlockCompareExchangePointer(&m_pUMThunkHash, pUMThunkHash, NULL) != NULL) - { - delete pUMThunkHash; - } - } - RETURN m_pUMThunkHash->GetUMThunk(pManagedIp, pSig, cSig); -} -#endif // FEATURE_MIXEDMODE && !CROSSGEN_COMPILE diff --git a/src/vm/domainfile.h b/src/vm/domainfile.h index e91077425d..a6efbaa79c 100644 --- a/src/vm/domainfile.h +++ b/src/vm/domainfile.h @@ -143,9 +143,6 @@ class DomainFile } #endif -#ifdef FEATURE_MIXEDMODE - LPVOID GetUMThunk(LPVOID pManagedIp, PCCOR_SIGNATURE pSig, ULONG cSig); -#endif void ReleaseFiles() DAC_EMPTY(); diff --git a/src/vm/i386/asmconstants.h b/src/vm/i386/asmconstants.h index 0d5237bd5a..6be010bd63 100644 --- a/src/vm/i386/asmconstants.h +++ b/src/vm/i386/asmconstants.h @@ -253,16 +253,6 @@ ASMCONSTANTS_C_ASSERT(Thread::TS_Hijacked == TS_Hijacked_ASM) ASMCONSTANTS_C_ASSERT(AppDomain__m_dwId == offsetof(AppDomain, m_dwId)); // from clr/src/vm/ceeload.cpp -#ifdef FEATURE_MIXEDMODE -#define IJWNOADThunk__m_cache 0x1C -ASMCONSTANTS_C_ASSERT(IJWNOADThunk__m_cache == offsetof(IJWNOADThunk, m_cache)) - -#define IJWNOADThunk__NextCacheOffset 0x8 -ASMCONSTANTS_C_ASSERT(IJWNOADThunk__NextCacheOffset == sizeof(IJWNOADThunkStubCache)) - -#define IJWNOADThunk__CodeAddrOffsetFromADID 0x4 -ASMCONSTANTS_C_ASSERT(IJWNOADThunk__CodeAddrOffsetFromADID == offsetof(IJWNOADThunkStubCache, m_CodeAddr)) -#endif //FEATURE_MIXEDMODE // from clr/src/vm/syncblk.h #define SizeOfSyncTableEntry_ASM 8 diff --git a/src/vm/i386/asmhelpers.asm b/src/vm/i386/asmhelpers.asm index 0456be82db..196fe82260 100644 --- a/src/vm/i386/asmhelpers.asm +++ b/src/vm/i386/asmhelpers.asm @@ -30,9 +30,6 @@ EXTERN __imp__RtlUnwind@16:DWORD ifdef _DEBUG EXTERN _HelperMethodFrameConfirmState@20:PROC endif -ifdef FEATURE_MIXEDMODE -EXTERN _IJWNOADThunkJumpTargetHelper@4:PROC -endif EXTERN _StubRareEnableWorker@4:PROC ifdef FEATURE_COMINTEROP EXTERN _StubRareDisableHRWorker@4:PROC @@ -608,105 +605,6 @@ _StubRareDisableTHROW proc public _StubRareDisableTHROW endp -ifdef FEATURE_MIXEDMODE -; VOID __stdcall IJWNOADThunkJumpTarget(void); -; This routine is used by the IJWNOADThunk to determine the callsite of the domain-specific stub to call. -_IJWNOADThunkJumpTarget@0 proc public - - push ebp - mov ebp, esp - - ; EAX contains IJWNOADThunk* - ; Must retain ebx, ecx, edx, esi, edi. - - ; save ebx - holds the IJWNOADThunk* - ; save ecx - holds the current AppDomain ID. - ; save edx - holds the cached AppDomain ID. - push ebx - push ecx - - ; put the IJWNOADThunk into ebx for safe keeping - mov ebx, eax - - ; get thread - assumes registers are preserved - call _GetThread@0 - - ; if thread is null, go down un-optimized path - test eax,eax - jz cachemiss - - ; get current domain - assumes registers are preserved - call _GetAppDomain@0 - - ; if domain is null, go down un-optimized path - test eax,eax - jz cachemiss - - ; get the current appdomain id - mov ecx, [eax + AppDomain__m_dwId] - - ; test it against each cache location - mov eax, ebx - add eax, IJWNOADThunk__m_cache - cmp ecx, [eax] - je cachehit - - add eax, IJWNOADThunk__NextCacheOffset - cmp ecx, [eax] - je cachehit - - add eax, IJWNOADThunk__NextCacheOffset - cmp ecx, [eax] - je cachehit - - add eax, IJWNOADThunk__NextCacheOffset - cmp ecx, [eax] - je cachehit - -cachemiss: - ; save extra registers - push edx - push esi - push edi - - ; call unoptimized path - push ebx ; only arg is IJWNOADThunk* - call _IJWNOADThunkJumpTargetHelper@4 - - ; restore extra registers - pop edi - pop esi - pop edx - - ; jump back up to the epilog - jmp complete - -cachehit: - ; found a matching ADID, get the code addr. - mov eax, [eax + IJWNOADThunk__CodeAddrOffsetFromADID] - - ; if the callsite is null, go down the un-optimized path - test eax, eax - jz cachemiss - -complete: - ; restore regs - pop ecx - pop ebx - - mov esp, ebp - pop ebp - - ; Jump to callsite - jmp eax - - ; This will never be executed. It is just to help out stack-walking logic - ; which disassembles the epilog to unwind the stack. - ret -_IJWNOADThunkJumpTarget@0 endp - -endif - InternalExceptionWorker proc public pop edx ; recover RETADDR add esp, eax ; release caller's args diff --git a/src/vm/jithelpers.cpp b/src/vm/jithelpers.cpp index d132741b0d..b4dc4c1382 100644 --- a/src/vm/jithelpers.cpp +++ b/src/vm/jithelpers.cpp @@ -1295,41 +1295,6 @@ HCIMPLEND // //======================================================================== -#ifdef FEATURE_MIXEDMODE -HCIMPL1(void*, JIT_GetStaticFieldAddr_Tls, FieldDesc *pFD) -{ - CONTRACTL { - FCALL_CHECK; - PRECONDITION(CheckPointer(pFD)); - PRECONDITION(pFD->IsStatic()); - PRECONDITION(pFD->IsRVA() && pFD->GetModule()->IsRvaFieldTls(pFD->GetOffset())); - } CONTRACTL_END; - - void *addr = NULL; - - HELPER_METHOD_FRAME_BEGIN_RET_0(); - - Module* pModule = pFD->GetModule(); - - // Get the ThreadLocalStoragePointer in the TEB. - LPVOID pTlsPtr = ClrTeb::GetLegacyThreadLocalStoragePointer(); - - // pTlsPtr is pointing at an array of pointers, each of which points to - // the TLS block of a dll. So here, we need to get the TLS index for - // the dll, add that to pTlsPtr, and dereference it to get the TLS - // block of the dll. - DWORD tlsIndex = pModule->GetTlsIndex(); - LPVOID pDllTlsBase = (LPVOID)*((UINT_PTR*)pTlsPtr + tlsIndex); - - // Finally, we need to find the field offset into the TLS block. - addr = (LPVOID)((PBYTE)pDllTlsBase + pModule->GetFieldTlsOffset(pFD->GetOffset())); - - HELPER_METHOD_FRAME_END(); - - return addr; -} -HCIMPLEND -#endif // FEATURE_MIXEDMODE #ifdef FEATURE_REMOTING HCIMPL1(void*, JIT_GetStaticFieldAddr_Context, FieldDesc *pFD) diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp index b05b891951..0a71d959a2 100644 --- a/src/vm/jitinterface.cpp +++ b/src/vm/jitinterface.cpp @@ -9581,27 +9581,6 @@ void* CEEInfo::getPInvokeUnmanagedTarget(CORINFO_METHOD_HANDLE method, if (pMD->NDirectTargetIsImportThunk()) { -#ifdef FEATURE_MIXEDMODE // IJW - if (pMD->IsEarlyBound() -#ifdef FEATURE_MULTICOREJIT - // Bug 126723: Calling ClassInit in multicore JIT background thread, return NULL - // When multicore JIT is enabled (StartProfile called), calling managed code is not allowed in the background thread - && GetAppDomain()->GetMulticoreJitManager().AllowCCtorsToRunDuringJITing() -#endif - ) - { - EX_TRY - { - pMD->InitEarlyBoundNDirectTarget(); - _ASSERTE(!pMD->NDirectTargetIsImportThunk()); - result = pMD->GetNDirectTarget(); - } - EX_CATCH - { - } - EX_END_CATCH(SwallowAllExceptions) - } -#endif // FEATURE_MIXEDMODE } else { diff --git a/src/vm/marshalnative.cpp b/src/vm/marshalnative.cpp index 5f05fa2daf..f72b74c224 100644 --- a/src/vm/marshalnative.cpp +++ b/src/vm/marshalnative.cpp @@ -446,29 +446,6 @@ FCIMPL3(LPVOID, MarshalNative::GetUnmanagedThunkForManagedMethodPtr, LPVOID pfnM CONTRACTL_END; LPVOID pThunk = NULL; -#ifdef FEATURE_MIXEDMODE - HELPER_METHOD_FRAME_BEGIN_RET_0(); - - if (pfnMethodToWrap == NULL) - COMPlusThrowArgumentNull(W("pfnMethodToWrap")); - if (pbSignature == NULL) - COMPlusThrowArgumentNull(W("pbSignature")); - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4996) // Suppress warning on call to deprecated method -#endif - Module *pModule = SystemDomain::GetCallersModule(1); -#ifdef _MSC_VER -#pragma warning(pop) -#endif - PREFIX_ASSUME(pModule != NULL); - pThunk = pModule->GetUMThunk(pfnMethodToWrap, pbSignature, cbSignature); - if (!pThunk) - COMPlusThrowOM(); - - HELPER_METHOD_FRAME_END(); -#endif // FEATURE_MIXEDMODE return pThunk; } FCIMPLEND @@ -488,31 +465,6 @@ FCIMPL3(LPVOID, MarshalNative::GetManagedThunkForUnmanagedMethodPtr, LPVOID pfnM CONTRACTL_END; LPVOID pThunk = NULL; -#ifdef FEATURE_MIXEDMODE - HELPER_METHOD_FRAME_BEGIN_RET_0(); - - if (pfnMethodToWrap == NULL) - COMPlusThrowArgumentNull(W("pfnMethodToWrap")); - if (pbSignature == NULL) - COMPlusThrowArgumentNull(W("pbSignature")); - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4996) // Suppress warning on call to deprecated method -#endif - Module *pModule = SystemDomain::GetCallersModule(1); -#ifdef _MSC_VER -#pragma warning(pop) -#endif - if (!pModule) - ThrowOutOfMemory(); - - pThunk = pModule->GetMUThunk(pfnMethodToWrap, pbSignature, cbSignature); - if (!pThunk) - ThrowOutOfMemory(); - - HELPER_METHOD_FRAME_END(); -#endif // FEATURE_MIXEDMODE return pThunk; } FCIMPLEND diff --git a/src/vm/method.cpp b/src/vm/method.cpp index 12eeb60c96..135787257b 100644 --- a/src/vm/method.cpp +++ b/src/vm/method.cpp @@ -5259,37 +5259,6 @@ LPVOID NDirectMethodDesc::FindEntryPoint(HINSTANCE hMod) const } #endif // CROSSGEN_COMPILE -#if defined(FEATURE_MIXEDMODE) && !defined(CROSSGEN_COMPILE) -//******************************************************************************* -void NDirectMethodDesc::InitEarlyBoundNDirectTarget() -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - INJECT_FAULT(COMPlusThrowOM();); - } - CONTRACTL_END - - _ASSERTE(IsEarlyBound()); - - if (IsClassConstructorTriggeredAtLinkTime()) - { - GetMethodTable()->CheckRunClassInitThrowing(); - } - - const void *target = GetModule()->GetInternalPInvokeTarget(GetRVA()); - _ASSERTE(target != 0); - - if (HeuristicDoesThisLookLikeAGetLastErrorCall((LPBYTE)target)) - target = (BYTE*) FalseGetLastError; - - // As long as we've set the NDirect target field we don't need to backpatch the import thunk glue. - // All NDirect calls all through the NDirect target, so if it's updated, then we won't go into - // NDirectImportThunk(). In fact, backpatching the import thunk glue leads to race conditions. - SetNDirectTarget((LPVOID)target); -} -#endif // FEATURE_MIXEDMODE && !CROSSGEN_COMPILE //******************************************************************************* void MethodDesc::ComputeSuppressUnmanagedCodeAccessAttr(IMDInternalImport *pImport) diff --git a/src/vm/method.hpp b/src/vm/method.hpp index 75ff246dc3..c62c3c0827 100644 --- a/src/vm/method.hpp +++ b/src/vm/method.hpp @@ -2645,19 +2645,6 @@ public: // Atomically set specified flags. Only setting of the bits is supported. void InterlockedSetNDirectFlags(WORD wFlags); -#ifdef FEATURE_MIXEDMODE // IJW - void SetIsEarlyBound() - { - LIMITED_METHOD_CONTRACT; - ndirect.m_wFlags |= kEarlyBound; - } - - BOOL IsEarlyBound() - { - LIMITED_METHOD_CONTRACT; - return (ndirect.m_wFlags & kEarlyBound) != 0; - } -#endif // FEATURE_MIXEDMODE BOOL IsNativeAnsi() const { @@ -2880,9 +2867,6 @@ public: } #endif // defined(_TARGET_X86_) -#ifdef FEATURE_MIXEDMODE // IJW - VOID InitEarlyBoundNDirectTarget(); -#endif // In AppDomains, we can trigger declarer's cctor when we link the P/Invoke, // which takes care of inlined calls as well. See code:NDirect.NDirectLink. diff --git a/src/vm/methodtablebuilder.cpp b/src/vm/methodtablebuilder.cpp index 1389f8f0b5..5b40131aa5 100644 --- a/src/vm/methodtablebuilder.cpp +++ b/src/vm/methodtablebuilder.cpp @@ -6269,14 +6269,6 @@ MethodTableBuilder::InitMethodDesc( pNewNMD->ndirect.m_cbStackArgumentSize = 0xFFFF; #endif // defined(_TARGET_X86_) -#ifdef FEATURE_MIXEDMODE // IJW - if (RVA != 0 && IsMiUnmanaged(dwImplFlags) && IsMiNative(dwImplFlags)) - { - // Note that we cannot initialize the stub directly now in the general case, - // as LoadLibrary may not have been performed yet. - pNewNMD->SetIsEarlyBound(); - } -#endif // FEATURE_MIXEDMODE pNewNMD->GetWriteableData()->m_pNDirectTarget = pNewNMD->GetNDirectImportThunkGlue()->GetEntrypoint(); } diff --git a/src/vm/mixedmode.hpp b/src/vm/mixedmode.hpp deleted file mode 100644 index 0010410f36..0000000000 --- a/src/vm/mixedmode.hpp +++ /dev/null @@ -1,139 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. -// =========================================================================== -// File: mixedmode.hpp -// - -// -// MIXEDMODE.HPP defines classes to support mixed mode dlls -// =========================================================================== - - -#ifndef _MIXEDMODE_H_ -#define _MIXEDMODE_H_ - -#ifdef FEATURE_MIXEDMODE - -#ifdef _TARGET_X86_ -extern "C" VOID __stdcall IJWNOADThunkJumpTarget(void); -#endif - - -#define IJWNOADThunkStubCacheSize 4 - -struct IJWNOADThunkStubCache -{ - ADID m_AppDomainID; // Must be the first member of the struct. - LPCVOID m_CodeAddr; -}; - - - -// Be sure to keep this structure and the assembly view in sync -class IJWNOADThunk -{ - UMEntryThunkCode m_code; - -protected: - static void __cdecl MakeCall(); - static void SafeNoModule(); - static void NoModule(); - - HMODULE m_pModulebase; - DWORD m_dwIndex; - mdToken m_Token; - - DWORD m_fAccessingCache; - -public: - IJWNOADThunkStubCache m_cache[IJWNOADThunkStubCacheSize]; - - BOOL IsCachedAppDomainID(ADID pID) - { - LIMITED_METHOD_CONTRACT; - - for (int i=0; i < IJWNOADThunkStubCacheSize; i++) - { - if (m_cache[i].m_AppDomainID == pID) - return TRUE; - } - - return FALSE; - }; - - void GetCachedInfo(ADID pID, LPCVOID* pCode) - { - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - INSTANCE_CHECK; - SO_TOLERANT; - PRECONDITION(CheckPointer(pCode)); - } - CONTRACTL_END; - - *pCode = NULL; - - for (int i=0; i < IJWNOADThunkStubCacheSize; i++) - { - if (m_cache[i].m_AppDomainID == pID) - *pCode = m_cache[i].m_CodeAddr; - } - } - - void SetCachedInfo(ADID pID, LPCVOID pCode) - { - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - MODE_ANY; - INSTANCE_CHECK; - SO_INTOLERANT; - } - CONTRACTL_END; - - YIELD_WHILE (FastInterlockCompareExchange((LONG*)&m_fAccessingCache, 1, 0) != 0); - - // Don't cache if the cache is already full. - for (int i=0; i < IJWNOADThunkStubCacheSize; i++) - { - if (m_cache[i].m_AppDomainID == (ADID)-1) - { - m_cache[i].m_CodeAddr = pCode; - MemoryBarrier(); - m_cache[i].m_AppDomainID = pID; - } - } - - m_fAccessingCache = 0; - } - - static IJWNOADThunk* FromCode(PCODE pCodeAddr) - { - LIMITED_METHOD_CONTRACT; - return (IJWNOADThunk*)(PCODEToPINSTR(pCodeAddr) - offsetof(IJWNOADThunk, m_code) - UMEntryThunkCode::GetEntryPointOffset()); - }; - mdToken GetToken() - { - LIMITED_METHOD_CONTRACT; - return m_Token; - } - - IJWNOADThunk(HMODULE pModulebase, DWORD dwIndex, mdToken Token); - - LPCBYTE GetCode() - { - WRAPPER_NO_CONTRACT; - return m_code.GetEntryPoint(); - } - - LPCVOID IJWNOADThunk::FindThunkTarget(); -}; - -#endif //FEATURE_MIXEDMODE - -#endif // _MIXEDMODE_H_ diff --git a/src/vm/pefile.cpp b/src/vm/pefile.cpp index f833a17c36..e322b26ddb 100644 --- a/src/vm/pefile.cpp +++ b/src/vm/pefile.cpp @@ -223,215 +223,6 @@ BOOL PEFile::CanLoadLibrary() return IsILOnly(); } -#ifdef FEATURE_MIXEDMODE - -#ifndef CROSSGEN_COMPILE - -// Returns TRUE if this file references managed CRT (msvcmNN*). -BOOL PEFile::ReferencesManagedCRT() -{ - STANDARD_VM_CONTRACT; - - IMDInternalImportHolder pImport = GetMDImport(); - MDEnumHolder hEnum(pImport); - - IfFailThrow(pImport->EnumInit(mdtModuleRef, mdTokenNil, &hEnum)); - - mdModuleRef tk; - while (pImport->EnumNext(&hEnum, &tk)) - { - // we are looking for "msvcmNN*" - LPCSTR szName; - IfFailThrow(pImport->GetModuleRefProps(tk, &szName)); - - if (_strnicmp(szName, "msvcm", 5) == 0 && isdigit(szName[5]) && isdigit(szName[6])) - { - return TRUE; - } - } - - return FALSE; -} - -void PEFile::CheckForDisallowedInProcSxSLoadWorker() -{ - STANDARD_VM_CONTRACT; - - // provide an opt-out switch for now - if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_DisableIJWVersionCheck) != 0) - return; - - // ************************************************************************************************ - // 1. See if this file should be checked - // The following checks filter out non-mixed mode assemblies that don't reference msvcmNN*. We only - // care about non-ILONLY images (IJW) or 2.0 C++/CLI pure images. - if (IsResource() || IsDynamic()) - return; - - // check the metadata version string - COUNT_T size; - PVOID pMetaData = (PVOID)GetMetadata(&size); - if (!pMetaData) - { - // No metadata section? Well somebody should have caught this earlier so report as - // ExecutionEngine rather than BIF. - EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE); - } - - LPCSTR pVersion = NULL; - IfFailThrow(GetImageRuntimeVersionString(pMetaData, &pVersion)); - - char chV; - unsigned uiMajor, uiMinor; - BOOL fLegacyImage = (sscanf_s(pVersion, "%c%u.%u", &chV, 1, &uiMajor, &uiMinor) == 3 && (chV == W('v') || chV == W('V')) && uiMajor <= 2); - - // Note that having VTFixups properly working really is limited to non-ILONLY images. In particular, - // the shim does not even attempt to patch ILONLY images in any way with bootstrap thunks. - if (IsILOnly()) - { - // all >2.0 ILONLY images are fine because >2.0 managed CRTs can be loaded in multiple runtimes - if (!fLegacyImage) - return; - - // legacy ILONLY images that don't reference the managed CRT are fine - if (!ReferencesManagedCRT()) - return; - } - - // get the version of this runtime - WCHAR wzThisRuntimeVersion[_MAX_PATH]; - DWORD cchVersion = COUNTOF(wzThisRuntimeVersion); - IfFailThrow(g_pCLRRuntime->GetVersionString(wzThisRuntimeVersion, &cchVersion)); - - // ************************************************************************************************ - // 2. For legacy assemblies, verify that legacy APIs are/would be bound to this runtime - if (fLegacyImage) - { - WCHAR wzAPIVersion[_MAX_PATH]; - bool fLegacyAPIsAreBound = false; - - { // Check if the legacy APIs have already been bound to us using the new hosting APIs. - ReleaseHolder<ICLRMetaHost> pMetaHost; - IfFailThrow(CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&pMetaHost)); - - ReleaseHolder<ICLRRuntimeInfo> pInfo; - // Returns S_FALSE when no runtime is currently bound, S_OK when one is. - HRESULT hr = pMetaHost->QueryLegacyV2RuntimeBinding(IID_ICLRRuntimeInfo, (LPVOID*)&pInfo); - IfFailThrow(hr); - - if (hr == S_OK) - { // Legacy APIs are bound, now check if they are bound to us. - fLegacyAPIsAreBound = true; - - cchVersion = COUNTOF(wzAPIVersion); - IfFailThrow(pInfo->GetVersionString(wzAPIVersion, &cchVersion)); - - if (SString::_wcsicmp(wzThisRuntimeVersion, wzAPIVersion) == 0) - { // This runtime is the one bound to the legacy APIs, ok to load legacy assembly. - return; - } - } - } - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4996) // we are going to call deprecated APIs -#endif - // We need the above QueryLegacyV2RuntimeBinding check because GetRequestedRuntimeInfo will not take into - // account the current binding, which could have been set by the host rather than through an EXE config. - // If, however, the legacy APIs are not bound (indicated in fLegacyAPIsAreBound) then we can assume that - // the legacy APIs would bind using the equivalent of CorBindToRuntime(NULL) as a result of loading this - // legacy IJW assembly, and so we use GetRequestedRuntimeInfo to check without actually causing the bind. - // By avoiding causing the bind, we avoid a binding side effect in the failure case. - if (!fLegacyAPIsAreBound && - SUCCEEDED(GetRequestedRuntimeInfo(NULL, NULL, NULL, 0, // pExe, pwszVersion, pConfigurationFile, startupFlags - RUNTIME_INFO_UPGRADE_VERSION | RUNTIME_INFO_DONT_RETURN_DIRECTORY | RUNTIME_INFO_DONT_SHOW_ERROR_DIALOG, - NULL, 0, NULL, // pDirectory, dwDirectory, pdwDirectoryLength - wzAPIVersion, COUNTOF(wzAPIVersion), &cchVersion))) // pVersion, cchBuffer, pdwLength - { - if (SString::_wcsicmp(wzThisRuntimeVersion, wzAPIVersion) == 0) - { - // it came back as this version - call CorBindToRuntime to actually bind it - ReleaseHolder<ICLRRuntimeHost> pHost; - IfFailThrow(CorBindToRuntime(wzAPIVersion, NULL, CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID *)&pHost)); - - // and verify that nobody beat us to it - IfFailThrow(GetCORVersion(wzAPIVersion, COUNTOF(wzAPIVersion), &cchVersion)); - - if (SString::_wcsicmp(wzThisRuntimeVersion, wzAPIVersion) == 0) - { - // we have verified that when the assembly calls CorBindToRuntime(NULL), - // it will get this runtime, so we allow it to be loaded - return; - } - } - } -#ifdef _MSC_VER -#pragma warning(pop) -#endif - - MAKE_WIDEPTR_FROMUTF8(pwzVersion, pVersion); - - ExternalLog(LF_LOADER, LL_ERROR, W("ERR: Rejecting IJW module built against %s because it could be loaded into another runtime in this process."), pwzVersion); - COMPlusThrow(kFileLoadException, IDS_EE_IJWLOAD_CROSSVERSION_DISALLOWED, pwzVersion, QUOTE_MACRO_L(VER_MAJORVERSION.VER_MINORVERSION)); - } - - // ************************************************************************************************ - // 3. For 4.0+ assemblies, verify that it hasn't been loaded into another runtime - ReleaseHolder<ICLRRuntimeHostInternal> pRuntimeHostInternal; - IfFailThrow(g_pCLRRuntime->GetInterface(CLSID_CLRRuntimeHostInternal, - IID_ICLRRuntimeHostInternal, - &pRuntimeHostInternal)); - - PTR_VOID pModuleBase = GetLoadedIL()->GetBase(); - - ReleaseHolder<ICLRRuntimeInfo> pRuntimeInfo; - HRESULT hr = pRuntimeHostInternal->LockModuleForRuntime((BYTE *)pModuleBase, IID_ICLRRuntimeInfo, &pRuntimeInfo); - - IfFailThrow(hr); - - if (hr == S_OK) - { - // this runtime was the first one to lock the module - return; - } - - // another runtime has loaded this module so we have to block the load - WCHAR wzLoadedRuntimeVersion[_MAX_PATH]; - cchVersion = COUNTOF(wzLoadedRuntimeVersion); - IfFailThrow(pRuntimeInfo->GetVersionString(wzLoadedRuntimeVersion, &cchVersion)); - - ExternalLog(LF_LOADER, LL_ERROR, W("ERR: Rejecting IJW module because it is already loaded into runtime version %s in this process."), wzLoadedRuntimeVersion); - COMPlusThrow(kFileLoadException, IDS_EE_IJWLOAD_MULTIRUNTIME_DISALLOWED, wzThisRuntimeVersion, wzLoadedRuntimeVersion); -} - -// We don't allow loading IJW and C++/CLI pure images built against <=2.0 if legacy APIs are not bound to this -// runtime. For IJW images built against >2.0, we don't allow the load if the image has already been loaded by -// another runtime in this process. -void PEFile::CheckForDisallowedInProcSxSLoad() -{ - STANDARD_VM_CONTRACT; - - // have we checked this one before? - if (!IsInProcSxSLoadVerified()) - { - CheckForDisallowedInProcSxSLoadWorker(); - - // if no exception was thrown, remember the fact that we don't have to do the check again - SetInProcSxSLoadVerified(); - } -} - -#else // CROSSGEN_COMPILE - -void PEFile::CheckForDisallowedInProcSxSLoad() -{ - // Noop for crossgen -} - -#endif // CROSSGEN_COMPILE - -#endif // FEATURE_MIXEDMODE //----------------------------------------------------------------------------------------------------- @@ -501,12 +292,6 @@ void PEFile::LoadLibrary(BOOL allowNativeSkip/*=TRUE*/) // if allowNativeSkip==F // See if we've already loaded it. if (CheckLoaded(allowNativeSkip)) { -#ifdef FEATURE_MIXEDMODE - // Prevent loading C++/CLI images into multiple runtimes in the same process. Note that if ILOnly images - // stop being LoadLibrary'ed, the check for pure 2.0 C++/CLI images will need to be done somewhere else. - if (!IsIntrospectionOnly()) - CheckForDisallowedInProcSxSLoad(); -#endif // FEATURE_MIXEDMODE RETURN; } @@ -597,11 +382,6 @@ void PEFile::LoadLibrary(BOOL allowNativeSkip/*=TRUE*/) // if allowNativeSkip==F } } -#ifdef FEATURE_MIXEDMODE - // Prevent loading C++/CLI images into multiple runtimes in the same process. Note that if ILOnly images - // stop being LoadLibrary'ed, the check for pure 2.0 C++/CLI images will need to be done somewhere else. - CheckForDisallowedInProcSxSLoad(); -#endif // FEATURE_MIXEDMODE RETURN; } @@ -2538,85 +2318,6 @@ PEAssembly *PEAssembly::DoOpenMemory( } #endif // !CROSSGEN_COMPILE -#if defined(FEATURE_MIXEDMODE) && !defined(CROSSGEN_COMPILE) -// Use for main exe loading -// This is also used for "spontaneous" (IJW) dll loading where -// we need to deliver DllMain callbacks, but we should eliminate this case - -/* static */ -PEAssembly *PEAssembly::OpenHMODULE(HMODULE hMod, - IAssembly *pFusionAssembly, - IBindResult *pNativeFusionAssembly, - IFusionBindLog *pFusionLog/*=NULL*/, - BOOL isIntrospectionOnly/*=FALSE*/) -{ - STANDARD_VM_CONTRACT; - - PEAssembly *result = NULL; - - ETWOnStartup (OpenHModule_V1, OpenHModuleEnd_V1); - - EX_TRY - { - result = DoOpenHMODULE(hMod, pFusionAssembly, pNativeFusionAssembly, pFusionLog, isIntrospectionOnly); - } - EX_HOOK - { - Exception *ex = GET_EXCEPTION(); - - // Rethrow non-transient exceptions as file load exceptions with proper - // context - if (!ex->IsTransient()) - EEFileLoadException::Throw(pFusionAssembly, NULL, ex->GetHR(), ex); - } - EX_END_HOOK; - return result; -} - -// Thread stress -class DoOpenHMODULEStress : APIThreadStress -{ -public: - HMODULE hMod; - IAssembly *pFusionAssembly; - IBindResult *pNativeFusionAssembly; - IFusionBindLog *pFusionLog; - DoOpenHMODULEStress(HMODULE hMod, IAssembly *pFusionAssembly, IBindResult *pNativeFusionAssembly, IFusionBindLog *pFusionLog) - : hMod(hMod), pFusionAssembly(pFusionAssembly), pNativeFusionAssembly(pNativeFusionAssembly),pFusionLog(pFusionLog) {LIMITED_METHOD_CONTRACT;} - void Invoke() - { - WRAPPER_NO_CONTRACT; - PEAssemblyHolder result(PEAssembly::OpenHMODULE(hMod, pFusionAssembly,pNativeFusionAssembly, pFusionLog, FALSE)); - } -}; - -/* static */ -PEAssembly *PEAssembly::DoOpenHMODULE(HMODULE hMod, - IAssembly *pFusionAssembly, - IBindResult *pNativeFusionAssembly, - IFusionBindLog *pFusionLog, - BOOL isIntrospectionOnly/*=FALSE*/) -{ - CONTRACT(PEAssembly *) - { - PRECONDITION(CheckPointer(hMod)); - PRECONDITION(CheckPointer(pFusionAssembly)); - PRECONDITION(CheckPointer(pNativeFusionAssembly,NULL_OK)); - POSTCONDITION(CheckPointer(RETVAL)); - THROWS; - GC_TRIGGERS; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM();); - } - CONTRACT_END; - - DoOpenHMODULEStress ts(hMod, pFusionAssembly, pNativeFusionAssembly, pFusionLog); - - PEImageHolder image(PEImage::LoadImage(hMod)); - - RETURN new PEAssembly(image, NULL, pFusionAssembly, pNativeFusionAssembly, NULL, pFusionLog, NULL, NULL, FALSE, isIntrospectionOnly); -} -#endif // FEATURE_MIXEDMODE && !CROSSGEN_COMPILE PEAssembly* PEAssembly::Open(CoreBindResult* pBindResult, diff --git a/src/vm/pefile.h b/src/vm/pefile.h index 697ce03749..421297303c 100644 --- a/src/vm/pefile.h +++ b/src/vm/pefile.h @@ -136,14 +136,6 @@ private: public: void LoadLibrary(BOOL allowNativeSkip = TRUE); -#ifdef FEATURE_MIXEDMODE -protected: - // Returns TRUE if this file references managed CRT (msvcmNN*). - BOOL ReferencesManagedCRT(); - - // Checks for unsupported loads of C++/CLI assemblies into multiple runtimes in this process. - void CheckForDisallowedInProcSxSLoad(); -#endif // FEATURE_MIXEDMODE private: void CheckForDisallowedInProcSxSLoadWorker(); diff --git a/src/vm/peimage.cpp b/src/vm/peimage.cpp index ed1c77b203..508f368e0e 100644 --- a/src/vm/peimage.cpp +++ b/src/vm/peimage.cpp @@ -28,10 +28,6 @@ CrstStatic PEImage::s_hashLock; PtrHashMap *PEImage::s_Images = NULL; -#ifdef FEATURE_MIXEDMODE -CrstStatic PEImage::s_ijwHashLock; -PtrHashMap *PEImage::s_ijwFixupDataHash; -#endif extern LocaleID g_lcid; // fusion path comparison lcid @@ -58,12 +54,6 @@ void PEImage::Startup() LockOwner lock = { &s_hashLock, IsOwnerOfCrst }; s_Images = ::new PtrHashMap; s_Images->Init(CompareImage, FALSE, &lock); -#ifdef FEATURE_MIXEDMODE - s_ijwHashLock.Init(CrstIJWHash, CRST_REENTRANCY); - LockOwner ijwLock = { &s_ijwHashLock, IsOwnerOfCrst }; - s_ijwFixupDataHash = ::new PtrHashMap; - s_ijwFixupDataHash->Init(CompareIJWDataBase, FALSE, &ijwLock); -#endif PEImageLayout::Startup(); #ifdef FEATURE_USE_LCID g_lcid = MAKELCID(LOCALE_INVARIANT, SORT_DEFAULT); @@ -226,22 +216,6 @@ PEImage::~PEImage() } -#ifdef FEATURE_MIXEDMODE -/* static */ -BOOL PEImage::CompareIJWDataBase(UPTR base, UPTR mapping) -{ - CONTRACTL { - PRECONDITION(CheckStartup()); - PRECONDITION(CheckPointer((BYTE *) (base<<1))); - PRECONDITION(CheckPointer((IJWFixupData *)mapping)); - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } CONTRACTL_END; - - return ((BYTE *) (base<<1) == ((IJWFixupData*)mapping)->GetBase()); -} -#endif // FEATURE_MIXEDMODE // Thread stress #if 0 @@ -734,148 +708,6 @@ void DECLSPEC_NORETURN PEImage::ThrowFormat(HRESULT hrError) -#if defined(FEATURE_MIXEDMODE) && !defined(CROSSGEN_COMPILE) - -//may outlive PEImage -PEImage::IJWFixupData::IJWFixupData(void *pBase) - : m_lock(CrstIJWFixupData), - m_base(pBase), m_flags(0),m_DllThunkHeap(NULL),m_iNextFixup(0),m_iNextMethod(0) -{ - WRAPPER_NO_CONTRACT; -} - -PEImage::IJWFixupData::~IJWFixupData() -{ - WRAPPER_NO_CONTRACT; - if (m_DllThunkHeap) - delete m_DllThunkHeap; -} - - -// Self-initializing accessor for m_DllThunkHeap -LoaderHeap *PEImage::IJWFixupData::GetThunkHeap() -{ - CONTRACT (LoaderHeap *) - { - INSTANCE_CHECK; - THROWS; - GC_NOTRIGGER; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM()); - POSTCONDITION(CheckPointer(RETVAL)); - } - CONTRACT_END - - if (!m_DllThunkHeap) - { - size_t * pPrivatePCLBytes = NULL; - size_t * pGlobalPCLBytes = NULL; - -#ifdef PROFILING_SUPPORTED - pPrivatePCLBytes = &(GetPerfCounters().m_Loading.cbLoaderHeapSize); -#endif - - LoaderHeap *pNewHeap = new LoaderHeap(VIRTUAL_ALLOC_RESERVE_GRANULARITY, // DWORD dwReserveBlockSize - 0, // DWORD dwCommitBlockSize - pPrivatePCLBytes, - ThunkHeapStubManager::g_pManager->GetRangeList(), - TRUE); // BOOL fMakeExecutable - - if (FastInterlockCompareExchangePointer((PVOID*)&m_DllThunkHeap, (VOID*)pNewHeap, (VOID*)0) != 0) - { - delete pNewHeap; - } - } - - RETURN m_DllThunkHeap; -} - -void PEImage::IJWFixupData::MarkMethodFixedUp(COUNT_T iFixup, COUNT_T iMethod) -{ - LIMITED_METHOD_CONTRACT; - // supports only sequential fixup/method - _ASSERTE( (iFixup == m_iNextFixup+1 && iMethod ==0) || //first method of the next fixup or - (iFixup == m_iNextFixup && iMethod == m_iNextMethod) ); //the method that was next to fixup - - m_iNextFixup = iFixup; - m_iNextMethod = iMethod+1; -} - -BOOL PEImage::IJWFixupData::IsMethodFixedUp(COUNT_T iFixup, COUNT_T iMethod) -{ - LIMITED_METHOD_CONTRACT; - if (iFixup < m_iNextFixup) - return TRUE; - if (iFixup > m_iNextFixup) - return FALSE; - if (iMethod < m_iNextMethod) - return TRUE; - - return FALSE; -} - -/*static */ -PTR_LoaderHeap PEImage::GetDllThunkHeap(void *pBase) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - } - CONTRACTL_END; - return GetIJWData(pBase)->GetThunkHeap(); -} - -/* static */ -PEImage::IJWFixupData *PEImage::GetIJWData(void *pBase) -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM();); - } CONTRACTL_END - - // Take the IJW hash lock - CrstHolder hashLockHolder(&s_ijwHashLock); - - // Try to find the data - IJWFixupData *pData = (IJWFixupData *)s_ijwFixupDataHash->LookupValue((UPTR) pBase, pBase); - - // No data, must create - if ((UPTR)pData == (UPTR)INVALIDENTRY) - { - pData = new IJWFixupData(pBase); - s_ijwFixupDataHash->InsertValue((UPTR) pBase, pData); - } - - // Return the new data - return (pData); -} - -/* static */ -void PEImage::UnloadIJWModule(void *pBase) -{ - CONTRACTL { - NOTHROW; - GC_TRIGGERS; - MODE_ANY; - } CONTRACTL_END - - // Take the IJW hash lock - CrstHolder hashLockHolder(&s_ijwHashLock); - - // Try to delete the hash entry - IJWFixupData *pData = (IJWFixupData *)s_ijwFixupDataHash->DeleteValue((UPTR) pBase, pBase); - - // Now delete the data - if ((UPTR)pData != (UPTR)INVALIDENTRY) - delete pData; - -} - -#endif // FEATURE_MIXEDMODE && !CROSSGEN_COMPILE #endif // #ifndef DACCESS_COMPILE diff --git a/src/vm/peimage.h b/src/vm/peimage.h index 2c8f834036..3245621610 100644 --- a/src/vm/peimage.h +++ b/src/vm/peimage.h @@ -290,9 +290,6 @@ private: }; static BOOL CompareImage(UPTR image1, UPTR image2); -#ifdef FEATURE_MIXEDMODE - static BOOL CompareIJWDataBase(UPTR base, UPTR mapping); -#endif // FEATURE_MIXEDMODE void DECLSPEC_NORETURN ThrowFormat(HRESULT hr); @@ -364,49 +361,6 @@ private: BOOL m_bSignatureInfoCached; HRESULT m_hrSignatureInfoStatus; DWORD m_dwSignatureInfo; -#ifdef FEATURE_MIXEDMODE - //@TODO:workaround: Remove this when we have one PEImage per mapped image, - //@TODO:workaround: and move the lock there - // This is for IJW thunk initialization, as it is no longer guaranteed - // that the initialization will occur under the loader lock. - static CrstStatic s_ijwHashLock; - static PtrHashMap *s_ijwFixupDataHash; - -public: - class IJWFixupData - { - private: - Crst m_lock; - void *m_base; - DWORD m_flags; - PTR_LoaderHeap m_DllThunkHeap; - - // the fixup for the next iteration in FixupVTables - // we use it to make sure that we do not try to fix up the same entry twice - // if there was a pass that was aborted in the middle - COUNT_T m_iNextFixup; - COUNT_T m_iNextMethod; - - enum { - e_FIXED_UP = 0x1 - }; - - public: - IJWFixupData(void *pBase); - ~IJWFixupData(); - void *GetBase() { LIMITED_METHOD_CONTRACT; return m_base; } - Crst *GetLock() { LIMITED_METHOD_CONTRACT; return &m_lock; } - BOOL IsFixedUp() { LIMITED_METHOD_CONTRACT; return m_flags & e_FIXED_UP; } - void SetIsFixedUp() { LIMITED_METHOD_CONTRACT; m_flags |= e_FIXED_UP; } - PTR_LoaderHeap GetThunkHeap(); - void MarkMethodFixedUp(COUNT_T iFixup, COUNT_T iMethod); - BOOL IsMethodFixedUp(COUNT_T iFixup, COUNT_T iMethod); - }; - - static IJWFixupData *GetIJWData(void *pBase); - static PTR_LoaderHeap GetDllThunkHeap(void *pBase); - static void UnloadIJWModule(void *pBase); -#endif //FEATURE_MIXEDMODE private: DWORD m_dwPEKind; DWORD m_dwMachine; diff --git a/src/vm/peimagelayout.cpp b/src/vm/peimagelayout.cpp index 9e258f4e8a..fb2ce5760c 100644 --- a/src/vm/peimagelayout.cpp +++ b/src/vm/peimagelayout.cpp @@ -409,34 +409,6 @@ MappedImageLayout::MappedImageLayout(HANDLE hFile, PEImage* pOwner) } #endif // _DEBUG -#ifdef FEATURE_MIXEDMODE - // - // For our preliminary loads, we don't want to take the preferred base address. We want to leave - // that open for a LoadLibrary. So, we first a phony MapViewOfFile to occupy the base - // address temporarily. - // - // Note that this is bad if we are racing another thread which is doing a LoadLibrary. We - // may want to tweak this logic, but it's pretty difficult to tell MapViewOfFileEx to map - // a file NOT at its preferred base address. Hopefully the ulimate solution here will be - // just mapping the file once. - // - // There are two distinct cases that this code takes care of: - // - // * NGened IL-only assembly: The IL image will get mapped here and LoadLibrary will be called - // on the NGen image later. If we need to, we can avoid creating the fake view on VISTA in this - // case. ASLR will map the IL image and NGen image at different addresses for free. - // - // * Mixed-mode assembly (either NGened or not): The mixed-mode image will get mapped here and - // LoadLibrary will be called on the same image again later. Note that ASLR does not help - // in this case. The fake view has to be created even on VISTA in this case to avoid relocations. - // - CLRMapViewHolder temp; - - // We don't want to map at the prefered address, so have the temporary view take it. - temp.Assign(CLRMapViewOfFile(m_FileMap, 0, 0, 0, 0)); - if (temp == NULL) - ThrowLastError(); -#endif // FEATURE_MIXEDMODE m_FileView.Assign(CLRMapViewOfFile(m_FileMap, 0, 0, 0, 0)); if (m_FileView == NULL) ThrowLastError(); diff --git a/src/vm/umthunkhash.cpp b/src/vm/umthunkhash.cpp deleted file mode 100644 index ab2732e03c..0000000000 --- a/src/vm/umthunkhash.cpp +++ /dev/null @@ -1,171 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. -// -// File: umthunkhash.cpp -// - -// - - -#include "common.h" -#include "umthunkhash.h" - -#ifdef FEATURE_MIXEDMODE - -UMThunkHash::UMThunkHash(Module *pModule, AppDomain *pDomain) : - CClosedHashBase( -#ifdef _DEBUG - 3, -#else - 17, // CClosedHashTable will grow as necessary -#endif - - sizeof(UTHEntry), - FALSE - ), - m_crst(CrstUMThunkHash) - -{ - WRAPPER_NO_CONTRACT; - m_pModule = pModule; - m_dwAppDomainId = pDomain->GetId(); -} - -UMThunkHash::~UMThunkHash() -{ - CONTRACT_VOID - { - NOTHROW; - DESTRUCTOR_CHECK; - GC_TRIGGERS; - FORBID_FAULT; - MODE_ANY; - } - CONTRACT_END - -#ifndef DACCESS_COMPILE - UTHEntry *phe = (UTHEntry*)GetFirst(); - while (phe) { - DeleteExecutable(phe->m_pUMEntryThunk); - phe->m_UMThunkMarshInfo.~UMThunkMarshInfo(); - phe = (UTHEntry*)GetNext((BYTE*)phe); - } -#endif - RETURN; -} - -LPVOID UMThunkHash::GetUMThunk(LPVOID pTarget, PCCOR_SIGNATURE pSig, DWORD cSig) -{ - CONTRACT (LPVOID) - { - INSTANCE_CHECK; - THROWS; - GC_TRIGGERS; - MODE_ANY; - POSTCONDITION(CheckPointer(RETVAL, NULL_OK)); - } - CONTRACT_END - - UTHEntry *phe; - CrstHolder ch(&m_crst); - - UTHKey key; - key.m_pTarget = pTarget; - key.m_pSig = pSig; - key.m_cSig = cSig; - - phe =(UTHEntry *)Find((LPVOID)&key); -#ifndef DACCESS_COMPILE - if (phe == NULL) - { - NewExecutableHolder<UMEntryThunk> uET= new (executable) UMEntryThunk(); - - bool bNew = FALSE; - phe = (UTHEntry *)FindOrAdd((LPVOID)&key,bNew); - if (phe != NULL) - { - _ASSERTE(bNew); // we are under lock - - phe->m_pUMEntryThunk=uET.Extract(); - - //nothrow - phe->m_UMThunkMarshInfo.LoadTimeInit(Signature(pSig, cSig), m_pModule); - phe->m_pUMEntryThunk->LoadTimeInit((PCODE)pTarget, NULL, &(phe->m_UMThunkMarshInfo), - MethodTable::GetMethodDescForSlotAddress((PCODE)pTarget), - m_dwAppDomainId); - - phe->m_key = key; - phe->m_status = USED; - } - } -#endif //DACESS_COMPILE - if (phe) - RETURN (LPVOID)(phe->m_pUMEntryThunk->GetCode()); - else - RETURN NULL; -} - - -unsigned int UMThunkHash::Hash(void const *pData) -{ - LIMITED_METHOD_CONTRACT; - UTHKey *pKey = (UTHKey*)pData; - return (ULONG)(size_t)(pKey->m_pTarget); -} - -inline unsigned int UMThunkHash::Compare( // 0, -1, or 1. - void const *pData, // Raw key data on lookup. - BYTE *pElement) // The element to compare data against. -{ - CONTRACTL - { - NOTHROW; - GC_TRIGGERS; - MODE_ANY; - } - CONTRACTL_END; - - UTHKey *pkey1 = (UTHKey*)pData; - UTHKey *pkey2 = &( ((UTHEntry*)pElement)->m_key ); - - if (pkey1->m_pTarget != pkey2->m_pTarget) - return 1; - - if (S_OK != MetaSig::CompareMethodSigsNT(pkey1->m_pSig, pkey1->m_cSig, m_pModule, NULL, pkey2->m_pSig, pkey2->m_cSig, m_pModule, NULL)) - return 1; - - return 0; -} - - - -CClosedHashBase::ELEMENTSTATUS UMThunkHash::Status( // The status of the entry. - BYTE *pElement) // The element to check. -{ - LIMITED_METHOD_CONTRACT; - return ((UTHEntry*)pElement)->m_status; -} - -//***************************************************************************** -// Sets the status of the given element. -//***************************************************************************** -void UMThunkHash::SetStatus( - BYTE *pElement, // The element to set status for. - ELEMENTSTATUS eStatus) // New status. -{ - LIMITED_METHOD_CONTRACT; - ((UTHEntry*)pElement)->m_status = eStatus; -} - -//***************************************************************************** -// Returns the internal key value for an element. -//***************************************************************************** -void *UMThunkHash::GetKey( // The data to hash on. - BYTE *pElement) // The element to return data ptr for. -{ - LIMITED_METHOD_CONTRACT; - return (BYTE*) &(((UTHEntry*)pElement)->m_key); -} - -#endif // FEATURE_MIXEDMODE diff --git a/src/vm/umthunkhash.h b/src/vm/umthunkhash.h deleted file mode 100644 index 343c55e344..0000000000 --- a/src/vm/umthunkhash.h +++ /dev/null @@ -1,87 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. -// -// File: umthunkhash.h -// - -// - - -#ifndef UMTHUNKHASH_H_ -#define UMTHUNKHASH_H_ -#include "dllimportcallback.h" - -#ifdef FEATURE_MIXEDMODE // IJW -// -// A hashtable for u->m thunks not represented in the fixup tables. -// -class UMThunkHash : public CClosedHashBase { - private: - //---------------------------------------------------- - // Hash key for CClosedHashBase - //---------------------------------------------------- - struct UTHKey { - LPVOID m_pTarget; - PCCOR_SIGNATURE m_pSig; - DWORD m_cSig; - }; - - //---------------------------------------------------- - // Hash entry for CClosedHashBase - //---------------------------------------------------- - struct UTHEntry { - UTHKey m_key; - ELEMENTSTATUS m_status; - UMEntryThunk *m_pUMEntryThunk; - UMThunkMarshInfo m_UMThunkMarshInfo; - }; - - public: - UMThunkHash(Module *pModule, AppDomain *pDomain); - ~UMThunkHash(); - LPVOID GetUMThunk(LPVOID pTarget, PCCOR_SIGNATURE pSig, DWORD cSig); - // *** OVERRIDES FOR CClosedHashBase ***/ - - //***************************************************************************** - // Hash is called with a pointer to an element in the table. You must override - // this method and provide a hash algorithm for your element type. - //***************************************************************************** - virtual unsigned int Hash( // The key value. - void const *pData); // Raw data to hash. - - //***************************************************************************** - // Compare is used in the typical memcmp way, 0 is eqaulity, -1/1 indicate - // direction of miscompare. In this system everything is always equal or not. - //***************************************************************************** - inline unsigned int Compare( // 0, -1, or 1. - void const *pData, // Raw key data on lookup. - BYTE *pElement); // The element to compare data against. - - //***************************************************************************** - // Return true if the element is free to be used. - //***************************************************************************** - virtual ELEMENTSTATUS Status( // The status of the entry. - BYTE *pElement); // The element to check. - - //***************************************************************************** - // Sets the status of the given element. - //***************************************************************************** - virtual void SetStatus( - BYTE *pElement, // The element to set status for. - ELEMENTSTATUS eStatus); // New status. - - //***************************************************************************** - // Returns the internal key value for an element. - //***************************************************************************** - virtual void *GetKey( // The data to hash on. - BYTE *pElement); // The element to return data ptr for. - -protected: - Module *m_pModule; - ADID m_dwAppDomainId; - Crst m_crst; -}; - -#endif -#endif |