summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Vorlicek <janvorli@microsoft.com>2015-06-25 22:51:16 +0200
committerJan Vorlicek <janvorli@microsoft.com>2015-06-25 22:51:16 +0200
commit575e0d05b748e4e11ff75d66fa085e8d976f2083 (patch)
tree4f78e7616f24d38f910eb13e6fcedc20ccf082ad
parentee26a59e352aa2beac79b2bb3b21176e9eb158cc (diff)
parent31ae12be0fe50183036a27e49fe99c6dac67e3ed (diff)
downloadcoreclr-575e0d05b748e4e11ff75d66fa085e8d976f2083.tar.gz
coreclr-575e0d05b748e4e11ff75d66fa085e8d976f2083.tar.bz2
coreclr-575e0d05b748e4e11ff75d66fa085e8d976f2083.zip
Merge pull request #1174 from mikem8361/palinit
Fixed the PAL_Initialize* order problem.
-rw-r--r--src/ToolBox/SOS/Strike/strike.cpp4
-rw-r--r--src/debug/daccess/dacdbiimpl.cpp15
-rw-r--r--src/debug/di/shimremotedatatarget.cpp17
-rw-r--r--src/dlls/mscoree/unixinterface.cpp2
-rw-r--r--src/pal/inc/pal.h10
-rw-r--r--src/pal/src/debug/debug.cpp16
-rw-r--r--src/pal/src/include/pal/module.h50
-rw-r--r--src/pal/src/include/pal/procobj.hpp7
-rw-r--r--src/pal/src/init/pal.cpp184
-rw-r--r--src/pal/src/init/sxs.cpp22
-rw-r--r--src/pal/src/loader/module.cpp271
-rw-r--r--src/pal/src/misc/miscpalapi.cpp8
-rw-r--r--src/pal/src/thread/process.cpp110
13 files changed, 356 insertions, 360 deletions
diff --git a/src/ToolBox/SOS/Strike/strike.cpp b/src/ToolBox/SOS/Strike/strike.cpp
index d9b96bfe7f..f87fa925a5 100644
--- a/src/ToolBox/SOS/Strike/strike.cpp
+++ b/src/ToolBox/SOS/Strike/strike.cpp
@@ -11545,6 +11545,10 @@ public:
}
ExtOut("=============================================================================\n");
+#ifdef FEATURE_PAL
+ // Temporary until we get a process exit notification plumbed from lldb
+ UninitCorDebugInterface();
+#endif
return S_OK;
}
};
diff --git a/src/debug/daccess/dacdbiimpl.cpp b/src/debug/daccess/dacdbiimpl.cpp
index 0535c57dec..619eb06f2d 100644
--- a/src/debug/daccess/dacdbiimpl.cpp
+++ b/src/debug/daccess/dacdbiimpl.cpp
@@ -5615,26 +5615,11 @@ void DacDbiInterfaceImpl::GetContext(VMPTR_Thread vmThread, DT_CONTEXT * pContex
if (pFilterContext == NULL)
{
// If the filter context is NULL, then we use the true context of the thread.
-
-#ifdef FEATURE_DBGIPC_TRANSPORT_DI
- // GetThreadContext() is currently not implemented in ShimRemoteDataTarget, which is used with our pipe transport
- // (FEATURE_DBGIPC_TRANSPORT_DI). Pipe transport is used on POSIX system, but occasionally we can turn it on for Windows for testing,
- // and then we'd like to have same behavior as on POSIX system (zero context).
- //
- // We don't have a good way to implement GetThreadContext() in ShimRemoteDataTarget yet, because we have no way to convert a thread ID to a
- // thread handle. The function to do the conversion is OpenThread(), which is not implemented in PAL. Even if we had a handle, PAL implementation
- // of GetThreadContext() is very limited and doesn't work when we're not attached with ptrace.
- // Instead, we just zero out the seed CONTEXT for the stackwalk. This tells the stackwalker to
- // start the stackwalk with the first explicit frame. This won't work when we do native debugging,
- // but that won't happen on the POSIX systems since they don't support native debugging.
- ZeroMemory(pContextBuffer, sizeof(*pContextBuffer));
-#else // DFEATURE_DBGIPC_TRANSPORT_DI
pContextBuffer->ContextFlags = CONTEXT_ALL;
IfFailThrow(m_pTarget->GetThreadContext(pThread->GetOSThreadId(),
pContextBuffer->ContextFlags,
sizeof(*pContextBuffer),
reinterpret_cast<BYTE *>(pContextBuffer)));
-#endif // DFEATURE_DBGIPC_TRANSPORT_DI
}
else
{
diff --git a/src/debug/di/shimremotedatatarget.cpp b/src/debug/di/shimremotedatatarget.cpp
index cf60e226b7..c6036f6324 100644
--- a/src/debug/di/shimremotedatatarget.cpp
+++ b/src/debug/di/shimremotedatatarget.cpp
@@ -281,12 +281,27 @@ ShimRemoteDataTarget::GetThreadContext(
BYTE * pContext)
{
ReturnFailureIfStateNotOk();
-
+
+#ifdef FEATURE_DBGIPC_TRANSPORT_DI
+ // GetThreadContext() is currently not implemented in ShimRemoteDataTarget, which is used with our pipe transport
+ // (FEATURE_DBGIPC_TRANSPORT_DI). Pipe transport is used on POSIX system, but occasionally we can turn it on for Windows for testing,
+ // and then we'd like to have same behavior as on POSIX system (zero context).
+ //
+ // We don't have a good way to implement GetThreadContext() in ShimRemoteDataTarget yet, because we have no way to convert a thread ID to a
+ // thread handle. The function to do the conversion is OpenThread(), which is not implemented in PAL. Even if we had a handle, PAL implementation
+ // of GetThreadContext() is very limited and doesn't work when we're not attached with ptrace.
+ // Instead, we just zero out the seed CONTEXT for the stackwalk. This tells the stackwalker to
+ // start the stackwalk with the first explicit frame. This won't work when we do native debugging,
+ // but that won't happen on the POSIX systems since they don't support native debugging.
+ ZeroMemory(pContext, contextSize);
+ return S_OK;
+#else
// ICorDebugDataTarget::GetThreadContext() and ICorDebugDataTarget::SetThreadContext() are currently only
// required for interop-debugging and inspection of floating point registers, both of which are not
// implemented on Mac.
_ASSERTE(!"The remote data target doesn't know how to get a thread's CONTEXT.");
return E_NOTIMPL;
+#endif // DFEATURE_DBGIPC_TRANSPORT_DI
}
// impl of interface method ICorDebugMutableDataTarget::SetThreadContext
diff --git a/src/dlls/mscoree/unixinterface.cpp b/src/dlls/mscoree/unixinterface.cpp
index 1cd9d679b8..21419173e9 100644
--- a/src/dlls/mscoree/unixinterface.cpp
+++ b/src/dlls/mscoree/unixinterface.cpp
@@ -130,7 +130,7 @@ HRESULT ExecuteAssembly(
}
*exitCode = -1;
- DWORD error = PAL_InitializeCoreCLR(exePath, coreClrPath, true);
+ DWORD error = PAL_InitializeCoreCLR(exePath);
HRESULT hr = HRESULT_FROM_WIN32(error);
// If PAL initialization failed, then we should return right away and avoid
diff --git a/src/pal/inc/pal.h b/src/pal/inc/pal.h
index e6c287f5d8..b9d537f654 100644
--- a/src/pal/inc/pal.h
+++ b/src/pal/inc/pal.h
@@ -478,9 +478,7 @@ PALIMPORT
DWORD
PALAPI
PAL_InitializeCoreCLR(
- const char *szExePath,
- const char *szCoreCLRPath,
- BOOL fStayInPAL);
+ const char *szExePath);
PALIMPORT
DWORD_PTR
@@ -5877,12 +5875,6 @@ VOID
PALAPI
PAL_LeaveTop();
-// Returns TRUE if the argument HMODULE denotes the PAL itself.
-PALIMPORT
-BOOL
-PALAPI
-PAL_IsSelf(IN HMODULE);
-
#ifdef __cplusplus
//
// A holder to enter the PAL for a specific region of code.
diff --git a/src/pal/src/debug/debug.cpp b/src/pal/src/debug/debug.cpp
index 536d40a283..1e108eef4f 100644
--- a/src/pal/src/debug/debug.cpp
+++ b/src/pal/src/debug/debug.cpp
@@ -37,6 +37,7 @@ Revision History:
#include "pal/debug.h"
#include "pal/misc.h"
#include "pal/malloc.hpp"
+#include "pal/module.h"
#include "pal/virtual.h"
#include <signal.h>
@@ -330,6 +331,9 @@ run_debug_command (const char *command)
}
#endif // ENABLE_RUN_ON_DEBUG_BREAK
+#define PID_TEXT "PAL_EXE_PID="
+#define EXE_TEXT "PAL_EXE_NAME="
+
static
int
DebugBreakCommand()
@@ -337,15 +341,13 @@ DebugBreakCommand()
#ifdef ENABLE_RUN_ON_DEBUG_BREAK
const char *command_string = getenv (PAL_RUN_ON_DEBUG_BREAK);
if (command_string) {
- char pid_buf[sizeof ("PAL_EXE_PID=") + 32];
- char exe_buf[sizeof ("PAL_EXE_NAME=") + MAX_PATH + 1];
- extern char g_ExePath[MAX_PATH];
- if (snprintf (pid_buf, sizeof (pid_buf),
- "PAL_EXE_PID=%d", getpid()) <= 0) {
+ char pid_buf[sizeof (PID_TEXT) + 32];
+ char exe_buf[sizeof (EXE_TEXT) + MAX_PATH + 1];
+
+ if (snprintf (pid_buf, sizeof (pid_buf), PID_TEXT "%d", getpid()) <= 0) {
goto FAILED;
}
- if (snprintf (exe_buf, sizeof (exe_buf),
- "PAL_EXE_NAME=%s", g_ExePath) <= 0) {
+ if (snprintf (exe_buf, sizeof (exe_buf), EXE_TEXT "%ls", (wchar_t *)exe_module.lib_name) <= 0) {
goto FAILED;
}
diff --git a/src/pal/src/include/pal/module.h b/src/pal/src/include/pal/module.h
index fada2ae169..e0986de8e0 100644
--- a/src/pal/src/include/pal/module.h
+++ b/src/pal/src/include/pal/module.h
@@ -44,14 +44,13 @@ typedef VOID (PALAPI *PUNREGISTER_MODULE)(HINSTANCE); /* used to clean
typedef struct _MODSTRUCT
{
- HMODULE self; /* circular reference to this module */
- void *dl_handle; /* handle returned by dlopen() */
- HINSTANCE hinstance; /* handle returned by PAL_RegisterLibrary */
- LPWSTR lib_name; /* full path of module */
- INT refcount; /* reference count */
- /* -1 means infinite reference count - module is never released */
- BOOL ThreadLibCalls; /* TRUE for DLL_THREAD_ATTACH/DETACH notifications
- enabled, FALSE if they are disabled */
+ HMODULE self; /* circular reference to this module */
+ void *dl_handle; /* handle returned by dlopen() */
+ HINSTANCE hinstance; /* handle returned by PAL_RegisterLibrary */
+ LPWSTR lib_name; /* full path of module */
+ INT refcount; /* reference count */
+ /* -1 means infinite reference count - module is never released */
+ BOOL threadLibCalls; /* TRUE for DLL_THREAD_ATTACH/DETACH notifications enabled, FALSE if they are disabled */
#if RETURNS_NEW_HANDLES_ON_REPEAT_DLOPEN
ino_t inode;
@@ -65,26 +64,23 @@ typedef struct _MODSTRUCT
struct _MODSTRUCT *prev;
} MODSTRUCT;
-extern MODSTRUCT pal_module;
-
+extern MODSTRUCT exe_module;
/*++
Function :
- LoadInitializeModules
+ LOADInitializeModules
Initialize the process-wide list of modules (2 initial modules : 1 for
the executable and 1 for the PAL)
Parameters :
- LPWSTR exe_name : full path to executable
+ None
Return value :
TRUE on success, FALSE on failure
-Notes :
- the module manager takes ownership of the string
--*/
-BOOL LOADInitializeModules(LPWSTR exe_name);
+BOOL LOADInitializeModules();
/*++
Function :
@@ -183,19 +179,33 @@ Return value:
BOOL PAL_LOADUnloadPEFile(void * ptr);
/*++
- LOADInitCoreCLRModules
+ LOADInitializeCoreCLRModule
- Run the initialization methods for CoreCLR modules that used to be standalone dynamic libraries (PALRT and
- mscorwks).
+ Run the initialization methods for CoreCLR module.
Parameters:
- Core CLR path
+ None
Return value:
TRUE if successful
FALSE if failure
--*/
-BOOL LOADInitCoreCLRModules(const char *szCoreCLRPath);
+BOOL LOADInitializeCoreCLRModule();
+
+/*++
+Function :
+ LOADGetPalLibrary
+
+ Load and initialize the PAL module.
+
+Parameters :
+ None
+
+Return value :
+ handle to loaded module
+
+--*/
+MODSTRUCT *LOADGetPalLibrary();
#ifdef __cplusplus
}
diff --git a/src/pal/src/include/pal/procobj.hpp b/src/pal/src/include/pal/procobj.hpp
index c3619300a3..2e00200736 100644
--- a/src/pal/src/include/pal/procobj.hpp
+++ b/src/pal/src/include/pal/procobj.hpp
@@ -102,12 +102,17 @@ namespace CorUnix
);
PAL_ERROR
- CreateInitialProcessAndThreadObjects(
+ InitializeProcessCommandLine(
CPalThread *pThread,
LPWSTR lpwstrCmdLine,
LPWSTR lpwstrFullPath
);
+ PAL_ERROR
+ CreateInitialProcessAndThreadObjects(
+ CPalThread *pThread
+ );
+
extern IPalObject *g_pobjProcess;
}
diff --git a/src/pal/src/init/pal.cpp b/src/pal/src/init/pal.cpp
index 14e5d0c984..c2e66a5d3e 100644
--- a/src/pal/src/init/pal.cpp
+++ b/src/pal/src/init/pal.cpp
@@ -85,6 +85,7 @@ SET_DEFAULT_DEBUG_CHANNEL(PAL);
Volatile<INT> init_count = 0;
Volatile<BOOL> shutdown_intent = 0;
+Volatile<LONG> g_coreclrInitialized = 0;
static BOOL g_fThreadDataAvailable = FALSE;
static pthread_mutex_t init_critsec_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -92,8 +93,6 @@ static pthread_mutex_t init_critsec_mutex = PTHREAD_MUTEX_INITIALIZER;
very first PAL_Initialize call, and is freed afterward. */
static PCRITICAL_SECTION init_critsec = NULL;
-char g_szCoreCLRPath[MAX_PATH] = { 0 };
-
static int Initialize(int argc, const char *const argv[], DWORD flags);
static BOOL INIT_IncreaseDescriptorLimit(void);
static LPWSTR INIT_FormatCommandLine (CPalThread *pThread, int argc, const char * const *argv);
@@ -103,8 +102,6 @@ static LPWSTR INIT_FindEXEPath(CPalThread *pThread, LPCSTR exe_name);
extern void PROCDumpThreadList(void);
#endif
-char g_ExePath[MAX_PATH] = { 0 };
-
#if defined(__APPLE__)
static bool RunningNatively()
{
@@ -230,19 +227,20 @@ Initialize(
InternalEnterCriticalSection(pThread, init_critsec); // here pThread is always NULL
- if(init_count==0)
+ if (init_count == 0)
{
// Set our pid.
gPID = getpid();
fFirstTimeInit = true;
+ exe_module.lib_name = NULL;
// Initialize the TLS lookaside cache
if (FALSE == TLSInitialize())
{
goto done;
}
-
+
// Initialize the environment.
if (FALSE == MiscInitialize())
{
@@ -263,11 +261,11 @@ Initialize(
if (VIRTUAL_PAGE_SIZE != getpagesize())
{
ASSERT("VIRTUAL_PAGE_SIZE is incorrect for this system!\n"
- "Change include/pal/virtual.h and clr/src/inc/stdmacros.h "
- "to reflect the correct page size of %d.\n", getpagesize());
+ "Change include/pal/virtual.h and clr/src/inc/stdmacros.h "
+ "to reflect the correct page size of %d.\n", getpagesize());
}
#endif // _DEBUG
-
+
if (!INIT_IncreaseDescriptorLimit())
{
ERROR("Unable to increase the file descriptor limit!\n");
@@ -276,7 +274,7 @@ Initialize(
}
/* initialize the shared memory infrastructure */
- if(!SHMInitialize())
+ if (!SHMInitialize())
{
ERROR("Shared memory initialization failed!\n");
goto CLEANUP0;
@@ -373,73 +371,84 @@ Initialize(
g_pSynchronizationManager =
CPalSynchMgrController::CreatePalSynchronizationManager(pThread);
- palError = ERROR_GEN_FAILURE;
-
if (NULL == g_pSynchronizationManager)
{
+ palError = ERROR_NOT_ENOUGH_MEMORY;
ERROR("Failure creating synchronization manager\n");
goto CLEANUP1c;
}
+ }
+ else
+ {
+ pThread = InternalGetCurrentThread();
+ }
+
+ palError = ERROR_GEN_FAILURE;
- if (argc > 0 && argv != NULL)
+ if (argc > 0 && argv != NULL)
+ {
+ /* build the command line */
+ command_line = INIT_FormatCommandLine(pThread, argc, argv);
+ if (NULL == command_line)
{
- /* build the command line */
- command_line = INIT_FormatCommandLine(pThread, argc, argv);
- if (NULL == command_line)
- {
- ERROR("Error building command line\n");
- goto CLEANUP1d;
- }
+ ERROR("Error building command line\n");
+ goto CLEANUP1d;
+ }
- /* find out the application's full path */
- exe_path = INIT_FindEXEPath(pThread, argv[0]);
- if (NULL == exe_path)
- {
- ERROR("Unable to find exe path\n");
- goto CLEANUP1e;
- }
+ /* find out the application's full path */
+ exe_path = INIT_FindEXEPath(pThread, argv[0]);
+ if (NULL == exe_path)
+ {
+ ERROR("Unable to find exe path\n");
+ goto CLEANUP1e;
+ }
- if (!WideCharToMultiByte(CP_ACP, 0, exe_path, -1, g_ExePath,
- sizeof(g_ExePath), NULL, NULL))
- {
- ERROR("Failed to store process executable path\n");
- goto CLEANUP2;
- }
+ if (NULL == command_line || NULL == exe_path)
+ {
+ ERROR("Failed to process command-line parameters!\n");
+ goto CLEANUP2;
+ }
- if (NULL == command_line || NULL == exe_path)
- {
- ERROR("Failed to process command-line parameters!\n");
- goto CLEANUP2;
- }
+ palError = InitializeProcessCommandLine(
+ pThread,
+ command_line,
+ exe_path);
+
+ if (NO_ERROR != palError)
+ {
+ ERROR("Unable to initialize command line\n");
+ goto CLEANUP2;
+ }
+
+ // InitializeProcessCommandLine took ownership of this memory.
+ command_line = NULL;
+
+ // Save the exe path in the exe module struct
+ InternalFree(pThread, exe_module.lib_name);
+ exe_module.lib_name = exe_path;
#ifdef PAL_PERF
- // Initialize the Profiling structure
- if(FALSE == PERFInitialize(command_line, exe_path))
- {
- ERROR("Performance profiling initial failed\n");
- goto done;
- }
- PERFAllocThreadInfo();
+ // Initialize the Profiling structure
+ if(FALSE == PERFInitialize(command_line, exe_path))
+ {
+ ERROR("Performance profiling initial failed\n");
+ goto done;
+ }
+ PERFAllocThreadInfo();
#endif
- }
+ }
+ if(init_count == 0)
+ {
//
// Create the initial process and thread objects
//
-
- palError = CreateInitialProcessAndThreadObjects(
- pThread,
- command_line,
- exe_path
- );
-
+ palError = CreateInitialProcessAndThreadObjects(pThread);
if (NO_ERROR != palError)
{
ERROR("Unable to create initial process and thread objects\n");
goto CLEANUP2;
}
- // CreateInitialProcessAndThreadObjects took ownership of this memory.
- command_line = NULL;
if (flags & PAL_INITIALIZE_SYNC_THREAD)
{
@@ -470,8 +479,8 @@ Initialize(
goto CLEANUP6;
}
- /* initialize module manager */
- if (FALSE == LOADInitializeModules(exe_path))
+ /* Initialize module manager */
+ if (FALSE == LOADInitializeModules())
{
ERROR("Unable to initialize module manager\n");
palError = GetLastError();
@@ -587,6 +596,7 @@ exit :
return retval;
}
+
/*++
Function:
PAL_InitializeCoreCLR
@@ -599,11 +609,6 @@ Abstract:
This routine also makes sure the psuedo dynamic libraries PALRT and mscorwks have their initialization
methods called.
- Which PAL (if any) we're executing in the context of is a function of the return code and the fStayInPAL
- argument. If an error is returned then the PAL context is that of the caller (i.e. this call doesn't switch
- into the context of the PAL being initialized). Otherwise (on success) the context is remains in that of the
- new PAL if and only if fStayInPAL is TRUE.
-
Return:
ERROR_SUCCESS if successful
An error code, if it failed
@@ -611,59 +616,26 @@ Return:
--*/
PAL_ERROR
PALAPI
-PAL_InitializeCoreCLR(
- const char *szExePath,
- const char *szCoreCLRPath,
- BOOL fStayInPAL)
+PAL_InitializeCoreCLR(const char *szExePath)
{
- // Check for a repeated call (this is a no-op).
- if (g_szCoreCLRPath[0] != '\0')
- {
- if (fStayInPAL)
- {
- PAL_Enter(PAL_BoundaryTop);
- }
- return ERROR_SUCCESS;
- }
-
- // Make sure it's an absolute path.
- if (szCoreCLRPath[0] != '/')
- {
- return ERROR_INVALID_PARAMETER;
- }
-
- // Check we can handle the length of the installation directory.
- size_t cchCoreCLRPath = strlen(szCoreCLRPath);
- if (cchCoreCLRPath >= sizeof(g_szCoreCLRPath))
- {
- ASSERT("CoreCLR installation path is too long");
- return ERROR_BAD_PATHNAME;
- }
-
- // Stash a copy of the CoreCLR installation path in a global variable.
- // Make sure it's terminated with a slash.
- if (strcpy_s(g_szCoreCLRPath, sizeof(g_szCoreCLRPath), szCoreCLRPath) != SAFECRT_SUCCESS)
- {
- ASSERT("strcpy_s failed!");
- return ERROR_FILENAME_EXCED_RANGE;
- }
-
-#ifdef __APPLE__ // Fake up a command line to call PAL_Initialize with.
- const char *argv[] = { "CoreCLR" };
- int result = PAL_Initialize(1, argv);
-#else // __APPLE__
// Fake up a command line to call PAL_Initialize with.
int result = PAL_Initialize(1, &szExePath);
-#endif // __APPLE__
if (result != 0)
{
return GetLastError();
}
+ // Check for a repeated call (this is a no-op).
+ if (InterlockedIncrement(&g_coreclrInitialized) > 1)
+ {
+ PAL_Enter(PAL_BoundaryTop);
+ return ERROR_SUCCESS;
+ }
+
// Now that the PAL is initialized it's safe to call the initialization methods for the code that used to
// be dynamically loaded libraries but is now statically linked into CoreCLR just like the PAL, i.e. the
// PAL RT and mscorwks.
- if (!LOADInitCoreCLRModules(g_szCoreCLRPath))
+ if (!LOADInitializeCoreCLRModule())
{
return ERROR_DLL_INIT_FAILED;
}
@@ -673,10 +645,6 @@ PAL_InitializeCoreCLR(
return ERROR_GEN_FAILURE;
}
- if (!fStayInPAL)
- {
- PAL_Leave(PAL_BoundaryTop);
- }
return ERROR_SUCCESS;
}
diff --git a/src/pal/src/init/sxs.cpp b/src/pal/src/init/sxs.cpp
index aeaa19353d..e3fed10849 100644
--- a/src/pal/src/init/sxs.cpp
+++ b/src/pal/src/init/sxs.cpp
@@ -25,28 +25,6 @@ SET_DEFAULT_DEBUG_CHANNEL(SXS);
PAL_ERROR AllocatePalThread(CPalThread **ppThread);
-/*++
-Function:
- PAL_IsSelf
-
-Abstract:
- Returns TRUE iff the argument module corresponds to this PAL.
- In other words, clients should not call PAL_Leave when calling
- functions obtained from this module using GetProcAddress.
---*/
-BOOL
-PALAPI
-PAL_IsSelf(HMODULE hModule)
-{
- ENTRY("PAL_IsSelf(hModule=%p)\n", hModule);
-
- MODSTRUCT *module = (MODSTRUCT *) hModule;
- BOOL fIsSelf = (module->dl_handle == pal_module.dl_handle);
-
- LOGEXIT("PAL_IsSelf returns %d\n", fIsSelf);
- return fIsSelf;
-}
-
/************************* Enter *************************/
/*++
diff --git a/src/pal/src/loader/module.cpp b/src/pal/src/loader/module.cpp
index ad61285a9f..2a7d2c4b54 100644
--- a/src/pal/src/loader/module.cpp
+++ b/src/pal/src/loader/module.cpp
@@ -89,7 +89,9 @@ SET_DEFAULT_DEBUG_CHANNEL(LOADER);
CRITICAL_SECTION module_critsec;
MODSTRUCT exe_module; /* always the first, in the in-load-order list */
-MODSTRUCT pal_module; /* always the second, in the in-load-order list */
+MODSTRUCT *pal_module = NULL;
+
+char g_szCoreCLRPath[MAX_PATH] = { 0 };
/* static function declarations ***********************************************/
@@ -158,14 +160,14 @@ LoadLibraryExA(
(lpLibFileName)?lpLibFileName:"NULL",
(lpLibFileName)?lpLibFileName:"NULL");
- if(NULL == lpLibFileName)
+ if (NULL == lpLibFileName)
{
ERROR("lpLibFileName is NULL;Exit.\n");
SetLastError(ERROR_MOD_NOT_FOUND);
goto Done;
}
- if(lpLibFileName[0]=='\0')
+ if (lpLibFileName[0]=='\0')
{
ERROR("can't load library with NULL file name...\n");
SetLastError(ERROR_INVALID_PARAMETER);
@@ -175,7 +177,7 @@ LoadLibraryExA(
pThread = InternalGetCurrentThread();
/* do the Dos/Unix conversion on our own copy of the name */
lpstr = InternalStrdup(pThread, lpLibFileName);
- if(!lpstr)
+ if (!lpstr)
{
ERROR("InternalStrdup failure!\n");
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
@@ -227,14 +229,14 @@ LoadLibraryExW(
lpLibFileName?lpLibFileName:W16_NULLSTRING,
lpLibFileName?lpLibFileName:W16_NULLSTRING);
- if(NULL == lpLibFileName)
+ if (NULL == lpLibFileName)
{
ERROR("lpLibFileName is NULL;Exit.\n");
SetLastError(ERROR_MOD_NOT_FOUND);
goto done;
}
- if(lpLibFileName[0]==0)
+ if (lpLibFileName[0]==0)
{
ERROR("Can't load library with NULL file name...\n");
SetLastError(ERROR_INVALID_PARAMETER);
@@ -245,10 +247,10 @@ LoadLibraryExW(
name_length = WideCharToMultiByte(CP_ACP, 0, lpLibFileName, -1, lpstr,
MAX_PATH, NULL, NULL);
- if( name_length == 0 )
+ if (name_length == 0)
{
DWORD dwLastError = GetLastError();
- if( dwLastError == ERROR_INSUFFICIENT_BUFFER )
+ if (dwLastError == ERROR_INSUFFICIENT_BUFFER)
{
ERROR("lpLibFileName is larger than MAX_PATH (%d)!\n", MAX_PATH);
}
@@ -297,14 +299,14 @@ GetProcAddress(
/* parameter validation */
- if( (lpProcName == NULL) || (*lpProcName == '\0') )
+ if ((lpProcName == NULL) || (*lpProcName == '\0'))
{
TRACE("No function name given\n");
SetLastError(ERROR_INVALID_PARAMETER);
goto done;
}
- if( !LOADValidateModule(module) )
+ if (!LOADValidateModule(module))
{
TRACE("Invalid module handle %p\n", hModule);
SetLastError(ERROR_INVALID_HANDLE);
@@ -316,7 +318,7 @@ GetProcAddress(
because of the address range reserved for ordinals contain can
be a valid string address on non-Windows systems
*/
- if( (DWORD_PTR)lpProcName < VIRTUAL_PAGE_SIZE )
+ if ((DWORD_PTR)lpProcName < VIRTUAL_PAGE_SIZE)
{
ASSERT("Attempt to locate symbol by ordinal?!\n");
}
@@ -326,7 +328,7 @@ GetProcAddress(
// If we're looking for a symbol inside the PAL, we try the PAL_ variant
// first because otherwise we run the risk of having the non-PAL_
// variant preferred over the PAL's implementation.
- if (module->dl_handle == pal_module.dl_handle)
+ if (pal_module && module->dl_handle == pal_module->dl_handle)
{
int iLen = 4 + strlen(lpProcName) + 1;
LPSTR lpPALProcName = (LPSTR) alloca(iLen);
@@ -363,13 +365,13 @@ GetProcAddress(
/* if we don't know the module's full name yet, this is our chance to
obtain it */
- if(!module->lib_name && module->dl_handle)
+ if (!module->lib_name && module->dl_handle)
{
const char* libName = PAL_dladdr((LPVOID)ProcAddress);
if (libName)
{
module->lib_name = UTIL_MBToWC_Alloc(libName, -1);
- if(NULL == module->lib_name)
+ if (NULL == module->lib_name)
{
ERROR("MBToWC failure; can't save module's full name\n");
}
@@ -424,14 +426,14 @@ FreeLibrary(
goto done;
}
- if( !LOADValidateModule( module ) )
+ if (!LOADValidateModule(module))
{
TRACE("Can't free invalid module handle %p\n", hLibModule);
SetLastError(ERROR_INVALID_HANDLE);
goto done;
}
- if( module->refcount == -1 )
+ if (module->refcount == -1)
{
/* special module - never released */
retval = TRUE;
@@ -442,7 +444,7 @@ FreeLibrary(
TRACE("Reference count for module %p (named %S) decreases to %d\n",
module, MODNAME(module), module->refcount);
- if( module->refcount != 0 )
+ if (module->refcount != 0)
{
retval = TRUE;
goto done;
@@ -462,7 +464,7 @@ FreeLibrary(
module->self = NULL;
/* Call DllMain if the module contains one */
- if(module->pDllMain)
+ if (module->pDllMain)
{
TRACE("Calling DllMain (%p) for module %S\n",
module->pDllMain,
@@ -497,7 +499,7 @@ FreeLibrary(
#endif /* !_NO_DEBUG_MESSAGES_ */
}
- if(module->dl_handle && 0 != dlclose(module->dl_handle))
+ if (module->dl_handle && 0 != dlclose(module->dl_handle))
{
/* report dlclose() failure, but proceed anyway. */
WARN("dlclose() call failed! error message is \"%s\"\n", dlerror());
@@ -570,7 +572,7 @@ GetModuleFileNameA(
hModule, lpFileName, nSize);
LockModuleList();
- if(hModule && !LOADValidateModule((MODSTRUCT *)hModule))
+ if (hModule && !LOADValidateModule((MODSTRUCT *)hModule))
{
TRACE("Can't find name for invalid module handle %p\n", hModule);
SetLastError(ERROR_INVALID_HANDLE);
@@ -578,7 +580,7 @@ GetModuleFileNameA(
}
wide_name = LOADGetModuleFileName((MODSTRUCT *)hModule);
- if(!wide_name)
+ if (!wide_name)
{
ASSERT("Can't find name for valid module handle %p\n", hModule);
SetLastError(ERROR_INTERNAL_ERROR);
@@ -589,7 +591,7 @@ GetModuleFileNameA(
name_length = WideCharToMultiByte(CP_ACP, 0, wide_name, -1, lpFileName,
nSize, NULL, NULL);
- if( name_length==0 )
+ if (name_length == 0)
{
TRACE("Buffer too small to copy module's file name.\n");
SetLastError(ERROR_INSUFFICIENT_BUFFER);
@@ -638,7 +640,7 @@ GetModuleFileNameW(
wcscpy_s(lpFileName, nSize, W(""));
- if(hModule && !LOADValidateModule((MODSTRUCT *)hModule))
+ if (hModule && !LOADValidateModule((MODSTRUCT *)hModule))
{
TRACE("Can't find name for invalid module handle %p\n", hModule);
SetLastError(ERROR_INVALID_HANDLE);
@@ -646,7 +648,7 @@ GetModuleFileNameW(
}
wide_name = LOADGetModuleFileName((MODSTRUCT *)hModule);
- if(!wide_name)
+ if (!wide_name)
{
TRACE("Can't find name for valid module handle %p\n", hModule);
SetLastError(ERROR_INTERNAL_ERROR);
@@ -656,7 +658,7 @@ GetModuleFileNameW(
/* Copy module name into supplied buffer */
name_length = lstrlenW(wide_name);
- if(name_length >= (INT)nSize)
+ if (name_length >= (INT)nSize)
{
TRACE("Buffer too small to copy module's file name.\n");
SetLastError(ERROR_INSUFFICIENT_BUFFER);
@@ -692,7 +694,7 @@ PAL_RegisterModule(
HINSTANCE hinstance = NULL;
int err = PAL_InitializeDLL();
- if(err == 0)
+ if (err == 0)
{
PERF_ENTRY(PAL_RegisterModule);
ENTRY("PAL_RegisterModule(%s)\n", lpLibFileName ? lpLibFileName : "");
@@ -838,77 +840,64 @@ Function :
the executable and 1 for the PAL)
Parameters :
- LPWSTR exe_name : full path to executable
+ None
-Return value:
+Return value :
TRUE if initialization succeedded
FALSE otherwise
-Notes :
- the module manager takes ownership of the exe_name string
--*/
extern "C"
-BOOL LOADInitializeModules(LPWSTR exe_name)
+BOOL LOADInitializeModules()
{
#if RETURNS_NEW_HANDLES_ON_REPEAT_DLOPEN
- LPSTR pszExeName = NULL;
- CPalThread *pThread = NULL;
+ LPSTR pszExeName = NULL;
#endif
- BOOL fRetCode = FALSE;
+ BOOL fRetCode = FALSE;
+ LPWSTR lpwstr = NULL;
- if(exe_module.prev)
+ if (exe_module.prev)
{
ERROR("Module manager already initialized!\n");
- SetLastError(ERROR_INTERNAL_ERROR);
- goto Done;
+ goto exit;
}
InternalInitializeCriticalSection(&module_critsec);
- /* initialize module for main executable */
+ // Initialize module for main executable
TRACE("Initializing module for main executable\n");
+
exe_module.self = (HMODULE)&exe_module;
exe_module.dl_handle = dlopen(NULL, RTLD_LAZY);
- if(!exe_module.dl_handle)
+ if (!exe_module.dl_handle)
{
- ASSERT("Main executable module will be broken : dlopen(NULL) failed. "
- "dlerror message is \"%s\" \n", dlerror());
+ ERROR("Main executable module will be broken : dlopen(NULL) failed"
+ "dlerror message is \"%s\" \n", dlerror());
+ goto exit;
}
- exe_module.lib_name = exe_name;
exe_module.refcount = -1;
- exe_module.next = &pal_module;
- exe_module.prev = &pal_module;
+ exe_module.next = &exe_module;
+ exe_module.prev = &exe_module;
exe_module.pDllMain = NULL;
exe_module.hinstance = NULL;
- exe_module.ThreadLibCalls = TRUE;
-
- TRACE("Initializing module for PAL library\n");
- pal_module.self = (HANDLE)&pal_module;
- pal_module.lib_name = NULL;
- pal_module.dl_handle = NULL;
- pal_module.refcount= - 1;
- pal_module.next = &exe_module;
- pal_module.prev = &exe_module;
- pal_module.pDllMain = NULL;
- pal_module.hinstance = NULL;
- pal_module.ThreadLibCalls = TRUE;
+ exe_module.threadLibCalls = TRUE;
// For platforms where we can't trust the handle to be constant, we need to
// store the inode/device pairs for the modules we just initialized.
#if RETURNS_NEW_HANDLES_ON_REPEAT_DLOPEN
{
struct stat stat_buf;
- pszExeName = UTIL_WCToMB_Alloc(exe_name, -1);
+ pszExeName = UTIL_WCToMB_Alloc(exe_module.lib_name, -1);
if (NULL == pszExeName)
{
ERROR("WCToMB failure, unable to get full name of exe\n");
- goto Done;
+ goto exit;
}
if ( -1 == stat(pszExeName, &stat_buf))
{
SetLastError(ERROR_MOD_NOT_FOUND);
- goto Done;
+ goto exit;
}
TRACE("Executable has inode %d and device %d\n",
@@ -916,32 +905,29 @@ BOOL LOADInitializeModules(LPWSTR exe_name)
exe_module.inode = stat_buf.st_ino;
exe_module.device = stat_buf.st_dev;
- if ( -1 == stat(librotor_fname, &stat_buf))
- {
- SetLastError(ERROR_MOD_NOT_FOUND);
- goto Done;
- }
-
- TRACE("PAL Library has inode %d and device %d\n",
- stat_buf.st_ino, stat_buf.st_dev);
-
- pal_module.inode = stat_buf.st_ino;
- pal_module.device = stat_buf.st_dev;
}
#endif
// If we got here, init succeeded.
fRetCode = TRUE;
- Done:
- if (!fRetCode && GetLastError() == ERROR_SUCCESS)
+
+exit:
+ CPalThread *pThread = InternalGetCurrentThread();
+ if (!fRetCode)
{
- ASSERT("returning failure, but last error not set\n");
+ InternalFree(pThread, lpwstr);
+ if (GetLastError() == ERROR_SUCCESS)
+ {
+ SetLastError(ERROR_INTERNAL_ERROR);
+ }
}
#if RETURNS_NEW_HANDLES_ON_REPEAT_DLOPEN
- pThread = InternalGetCurrentThread();
if (pszExeName)
+ {
InternalFree(pThread, pszExeName);
+ }
+
#endif
TRACE("Module manager initialization returning %d.\n", fRetCode);
return fRetCode;
@@ -964,7 +950,7 @@ void LOADFreeModules(BOOL bTerminateUnconditionally)
MODSTRUCT *module;
CPalThread *pThread = InternalGetCurrentThread();
- if(!exe_module.prev)
+ if (!exe_module.prev)
{
ERROR("Module manager not initialized!\n");
return;
@@ -980,10 +966,10 @@ void LOADFreeModules(BOOL bTerminateUnconditionally)
// Call DllMain if the module contains one and if we're supposed
// to call DllMains.
- if( !bTerminateUnconditionally && module->pDllMain )
+ if (!bTerminateUnconditionally && module->pDllMain)
{
/* Exception-safe call to DllMain */
- LOAD_SEH_CallDllMain( module, DLL_PROCESS_DETACH, (LPVOID)-1 );
+ LOAD_SEH_CallDllMain(module, DLL_PROCESS_DETACH, (LPVOID)-1);
}
/* Remove the current MODSTRUCT from the list, then free its memory */
@@ -996,12 +982,12 @@ void LOADFreeModules(BOOL bTerminateUnconditionally)
InternalFree( pThread, module->lib_name );
module->lib_name = NULL;
- if (module != &exe_module && module != &pal_module)
+ if (module != &exe_module)
{
InternalFree( pThread, module );
}
}
- while( module != &exe_module );
+ while (module != &exe_module);
/* Flag the module manager as uninitialized */
exe_module.prev = NULL;
@@ -1074,9 +1060,9 @@ void LOADCallDllMain(DWORD dwReason, LPVOID lpReserved)
if (!InLoadOrder)
module = module->prev;
- if (module->ThreadLibCalls)
+ if (module->threadLibCalls)
{
- if(module->pDllMain)
+ if (module->pDllMain)
{
#if !_NO_DEBUG_MESSAGES_
/* reset ENTRY nesting level back to zero while inside the callback... */
@@ -1132,7 +1118,7 @@ DisableThreadLibraryCalls(
LockModuleList();
module = (MODSTRUCT *) hLibModule;
- if(!LOADValidateModule(module))
+ if (!LOADValidateModule(module))
{
// DisableThreadLibraryCalls() does nothing when given
// an invalid module handle. This matches the Windows
@@ -1142,7 +1128,7 @@ DisableThreadLibraryCalls(
goto done;
}
- module->ThreadLibCalls = FALSE;
+ module->threadLibCalls = FALSE;
ret = TRUE;
done:
@@ -1181,10 +1167,10 @@ static BOOL LOADValidateModule(MODSTRUCT *module)
really a module (HMODULEs are actually MODSTRUCT pointers) */
do
{
- if(module == modlist_enum)
+ if (module == modlist_enum)
{
/* found it; check its integrity to be on the safe side */
- if(module->self != module)
+ if (module->self != module)
{
ERROR("Found corrupt module %p!\n",module);
UnlockModuleList();
@@ -1224,7 +1210,7 @@ static LPWSTR LOADGetModuleFileName(MODSTRUCT *module)
{
LPWSTR module_name;
/* special case : if module is NULL, we want the name of the executable */
- if(!module)
+ if (!module)
{
module_name = exe_module.lib_name;
TRACE("Returning name of main executable\n");
@@ -1265,15 +1251,15 @@ static MODSTRUCT *LOADAllocModule(void *dl_handle, LPCSTR name)
pThread = InternalGetCurrentThread();
/* no match found : try to create a new module structure */
- module=(MODSTRUCT *) InternalMalloc(pThread, sizeof(MODSTRUCT));
- if(!module)
+ module = (MODSTRUCT *)InternalMalloc(pThread, sizeof(MODSTRUCT));
+ if (!module)
{
ERROR("malloc() failed! errno is %d (%s)\n", errno, strerror(errno));
return NULL;
}
wide_name = UTIL_MBToWC_Alloc(name, -1);
- if(NULL == wide_name)
+ if (NULL == wide_name)
{
ERROR("couldn't convert name to a wide-character string\n");
InternalFree(pThread, module);
@@ -1295,7 +1281,7 @@ static MODSTRUCT *LOADAllocModule(void *dl_handle, LPCSTR name)
#endif // NEED_DLCOMPAT
module->self = module;
module->hinstance = NULL;
- module->ThreadLibCalls = TRUE;
+ module->threadLibCalls = TRUE;
module->next = NULL;
module->prev = NULL;
@@ -1325,6 +1311,7 @@ static HMODULE LOADLoadLibrary(LPCSTR shortAsciiName, BOOL fDynamic)
MODSTRUCT *module = NULL;
void *dl_handle;
DWORD dwError;
+ DWORD retval;
// Check whether we have been requested to load 'libc'. If that's the case then use the
// full name of the library that is defined in <gnu/lib-names.h> by the LIBC_SO constant.
@@ -1344,9 +1331,7 @@ static HMODULE LOADLoadLibrary(LPCSTR shortAsciiName, BOOL fDynamic)
LockModuleList();
- /* see if file can be dlopen()ed; this should work even if it's already
- loaded */
-
+ // See if file can be dlopen()ed; this should work even if it's already loaded
{
// See GetProcAddress for an explanation why we leave the PAL.
PAL_LeaveHolder holder;
@@ -1407,7 +1392,7 @@ static HMODULE LOADLoadLibrary(LPCSTR shortAsciiName, BOOL fDynamic)
TRACE("Module doesn't exist : creating %s.\n", shortAsciiName);
module = LOADAllocModule(dl_handle, shortAsciiName);
- if(NULL == module)
+ if (NULL == module)
{
ERROR("couldn't create new module\n");
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
@@ -1426,8 +1411,7 @@ static HMODULE LOADLoadLibrary(LPCSTR shortAsciiName, BOOL fDynamic)
module->device = stat_buf.st_dev;
#endif
- /* If we get here, then we have created a new module structure. We can now
- get the address of DllMain if the module contains one. We save
+ /* We now get the address of DllMain if the module contains one. We save
the last error and restore it afterward, because our caller doesn't
care about GetProcAddress failures. */
dwError = GetLastError();
@@ -1437,13 +1421,11 @@ static HMODULE LOADLoadLibrary(LPCSTR shortAsciiName, BOOL fDynamic)
SetLastError(dwError);
/* If it did contain a DllMain, call it. */
- if(module->pDllMain)
+ if (module->pDllMain)
{
- DWORD dllmain_retval = FALSE;
-
- TRACE("Calling DllMain (%p) for module %S\n",
- module->pDllMain,
- module->lib_name ? module->lib_name : W16_NULLSTRING);
+ TRACE("Calling DllMain (%p) for module %S\n",
+ module->pDllMain,
+ module->lib_name ? module->lib_name : W16_NULLSTRING);
if (NULL == module->hinstance)
{
@@ -1472,7 +1454,7 @@ static HMODULE LOADLoadLibrary(LPCSTR shortAsciiName, BOOL fDynamic)
// This module may be foreign to our PAL, so leave our PAL.
// If it depends on us, it will re-enter.
PAL_LeaveHolder holder;
- dllmain_retval = module->pDllMain(module->hinstance, DLL_PROCESS_ATTACH, fDynamic ? NULL : (LPVOID)-1);
+ retval = module->pDllMain(module->hinstance, DLL_PROCESS_ATTACH, fDynamic ? NULL : (LPVOID)-1);
}
#if !_NO_DEBUG_MESSAGES_
@@ -1481,16 +1463,15 @@ static HMODULE LOADLoadLibrary(LPCSTR shortAsciiName, BOOL fDynamic)
#endif /* !_NO_DEBUG_MESSAGES_ */
}
- /* If DlMain(DLL_PROCESS_ATTACH) returns FALSE, we must immediately
- unload the module.*/
- if(FALSE == dllmain_retval)
+ // If DlMain(DLL_PROCESS_ATTACH) returns FALSE, we must immediately unload the module
+ if (!retval)
{
- TRACE("DllMain returned FALSE; unloading module.\n");
+ ERROR("DllMain returned FALSE; unloading module.\n");
module->pDllMain = NULL;
- FreeLibrary((HMODULE) module);
- ERROR("DllMain failed and returned NULL. \n");
+ FreeLibrary((HMODULE)module);
SetLastError(ERROR_DLL_INIT_FAILED);
module = NULL;
+ goto done;
}
}
else
@@ -1687,44 +1668,74 @@ BOOL PAL_LOADUnloadPEFile(void * ptr)
}
/*++
- LOADInitCoreCLRModules
+ LOADInitializeCoreCLRModule
- Run the initialization methods for CoreCLR modules that used to be standalone dynamic libraries (PALRT and
- mscorwks).
+ Run the initialization methods for CoreCLR module (the module containing this PAL).
Parameters:
- Core CLR path
+ None
Return value:
TRUE if successful
FALSE if failure
--*/
-BOOL LOADInitCoreCLRModules(
- const char *szCoreCLRPath)
+BOOL LOADInitializeCoreCLRModule()
{
- TRACE("PAL library is %s\n", szCoreCLRPath);
- LPWSTR lpwstr = UTIL_MBToWC_Alloc(szCoreCLRPath, -1);
- if(!lpwstr)
+ MODSTRUCT *module = LOADGetPalLibrary();
+ if (!module)
{
- ERROR("MBToWC failure, unable to save full name of PAL module\n");
+ ERROR("Can not load the PAL module\n");
return FALSE;
}
- pal_module.lib_name = lpwstr;
- pal_module.dl_handle = dlopen(szCoreCLRPath, RTLD_LAZY);
- if(!pal_module.dl_handle)
+ PDLLMAIN pRuntimeDllMain = (PDLLMAIN)dlsym(module->dl_handle, "CoreDllMain");
+ if (!pRuntimeDllMain)
{
- ERROR("PAL module will be broken : dlopen(%s) failed. dlerror message is \"%s\"\n ",
- szCoreCLRPath, dlerror());
+ ERROR("Can not find the CoreDllMain entry point\n");
return FALSE;
}
- PDLLMAIN pRuntimeDllMain = (PDLLMAIN)dlsym(pal_module.dl_handle, "CoreDllMain");
- if (!pRuntimeDllMain)
+ return pRuntimeDllMain(module->hinstance, DLL_PROCESS_ATTACH, NULL);
+}
+
+/*++
+Function :
+ LOADGetPalLibrary
+
+ Load and initialize the PAL module.
+
+Parameters :
+ None
+
+Return value :
+ pointer to module struct
+
+--*/
+MODSTRUCT *LOADGetPalLibrary()
+{
+ if (pal_module == NULL)
{
- ERROR("Can not find the CoreDllMain entry point in %s\n", szCoreCLRPath);
- return FALSE;
+ // Initialize the pal module (the module containing LOADPalLibrary). Assumes that
+ // the PAL is linked into the coreclr module because we use the module name containing
+ // this function for the coreclr path.
+ TRACE("Loading module for PAL library\n");
+
+ Dl_info info;
+ if (dladdr((PVOID)&LOADGetPalLibrary, &info) == 0)
+ {
+ ERROR("LOADGetPalLibrary: dladdr() failed. dlerror message is \"%s\"\n", dlerror());
+ goto exit;
+ }
+ // Stash a copy of the CoreCLR installation path in a global variable.
+ // Make sure it's terminated with a slash.
+ if (strcpy_s(g_szCoreCLRPath, sizeof(g_szCoreCLRPath), info.dli_fname) != SAFECRT_SUCCESS)
+ {
+ ERROR("LOADGetPalLibrary: strcpy_s failed!");
+ goto exit;
+ }
+ pal_module = (MODSTRUCT *)LOADLoadLibrary(info.dli_fname, FALSE);
}
- pal_module.hinstance = (HINSTANCE)LOADLoadLibrary(szCoreCLRPath, FALSE);
- return pRuntimeDllMain(pal_module.hinstance, DLL_PROCESS_ATTACH, NULL);
+
+exit:
+ return pal_module;
}
// Get base address of the module containing a given symbol
diff --git a/src/pal/src/misc/miscpalapi.cpp b/src/pal/src/misc/miscpalapi.cpp
index 88e285929a..45596a513e 100644
--- a/src/pal/src/misc/miscpalapi.cpp
+++ b/src/pal/src/misc/miscpalapi.cpp
@@ -68,7 +68,13 @@ PAL_GetPALDirectoryW( OUT LPWSTR lpDirectoryName, IN UINT cchDirectoryName )
PERF_ENTRY(PAL_GetPALDirectoryW);
ENTRY( "PAL_GetPALDirectoryW( %p, %d )\n", lpDirectoryName, cchDirectoryName );
- lpFullPathAndName = pal_module.lib_name;
+ MODSTRUCT *module = LOADGetPalLibrary();
+ if (!module)
+ {
+ SetLastError(ERROR_INTERNAL_ERROR);
+ goto EXIT;
+ }
+ lpFullPathAndName = module->lib_name;
if (lpFullPathAndName == NULL)
{
SetLastError(ERROR_INTERNAL_ERROR);
diff --git a/src/pal/src/thread/process.cpp b/src/pal/src/thread/process.cpp
index 498d05fc7d..63027d5a2f 100644
--- a/src/pal/src/thread/process.cpp
+++ b/src/pal/src/thread/process.cpp
@@ -121,11 +121,11 @@ CPalThread* CorUnix::pGThreadList;
DWORD g_dwThreadCount;
//
-// The command line for the process
+// The command line and app name for the process
//
-LPWSTR g_lpwstrCmdLine;
-
+LPWSTR g_lpwstrCmdLine = NULL;
+LPWSTR g_lpwstrAppDir = NULL;
/* Thread ID of thread that has started the ExitProcess process */
Volatile<LONG> terminator = 0;
@@ -133,8 +133,6 @@ Volatile<LONG> terminator = 0;
// Process ID of this process.
DWORD gPID = (DWORD) -1;
-LPWSTR pAppDir = NULL;
-
//
// Key used for associating CPalThread's with the underlying pthread
// (through pthread_setspecific)
@@ -1631,17 +1629,19 @@ See MSDN doc.
LPWSTR
PALAPI
GetCommandLineW(
- VOID)
+ VOID)
{
PERF_ENTRY(GetCommandLineW);
ENTRY("GetCommandLineW()\n");
+ LPWSTR lpwstr = g_lpwstrCmdLine ? g_lpwstrCmdLine : (LPWSTR)W("");
+
LOGEXIT("GetCommandLineW returns LPWSTR %p (%S)\n",
g_lpwstrCmdLine,
- g_lpwstrCmdLine);
+ lpwstr);
PERF_EXIT(GetCommandLineW);
- return g_lpwstrCmdLine;
+ return lpwstr;
}
/*++
@@ -2159,49 +2159,39 @@ CorUnix::InitializeProcessData(
}
/*++
-Function:
- CreateInitialProcessAndThreadObjects
+Function
+ InitializeProcessCommandLine
Abstract
- Creates the IPalObjects that represent the current process
- and the initial thread
+ Initializes (or re-initializes) the saved command line and exe path.
Parameter
- pThread - the initial thread
- lpwstrCmdLine
- lpwstrFullPath
+ pThread - the initial thread
+ lpwstrCmdLine
+ lpwstrFullPath
Return
- PAL_ERROR
+ PAL_ERROR
-Notes :
+Notes
This function takes ownership of lpwstrCmdLine, but not of lpwstrFullPath
--*/
PAL_ERROR
-CorUnix::CreateInitialProcessAndThreadObjects(
+CorUnix::InitializeProcessCommandLine(
CPalThread *pThread,
LPWSTR lpwstrCmdLine,
LPWSTR lpwstrFullPath
- )
+)
{
PAL_ERROR palError = NO_ERROR;
- HANDLE hThread;
- IPalObject *pobjProcess = NULL;
- IDataLock *pDataLock;
- CProcProcessLocalData *pLocalData;
- CProcSharedData *pSharedData;
- CObjectAttributes oa;
- HANDLE hProcess;
LPWSTR initial_dir = NULL;
//
// Save the command line and initial directory
//
- g_lpwstrCmdLine = lpwstrCmdLine ? lpwstrCmdLine : (LPWSTR)W("");
-
- if (lpwstrCmdLine)
+ if (lpwstrFullPath)
{
LPWSTR lpwstr = PAL_wcsrchr(lpwstrFullPath, '/');
lpwstr[0] = '\0';
@@ -2212,20 +2202,60 @@ CorUnix::CreateInitialProcessAndThreadObjects(
if (NULL == initial_dir)
{
ERROR("malloc() failed! (initial_dir) \n");
- goto CreateInitialProcessAndThreadObjectsExit;
+ palError = ERROR_NOT_ENOUGH_MEMORY;
+ goto exit;
}
if (wcscpy_s(initial_dir, iLen, lpwstrFullPath) != SAFECRT_SUCCESS)
{
ERROR("wcscpy_s failed!\n");
+ InternalFree(pThread, initial_dir);
palError = ERROR_INTERNAL_ERROR;
- goto CreateInitialProcessAndThreadObjectsExit;
+ goto exit;
}
lpwstr[0] = '/';
+
+ InternalFree(pThread, g_lpwstrAppDir);
+ g_lpwstrAppDir = initial_dir;
}
-
- pAppDir = initial_dir;
+
+ InternalFree(pThread, g_lpwstrCmdLine);
+ g_lpwstrCmdLine = lpwstrCmdLine;
+
+exit:
+ return palError;
+}
+
+
+/*++
+Function:
+ CreateInitialProcessAndThreadObjects
+
+Abstract
+ Creates the IPalObjects that represent the current process
+ and the initial thread
+
+Parameter
+ pThread - the initial thread
+
+Return
+ PAL_ERROR
+--*/
+
+PAL_ERROR
+CorUnix::CreateInitialProcessAndThreadObjects(
+ CPalThread *pThread
+ )
+{
+ PAL_ERROR palError = NO_ERROR;
+ HANDLE hThread;
+ IPalObject *pobjProcess = NULL;
+ IDataLock *pDataLock;
+ CProcProcessLocalData *pLocalData;
+ CProcSharedData *pSharedData;
+ CObjectAttributes oa;
+ HANDLE hProcess;
//
// Create initial thread object
@@ -2329,14 +2359,6 @@ CreateInitialProcessAndThreadObjectsExit:
pobjProcess->ReleaseReference(pThread);
}
- if (NO_ERROR != palError)
- {
- if (NULL != initial_dir)
- {
- InternalFree(pThread, initial_dir);
- }
- }
-
return palError;
}
@@ -2359,13 +2381,11 @@ VOID
PROCCleanupInitialProcess(VOID)
{
CPalThread *pThread = InternalGetCurrentThread();
- LPWSTR lpwstr;
InternalEnterCriticalSection(pThread, &g_csProcess);
/* Free the application directory */
- lpwstr=pAppDir;
- InternalFree (pThread, lpwstr);
+ InternalFree (pThread, g_lpwstrAppDir);
/* Free the stored command line */
InternalFree (pThread, g_lpwstrCmdLine);
@@ -3746,7 +3766,7 @@ getPath(
}
/* first look in directory from which the application loaded */
- lpwstr=pAppDir;
+ lpwstr = g_lpwstrAppDir;
if (lpwstr)
{