summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/debug/daccess/nidump.cpp6
-rw-r--r--src/debug/daccess/request.cpp3
-rw-r--r--src/inc/jithelpers.h5
-rw-r--r--src/utilcode/pedecoder.cpp2
-rw-r--r--src/vm/amd64/UMThunkStub.asm43
-rw-r--r--src/vm/appdomain.cpp172
-rw-r--r--src/vm/appdomain.hpp9
-rw-r--r--src/vm/arm/asmhelpers.asm40
-rw-r--r--src/vm/assembly.cpp31
-rw-r--r--src/vm/assembly.hpp4
-rw-r--r--src/vm/assemblyspec.cpp40
-rw-r--r--src/vm/assemblyspec.hpp3
-rw-r--r--src/vm/ceeload.cpp907
-rw-r--r--src/vm/ceeload.h44
-rw-r--r--src/vm/ceemain.cpp415
-rw-r--r--src/vm/common.h1
-rw-r--r--src/vm/dllimport.cpp260
-rw-r--r--src/vm/dllimport.h9
-rw-r--r--src/vm/domainfile.cpp36
-rw-r--r--src/vm/domainfile.h3
-rw-r--r--src/vm/i386/asmconstants.h10
-rw-r--r--src/vm/i386/asmhelpers.asm102
-rw-r--r--src/vm/jithelpers.cpp35
-rw-r--r--src/vm/jitinterface.cpp21
-rw-r--r--src/vm/marshalnative.cpp48
-rw-r--r--src/vm/method.cpp31
-rw-r--r--src/vm/method.hpp16
-rw-r--r--src/vm/methodtablebuilder.cpp8
-rw-r--r--src/vm/mixedmode.hpp139
-rw-r--r--src/vm/pefile.cpp299
-rw-r--r--src/vm/pefile.h8
-rw-r--r--src/vm/peimage.cpp168
-rw-r--r--src/vm/peimage.h46
-rw-r--r--src/vm/peimagelayout.cpp28
-rw-r--r--src/vm/umthunkhash.cpp171
-rw-r--r--src/vm/umthunkhash.h87
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, &param);
-}
-
-// <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, &param)
- {
- 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