Skip to content

Reducing DllMain responsibilities, so that singlefile would not need it #43423

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
1 commit merged into from
Oct 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/coreclr/src/dlls/mscoree/coreclr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ if (CLR_CMAKE_HOST_WIN32)

list(APPEND CLR_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/coreclr.def)

add_linker_flag("/ENTRY:CoreDllMain")

# Incremental linking results in the linker inserting extra padding and routing function calls via thunks that can break the
# invariants (e.g. size of region between Jit_PatchedCodeLast-Jit_PatchCodeStart needs to fit in a page).
add_linker_flag("/INCREMENTAL:NO")
Expand Down
93 changes: 1 addition & 92 deletions src/coreclr/src/dlls/mscoree/mscoree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,65 +34,9 @@ BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error.
#include <shlwapi.h>

#ifdef TARGET_WINDOWS

#include <process.h> // for __security_init_cookie()

extern "C" BOOL WINAPI _CRT_INIT(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved);
extern "C" BOOL WINAPI DllMain(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved);

// For the CoreClr, this is the real DLL entrypoint. We make ourselves the first entrypoint as
// we need to capture coreclr's hInstance before the C runtime initializes. This function
// will capture hInstance, let the C runtime initialize and then invoke the "classic"
// DllMain that initializes everything else.
extern "C" BOOL WINAPI CoreDllMain(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved)
{
STATIC_CONTRACT_NOTHROW;

BOOL result;
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
// Make sure the /GS security cookie is initialized before we call anything else.
// BinScope detects the call to __security_init_cookie in its "Has Non-GS-friendly
// Initialization" check and makes it pass.
__security_init_cookie();

// It's critical that we initialize g_hmodCoreCLR before the CRT initializes.
// We have a lot of global ctors that will break if we let the CRT initialize without
// this step having been done.

g_hmodCoreCLR = (HINSTANCE)hInstance;

if (!(result = _CRT_INIT(hInstance, dwReason, lpReserved)))
{
// CRT_INIT may fail to initialize the CRT heap. Make sure we don't continue
// down a path that would trigger an AV and tear down the host process
break;
}
result = DllMain(hInstance, dwReason, lpReserved);
break;

case DLL_THREAD_ATTACH:
_CRT_INIT(hInstance, dwReason, lpReserved);
result = DllMain(hInstance, dwReason, lpReserved);
break;

case DLL_PROCESS_DETACH: // intentional fallthru
case DLL_THREAD_DETACH:
result = DllMain(hInstance, dwReason, lpReserved);
_CRT_INIT(hInstance, dwReason, lpReserved);
break;

default:
result = FALSE; // it'd be an OS bug if we got here - not much we can do.
break;
}
return result;
}

#endif // TARGET_WINDOWS


extern "C"
#ifdef TARGET_UNIX
DLLEXPORT // For Win32 PAL LoadLibrary emulation
Expand All @@ -101,42 +45,7 @@ BOOL WINAPI DllMain(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved)
{
STATIC_CONTRACT_NOTHROW;

switch (dwReason)
{
case DLL_PROCESS_ATTACH:
{
#ifndef TARGET_WINDOWS
g_hmodCoreCLR = (HINSTANCE)hInstance;
#endif

// Save the module handle.
g_hThisInst = (HINSTANCE)hInstance;

// Prevent buffer-overruns
// If buffer is overrun, it is possible the saved callback has been trashed.
// The callback is unsafe.
//SetBufferOverrunHandler();
if (!EEDllMain((HINSTANCE)hInstance, dwReason, lpReserved))
{
return FALSE;
}
}
break;

case DLL_PROCESS_DETACH:
{
EEDllMain((HINSTANCE)hInstance, dwReason, lpReserved);
}
break;

case DLL_THREAD_DETACH:
{
EEDllMain((HINSTANCE)hInstance, dwReason, lpReserved);
}
break;
}

return TRUE;
return EEDllMain((HINSTANCE)hInstance, dwReason, lpReserved);
}

