summaryrefslogtreecommitdiff
path: root/src/vm/ceemain.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/ceemain.cpp')
-rw-r--r--src/vm/ceemain.cpp1830
1 files changed, 91 insertions, 1739 deletions
diff --git a/src/vm/ceemain.cpp b/src/vm/ceemain.cpp
index ca819ecbfd..6b0c0dfbba 100644
--- a/src/vm/ceemain.cpp
+++ b/src/vm/ceemain.cpp
@@ -39,25 +39,25 @@
//
//*************************************************************************************************
//
-// * Introduction to the rutnime file:../../doc/BookOfTheRuntime/Introduction/BOTR%20Introduction.docx
+// * Introduction to the runtime file:../../Documentation/botr/botr-faq.md
//
// #MajorDataStructures. The major data structures associated with the runtime are
// * code:Thread (see file:threads.h#ThreadClass) - the additional thread state the runtime needs.
// * code:AppDomain - The managed version of a process
-// * code:Assembly - The unit of deployment and versioing (may be several DLLs but often is only one).
-// * code:Module -represents a Module (DLL or EXE).
+// * code:Assembly - The unit of deployment and versioning (may be several DLLs but often is only one).
+// * code:Module - represents a Module (DLL or EXE).
// * code:MethodTable - represents the 'hot' part of a type (needed during normal execution)
// * code:EEClass - represents the 'cold' part of a type (used during compilation, interop, ...)
// * code:MethodDesc - represents a Method
// * code:FieldDesc - represents a Field.
-// * code:Object - represents a object on the GC heap alloated with code:Alloc
+// * code:Object - represents a object on the GC heap allocated with code:Alloc
//
// * ECMA specifications
// * Partition I Concepts
// http://download.microsoft.com/download/D/C/1/DC1B219F-3B11-4A05-9DA3-2D0F98B20917/Partition%20I%20Architecture.doc
// * Partition II Meta Data
// http://download.microsoft.com/download/D/C/1/DC1B219F-3B11-4A05-9DA3-2D0F98B20917/Partition%20II%20Metadata.doc
-// * Parition III IL
+// * Partition III IL
// http://download.microsoft.com/download/D/C/1/DC1B219F-3B11-4A05-9DA3-2D0F98B20917/Partition%20III%20CIL.doc
//
// * Serge Liden (worked on the CLR and owned ILASM / ILDASM for a long time wrote a good book on IL
@@ -76,7 +76,7 @@
// * code:ICorJitCompiler#EEToJitInterface - This is the interface from the the EE to the Just in time (JIT)
// compiler. The interface to the JIT is relatively simple (compileMethod), however the EE provides a
// rich set of callbacks so the JIT can get all the information it needs. See also
-// file:../../doc/BookOfTheRuntime/JIT/JIT%20Design.doc for general information on the JIT.
+// file:../../Documentation/botr/ryujit-overview.md for general information on the JIT.
//
// * code:VirtualCallStubManager - This is the main class that implements interface dispatch
//
@@ -85,36 +85,22 @@
// and will call the JIT compiler if the code does not yet exist.
//
// * NGEN - NGen stands for Native code GENeration and it is the runtime way of precomiling IL and IL
-// Meta-data into native code and runtime data structures. See
-// file:../../doc/BookOfTheRuntime/NGEN/NGENDesign.doc for an overview. At compilation time the most
+// Meta-data into native code and runtime data structures. At compilation time the most
// fundamental data structures is the code:ZapNode which represents something that needs to go into the
// NGEN image.
//
// * What is cooperative / preemtive mode ? file:threads.h#CooperativeMode and
-// file:threads.h#SuspendingTheRuntime
-// * Garbage collection - file:gc.cpp#Overview
+// file:threads.h#SuspendingTheRuntime and file:../../Documentation/botr/threading.md
+// * Garbage collection - file:gc.cpp#Overview and file:../../Documentation/botr/garbage-collection.md
// * code:AppDomain - The managed version of a process.
-// * Calling Into the runtime (FCALLs QCalls) file:../../doc/BookOfTheRuntime/mscorlib/mscorlibDesign.doc
-// * Exceptions - file:../../doc/BookOfTheRuntime/ManagedEH\Design.doc. The most important routine to start
-// with is code:COMPlusFrameHandler which is the routine that we hook up to get called when an unanaged
+// * Calling Into the runtime (FCALLs QCalls) file:../../Documentation/botr/mscorlib.md
+// * Exceptions - file:../../Documentation/botr/exceptions.md. The most important routine to start
+// with is code:COMPlusFrameHandler which is the routine that we hook up to get called when an unmanaged
// exception happens.
-// * Constrain Execution Regions (reliability) file:../../doc/BookOfTheRuntime/CER/CERDesign.doc)
-// * Assembly Loading file:../../doc/BookOfTheRuntime/AssemblyLoader/AssemblyLoader.doc
-// * Fusion and loading files file:../../doc/BookOfTheRuntime/AssemblyLoader/FusionDesign.doc
-// * Strings file:../../doc/BookOfTheRuntime/BCL/SystemStringDesign.doc
-// * Profiling file:../../doc/BookOfTheRuntime/DiagnosticServices/ProfilingAPIDesign.doc
-// * Remoting file:../../doc/BookOfTheRuntime/EERemotingSupport/RemotingDesign.doc
-// * Managed Debug Assitants file:../../doc/BookOfTheRuntime/MDA/MDADesign.doc
+// * Assembly Loading file:../../Documentation/botr/type-loader.md
+// * Profiling file:../../Documentation/botr/profiling.md and file:../../Documentation/botr/profilability.md
// * FCALLS QCALLS (calling into the runtime from managed code)
-// file:../../doc/BookOfTheRuntime/Mscorlib/MscorlibDesign.doc
-// * Reflection file:../../doc/BookOfTheRuntime/Reflection/ReflectionDesign.doc
-// * Security
-// * file:../../doc/BookOfTheRuntime/RuntimeSecurity/RuntimeSecurityDesign.doc
-// * file:../../doc/BookOfTheRuntime/LoadtimeSecurity/DeclarativeSecurity-Design.doc
-// * file:../../doc/BookOfTheRuntime/LoadtimeSecurity/StrongName.doc
-// * file:../../doc/BookOfTheRuntime/RuntimeSecurity/ClickOnce Activation.doc
-// * file:../../doc/BookOfTheRuntime/RuntimeSecurity/Cryptography.doc
-// * file:../../doc/BookOfTheRuntime/RuntimeSecurity/DemandEvalDesign.doc
+// file:../../Documentation/botr/mscorlib.md
// * Event Tracing for Windows
// * file:../inc/eventtrace.h#EventTracing -
// * This is the main file dealing with event tracing in CLR
@@ -158,13 +144,9 @@
#include "eedbginterfaceimpl.h"
#include "debugdebugger.h"
#include "cordbpriv.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "comdelegate.h"
#include "appdomain.hpp"
#include "perfcounters.h"
-#include "rwlock.h"
#ifdef FEATURE_IPCMAN
#include "ipcmanagerinterface.h"
#endif // FEATURE_IPCMAN
@@ -213,10 +195,6 @@
#include "bbsweep.h"
-#ifndef FEATURE_CORECLR
-#include <metahost.h>
-#include "assemblyusagelogmanager.h"
-#endif
#ifdef FEATURE_COMINTEROP
#include "runtimecallablewrapper.h"
@@ -244,19 +222,15 @@
#include "interpreter.h"
#endif // FEATURE_INTERPRETER
-#ifndef FEATURE_FUSION
#include "../binder/inc/coreclrbindercommon.h"
-#endif // !FEATURE_FUSION
-#ifdef FEATURE_UEF_CHAINMANAGER
-// This is required to register our UEF callback with the UEF chain manager
-#include <mscoruefwrapper.h>
-#endif // FEATURE_UEF_CHAINMANAGER
#ifdef FEATURE_PERFMAP
#include "perfmap.h"
#endif
+#include "eventpipe.h"
+
#ifndef FEATURE_PAL
// Included for referencing __security_cookie
#include "process.h"
@@ -275,21 +249,7 @@ static HRESULT GetThreadUICultureNames(__inout StringArrayList* pCultureNames);
#endif // !CROSSGEN_COMPILE
HRESULT EEStartup(COINITIEE fFlags);
-#ifdef FEATURE_FUSION
-extern "C" HRESULT STDMETHODCALLTYPE InitializeFusion();
-#endif
-#ifdef FEATURE_MIXEDMODE
-HRESULT PrepareExecuteDLLForThunk(HINSTANCE hInst,
- DWORD dwReason,
- LPVOID lpReserved);
-#endif // FEATURE_MIXEDMODE
-#ifndef FEATURE_CORECLR
-BOOL STDMETHODCALLTYPE ExecuteDLL(HINSTANCE hInst,
- DWORD dwReason,
- LPVOID lpReserved,
- BOOL fFromThunk);
-#endif // !FEATURE_CORECLR
BOOL STDMETHODCALLTYPE ExecuteEXE(HMODULE hMod);
BOOL STDMETHODCALLTYPE ExecuteEXE(__in LPWSTR pImageNameIn);
@@ -305,12 +265,6 @@ extern "C" HRESULT __cdecl CorDBGetInterface(DebugInterface** rcInterface);
#endif // !CROSSGEN_COMPILE
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
-
-// Pointer to the activated CLR interface provided by the shim.
-ICLRRuntimeInfo *g_pCLRRuntime = NULL;
-
-#endif // !FEATURE_CORECLR && !CROSSGEN_COMPILE
extern "C" IExecutionEngine* __stdcall IEE();
@@ -391,7 +345,7 @@ HRESULT EnsureEEStarted(COINITIEE flags)
{
BEGIN_ENTRYPOINT_NOTHROW;
-#if defined(FEATURE_CORECLR) && defined(FEATURE_APPX) && !defined(CROSSGEN_COMPILE)
+#if defined(FEATURE_APPX) && !defined(CROSSGEN_COMPILE)
STARTUP_FLAGS startupFlags = CorHost2::GetStartupFlags();
// On CoreCLR, the host is in charge of determining whether the process is AppX or not.
AppX::SetIsAppXProcess(!!(startupFlags & STARTUP_APPX_APP_MODEL));
@@ -403,15 +357,6 @@ HRESULT EnsureEEStarted(COINITIEE flags)
REGUTIL::InitOptionalConfigCache();
#endif
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostTaskManager *pHostTaskManager = CorHost2::GetHostTaskManager();
- if (pHostTaskManager)
- {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- pHostTaskManager->BeginThreadAffinity();
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
BOOL bStarted=FALSE;
@@ -442,14 +387,6 @@ HRESULT EnsureEEStarted(COINITIEE flags)
}
}
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (pHostTaskManager)
- {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- pHostTaskManager->EndThreadAffinity();
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
#ifdef FEATURE_TESTHOOKS
if(bStarted)
TESTHOOKCALL(RuntimeStarted(RTS_INITIALIZED));
@@ -528,58 +465,7 @@ static BOOL WINAPI DbgCtrlCHandler(DWORD dwCtrlType)
// A host can specify that it only wants one version of hosting interface to be used.
BOOL g_singleVersionHosting;
-#ifndef FEATURE_CORECLR
-HRESULT STDMETHODCALLTYPE
-SetRuntimeInfo(
- IUnknown * pUnk,
- STARTUP_FLAGS dwStartupFlags,
- LPCWSTR pwzHostConfig,
- const CoreClrCallbacks ** ppClrCallbacks)
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- ENTRY_POINT;
- PRECONDITION(CheckPointer(pUnk));
- PRECONDITION(CheckPointer(pwzHostConfig, NULL_OK));
- } CONTRACTL_END;
-
- ICLRRuntimeInfo *pRuntime;
- HRESULT hr;
-
- IfFailGo(pUnk->QueryInterface(IID_ICLRRuntimeInfo, (LPVOID *)&pRuntime));
-
- IfFailGo(CorHost2::SetFlagsAndHostConfig(dwStartupFlags, pwzHostConfig, FALSE));
- if (InterlockedCompareExchangeT(&g_pCLRRuntime, pRuntime, NULL) != NULL)
- {
- // already set, release this one
- pRuntime->Release();
- }
- *ppClrCallbacks = &GetClrCallbacks();
-
-ErrExit:
- return hr;
-}
-#endif // !FEATURE_CORECLR
-
-#ifndef FEATURE_CORECLR
-HRESULT InitializeHostConfigFile()
-{
- CONTRACTL {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(return E_OUTOFMEMORY);
- } CONTRACTL_END;
-
- g_pszHostConfigFile = CorHost2::GetHostConfigFile();
- g_dwHostConfigFile = (g_pszHostConfigFile == NULL ? 0 : wcslen(g_pszHostConfigFile));
-
- return S_OK;
-}
-#endif // !FEATURE_CORECLR
void InitializeStartupFlags()
{
@@ -591,56 +477,15 @@ void InitializeStartupFlags()
STARTUP_FLAGS flags = CorHost2::GetStartupFlags();
-#ifndef FEATURE_CORECLR
- // If we are running under a requested performance default mode, honor any changes to startup flags
- // In the future, we could make this conditional on the host telling us which subset of flags is
- // valid to override. See file:PerfDefaults.h
- flags = PerformanceDefaults::GetModifiedStartupFlags(flags);
-#endif // !FEATURE_CORECLR
if (flags & STARTUP_CONCURRENT_GC)
g_IGCconcurrent = 1;
else
g_IGCconcurrent = 0;
-#ifndef FEATURE_CORECLR // TODO: We can remove this. Retaining it now just to be safe
- if (flags & STARTUP_SINGLE_VERSION_HOSTING_INTERFACE)
- {
- g_singleVersionHosting = TRUE;
- }
-
-#ifndef FEATURE_CORECLR
- g_pConfig->SetDisableCommitThreadStack(!CLRHosted() || (flags & STARTUP_DISABLE_COMMITTHREADSTACK));
-#else
- g_pConfig->SetDisableCommitThreadStack(true);
-#endif
-
- if(flags & STARTUP_LEGACY_IMPERSONATION)
- g_pConfig->SetLegacyImpersonationPolicy();
-
- if(flags & STARTUP_ALWAYSFLOW_IMPERSONATION)
- g_pConfig->SetAlwaysFlowImpersonationPolicy();
-
- if(flags & STARTUP_HOARD_GC_VM)
- g_IGCHoardVM = 1;
- else
- g_IGCHoardVM = 0;
-
-#ifdef GCTRIMCOMMIT
- if (flags & STARTUP_TRIM_GC_COMMIT)
- g_IGCTrimCommit = 1;
- else
- g_IGCTrimCommit = 0;
-#endif
-
- if(flags & STARTUP_ETW)
- g_fEnableETW = TRUE;
-
- if(flags & STARTUP_ARM)
- g_fEnableARM = TRUE;
-#endif // !FEATURE_CORECLR
InitializeHeapType((flags & STARTUP_SERVER_GC) != 0);
+ g_heap_type = (flags & STARTUP_SERVER_GC) == 0 ? GC_HEAP_WKS : GC_HEAP_SVR;
#ifdef FEATURE_LOADER_OPTIMIZATION
g_dwGlobalSharePolicy = (flags&STARTUP_LOADER_OPTIMIZATION_MASK)>>1;
@@ -740,37 +585,23 @@ void InitGSCookie()
}
}
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
-void InitAssemblyUsageLogManager()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- } CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- g_pIAssemblyUsageLogGac = NULL;
-
- AssemblyUsageLogManager::Config config;
+Volatile<BOOL> g_bIsGarbageCollectorFullyInitialized = FALSE;
- config.wszLogDir = NULL;
- config.cLogBufferSize = 32768;
-#ifdef FEATURE_APPX
- config.uiLogRefreshInterval = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_NGenAssemblyUsageLogRefreshInterval);
-#endif
+void SetGarbageCollectorFullyInitialized()
+{
+ LIMITED_METHOD_CONTRACT;
- NewArrayHolder<WCHAR> szCustomLogDir(CLRConfig::GetConfigValue(CLRConfig::INTERNAL_NGenAssemblyUsageLog));
- config.wszLogDir = szCustomLogDir;
+ g_bIsGarbageCollectorFullyInitialized = TRUE;
+}
- AssemblyUsageLogManager::Init(&config);
+// Tells whether the garbage collector is fully initialized
+// Stronger than IsGCHeapInitialized
+BOOL IsGarbageCollectorFullyInitialized()
+{
+ LIMITED_METHOD_CONTRACT;
- // Once the logger is initialized, create a log object for logging GAC loads.
- AssemblyUsageLogManager::GetUsageLogForContext(W("fusion"), W("GAC"), &g_pIAssemblyUsageLogGac);
+ return g_bIsGarbageCollectorFullyInitialized;
}
-#endif
// ---------------------------------------------------------------------------
// %%Function: EEStartupHelper
@@ -845,10 +676,6 @@ void EEStartupHelper(COINITIEE fFlags)
if (!g_pConfig)
{
IfFailGo(EEConfig::Setup());
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
- IfFailGo(InitializeHostConfigFile());
- IfFailGo(g_pConfig->SetupConfiguration());
-#endif // !FEATURE_CORECLR && !CROSSGEN_COMPILE
}
#ifndef CROSSGEN_COMPILE
@@ -858,11 +685,6 @@ void EEStartupHelper(COINITIEE fFlags)
NumaNodeInfo::InitNumaNodeInfo();
CPUGroupInfo::EnsureInitialized();
-#ifndef FEATURE_CORECLR
- // Check in EEConfig whether a workload-specific set of performance defaults have been requested
- // This needs to be done before InitializeStartupFlags in case one is to be overridden
- PerformanceDefaults::InitializeForScenario(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_PerformanceScenario));
-#endif
// Initialize global configuration settings based on startup flags
// This needs to be done before the EE has started
@@ -897,10 +719,6 @@ void EEStartupHelper(COINITIEE fFlags)
#endif // CROSSGEN_COMPILE
-#ifndef FEATURE_CORECLR
- // Ensure initialization of Apphacks environment variables
- GetGlobalCompatibilityFlags();
-#endif // !FEATURE_CORECLR
#ifdef STRESS_LOG
if (REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_StressLog, g_pConfig->StressLog ()) != 0) {
@@ -935,15 +753,8 @@ void EEStartupHelper(COINITIEE fFlags)
#endif
// Fusion
-#ifdef FEATURE_FUSION
- {
- ETWOnStartup (FusionInit_V1, FusionInitEnd_V1);
- IfFailGoLog(InitializeFusion());
- }
-#else // FEATURE_FUSION
// Initialize the general Assembly Binder infrastructure
IfFailGoLog(CCoreCLRBinderHelper::Init());
-#endif // FEATURE_FUSION
if (g_pConfig != NULL)
{
@@ -988,21 +799,10 @@ void EEStartupHelper(COINITIEE fFlags)
#ifndef CROSSGEN_COMPILE
-#if defined(STRESS_HEAP) && defined(_DEBUG) && !defined(FEATURE_CORECLR)
- // TODO: is this still an issue?
- // There is a race that causes random AVs on dual proc boxes
- // that we suspect is due to memory coherancy problems (see Whidbey bug 2360)
- // Avoid the issue by making the box effectively single proc.
- if (GCStress<cfg_instr>::IsEnabled() &&
- g_SystemInfo.dwNumberOfProcessors > 1)
- SetProcessAffinityMask(GetCurrentProcess(),
- 1 << (DbgGetEXETimeStamp() % g_SystemInfo.dwNumberOfProcessors));
-#endif // STRESS_HEAP && _DEBUG && !FEATURE_CORECLR
#ifdef FEATURE_PREJIT
- // Initialize the sweeper thread. THis is violating our rules with hosting
- // so we only do it in the non-hosted case
- if (g_pConfig->GetZapBBInstr() != NULL && !CLRTaskHosted())
+ // Initialize the sweeper thread.
+ if (g_pConfig->GetZapBBInstr() != NULL)
{
DWORD threadID;
HANDLE hBBSweepThread = ::CreateThread(NULL,
@@ -1065,14 +865,14 @@ void EEStartupHelper(COINITIEE fFlags)
#ifndef CROSSGEN_COMPILE
+ InitializeGarbageCollector();
+
// Initialize remoting
-#ifdef FEATURE_REMOTING
- CRemotingServices::Initialize();
-#endif // FEATURE_REMOTING
- // weak_short, weak_long, strong; no pin
- if (!Ref_Initialize())
+ if (!GCHandleTableUtilities::GetGCHandleTable()->Initialize())
+ {
IfFailGo(E_OUTOFMEMORY);
+ }
// Initialize contexts
Context::Initialize();
@@ -1080,16 +880,6 @@ void EEStartupHelper(COINITIEE fFlags)
g_pEEShutDownEvent = new CLREvent();
g_pEEShutDownEvent->CreateManualEvent(FALSE);
-#ifdef FEATURE_RWLOCK
- // Initialize RWLocks
- CRWLock::ProcessInit();
-#endif // FEATURE_RWLOCK
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- // Initialize debugger manager
- CCLRDebugManager::ProcessInit();
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
#ifdef FEATURE_IPCMAN
// Initialize CCLRSecurityAttributeManager
CCLRSecurityAttributeManager::ProcessInit();
@@ -1099,11 +889,6 @@ void EEStartupHelper(COINITIEE fFlags)
GCInterface::m_MemoryPressureLock.Init(CrstGCMemoryPressure);
-#ifndef FEATURE_CORECLR
- // Initialize Assembly Usage Logger
- InitAssemblyUsageLogManager();
-#endif
-
#endif // CROSSGEN_COMPILE
// Setup the domains. Threads are started in a default domain.
@@ -1122,6 +907,10 @@ void EEStartupHelper(COINITIEE fFlags)
#ifndef CROSSGEN_COMPILE
+ // This isn't done as part of InitializeGarbageCollector() above because thread
+ // creation requires AppDomains to have been set up.
+ FinalizerThread::FinalizerThreadCreate();
+
#ifndef FEATURE_PAL
// Watson initialization must precede InitializeDebugger() and InstallUnhandledExceptionFilter()
// because on CoreCLR when Waston is enabled, debugging service needs to be enabled and UEF will be used.
@@ -1225,7 +1014,14 @@ void EEStartupHelper(COINITIEE fFlags)
}
#endif
- InitializeGarbageCollector();
+ // This isn't done as part of InitializeGarbageCollector() above because it
+ // requires write barriers to have been set up on x86, which happens as part
+ // of InitJITHelpers1.
+ hr = g_pGCHeap->Initialize();
+ IfFailGo(hr);
+
+ // Now we really have fully initialized the garbage collector
+ SetGarbageCollectorFullyInitialized();
InitializePinHandleTable();
@@ -1238,10 +1034,12 @@ void EEStartupHelper(COINITIEE fFlags)
SystemDomain::System()->DefaultDomain()));
SystemDomain::System()->PublishAppDomainAndInformDebugger(SystemDomain::System()->DefaultDomain());
#endif
-
-#ifndef FEATURE_CORECLR
- ExistingOobAssemblyList::Init();
-#endif
+
+#ifdef FEATURE_PERFTRACING
+ // Initialize the event pipe and start it if requested.
+ EventPipe::Initialize();
+ EventPipe::EnableOnStartup();
+#endif // FEATURE_PERFTRACING
#endif // CROSSGEN_COMPILE
@@ -1329,12 +1127,10 @@ void EEStartupHelper(COINITIEE fFlags)
}
//For a similar reason, let's not run VerifyAllOnLoad either.
-#ifdef FEATURE_CORECLR
if (g_pConfig->VerifyModulesOnLoad())
{
SystemDomain::SystemModule()->VerifyAllMethods();
}
-#endif //FEATURE_CORECLR
// Perform mscorlib consistency check if requested
g_Mscorlib.CheckExtended();
@@ -1595,11 +1391,6 @@ static void ExternalShutdownHelper(int exitCode, ShutdownCompleteAction sca)
// process exit code. This can be modified by the app via System.SetExitCode().
SetLatchedExitCode(exitCode);
-#ifndef FEATURE_CORECLR // no shim
- // Bump up the ref-count on the module
- for (int i =0; i<6; i++)
- CLRLoadLibrary(MSCOREE_SHIM_W);
-#endif // FEATURE_CORECLR
ForceEEShutdown(sca);
@@ -1671,12 +1462,6 @@ BOOL IsRuntimeStarted(DWORD *pdwStartupFlags)
if (pdwStartupFlags != NULL) // this parameter is optional
{
*pdwStartupFlags = 0;
-#ifndef FEATURE_CORECLR
- if (g_fEEStarted)
- {
- *pdwStartupFlags = CorHost2::GetStartupFlags();
- }
-#endif
}
return g_fEEStarted;
}
@@ -1791,7 +1576,7 @@ void STDMETHODCALLTYPE EEShutDownHelper(BOOL fIsDllUnloading)
ETW::EnumerationLog::ProcessShutdown();
}
-#if defined(FEATURE_CAS_POLICY) || defined(FEATURE_COMINTEROP)
+#if defined(FEATURE_COMINTEROP)
// Get the current thread.
Thread * pThisThread = GetThread();
#endif
@@ -1869,14 +1654,6 @@ void STDMETHODCALLTYPE EEShutDownHelper(BOOL fIsDllUnloading)
fFinalizeOK = FinalizerThread::FinalizerThreadWatchDog();
}
-#ifndef FEATURE_CORECLR
- if (!g_fFastExitProcess)
- {
- // Log usage data to disk. (Only do this in normal shutdown scenarios, and not involving ngen)
- if (!IsCompilationProcess())
- AssemblyUsageLogManager::GenerateLog(AssemblyUsageLogManager::GENERATE_LOG_FLAGS_NONE);
- }
-#endif
// Ok. Let's stop the EE.
if (!g_fProcessDetach)
@@ -1931,6 +1708,11 @@ void STDMETHODCALLTYPE EEShutDownHelper(BOOL fIsDllUnloading)
PerfMap::Destroy();
#endif
+#ifdef FEATURE_PERFTRACING
+ // Shutdown the event pipe.
+ EventPipe::Shutdown();
+#endif // FEATURE_PERFTRACING
+
#ifdef FEATURE_PREJIT
{
// If we're doing basic block profiling, we need to write the log files to disk.
@@ -1939,8 +1721,19 @@ void STDMETHODCALLTYPE EEShutDownHelper(BOOL fIsDllUnloading)
if (!fIBCLoggingDone)
{
if (g_IBCLogger.InstrEnabled())
- Module::WriteAllModuleProfileData(true);
+ {
+ Thread * pThread = GetThread();
+ ThreadLocalIBCInfo* pInfo = pThread->GetIBCInfo();
+ // Acquire the Crst lock before creating the IBCLoggingDisabler object.
+ // Only one thread at a time can be processing an IBC logging event.
+ CrstHolder lock(g_IBCLogger.GetSync());
+ {
+ IBCLoggingDisabler disableLogging( pInfo ); // runs IBCLoggingDisabler::DisableLogging
+
+ Module::WriteAllModuleProfileData(true);
+ }
+ }
fIBCLoggingDone = TRUE;
}
}
@@ -1990,22 +1783,6 @@ void STDMETHODCALLTYPE EEShutDownHelper(BOOL fIsDllUnloading)
}
#endif // PROFILING_SUPPORTED
-#ifndef FEATURE_CORECLR
- // CoEEShutDownCOM moved to
- // the Finalizer thread. See bug 87809
- if (!g_fProcessDetach && !g_fFastExitProcess)
- {
- g_fEEShutDown |= ShutDown_COM;
- if (fFinalizeOK)
- {
- FinalizerThread::FinalizerThreadWatchDog();
- }
- }
-#ifdef _DEBUG
- else
- g_fEEShutDown |= ShutDown_COM;
-#endif
-#endif //FEATURE_CORECLR
#ifdef _DEBUG
g_fEEShutDown |= ShutDown_SyncBlock;
@@ -2015,15 +1792,6 @@ void STDMETHODCALLTYPE EEShutDownHelper(BOOL fIsDllUnloading)
// because we are shutting down.
CONTRACT_VIOLATION(ModeViolation);
-#ifdef FEATURE_CAS_POLICY
- // Save the security policy cache as necessary.
- if (!g_fProcessDetach || pThisThread != NULL)
- {
- // If process shutdown has started, it is not safe to create Thread object which is needed
- // by the following call.
- Security::SaveCache();
- }
-#endif
#ifdef FEATURE_COMINTEROP
// We need to call CoUninitialize in part one to ensure orderly shutdown of COM dlls.
if (!g_fFastExitProcess)
@@ -2112,7 +1880,7 @@ part2:
#ifdef SHOULD_WE_CLEANUP
if (!g_fFastExitProcess)
{
- Ref_Shutdown(); // shut down the handle table
+ GCHandleTableUtilities::GetGCHandleTable()->Shutdown();
}
#endif /* SHOULD_WE_CLEANUP */
@@ -2662,774 +2430,6 @@ void STDMETHODCALLTYPE CoUninitializeEE(BOOL fIsDllUnloading)
}
-#ifndef FEATURE_CORECLR
-//*****************************************************************************
-// This entry point is called from the native DllMain of the loaded image.
-// This gives the COM+ loader the chance to dispatch the loader event. The
-// first call will cause the loader to look for the entry point in the user
-// image. Subsequent calls will dispatch to either the user's DllMain or
-// their Module derived class.
-//*****************************************************************************
-BOOL STDMETHODCALLTYPE _CorDllMain( // TRUE on success, FALSE on error.
- HINSTANCE hInst, // Instance handle of the loaded module.
- DWORD dwReason, // Reason for loading.
- LPVOID lpReserved // Unused.
- )
-{
- STATIC_CONTRACT_NOTHROW;
- //STATIC_CONTRACT_GC_TRIGGERS;
- STATIC_CONTRACT_ENTRY_POINT;
-
- //BEGIN_ENTRYPOINT_NOTHROW;
-
- struct Param
- {
- HINSTANCE hInst;
- DWORD dwReason;
- LPVOID lpReserved;
- BOOL retval;
- } param;
- param.hInst = hInst;
- param.dwReason = dwReason;
- param.lpReserved = lpReserved;
- param.retval = FALSE;
-
- // Can't use PAL_TRY/EX_TRY here as they access the ClrDebugState which gets blown away as part of the
- // PROCESS_DETACH path. Must use special PAL_TRY_FOR_DLLMAIN, passing the reason were in the DllMain.
- PAL_TRY_FOR_DLLMAIN(Param *, pParam, &param, pParam->dwReason)
- {
-#ifdef _DEBUG
- if (CLRTaskHosted() &&
- ((pParam->dwReason == DLL_PROCESS_ATTACH && pParam->lpReserved == NULL) || // LoadLibrary of a managed dll
- (pParam->dwReason == DLL_PROCESS_DETACH && pParam->lpReserved == NULL) // FreeLibrary of a managed dll
- )) {
- // OS loader lock is being held by the current thread. We can not allow the fiber
- // to be rescheduled here while processing DllMain for managed dll.
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostTask *pTask = GetCurrentHostTask();
- if (pTask) {
- Thread *pThread = GetThread();
- _ASSERTE (pThread);
- _ASSERTE (pThread->HasThreadAffinity());
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
- }
-#endif
- // Since we're in _CorDllMain, we know that we were not called because of a
- // bootstrap thunk, since they will call CorDllMainForThunk. Because of this,
- // we can pass FALSE for the fFromThunk parameter.
- pParam->retval = ExecuteDLL(pParam->hInst,pParam->dwReason,pParam->lpReserved, FALSE);
- }
- PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- }
- PAL_ENDTRY;
-
- //END_ENTRYPOINT_NOTHROW;
-
- return param.retval;
-}
-
-#endif // !FEATURE_CORECLR
-
-#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
-
-
-#ifndef FEATURE_CORECLR
-
-// This function will do some additional PE Checks to make sure everything looks good.
-// We must do these before we run any managed code (that's why we can't do them in PEVerifier, as
-// managed code is used to determine the policy settings)
-HRESULT DoAdditionalPEChecks(HINSTANCE hInst)
-{
- STATIC_CONTRACT_NOTHROW;
- STATIC_CONTRACT_GC_TRIGGERS;
-
- struct Param
- {
- HINSTANCE hInst;
- HRESULT hr;
- } param;
- param.hInst = hInst;
- param.hr = S_OK;
-
- PAL_TRY(Param *, pParam, &param)
- {
- PEDecoder pe(pParam->hInst);
-
- if (!pe.CheckWillCreateGuardPage())
- pParam->hr = COR_E_BADIMAGEFORMAT;
- }
- PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- }
- PAL_ENDTRY
-
- return param.hr;
-}
-
-//*****************************************************************************
-// This entry point is called from the native entry point of the loaded
-// executable image. This simply calls into _CorExeMainInternal, the real
-// entry point inside a filter to trigger unhandled exception processing in the
-// event an exception goes unhandled, independent of the OS UEF mechanism.
-//*****************************************************************************
-__int32 STDMETHODCALLTYPE _CorExeMain( // Executable exit code.
- )
-{
- STATIC_CONTRACT_GC_TRIGGERS;
- STATIC_CONTRACT_THROWS;
-
- // We really have nothing to share with our filter at this point.
- struct Param
- {
- PVOID pData;
- } param;
- param.pData = NULL;
-
- PAL_TRY(Param*, _pParam, &param)
- {
- // Call the real function that will invoke the managed entry point
- _CorExeMainInternal();
- }
- PAL_EXCEPT_FILTER(EntryPointFilter)
- {
- LOG((LF_STARTUP, LL_INFO10, "EntryPointFilter returned EXCEPTION_EXECUTE_HANDLER!"));
- }
- PAL_ENDTRY;
-
- return 0;
-}
-
-//*****************************************************************************
-// This entry point is called from _CorExeMain. If an exception goes unhandled
-// from here, we will trigger unhandled exception processing in _CorExeMain.
-//
-// The command line arguments and other entry point data
-// will be gathered here. The entry point for the user image will be found
-// and handled accordingly.
-//*****************************************************************************
-__int32 STDMETHODCALLTYPE _CorExeMainInternal( // Executable exit code.
- )
-{
- STATIC_CONTRACT_GC_TRIGGERS;
- STATIC_CONTRACT_THROWS;
- STATIC_CONTRACT_ENTRY_POINT;
-
- // Yes, CorExeMain needs throws. If an exception passes through here, it will cause the
- // "The application has generated an unhandled exception" dialog and offer to debug.
-
- BEGIN_ENTRYPOINT_THROWS;
-
- // Make sure PE file looks ok
- HRESULT hr;
- {
- // We are early in the process, if we get an SO here we will just rip
- CONTRACT_VIOLATION(SOToleranceViolation);
- if (FAILED(hr = DoAdditionalPEChecks(WszGetModuleHandle(NULL))))
- {
- GCX_PREEMP();
- VMDumpCOMErrors(hr);
- SetLatchedExitCode (-1);
- goto exit;
- }
- }
-
- g_fEEManagedEXEStartup = TRUE;
- // Before we initialize the EE, make sure we've snooped for all EE-specific
- // command line arguments that might guide our startup.
- WCHAR *pCmdLine = WszGetCommandLine();
- HRESULT result = CorCommandLine::SetArgvW(pCmdLine);
-
- if (SUCCEEDED(result))
- {
- g_fWeOwnProcess = TRUE;
- result = EnsureEEStarted(COINITEE_MAIN);
- }
-
- if (FAILED(result))
- {
- g_fWeOwnProcess = FALSE;
- GCX_PREEMP();
- VMDumpCOMErrors(result);
- SetLatchedExitCode (-1);
- goto exit;
- }
-
- INSTALL_UNWIND_AND_CONTINUE_HANDLER;
-
- // This will be called from a EXE so this is a self referential file so I am going to call
- // ExecuteEXE which will do the work to make a EXE load.
-
- BOOL bretval = 0;
-
- bretval = ExecuteEXE(WszGetModuleHandle(NULL));
- if (!bretval) {
- // The only reason I've seen this type of error in the wild is bad
- // metadata file format versions and inadequate error handling for
- // partially signed assemblies. While this may happen during
- // development, our customers should not get here. This is a back-stop
- // to catch CLR bugs. If you see this, please try to find a better way
- // to handle your error, like throwing an unhandled exception.
- EEMessageBoxCatastrophic(IDS_EE_COREXEMAIN_FAILED_TEXT, IDS_EE_COREXEMAIN_FAILED_TITLE);
- SetLatchedExitCode (-1);
- }
-
- UNINSTALL_UNWIND_AND_CONTINUE_HANDLER;
-
-exit:
- STRESS_LOG1(LF_STARTUP, LL_ALWAYS, "Program exiting: return code = %d", GetLatchedExitCode());
-
- STRESS_LOG0(LF_STARTUP, LL_INFO10, "EEShutDown invoked from _CorExeMainInternal");
-
- EEPolicy::HandleExitProcess();
-
- END_ENTRYPOINT_THROWS;
-
- return 0;
-}
-
-
-static BOOL CacheCommandLine(__in LPWSTR pCmdLine, __in_opt LPWSTR* ArgvW)
-{
- CONTRACTL {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(CheckPointer(pCmdLine));
- PRECONDITION(CheckPointer(ArgvW));
- } CONTRACTL_END;
-
- if (pCmdLine) {
- size_t len = wcslen(pCmdLine);
-
- _ASSERT(g_pCachedCommandLine== NULL);
- g_pCachedCommandLine = new WCHAR[len+1];
- wcscpy_s(g_pCachedCommandLine, len+1, pCmdLine);
- }
-
- if (ArgvW != NULL && ArgvW[0] != NULL) {
- PathString wszModuleName;
- PathString wszCurDir;
- if (!WszGetCurrentDirectory(wszCurDir))
- return FALSE;
-
-#ifdef _PREFAST_
-#pragma warning(push)
-#pragma warning(disable:25025)
-#endif
-
- // usage of PathCombine is safe if we ensure that buffer specified by
- // parameter1 can accomodate buffers specified by paramater2, parameter3
- // and one path separator
- COUNT_T wszModuleName_len = wszCurDir.GetCount() + lstrlenW(ArgvW[0]);
- WCHAR* wszModuleName_buf = wszModuleName.OpenUnicodeBuffer(wszModuleName_len);
-
- if (PathCombine(wszModuleName_buf, wszCurDir, ArgvW[0]) == NULL)
- return FALSE;
- wszModuleName.CloseBuffer();
-#ifdef _PREFAST_
-#pragma warning(pop)
-#endif
-
- size_t len = wszModuleName.GetCount();
- _ASSERT(g_pCachedModuleFileName== NULL);
- g_pCachedModuleFileName = new WCHAR[len+1];
- wcscpy_s(g_pCachedModuleFileName, len+1, wszModuleName);
- }
-
- return TRUE;
-}
-
-//*****************************************************************************
-// This entry point is called from the native entry point of the loaded
-// executable image. The command line arguments and other entry point data
-// will be gathered here. The entry point for the user image will be found
-// and handled accordingly.
-//*****************************************************************************
-__int32 STDMETHODCALLTYPE _CorExeMain2( // Executable exit code.
- PBYTE pUnmappedPE, // -> memory mapped code
- DWORD cUnmappedPE, // Size of memory mapped code
- __in LPWSTR pImageNameIn, // -> Executable Name
- __in LPWSTR pLoadersFileName, // -> Loaders Name
- __in LPWSTR pCmdLine) // -> Command Line
-{
-
- // This entry point is used by clix
- BOOL bRetVal = 0;
-
- BEGIN_ENTRYPOINT_VOIDRET;
- {
- // Before we initialize the EE, make sure we've snooped for all EE-specific
- // command line arguments that might guide our startup.
- HRESULT result = CorCommandLine::SetArgvW(pCmdLine);
-
- if (!CacheCommandLine(pCmdLine, CorCommandLine::GetArgvW(NULL))) {
- LOG((LF_STARTUP, LL_INFO10, "Program exiting - CacheCommandLine failed\n"));
- bRetVal = -1;
- goto exit;
- }
-
- if (SUCCEEDED(result))
- result = InitializeEE(COINITEE_MAIN);
-
- if (FAILED(result)) {
- VMDumpCOMErrors(result);
- SetLatchedExitCode (-1);
- goto exit;
- }
-
- // Load the executable
- bRetVal = ExecuteEXE(pImageNameIn);
-
- if (!bRetVal) {
- // The only reason I've seen this type of error in the wild is bad
- // metadata file format versions and inadequate error handling for
- // partially signed assemblies. While this may happen during
- // development, our customers should not get here. This is a back-stop
- // to catch CLR bugs. If you see this, please try to find a better way
- // to handle your error, like throwing an unhandled exception.
- EEMessageBoxCatastrophic(IDS_EE_COREXEMAIN2_FAILED_TEXT, IDS_EE_COREXEMAIN2_FAILED_TITLE);
- SetLatchedExitCode (-1);
- }
-
-exit:
- STRESS_LOG1(LF_STARTUP, LL_ALWAYS, "Program exiting: return code = %d", GetLatchedExitCode());
-
- STRESS_LOG0(LF_STARTUP, LL_INFO10, "EEShutDown invoked from _CorExeMain2");
-
- EEPolicy::HandleExitProcess();
- }
- END_ENTRYPOINT_VOIDRET;
-
- return bRetVal;
-}
-
-//*****************************************************************************
-// This is the call point to wire up an EXE. In this case we have the HMODULE
-// and just need to make sure we do to correct self referantial things.
-//*****************************************************************************
-
-
-BOOL STDMETHODCALLTYPE ExecuteEXE(HMODULE hMod)
-{
- STATIC_CONTRACT_GC_TRIGGERS;
-
- _ASSERTE(hMod);
- if (!hMod)
- return FALSE;
-
- ETWFireEvent(ExecExe_V1);
-
- struct Param
- {
- HMODULE hMod;
- } param;
- param.hMod = hMod;
-
- EX_TRY_NOCATCH(Param *, pParam, &param)
- {
- // Executables are part of the system domain
- SystemDomain::ExecuteMainMethod(pParam->hMod);
- }
- EX_END_NOCATCH;
-
- ETWFireEvent(ExecExeEnd_V1);
-
- return TRUE;
-}
-
-BOOL STDMETHODCALLTYPE ExecuteEXE(__in LPWSTR pImageNameIn)
-{
- STATIC_CONTRACT_GC_TRIGGERS;
-
- EX_TRY_NOCATCH(LPWSTR, pImageNameInner, pImageNameIn)
- {
- WCHAR wzPath[MAX_LONGPATH];
- DWORD dwPathLength = 0;
-
- // get the path of executable
- dwPathLength = WszGetFullPathName(pImageNameInner, MAX_LONGPATH, wzPath, NULL);
-
- if (!dwPathLength || dwPathLength > MAX_LONGPATH)
- {
- ThrowWin32( !dwPathLength ? GetLastError() : ERROR_FILENAME_EXCED_RANGE);
- }
-
- SystemDomain::ExecuteMainMethod( NULL, (WCHAR *)wzPath );
- }
- EX_END_NOCATCH;
-
- return TRUE;
-}
-#endif // FEATURE_CORECLR
-
-#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)
{
@@ -3449,252 +2449,6 @@ BOOL ExecuteDLL_ReturnOrThrow(HRESULT hr, BOOL fFromThunk)
return SUCCEEDED(hr);
}
-#if !defined(FEATURE_CORECLR) && defined(_DEBUG)
-//*****************************************************************************
-// Factor some common debug code.
-//*****************************************************************************
-static void EnsureManagedThreadExistsForHostedThread()
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- } CONTRACTL_END;
-
- if (CLRTaskHosted()) {
- // If CLR is hosted, and this is on a thread that a host controls,
- // we must have created Thread object.
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostTask *pHostTask = GetCurrentHostTask();
- if (pHostTask)
- {
- CONSISTENCY_CHECK(CheckPointer(GetThread()));
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
- }
-}
-#endif // !FEATURE_CORECLR && _DEBUG
-
-#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
-
-#ifndef FEATURE_CORECLR
-//*****************************************************************************
-// This is the call point to make a DLL that is already loaded into our address
-// space run. There will be other code to actually have us load a DLL due to a
-// class reference.
-//*****************************************************************************
-BOOL STDMETHODCALLTYPE ExecuteDLL(HINSTANCE hInst,
- DWORD dwReason,
- LPVOID lpReserved,
- BOOL fFromThunk)
-{
-
- CONTRACTL{
- THROWS;
- WRAPPER(GC_TRIGGERS);
- MODE_ANY;
- ENTRY_POINT;
- PRECONDITION(CheckPointer(lpReserved, NULL_OK));
- PRECONDITION(CheckPointer(hInst));
- PRECONDITION(GetThread() != NULL || !fFromThunk);
- } CONTRACTL_END;
-
- HRESULT hr = S_OK;
- BOOL fRetValue = FALSE;
-
- // This needs to be before the BEGIN_ENTRYPOINT_THROWS since
- // we can't call ReportStackOverflow if we're almost done with
- // shutdown and can't run managed code.
- if (!CanRunManagedCode(LoaderLockCheck::None))
- {
- return fRetValue;
- }
-
- BEGIN_ENTRYPOINT_THROWS;
-
- Thread *pThread = GetThread();
-
- if (!hInst)
- {
- fRetValue = ExecuteDLL_ReturnOrThrow(E_FAIL, fFromThunk);
- goto Exit;
- }
-
- // Note that we always check fFromThunk before checking the dwReason value.
- // This is because the dwReason value is undefined in the case that we're
- // being invoked due to a bootstrap (because that is by definition outside
- // of the loader lock and there is no appropriate dwReason value).
- if (fFromThunk ||
- dwReason == DLL_PROCESS_ATTACH ||
- dwReason == DLL_THREAD_ATTACH)
- {
- INDEBUG(EnsureManagedThreadExistsForHostedThread();)
-
-
- // If necessary, start the runtime and create a managed thread object.
- if (fFromThunk || dwReason == DLL_PROCESS_ATTACH)
- {
- hr = EnsureEEStarted(COINITEE_DLL);
-
- if (SUCCEEDED(hr) && pThread == NULL)
- {
- pThread = SetupThreadNoThrow(&hr);
- }
-
- if(FAILED(hr))
- {
- fRetValue = ExecuteDLL_ReturnOrThrow(hr, fFromThunk);
- goto Exit;
- }
- }
-
- // IJW assemblies cause the thread doing the process attach to
- // re-enter ExecuteDLL and do a thread attach. This happens when
- // CoInitializeEE() above executed
- else if (!(pThread &&
- pThread->GetDomain() &&
- CanRunManagedCode(LoaderLockCheck::None)))
- {
- fRetValue = ExecuteDLL_ReturnOrThrow(S_OK, fFromThunk);
- goto Exit;
- }
-
- // we now have a thread setup - either the 1st if set it up, or
- // the else if ran if we didn't have a thread setup.
-
-#ifdef FEATURE_MIXEDMODE
-
- EX_TRY
- {
- hr = ExecuteDLLForAttach(hInst, dwReason, lpReserved, fFromThunk);
- }
- EX_CATCH
- {
- // We rethrow directly here instead of using ExecuteDLL_ReturnOrThrow() to
- // preserve the full exception information, rather than just the HRESULT
- if (fFromThunk)
- {
- EX_RETHROW;
- }
- else
- {
- hr = GET_EXCEPTION()->GetHR();
- }
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- if (FAILED(hr))
- {
- fRetValue = ExecuteDLL_ReturnOrThrow(hr, fFromThunk);
- goto Exit;
- }
-#endif // FEATURE_MIXEDMODE
- }
- else
- {
- PEDecoder pe(hInst);
- if (pe.HasManagedEntryPoint())
- {
- // If the EE is still intact, then run user entry points. Otherwise
- // detach was handled when the app domain was stopped.
- //
- // Checks for the loader lock will occur within RunDllMain, if that's
- FAULT_NOT_FATAL();
- if (CanRunManagedCode(LoaderLockCheck::None))
- {
- hr = SystemDomain::RunDllMain(hInst, dwReason, lpReserved);
- }
- }
- // This does need to match the attach. We will only unload dll's
- // at the end and CoUninitialize will just bounce at 0. WHEN and IF we
- // get around to unloading IL DLL's during execution prior to
- // shutdown we will need to bump the reference one to compensate
- // for this call.
- if (dwReason == DLL_PROCESS_DETACH && !g_fForbidEnterEE)
- {
-#ifdef FEATURE_MIXEDMODE
- // If we're in a decent state, we need to free the memory associated
- // with the IJW thunk fixups.
- // we are not in a decent state if the process is terminating (lpReserved!=NULL)
- if (g_fEEStarted && !g_fEEShutDown && !lpReserved)
- {
- PEImage::UnloadIJWModule(hInst);
- }
-#endif // FEATURE_MIXEDMODE
- }
- }
-
- fRetValue = ExecuteDLL_ReturnOrThrow(hr, fFromThunk);
-
-Exit:
-
- END_ENTRYPOINT_THROWS;
- return fRetValue;
-}
-#endif // !FEATURE_CORECLR
-
-
-Volatile<BOOL> g_bIsGarbageCollectorFullyInitialized = FALSE;
-
-void SetGarbageCollectorFullyInitialized()
-{
- LIMITED_METHOD_CONTRACT;
-
- g_bIsGarbageCollectorFullyInitialized = TRUE;
-}
-
-// Tells whether the garbage collector is fully initialized
-// Stronger than IsGCHeapInitialized
-BOOL IsGarbageCollectorFullyInitialized()
-{
- LIMITED_METHOD_CONTRACT;
-
- return g_bIsGarbageCollectorFullyInitialized;
-}
-
//
// Initialize the Garbage Collector
//
@@ -3729,19 +2483,24 @@ void InitializeGarbageCollector()
IGCToCLR* gcToClr = nullptr;
#endif
- IGCHeap *pGCHeap = InitializeGarbageCollector(gcToClr);
- g_pGCHeap = pGCHeap;
- if (!pGCHeap)
- ThrowOutOfMemory();
+ IGCHandleTable *pGcHandleTable;
- hr = pGCHeap->Initialize();
- IfFailThrow(hr);
+ IGCHeap *pGCHeap;
+ if (!InitializeGarbageCollector(gcToClr, &pGCHeap, &pGcHandleTable, &g_gc_dac_vars))
+ {
+ ThrowOutOfMemory();
+ }
- // Thread for running finalizers...
- FinalizerThread::FinalizerThreadCreate();
+ assert(pGCHeap != nullptr);
+ g_pGCHeap = pGCHeap;
+ g_pGCHandleTable = pGcHandleTable;
+ g_gcDacGlobals = &g_gc_dac_vars;
- // Now we really have fully initialized the garbage collector
- SetGarbageCollectorFullyInitialized();
+ // Apparently the Windows linker removes global variables if they are never
+ // read from, which is a problem for g_gcDacGlobals since it's expected that
+ // only the DAC will read from it. This forces the linker to include
+ // g_gcDacGlobals.
+ volatile void* _dummy = g_gcDacGlobals;
}
/*****************************************************************************/
@@ -3803,15 +2562,6 @@ BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error.
// Remember module instance
g_pMSCorEE = pParam->hInst;
-#ifndef FEATURE_CORECLR
- CoreClrCallbacks cccallbacks;
- cccallbacks.m_hmodCoreCLR = (HINSTANCE)g_pMSCorEE;
- cccallbacks.m_pfnIEE = IEE;
- cccallbacks.m_pfnGetCORSystemDirectory = GetCORSystemDirectoryInternaL;
- cccallbacks.m_pfnGetCLRFunction = GetCLRFunction;
-
- InitUtilcode(cccallbacks);
-#endif // !FEATURE_CORECLR
// Set callbacks so that LoadStringRC knows which language our
// threads are in so that it can return the proper localized string.
@@ -3920,139 +2670,11 @@ BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error.
if (dwReason == DLL_THREAD_DETACH || dwReason == DLL_PROCESS_DETACH)
{
- if (CLRMemoryHosted())
- {
- // A host may not support memory operation inside OS loader lock.
- // We will free these memory on finalizer thread.
- CExecutionEngine::DetachTlsInfo(param.pTlsData);
- }
- else
- {
- CExecutionEngine::ThreadDetaching(param.pTlsData);
- }
+ CExecutionEngine::ThreadDetaching(param.pTlsData);
}
return TRUE;
}
-#ifdef FEATURE_COMINTEROP_REGISTRATION
-//*****************************************************************************
-// Helper function to call the managed registration services.
-//*****************************************************************************
-enum EnumRegServicesMethods
-{
- RegServicesMethods_RegisterAssembly = 0,
- RegServicesMethods_UnregisterAssembly,
- RegServicesMethods_LastMember
-};
-
-void InvokeRegServicesMethod(EnumRegServicesMethods Method, HMODULE hMod)
-{
- CONTRACT_VOID
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(Method == RegServicesMethods_RegisterAssembly ||
- Method == RegServicesMethods_UnregisterAssembly);
- }
- CONTRACT_END;
-
- GCX_PREEMP();
- Assembly *pAssembly = GetAppDomain()->LoadExplicitAssembly(hMod, TRUE);
-
- {
- GCX_COOP();
-
- // The names of the RegistrationServices methods.
- static const BinderMethodID aMethods[] =
- {
- METHOD__REGISTRATION_SERVICES__REGISTER_ASSEMBLY,
- METHOD__REGISTRATION_SERVICES__UNREGISTER_ASSEMBLY
- };
-
- // Allocate the RegistrationServices object.
- OBJECTREF RegServicesObj = AllocateObject(MscorlibBinder::GetClass(CLASS__REGISTRATION_SERVICES));
- GCPROTECT_BEGIN(RegServicesObj)
- {
- MethodDescCallSite registrationMethod(aMethods[Method], &RegServicesObj);
-
- ARG_SLOT Args[] =
- {
- ObjToArgSlot(RegServicesObj),
- ObjToArgSlot(pAssembly->GetExposedObject()),
- 0 // unused by UnregisterAssembly
- };
-
- registrationMethod.Call(Args);
- }
- GCPROTECT_END();
- }
- RETURN;
-}
-
-//*****************************************************************************
-// This entry point is called to register the classes contained inside a
-// COM+ assembly.
-//*****************************************************************************
-STDAPI EEDllRegisterServer(HMODULE hMod)
-{
-
- CONTRACTL{
- NOTHROW;
- GC_TRIGGERS;
- ENTRY_POINT;
- MODE_PREEMPTIVE;
- } CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- // Start up the runtime since we are going to use managed code to actually
- // do the registration.
- IfFailGo(EnsureEEStarted(COINITEE_DEFAULT));
-
- BEGIN_EXTERNAL_ENTRYPOINT(&hr)
- {
- InvokeRegServicesMethod(RegServicesMethods_RegisterAssembly, hMod);
- }
- END_EXTERNAL_ENTRYPOINT;
-
-ErrExit:
-
-
- return hr;
-}
-
-//*****************************************************************************
-// This entry point is called to unregister the classes contained inside a
-// COM+ assembly.
-//*****************************************************************************
-STDAPI EEDllUnregisterServer(HMODULE hMod)
-{
-
- CONTRACTL{
- NOTHROW;
- GC_TRIGGERS;
- MODE_PREEMPTIVE;
- ENTRY_POINT;
- } CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- // Start up the runtime since we are going to use managed code to actually
- // do the registration.
- IfFailGo(EnsureEEStarted(COINITEE_DEFAULT));
-
- BEGIN_EXTERNAL_ENTRYPOINT(&hr)
- {
- InvokeRegServicesMethod(RegServicesMethods_UnregisterAssembly, hMod);
- }
- END_EXTERNAL_ENTRYPOINT;
-ErrExit:
-
-
- return hr;
-}
-#endif // FEATURE_COMINTEROP_REGISTRATION
#ifdef FEATURE_IPCMAN
extern CCLRSecurityAttributeManager s_CLRSecurityAttributeManager;
@@ -4124,7 +2746,6 @@ static void InitializeDebugger(void)
hr = g_pDebugInterface->Startup(); // throw on error
_ASSERTE(SUCCEEDED(hr));
-#ifdef FEATURE_CORECLR
//
// If the debug pack is not installed, Startup will return S_FALSE
// and we should cleanup and proceed without debugging support.
@@ -4133,31 +2754,8 @@ static void InitializeDebugger(void)
{
return;
}
-#endif // FEATURE_CORECLR
- }
-
-#if !defined(FEATURE_CORECLR) // simple hosting
- // If there's a DebuggerThreadControl interface, then we
- // need to update the DebuggerSpecialThread list.
- if (CorHost::GetDebuggerThreadControl())
- {
- hr = CorHost::RefreshDebuggerSpecialThreadList();
- _ASSERTE((SUCCEEDED(hr)) && (hr != S_FALSE));
-
- // So we don't think this will ever fail, but just in case...
- IfFailThrow(hr);
}
- // If there is a DebuggerThreadControl interface, then it was set before the debugger
- // was initialized and we need to provide this interface now. If debugging is already
- // initialized then the IDTC pointer is passed in when it is set through CorHost
- IDebuggerThreadControl *pDTC = CorHost::GetDebuggerThreadControl();
-
- if (pDTC != NULL)
- {
- g_pDebugInterface->SetIDbgThreadControl(pDTC);
- }
-#endif // !defined(FEATURE_CORECLR)
LOG((LF_CORDB, LL_INFO10, "Left-side debugging services setup.\n"));
@@ -4198,9 +2796,6 @@ static void TerminateDebugger(void)
g_CORDebuggerControlFlags = DBCF_NORMAL_OPERATION;
-#if !defined(FEATURE_CORECLR) // simple hosting
- CorHost::CleanupDebuggerThreadControl();
-#endif // !defined(FEATURE_CORECLR)
}
@@ -4825,247 +3420,4 @@ void ContractRegressionCheck()
#endif // ENABLE_CONTRACTS_IMPL
-#ifndef FEATURE_CORECLR
-//-------------------------------------------------------------------------
-// CorCommandLine state and methods
-//-------------------------------------------------------------------------
-// Class to encapsulate Cor Command line processing
-
-// Statics for the CorCommandLine class
-DWORD CorCommandLine::m_NumArgs = 0;
-LPWSTR *CorCommandLine::m_ArgvW = 0;
-
-LPWSTR CorCommandLine::m_pwszAppFullName = NULL;
-DWORD CorCommandLine::m_dwManifestPaths = 0;
-LPWSTR *CorCommandLine::m_ppwszManifestPaths = NULL;
-DWORD CorCommandLine::m_dwActivationData = 0;
-LPWSTR *CorCommandLine::m_ppwszActivationData = NULL;
-
-#ifdef _DEBUG
-LPCWSTR g_CommandLine;
-#endif
-
-// Set argvw from command line
-/* static */
-HRESULT CorCommandLine::SetArgvW(LPCWSTR lpCommandLine)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- INJECT_FAULT(return E_OUTOFMEMORY;);
-
- PRECONDITION(CheckPointer(lpCommandLine));
- }
- CONTRACTL_END
-
- HRESULT hr = S_OK;
- if(!m_ArgvW) {
- INDEBUG(g_CommandLine = lpCommandLine);
-
- InitializeLogging(); // This is so early, we may not be initialized
- LOG((LF_ALWAYS, LL_INFO10, "Executing program with command line '%S'\n", lpCommandLine));
-
- m_ArgvW = SegmentCommandLine(lpCommandLine, &m_NumArgs);
-
- if (!m_ArgvW)
- return E_OUTOFMEMORY;
-
- // Click once specific parsing
- hr = ReadClickOnceEnvVariables();
- }
-
- return hr;
-}
-
-// Retrieve the command line
-/* static */
-LPWSTR* CorCommandLine::GetArgvW(DWORD *pNumArgs)
-{
- LIMITED_METHOD_CONTRACT;
-
- if (pNumArgs != 0)
- *pNumArgs = m_NumArgs;
-
- return m_ArgvW;
-}
-
-HRESULT CorCommandLine::ReadClickOnceEnvVariables()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- } CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW);
-
- EX_TRY
- {
- // Find out if this is a ClickOnce application being activated.
- PathString m_pwszAppFullNameHolder;
- DWORD cAppFullName = WszGetEnvironmentVariable(g_pwzClickOnceEnv_FullName, m_pwszAppFullNameHolder);
- if (cAppFullName > 0) {
- // get the application full name.
- m_pwszAppFullName = m_pwszAppFullNameHolder.GetCopyOfUnicodeString();
-
- // reset the variable now that we read it so child processes
- // do not think they are a clickonce app.
- WszSetEnvironmentVariable(g_pwzClickOnceEnv_FullName, NULL);
-
- // see if we have application manifest files.
- DWORD dwManifestPaths = 0;
- while (1) {
- StackSString manifestFile(g_pwzClickOnceEnv_Manifest);
- StackSString buf;
- COUNT_T size = buf.GetUnicodeAllocation();
- _itow_s(dwManifestPaths, buf.OpenUnicodeBuffer(size), size, 10);
- buf.CloseBuffer();
- manifestFile.Append(buf);
- SString temp;
- if (WszGetEnvironmentVariable(manifestFile.GetUnicode(), temp) > 0)
- dwManifestPaths++;
- else
- break;
- }
- m_ppwszManifestPaths = new LPWSTR[dwManifestPaths];
- for (DWORD i=0; i<dwManifestPaths; i++) {
- StackSString manifestFile(g_pwzClickOnceEnv_Manifest);
- StackSString buf;
- COUNT_T size = buf.GetUnicodeAllocation();
- _itow_s(i, buf.OpenUnicodeBuffer(size), size, 10);
- buf.CloseBuffer();
- manifestFile.Append(buf);
- PathString m_ppwszManifestPathsHolder;
- DWORD cManifestPath = WszGetEnvironmentVariable(manifestFile.GetUnicode(), m_ppwszManifestPathsHolder);
- if (cManifestPath > 0) {
-
- m_ppwszManifestPaths[i] = m_ppwszManifestPathsHolder.GetCopyOfUnicodeString();
- WszSetEnvironmentVariable(manifestFile.GetUnicode(), NULL); // reset the env. variable.
- }
- }
- m_dwManifestPaths = dwManifestPaths;
-
- // see if we have activation data arguments.
- DWORD dwActivationData = 0;
- while (1) {
- StackSString activationData(g_pwzClickOnceEnv_Parameter);
- StackSString buf;
- COUNT_T size = buf.GetUnicodeAllocation();
- _itow_s(dwActivationData, buf.OpenUnicodeBuffer(size), size, 10);
- buf.CloseBuffer();
- activationData.Append(buf);
- SString temp;
- if (WszGetEnvironmentVariable(activationData.GetUnicode(), temp) > 0)
- dwActivationData++;
- else
- break;
- }
- m_ppwszActivationData = new LPWSTR[dwActivationData];
- for (DWORD i=0; i<dwActivationData; i++) {
- StackSString activationData(g_pwzClickOnceEnv_Parameter);
- StackSString buf;
- COUNT_T size = buf.GetUnicodeAllocation();
- _itow_s(i, buf.OpenUnicodeBuffer(size), size, 10);
- buf.CloseBuffer();
- activationData.Append(buf);
- PathString m_ppwszActivationDataHolder;
- DWORD cActivationData = WszGetEnvironmentVariable(activationData.GetUnicode(), m_ppwszActivationDataHolder);
- if (cActivationData > 0) {
- m_ppwszActivationData[i] = m_ppwszActivationDataHolder.GetCopyOfUnicodeString();
- WszSetEnvironmentVariable(activationData.GetUnicode(), NULL); // reset the env. variable.
- }
- }
- m_dwActivationData = dwActivationData;
- }
- }
- EX_CATCH_HRESULT(hr);
-
- END_SO_INTOLERANT_CODE;
-
- return hr;
-}
-
-#endif // !FEATURE_CORECLR
-
#endif // CROSSGEN_COMPILE
-
-
-//
-// GetOSVersion - Gets the real OS version bypassing the OS compatibility shim
-// Mscoree.dll resides in System32 dir and is always excluded from compat shim.
-// This function calls mscoree!shim function via mscoreei ICLRRuntimeHostInternal interface
-// to get the OS version. We do not do this PAL or coreclr..we direclty call the OS
-// in that case.
-//
-BOOL GetOSVersion(LPOSVERSIONINFO lposVer)
-{
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
-
- //declared static to cache the version info
- static OSVERSIONINFOEX osvi = {0};
- BOOL ret = TRUE;
-
- BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), return FALSE);
-
- //If not yet cached get the OS version info
- if(osvi.dwMajorVersion == 0)
- {
- osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
-
- ReleaseHolder<ICLRRuntimeHostInternal> pRuntimeHostInternal;
- //Get the interface
- HRESULT hr = g_pCLRRuntime->GetInterface(CLSID_CLRRuntimeHostInternal,
- IID_ICLRRuntimeHostInternal,
- &pRuntimeHostInternal);
-
- _ASSERT(SUCCEEDED(hr));
-
- //Call mscoree!GetVersionExWrapper() through mscoreei interface method
- hr = pRuntimeHostInternal->GetTrueOSVersion((LPOSVERSIONINFO)&osvi);
- if(!SUCCEEDED(hr))
- {
- osvi.dwMajorVersion = 0;
- ret = FALSE;
- goto FUNCEND;
- }
- }
-
- if(lposVer->dwOSVersionInfoSize==sizeof(OSVERSIONINFOEX)||lposVer->dwOSVersionInfoSize==sizeof(OSVERSIONINFO))
- {
- //Copy the cached version info to the return memory location
- memcpy(lposVer,&osvi, lposVer->dwOSVersionInfoSize);
- }
- else
- {
- //return failure if dwOSVersionInfoSize not set properly
- ret = FALSE;
- }
-
-FUNCEND:
- END_SO_INTOLERANT_CODE;
-
- return ret;
-#else
-// Fix for warnings when building against WinBlue build 9444.0.130614-1739
-// warning C4996: 'GetVersionExW': was declared deprecated
-// externalapis\windows\winblue\sdk\inc\sysinfoapi.h(442)
-// Deprecated. Use VerifyVersionInfo* or IsWindows* macros from VersionHelpers.
-#pragma warning( disable : 4996 )
- return WszGetVersionEx(lposVer);
-#pragma warning( default : 4996 )
-#endif
-}