#endif // CROSSGEN_COMPILE
Expand Down
91 changes: 49 additions & 42 deletions src/coreclr/src/vm/ceemain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,15 @@ void EEStartupHelper()

#ifndef CROSSGEN_COMPILE

// We cache the SystemInfo for anyone to use throughout the life of the EE.
GetSystemInfo(&g_SystemInfo);

// Set callbacks so that LoadStringRC knows which language our
// threads are in so that it can return the proper localized string.
// TODO: This shouldn't rely on the LCID (id), but only the name
SetResourceCultureCallbacks(GetThreadUICultureNames,
GetThreadUICultureId);

#ifndef TARGET_UNIX
::SetConsoleCtrlHandler(DbgCtrlCHandler, TRUE/*add*/);
#endif
Expand Down Expand Up @@ -1820,16 +1829,9 @@ BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error.
{
case DLL_PROCESS_ATTACH:
{
// We cache the SystemInfo for anyone to use throughout the
// life of the DLL.
GetSystemInfo(&g_SystemInfo);

// Set callbacks so that LoadStringRC knows which language our
// threads are in so that it can return the proper localized string.
// TODO: This shouldn't rely on the LCID (id), but only the name
SetResourceCultureCallbacks(GetThreadUICultureNames,
GetThreadUICultureId);

g_hmodCoreCLR = pParam->hInst;
// Save the module handle.
g_hThisInst = pParam->hInst;
break;
}

Expand Down Expand Up @@ -1859,35 +1861,6 @@ BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error.
}
break;
}

case DLL_THREAD_DETACH:
{
// Don't destroy threads here if we're in shutdown (shutdown will
// clean up for us instead).

Thread* thread = GetThread();
if (thread)
{
#ifdef FEATURE_COMINTEROP
// reset the CoInitialize state
// so we don't call CoUninitialize during thread detach
thread->ResetCoInitialized();
#endif // FEATURE_COMINTEROP
// For case where thread calls ExitThread directly, we need to reset the
// frame pointer. Otherwise stackwalk would AV. We need to do it in cooperative mode.
// We need to set m_GCOnTransitionsOK so this thread won't trigger GC when toggle GC mode
if (thread->m_pFrame != FRAME_TOP)
{
#ifdef _DEBUG
thread->m_GCOnTransitionsOK = FALSE;
#endif
GCX_COOP_NO_DTOR();
thread->m_pFrame = FRAME_TOP;
GCX_COOP_NO_DTOR_END();
}
thread->DetachThread(TRUE);
}
}
}

}
Expand All @@ -1896,12 +1869,46 @@ BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error.
}
PAL_ENDTRY;

if (dwReason == DLL_THREAD_DETACH || dwReason == DLL_PROCESS_DETACH)
return TRUE;
}

struct TlsDestructionMonitor
{
~TlsDestructionMonitor()
{
// Don't destroy threads here if we're in shutdown (shutdown will
// clean up for us instead).

Thread* thread = GetThread();
if (thread)
{
#ifdef FEATURE_COMINTEROP
// reset the CoInitialize state
// so we don't call CoUninitialize during thread detach
thread->ResetCoInitialized();
#endif // FEATURE_COMINTEROP
// For case where thread calls ExitThread directly, we need to reset the
// frame pointer. Otherwise stackwalk would AV. We need to do it in cooperative mode.
// We need to set m_GCOnTransitionsOK so this thread won't trigger GC when toggle GC mode
if (thread->m_pFrame != FRAME_TOP)
{
#ifdef _DEBUG
thread->m_GCOnTransitionsOK = FALSE;
#endif
GCX_COOP_NO_DTOR();
thread->m_pFrame = FRAME_TOP;
GCX_COOP_NO_DTOR_END();
}
thread->DetachThread(TRUE);
}

ThreadDetaching();
}
return TRUE;
}
};

// This thread local object is used to detect thread shutdown. Its destructor
// is called when a thread is being shut down.
thread_local TlsDestructionMonitor tls_destructionMonitor;

#ifdef DEBUGGING_SUPPORTED
//
Expand Down