summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/debug/debug-pal/CMakeLists.txt1
-rw-r--r--src/debug/debug-pal/unix/dynamiclibaddress.cpp91
-rw-r--r--src/dlls/dbgshim/dbgshim.cpp168
-rw-r--r--src/pal/inc/pal.h28
-rw-r--r--src/pal/src/include/pal/module.h58
-rw-r--r--src/pal/src/include/pal/palinternal.h1
-rw-r--r--src/pal/src/loader/module.cpp370
-rw-r--r--src/pal/src/thread/process.cpp239
8 files changed, 394 insertions, 562 deletions
diff --git a/src/debug/debug-pal/CMakeLists.txt b/src/debug/debug-pal/CMakeLists.txt
index 01284029dc..43c1c9fdbe 100644
--- a/src/debug/debug-pal/CMakeLists.txt
+++ b/src/debug/debug-pal/CMakeLists.txt
@@ -23,7 +23,6 @@ if(CLR_CMAKE_PLATFORM_UNIX)
set(TWO_WAY_PIPE_SOURCES
unix/twowaypipe.cpp
- unix/dynamiclibaddress.cpp
)
endif(CLR_CMAKE_PLATFORM_UNIX)
diff --git a/src/debug/debug-pal/unix/dynamiclibaddress.cpp b/src/debug/debug-pal/unix/dynamiclibaddress.cpp
deleted file mode 100644
index 56ab558865..0000000000
--- a/src/debug/debug-pal/unix/dynamiclibaddress.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-//
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-//
-#include "windefs.h"
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <limits.h>
-
-
-void *GetDynamicLibraryAddressInProcess(DWORD pid, const char *libraryName)
-{
-
-// We don't have proper API detection in debug-pal
-// that's why so far we'll just assume that we run on OS with ProcFS (which is not true on Mac OS)
-// TODO: We need to implement this function for Mac OS
-#define HAVE_PROCFS_CTL
-#ifdef HAVE_PROCFS_CTL
-
- // Here we read /proc/<pid>/maps file in order to parse it and figure out what it says
- // about a library we are looking for. This file looks something like this:
- //
- // [address] [perms] [offset] [dev] [inode] [pathname] - HEADER is not preset in an actual file
- //
- // 35b1800000-35b1820000 r-xp 00000000 08:02 135522 /usr/lib64/ld-2.15.so
- // 35b1a1f000-35b1a20000 r--p 0001f000 08:02 135522 /usr/lib64/ld-2.15.so
- // 35b1a20000-35b1a21000 rw-p 00020000 08:02 135522 /usr/lib64/ld-2.15.so
- // 35b1a21000-35b1a22000 rw-p 00000000 00:00 0 [heap]
- // 35b1c00000-35b1dac000 r-xp 00000000 08:02 135870 /usr/lib64/libc-2.15.so
- // 35b1dac000-35b1fac000 ---p 001ac000 08:02 135870 /usr/lib64/libc-2.15.so
- // 35b1fac000-35b1fb0000 r--p 001ac000 08:02 135870 /usr/lib64/libc-2.15.so
- // 35b1fb0000-35b1fb2000 rw-p 001b0000 08:02 135870 /usr/lib64/libc-2.15.so
-
- void *result = NULL;
-
- // Making something like: /proc/123/maps
- char mapFileName[100];
- int chars = snprintf(mapFileName, sizeof(mapFileName), "/proc/%d/maps", pid);
- _ASSERTE(chars > 0 && chars <= sizeof(mapFileName));
-
- // Making something like: /libcoreclr.so
- char slashLibName[PATH_MAX];
- chars = snprintf(slashLibName, sizeof(slashLibName), "/%s", libraryName);
- _ASSERTE(chars > 0 && chars <= sizeof(mapFileName));
- size_t slashLibNameLen = strlen(slashLibName);
-
- FILE *mapsFile = fopen(mapFileName, "r");
- if (mapsFile == NULL)
- {
- return NULL;
- }
-
- char *line = NULL;
- size_t len = 0;
- ssize_t read;
-
- // Reading maps file line by line
- while ((read = getline(&line, &len, mapsFile)) != -1)
- {
- //Checking if this line ends with /libraryName\n
- const char *expectedLibLocation = line + strlen(line) - 1 - slashLibNameLen;
- if (expectedLibLocation > line && strncmp(expectedLibLocation, slashLibName, slashLibNameLen) == 0)
- {
- void *address1, *address2, *offset;
- // We found a record for our library
- // let's parse address and offset
-
- if (sscanf(line, "%p-%p %*[-rwxsp] %p", &address1, &address2, &offset) == 3)
- {
- // We were able to read all the info we need
- if (offset == 0)
- {
- // We found address that corresponds to the very beginning of the lib we're looking for
- result = address1;
- break;
- }
- }
- }
- }
-
- free(line); // We didn't allocate line, but as per contract of getline we should free it
- fclose(mapsFile);
- return result;
-
-#else
- _ASSERTE(!"Not implemented on this platform");
- return NULL;
-#endif
-}
diff --git a/src/dlls/dbgshim/dbgshim.cpp b/src/dlls/dbgshim/dbgshim.cpp
index 79a33cdcb7..3b7afce04c 100644
--- a/src/dlls/dbgshim/dbgshim.cpp
+++ b/src/dlls/dbgshim/dbgshim.cpp
@@ -169,47 +169,6 @@ HRESULT GetStartupNotificationEvent(DWORD debuggeePID,
return S_OK;
}
-//-----------------------------------------------------------------------------
-// Public API.
-//
-// CloseCLREnumeration -- used to free resources allocated by EnumerateCLRs
-//
-// pHandleArray -- handle array originally returned by EnumerateCLRs
-// pStringArray -- string array originally returned by EnumerateCLRs
-// dwArrayLength -- array length originally returned by EnumerateCLRs
-//
-//-----------------------------------------------------------------------------
-HRESULT CloseCLREnumeration(HANDLE* pHandleArray, LPWSTR* pStringArray, DWORD dwArrayLength)
-{
- PUBLIC_CONTRACT;
-
- if ((pHandleArray + dwArrayLength) != (HANDLE*)pStringArray)
- return E_INVALIDARG;
-
- // It's possible that EnumerateCLRs found nothing to enumerate, in which case
- // pointers and count are zeroed. If a debugger calls this function in that
- // case, let's not try to delete [] on NULL.
- if (pHandleArray == NULL)
- return S_OK;
-
-#ifndef FEATURE_PAL
- for (DWORD i = 0; i < dwArrayLength; i++)
- {
- HANDLE hTemp = pHandleArray[i];
- if ( (NULL != hTemp)
- && (INVALID_HANDLE_VALUE != hTemp))
- {
- CloseHandle(hTemp);
- }
- }
-#endif // FEATURE_PAL
-
- delete[] pHandleArray;
- return S_OK;
-}
-
-#ifndef FEATURE_PAL
-
HRESULT GetContinueStartupEvent(DWORD debuggeePID,
LPCWSTR szTelestoFullPath,
__out HANDLE* phContinueStartupEvent);
@@ -250,8 +209,9 @@ void GetTargetCLRMetrics(LPCWSTR szTelestoFullPath,
CONSISTENCY_CHECK(szTelestoFullPath != NULL);
CONSISTENCY_CHECK(pEngineMetricsOut != NULL);
+#ifndef FEATURE_PAL
HRESULT hr = S_OK;
-
+
HandleHolder hCoreClrFile = WszCreateFile(szTelestoFullPath,
GENERIC_READ,
FILE_SHARE_READ,
@@ -380,8 +340,14 @@ void GetTargetCLRMetrics(LPCWSTR szTelestoFullPath,
}
// Holder will call FreeLibrary()
+#else
+ //TODO: So far on POSIX systems we only support one version of debugging interface
+ // in future we might want to detect it the same way we do it on Windows.
+ pEngineMetricsOut->dwDbiVersion = CorDebugLatestVersion;
+#endif // FEATURE_PAL
}
+
// Returns true iff the module represents CoreClr.
bool IsCoreClr(const WCHAR* pModulePath)
{
@@ -389,9 +355,9 @@ bool IsCoreClr(const WCHAR* pModulePath)
//strip off everything up to and including the last slash in the path to get name
const WCHAR* pModuleName = pModulePath;
- while(wcschr(pModuleName, W('\\')) != NULL)
+ while(wcschr(pModuleName, DIRECTORY_SEPARATOR_CHAR_W) != NULL)
{
- pModuleName = wcschr(pModuleName, W('\\'));
+ pModuleName = wcschr(pModuleName, DIRECTORY_SEPARATOR_CHAR_W);
pModuleName++; // pass the slash
}
@@ -433,8 +399,6 @@ bool IsCoreClrWithGoodHeader(HANDLE hProcess, HMODULE hModule)
return false;
}
-#endif // !FEATURE_PAL
-
//-----------------------------------------------------------------------------
// Public API.
//
@@ -466,7 +430,6 @@ HRESULT EnumerateCLRs(DWORD debuggeePID,
if ((ppHandleArrayOut == NULL) || (ppStringArrayOut == NULL) || (pdwArrayLengthOut == NULL))
return E_INVALIDARG;
-#ifndef FEATURE_PAL
HandleHolder hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, debuggeePID);
if (NULL == hProcess)
ThrowHR(E_FAIL);
@@ -501,9 +464,6 @@ HRESULT EnumerateCLRs(DWORD debuggeePID,
return S_OK;
}
-#else
- DWORD count = 1;
-#endif // FEATURE_PAL
size_t cbEventArrayData = sizeof(HANDLE) * count; // event array data
size_t cbStringArrayData = sizeof(LPWSTR) * count; // string array data
@@ -521,7 +481,6 @@ HRESULT EnumerateCLRs(DWORD debuggeePID,
WCHAR* pStringData = (WCHAR*) &pOutBuffer[cbEventArrayData + cbStringArrayData];
DWORD idx = 0;
-#ifndef FEATURE_PAL
// There's no guarantee that another coreclr hasn't loaded already anyhow,
// so if we get the corner case that the second time through we enumerate
// more coreclrs, just ignore the extras.
@@ -541,6 +500,7 @@ HRESULT EnumerateCLRs(DWORD debuggeePID,
pStringArray[idx] = &pStringData[idx * MAX_PATH];
GetModuleFileNameEx(hProcess, modules[i], pStringArray[idx], MAX_PATH);
+#ifndef FEATURE_PAL
// fill in event handle -- if GetContinueStartupEvent fails, it will still return
// INVALID_HANDLE_VALUE in hContinueStartupEvent, which is what we want. we don't
// want to bail out of the enumeration altogether if we can't get an event from
@@ -551,6 +511,9 @@ HRESULT EnumerateCLRs(DWORD debuggeePID,
_ASSERTE(SUCCEEDED(hr) == (hContinueStartupEvent != INVALID_HANDLE_VALUE));
pEventArray[idx] = hContinueStartupEvent;
+#else
+ pEventArray[idx] = NULL;
+#endif // FEATURE_PAL
idx++;
}
@@ -575,11 +538,6 @@ HRESULT EnumerateCLRs(DWORD debuggeePID,
// Strings themselves don't need moved.
}
-#else
- pStringArray[idx] = &pStringData[idx * MAX_PATH];
- wcscpy_s(pStringArray[idx], MAX_PATH, MAKEDLLNAME_W(W("coreclr")));
- idx++;
-#endif // FEATURE_PAL
*ppHandleArrayOut = pEventArray;
*ppStringArrayOut = pStringArray;
@@ -588,7 +546,44 @@ HRESULT EnumerateCLRs(DWORD debuggeePID,
return S_OK;
}
+//-----------------------------------------------------------------------------
+// Public API.
+//
+// CloseCLREnumeration -- used to free resources allocated by EnumerateCLRs
+//
+// pHandleArray -- handle array originally returned by EnumerateCLRs
+// pStringArray -- string array originally returned by EnumerateCLRs
+// dwArrayLength -- array length originally returned by EnumerateCLRs
+//
+//-----------------------------------------------------------------------------
+HRESULT CloseCLREnumeration(HANDLE* pHandleArray, LPWSTR* pStringArray, DWORD dwArrayLength)
+{
+ PUBLIC_CONTRACT;
+
+ if ((pHandleArray + dwArrayLength) != (HANDLE*)pStringArray)
+ return E_INVALIDARG;
+
+ // It's possible that EnumerateCLRs found nothing to enumerate, in which case
+ // pointers and count are zeroed. If a debugger calls this function in that
+ // case, let's not try to delete [] on NULL.
+ if (pHandleArray == NULL)
+ return S_OK;
+
#ifndef FEATURE_PAL
+ for (DWORD i = 0; i < dwArrayLength; i++)
+ {
+ HANDLE hTemp = pHandleArray[i];
+ if ( (NULL != hTemp)
+ && (INVALID_HANDLE_VALUE != hTemp))
+ {
+ CloseHandle(hTemp);
+ }
+ }
+#endif // FEATURE_PAL
+
+ delete[] pHandleArray;
+ return S_OK;
+}
//-----------------------------------------------------------------------------
// Get the base address of a module from the remote process.
@@ -608,7 +603,9 @@ BYTE* GetRemoteModuleBaseAddress(DWORD dwPID, LPCWSTR szFullModulePath)
HandleHolder hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
if (NULL == hProcess)
+ {
ThrowHR(E_FAIL);
+ }
// These shouldn't be freed
HMODULE modules[1000];
@@ -636,13 +633,10 @@ BYTE* GetRemoteModuleBaseAddress(DWORD dwPID, LPCWSTR szFullModulePath)
}
}
-
// Successfully enumerated modules but couldn't find the requested one.
return NULL;
}
-#endif // FEATURE_PAL
-
// DBI version: max 8 hex chars
// SEMICOLON: 1
// PID: max 8 hex chars
@@ -719,20 +713,12 @@ HRESULT CreateVersionStringFromModule(DWORD pidDebuggee,
{
CorDebugInterfaceVersion dbiVersion = CorDebugInvalidVersion;
BYTE* hmodTargetCLR = NULL;
-#ifndef FEATURE_PAL
CLR_ENGINE_METRICS metricsStruct;
GetTargetCLRMetrics(szModuleName, &metricsStruct); // throws
dbiVersion = (CorDebugInterfaceVersion) metricsStruct.dwDbiVersion;
-
- hmodTargetCLR = GetRemoteModuleBaseAddress(pidDebuggee, szModuleName); // throws
-#else
- //TODO: So far on POSIX systems we only support one version of debugging interface
- // in future we might want to detect it the same way we do it on Windows.
- dbiVersion = CorDebugLatestVersion;
- hmodTargetCLR = (BYTE *)GetDynamicLibraryAddressInProcess(pidDebuggee, MAKEDLLNAME_A(MAIN_CLR_MODULE_NAME_A));
-#endif // FEATURE_PAL
+ hmodTargetCLR = GetRemoteModuleBaseAddress(pidDebuggee, szModuleName); // throws
if (hmodTargetCLR == NULL)
{
hr = COR_E_FILENOTFOUND;
@@ -795,7 +781,6 @@ HRESULT ParseVersionString(LPCWSTR szDebuggeeVersion, CorDebugInterfaceVersion *
return S_OK;
}
-#ifndef FEATURE_PAL
//-----------------------------------------------------------------------------
// Appends "\mscordbi.dll" to the path. This converts a directory name into the full path to mscordbi.dll.
//
@@ -804,10 +789,11 @@ HRESULT ParseVersionString(LPCWSTR szDebuggeeVersion, CorDebugInterfaceVersion *
//-----------------------------------------------------------------------------
void AppendDbiDllName(SString & szFullDbiPath)
{
- const WCHAR * pDbiDllName = W("\\") MAKEDLLNAME_W(W("mscordbi"));
+ const WCHAR * pDbiDllName = DIRECTORY_SEPARATOR_STR_W MAKEDLLNAME_W(W("mscordbi"));
szFullDbiPath.Append(pDbiDllName);
}
+
//-----------------------------------------------------------------------------
// Return a path to the dbi next to the runtime, if present.
//
@@ -838,7 +824,7 @@ void GetDbiFilenameNextToRuntime(DWORD pidDebuggee, HMODULE hmodTargetCLR, SStri
// Step 2: 'Coreclr.dll' --> 'mscordbi.dll'
//
WCHAR * pCoreClrPath = modulePath;
- WCHAR * pLast = wcsrchr(pCoreClrPath, '\\');
+ WCHAR * pLast = wcsrchr(pCoreClrPath, DIRECTORY_SEPARATOR_CHAR_W);
if (pLast == NULL)
{
ThrowHR(E_FAIL);
@@ -860,6 +846,7 @@ void GetDbiFilenameNextToRuntime(DWORD pidDebuggee, HMODULE hmodTargetCLR, SStri
szFullCoreClrPath.Set(pCoreClrPath, (COUNT_T)wcslen(pCoreClrPath));
}
+
//---------------------------------------------------------------------------------------
//
// The current policy is that the DBI DLL must live right next to the coreclr DLL. We check the product
@@ -875,6 +862,7 @@ void GetDbiFilenameNextToRuntime(DWORD pidDebuggee, HMODULE hmodTargetCLR, SStri
bool CheckDbiAndRuntimeVersion(SString & szFullDbiPath, SString & szFullCoreClrPath)
{
+#ifndef FEATURE_PAL
DWORD dwDbiVersionMS = 0;
DWORD dwDbiVersionLS = 0;
DWORD dwCoreClrVersionMS = 0;
@@ -893,16 +881,11 @@ bool CheckDbiAndRuntimeVersion(SString & szFullDbiPath, SString & szFullCoreClrP
{
return false;
}
-}
-
#else
-
-// Functions that we'll look for in the loaded Mscordbi module.
-typedef HRESULT (STDAPICALLTYPE *FPCreateCordbObject)(
- int iDebuggerVersion,
- IUnknown ** ppCordb);
-
+ return true;
#endif // FEATURE_PAL
+}
+
//-----------------------------------------------------------------------------
// Public API.
@@ -932,6 +915,8 @@ HRESULT CreateDebuggingInterfaceFromVersionEx(
HRESULT hr = S_OK;
HMODULE hMod = NULL;
IUnknown * pCordb = NULL;
+ FPCoreCLRCreateCordbObject fpCreate2 = NULL;
+
LOG((LF_CORDB, LL_EVERYTHING, "Calling CreateDebuggerInterfaceFromVersion, ver=%S\n", szDebuggeeVersion));
if ((szDebuggeeVersion == NULL) || (ppCordb == NULL))
@@ -942,7 +927,6 @@ HRESULT CreateDebuggingInterfaceFromVersionEx(
*ppCordb = NULL;
-
//
// Step 1: Parse version information into internal data structures
//
@@ -955,7 +939,6 @@ HRESULT CreateDebuggingInterfaceFromVersionEx(
if (FAILED(hr))
goto Exit;
-#ifndef FEATURE_PAL
//
// Step 2: Find the proper Dbi module (mscordbi.dll) and load it.
//
@@ -981,7 +964,11 @@ HRESULT CreateDebuggingInterfaceFromVersionEx(
// Issue:951525: coreclr mscordbi load fails on downlevel OS since LoadLibraryEx can't find
// dependent forwarder DLLs. Force LoadLibrary to look for dependencies in szFullDbiPath plus the default
// search paths.
+#ifndef FEATURE_PAL
hMod = WszLoadLibraryEx(szFullDbiPath, NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
+#else
+ hMod = LoadLibraryExW(szFullDbiPath, NULL, 0);
+#endif
}
EX_CATCH_HRESULT(hrIgnore); // failure leaves hMod null
@@ -1004,7 +991,7 @@ HRESULT CreateDebuggingInterfaceFromVersionEx(
//
// Step 3: Now that module is loaded, instantiate an ICorDebug.
//
- FPCoreCLRCreateCordbObject fpCreate2 = (FPCoreCLRCreateCordbObject)GetProcAddress(hMod, "CoreCLRCreateCordbObject");
+ fpCreate2 = (FPCoreCLRCreateCordbObject)GetProcAddress(hMod, "CoreCLRCreateCordbObject");
if (fpCreate2 == NULL)
{
// New-style creation API didn't exist - this DBI must be the wrong version, for the Mix07 protocol
@@ -1014,23 +1001,6 @@ HRESULT CreateDebuggingInterfaceFromVersionEx(
// Invoke to instantiate an ICorDebug. This export was introduced after the Mix'07 release.
hr = fpCreate2(iDebuggerVersion, pidDebuggee, hmodTargetCLR, &pCordb);
-#else
- {
- hMod = LoadLibraryExW(MAKEDLLNAME_W(W("mscordbi")), NULL, 0);
- if (NULL == hMod)
- {
- hr = CORDBG_E_DEBUG_COMPONENT_MISSING;
- goto Exit;
- }
- FPCoreCLRCreateCordbObject fpCreate2 = (FPCoreCLRCreateCordbObject)GetProcAddress(hMod, "CoreCLRCreateCordbObject");
- if (hmodTargetCLR == NULL || fpCreate2 == NULL)
- {
- hr = CORDBG_E_INCOMPATIBLE_PROTOCOL;
- goto Exit;
- }
- hr = fpCreate2(iDebuggerVersion, pidDebuggee, hmodTargetCLR, &pCordb);
- }
-#endif // FEATURE_PAL
_ASSERTE((pCordb == NULL) == FAILED(hr));
Exit:
diff --git a/src/pal/inc/pal.h b/src/pal/inc/pal.h
index 69b5362b45..e6c287f5d8 100644
--- a/src/pal/inc/pal.h
+++ b/src/pal/inc/pal.h
@@ -3358,6 +3358,20 @@ GetModuleFileNameW(
#define GetModuleFileName GetModuleFileNameA
#endif
+PALIMPORT
+DWORD
+PALAPI
+GetModuleFileNameExW(
+ IN HANDLE hProcess,
+ IN HMODULE hModule,
+ OUT LPWSTR lpFilename,
+ IN DWORD nSize
+ );
+
+#ifdef UNICODE
+#define GetModuleFileNameEx GetModuleFileNameExW
+#endif
+
// Get base address of the module containing a given symbol
PALAPI
LPCVOID
@@ -4550,16 +4564,26 @@ OpenProcess(
);
PALIMPORT
+BOOL
+PALAPI
+EnumProcessModules(
+ IN HANDLE hProcess,
+ OUT HMODULE *lphModule,
+ IN DWORD cb,
+ OUT LPDWORD lpcbNeeded
+ );
+
+PALIMPORT
VOID
PALAPI
OutputDebugStringA(
- IN LPCSTR lpOutputString);
+ IN LPCSTR lpOutputString);
PALIMPORT
VOID
PALAPI
OutputDebugStringW(
- IN LPCWSTR lpOutputStrig);
+ IN LPCWSTR lpOutputStrig);
#ifdef UNICODE
#define OutputDebugString OutputDebugStringW
diff --git a/src/pal/src/include/pal/module.h b/src/pal/src/include/pal/module.h
index a58a82a458..fada2ae169 100644
--- a/src/pal/src/include/pal/module.h
+++ b/src/pal/src/include/pal/module.h
@@ -21,24 +21,6 @@ Abstract:
#ifndef _PAL_MODULE_H_
#define _PAL_MODULE_H_
-#if defined(CORECLR) && defined(__APPLE__)
-
-#include <CoreFoundation/CFBundle.h>
-
-// Name of the CoreCLR bundle executable
-#define CORECLR_BUNDLE_NAME "coreclr"
-
-// Name of the CoreCLR bundle root directory.
-#define CORECLR_BUNDLE_DIR "CoreCLR.bundle"
-
-// Directory components between the bundle root and the executable.
-#define CORECLR_BUNDLE_PATH "Contents/MacOS/"
-
-// Abstract the API used to load and query for functions in the CoreCLR binary to make it easier to change the
-// underlying implementation.
-typedef CFBundleRef CORECLRHANDLE;
-#endif // CORECLR && __APPLE__
-
#ifdef __cplusplus
extern "C"
{
@@ -65,22 +47,18 @@ typedef struct _MODSTRUCT
HMODULE self; /* circular reference to this module */
void *dl_handle; /* handle returned by dlopen() */
HINSTANCE hinstance; /* handle returned by PAL_RegisterLibrary */
-#if defined(CORECLR) && defined(__APPLE__)
- CORECLRHANDLE sys_module; /* System modules can be loaded via mechanisms other than dlopen() under
- * CoreCLR/Mac */
-#endif // CORECLR && __APPLE__
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 */
+ enabled, FALSE if they are disabled */
#if RETURNS_NEW_HANDLES_ON_REPEAT_DLOPEN
ino_t inode;
dev_t device;
#endif
- PDLLMAIN pDllMain; /* entry point of module */
+ PDLLMAIN pDllMain; /* entry point of module */
/* reference to next and previous modules in list (in load order) */
struct _MODSTRUCT *next;
@@ -204,23 +182,6 @@ Return value:
--*/
BOOL PAL_LOADUnloadPEFile(void * ptr);
-
-#if !defined(CORECLR) || !defined(__APPLE__)
-/*++
- LOADGetLibRotorPalSoFileName
-
- Retrieve the full path of the librotor_pal.so being used.
-
-Parameters:
- OUT pwzBuf - WCHAR buffer of MAX_PATH length to receive file name
-
-Return value:
- 0 if successful
- -1 if failure, with last error set.
---*/
-int LOADGetLibRotorPalSoFileName(LPSTR pszBuf);
-#endif // !CORECLR || !__APPLE__
-
/*++
LOADInitCoreCLRModules
@@ -236,21 +197,6 @@ Return value:
--*/
BOOL LOADInitCoreCLRModules(const char *szCoreCLRPath);
-#if defined(CORECLR) && defined(__APPLE__)
-// Abstract the API used to load and query for functions in the CoreCLR binary to make it easier to change the
-// underlying implementation.
-
-// Load the CoreCLR module into memory given the directory in which it resides. Returns NULL on failure.
-CORECLRHANDLE LoadCoreCLR(const char *szPath);
-
-// Lookup the named function in the given CoreCLR image. Returns NULL on failure.
-void *LookupFunctionInCoreCLR(CORECLRHANDLE hCoreCLR, const char *szFunction);
-
-// Locate the CoreCLR module handle associated with the code currently executing. Returns NULL on failure.
-CORECLRHANDLE FindCoreCLRHandle();
-
-#endif // CORECLR && __APPLE__
-
#ifdef __cplusplus
}
#endif // __cplusplus
diff --git a/src/pal/src/include/pal/palinternal.h b/src/pal/src/include/pal/palinternal.h
index 1fc583451b..6bf51e4f84 100644
--- a/src/pal/src/include/pal/palinternal.h
+++ b/src/pal/src/include/pal/palinternal.h
@@ -560,6 +560,7 @@ function_name() to call the system's implementation
#endif
#include <ctype.h>
+#define _WITH_GETLINE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
diff --git a/src/pal/src/loader/module.cpp b/src/pal/src/loader/module.cpp
index aadf12850e..ad61285a9f 100644
--- a/src/pal/src/loader/module.cpp
+++ b/src/pal/src/loader/module.cpp
@@ -95,10 +95,9 @@ MODSTRUCT pal_module; /* always the second, in the in-load-order list */
static BOOL LOADValidateModule(MODSTRUCT *module);
static LPWSTR LOADGetModuleFileName(MODSTRUCT *module);
-static HMODULE LOADLoadLibrary(LPCSTR ShortAsciiName, BOOL fDynamic);
+static HMODULE LOADLoadLibrary(LPCSTR shortAsciiName, BOOL fDynamic);
static void LOAD_SEH_CallDllMain(MODSTRUCT *module, DWORD dwReason, LPVOID lpReserved);
static MODSTRUCT *LOADAllocModule(void *dl_handle, LPCSTR name);
-static INT FindLibrary(CHAR* pszRelName, CHAR** ppszFullName);
/* API function definitions ***************************************************/
@@ -111,7 +110,7 @@ See MSDN doc.
HMODULE
PALAPI
LoadLibraryA(
- IN LPCSTR lpLibFileName)
+ IN LPCSTR lpLibFileName)
{
return LoadLibraryExA(lpLibFileName, NULL, 0);
}
@@ -125,7 +124,7 @@ See MSDN doc.
HMODULE
PALAPI
LoadLibraryW(
- IN LPCWSTR lpLibFileName)
+ IN LPCWSTR lpLibFileName)
{
return LoadLibraryExW(lpLibFileName, NULL, 0);
}
@@ -139,9 +138,9 @@ See MSDN doc.
HMODULE
PALAPI
LoadLibraryExA(
- IN LPCSTR lpLibFileName,
- IN /*Reserved*/ HANDLE hFile,
- IN DWORD dwFlags)
+ IN LPCSTR lpLibFileName,
+ IN /*Reserved*/ HANDLE hFile,
+ IN DWORD dwFlags)
{
if (dwFlags != 0)
{
@@ -208,9 +207,9 @@ See MSDN doc.
HMODULE
PALAPI
LoadLibraryExW(
- IN LPCWSTR lpLibFileName,
- IN /*Reserved*/ HANDLE hFile,
- IN DWORD dwFlags)
+ IN LPCWSTR lpLibFileName,
+ IN /*Reserved*/ HANDLE hFile,
+ IN DWORD dwFlags)
{
if (dwFlags != 0)
{
@@ -281,8 +280,8 @@ See MSDN doc.
FARPROC
PALAPI
GetProcAddress(
- IN HMODULE hModule,
- IN LPCSTR lpProcName)
+ IN HMODULE hModule,
+ IN LPCSTR lpProcName)
{
MODSTRUCT *module;
FARPROC ProcAddress = NULL;
@@ -305,7 +304,7 @@ GetProcAddress(
goto done;
}
- if( !LOADValidateModule( module ) )
+ if( !LOADValidateModule(module) )
{
TRACE("Invalid module handle %p\n", hModule);
SetLastError(ERROR_INVALID_HANDLE);
@@ -405,7 +404,7 @@ See MSDN doc.
BOOL
PALAPI
FreeLibrary(
- IN OUT HMODULE hLibModule)
+ IN OUT HMODULE hLibModule)
{
MODSTRUCT *module;
BOOL retval = FALSE;
@@ -435,7 +434,7 @@ FreeLibrary(
if( module->refcount == -1 )
{
/* special module - never released */
- retval=TRUE;
+ retval = TRUE;
goto done;
}
@@ -445,7 +444,7 @@ FreeLibrary(
if( module->refcount != 0 )
{
- retval=TRUE;
+ retval = TRUE;
goto done;
}
@@ -460,7 +459,7 @@ FreeLibrary(
module->next->prev = module->prev;
/* remove the circular reference so that LOADValidateModule will fail */
- module->self=NULL;
+ module->self = NULL;
/* Call DllMain if the module contains one */
if(module->pDllMain)
@@ -498,7 +497,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());
@@ -509,7 +508,7 @@ FreeLibrary(
InternalFree(pThread, module->lib_name);
InternalFree(pThread, module);
- retval=TRUE;
+ retval = TRUE;
done:
UnlockModuleList();
@@ -530,8 +529,8 @@ PALIMPORT
VOID
PALAPI
FreeLibraryAndExitThread(
- IN HMODULE hLibModule,
- IN DWORD dwExitCode)
+ IN HMODULE hLibModule,
+ IN DWORD dwExitCode)
{
PERF_ENTRY(FreeLibraryAndExitThread);
ENTRY("FreeLibraryAndExitThread()\n");
@@ -558,12 +557,12 @@ Notes :
DWORD
PALAPI
GetModuleFileNameA(
- IN HMODULE hModule,
- OUT LPSTR lpFileName,
- IN DWORD nSize)
+ IN HMODULE hModule,
+ OUT LPSTR lpFileName,
+ IN DWORD nSize)
{
INT name_length;
- DWORD retval=0;
+ DWORD retval = 0;
LPWSTR wide_name = NULL;
PERF_ENTRY(GetModuleFileNameA);
@@ -577,7 +576,7 @@ GetModuleFileNameA(
SetLastError(ERROR_INVALID_HANDLE);
goto done;
}
- wide_name=LOADGetModuleFileName((MODSTRUCT *)hModule);
+ wide_name = LOADGetModuleFileName((MODSTRUCT *)hModule);
if(!wide_name)
{
@@ -598,7 +597,7 @@ GetModuleFileNameA(
}
TRACE("File name of module %p is %s\n", hModule, lpFileName);
- retval=name_length;
+ retval = name_length;
done:
UnlockModuleList();
LOGEXIT("GetModuleFileNameA returns DWORD %d\n", retval);
@@ -623,12 +622,12 @@ Notes :
DWORD
PALAPI
GetModuleFileNameW(
- IN HMODULE hModule,
- OUT LPWSTR lpFileName,
- IN DWORD nSize)
+ IN HMODULE hModule,
+ OUT LPWSTR lpFileName,
+ IN DWORD nSize)
{
INT name_length;
- DWORD retval=0;
+ DWORD retval = 0;
LPWSTR wide_name = NULL;
PERF_ENTRY(GetModuleFileNameW);
@@ -645,7 +644,7 @@ GetModuleFileNameW(
SetLastError(ERROR_INVALID_HANDLE);
goto done;
}
- wide_name=LOADGetModuleFileName((MODSTRUCT *)hModule);
+ wide_name = LOADGetModuleFileName((MODSTRUCT *)hModule);
if(!wide_name)
{
@@ -657,7 +656,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);
@@ -667,7 +666,7 @@ GetModuleFileNameW(
wcscpy_s(lpFileName, nSize, wide_name);
TRACE("file name of module %p is %S\n", hModule, lpFileName);
- retval=name_length;
+ retval = name_length;
done:
UnlockModuleList();
LOGEXIT("GetModuleFileNameW returns DWORD %u\n", retval);
@@ -675,6 +674,7 @@ done:
return retval;
}
+
/*++
Function:
PAL_RegisterModule
@@ -737,7 +737,7 @@ Function:
HMODULE
PALAPI
PAL_RegisterLibraryW(
- IN LPCWSTR lpLibFileName)
+ IN LPCWSTR lpLibFileName)
{
HMODULE hModule = NULL;
CHAR lpstr[MAX_PATH];
@@ -814,7 +814,7 @@ Function:
BOOL
PALAPI
PAL_UnregisterLibraryW(
- IN OUT HMODULE hLibModule)
+ IN OUT HMODULE hLibModule)
{
BOOL retval;
@@ -831,81 +831,6 @@ PAL_UnregisterLibraryW(
/* Internal PAL functions *****************************************************/
/*++
- LOADGetLibRotorPalSoFileName
-
- Search LD_LIBRARY_PATH (or DYLD_LIBRARY_PATH) for LibRotorPal. This
- defines the working directory for PAL.
-
-Parameters:
- OUT LPSTR pszBuf - WCHAR buffer of MAX_PATH length to receive file name
-
-Return value:
- 0 if successful
- -1 if failure, with last error set.
---*/
-extern "C"
-int LOADGetLibRotorPalSoFileName(LPSTR pszBuf)
-{
- INT iRetVal = -1;
- CHAR* pszFileName = NULL;
- CPalThread *pthrThread = InternalGetCurrentThread();
-
- if (!pszBuf)
- {
- ASSERT("LOADGetLibRotorPalSoFileName requires non-NULL pszBuf\n");
- SetLastError(ERROR_INTERNAL_ERROR);
- goto Done;
- }
- iRetVal = FindLibrary((CHAR*)MAKEDLLNAME_A("coreclrpal"), &pszFileName);
- if (pszFileName)
- {
- UINT cchFileName = strlen(pszFileName);
- if (cchFileName + 1 > MAX_PATH)
- {
- ASSERT("Filename returned by FindLibrary was longer than"
- "MAX_PATH!\n");
- SetLastError(ERROR_FILENAME_EXCED_RANGE);
- goto Done;
- }
- // If the path is relative, get current working directory and prepend
- // it (Note that this function is called only on PAL startup, so
- // current working directory should still be correct)
- if (pszFileName[0] != '/')
- {
- CHAR szCurDir[MAX_PATH];
- CHAR* pszRetVal = NULL;
- if ((pszRetVal = InternalGetcwd(pthrThread, szCurDir, MAX_PATH)) == NULL)
- {
- SetLastError(DIRGetLastErrorFromErrno());
- goto Done;
- }
- // If the strings would overflow (note that if the sum of the
- // lengths == MAX_PATH, the string would overflow b/c of the null
- // terminator -- the 1 is added to account for the /)
- if ((strlen(szCurDir) + strlen(pszFileName) + 1) >= MAX_PATH)
- {
- SetLastError(ERROR_FILENAME_EXCED_RANGE);
- goto Done;
- }
- strcat_s(pszBuf, MAX_PATH, szCurDir);
- strcat_s(pszBuf, MAX_PATH, "/");
- strcat_s(pszBuf, MAX_PATH, pszFileName);
- }
- else
- {
- strcpy_s(pszBuf, MAX_PATH, pszFileName);
- }
- iRetVal = 0;
- }
-Done:
- if (pszFileName)
- {
- InternalFree(pthrThread, pszFileName);
- }
- return iRetVal;
-}
-
-/*++
Function :
LOADInitializeModules
@@ -1207,7 +1132,7 @@ DisableThreadLibraryCalls(
LockModuleList();
module = (MODSTRUCT *) hLibModule;
- if(!module || !LOADValidateModule(module))
+ if(!LOADValidateModule(module))
{
// DisableThreadLibraryCalls() does nothing when given
// an invalid module handle. This matches the Windows
@@ -1250,24 +1175,23 @@ static BOOL LOADValidateModule(MODSTRUCT *module)
LockModuleList();
- modlist_enum=&exe_module;
+ modlist_enum = &exe_module;
/* enumerate through the list of modules to make sure the given handle is
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();
return FALSE;
}
UnlockModuleList();
- TRACE("Module %p is valid (name : %S)\n", module,
- MODNAME(module));
+ TRACE("Module %p is valid (name : %S)\n", module, MODNAME(module));
return TRUE;
}
modlist_enum = modlist_enum->next;
@@ -1387,7 +1311,7 @@ Function :
implementation of LoadLibrary (for use by the A/W variants)
Parameters :
- LPSTR ShortAsciiName : name of module as specified to LoadLibrary
+ LPSTR shortAsciiName : name of module as specified to LoadLibrary
BOOL fDynamic : TRUE if dynamic load through LoadLibrary, FALSE if static load through RegisterLibrary
@@ -1395,7 +1319,7 @@ Return value :
handle to loaded module
--*/
-static HMODULE LOADLoadLibrary(LPCSTR ShortAsciiName, BOOL fDynamic)
+static HMODULE LOADLoadLibrary(LPCSTR shortAsciiName, BOOL fDynamic)
{
CHAR fullLibraryName[MAX_PATH];
MODSTRUCT *module = NULL;
@@ -1407,14 +1331,14 @@ static HMODULE LOADLoadLibrary(LPCSTR ShortAsciiName, BOOL fDynamic)
// The problem is that calling dlopen("libc.so") will fail for libc even thought it works
// for other libraries. The reason is that libc.so is just linker script (i.e. a test file).
// As a result, we have to use the full name (i.e. lib.so.6) that is defined by LIBC_SO.
- if (strcmp(ShortAsciiName, LIBC_NAME_WITHOUT_EXTENSION) == 0)
+ if (strcmp(shortAsciiName, LIBC_NAME_WITHOUT_EXTENSION) == 0)
{
#if defined(__APPLE__)
- ShortAsciiName = "libc.dylib";
+ shortAsciiName = "libc.dylib";
#elif defined(__FreeBSD__)
- ShortAsciiName = FREEBSD_LIBC;
+ shortAsciiName = FREEBSD_LIBC;
#else
- ShortAsciiName = LIBC_SO;
+ shortAsciiName = LIBC_SO;
#endif
}
@@ -1426,10 +1350,10 @@ static HMODULE LOADLoadLibrary(LPCSTR ShortAsciiName, BOOL fDynamic)
{
// See GetProcAddress for an explanation why we leave the PAL.
PAL_LeaveHolder holder;
- dl_handle = dlopen(ShortAsciiName, RTLD_LAZY | RTLD_NOLOAD);
+ dl_handle = dlopen(shortAsciiName, RTLD_LAZY | RTLD_NOLOAD);
if (!dl_handle)
{
- dl_handle = dlopen(ShortAsciiName, RTLD_LAZY);
+ dl_handle = dlopen(shortAsciiName, RTLD_LAZY);
}
// P/Invoke calls are often defined without an extension in the name of the
@@ -1437,7 +1361,7 @@ static HMODULE LOADLoadLibrary(LPCSTR ShortAsciiName, BOOL fDynamic)
// a proper extension and load the library again.
if (!dl_handle)
{
- if (snprintf(fullLibraryName, MAX_PATH, "%s%s", ShortAsciiName, PAL_SHLIB_SUFFIX) < MAX_PATH)
+ if (snprintf(fullLibraryName, MAX_PATH, "%s%s", shortAsciiName, PAL_SHLIB_SUFFIX) < MAX_PATH)
{
dl_handle = dlopen(fullLibraryName, RTLD_LAZY | RTLD_NOLOAD);
if (!dl_handle)
@@ -1446,7 +1370,7 @@ static HMODULE LOADLoadLibrary(LPCSTR ShortAsciiName, BOOL fDynamic)
}
if (dl_handle)
{
- ShortAsciiName = fullLibraryName;
+ shortAsciiName = fullLibraryName;
}
}
}
@@ -1458,8 +1382,7 @@ static HMODULE LOADLoadLibrary(LPCSTR ShortAsciiName, BOOL fDynamic)
SetLastError(ERROR_MOD_NOT_FOUND);
goto done;
}
- TRACE("dlopen() found module %s\n", ShortAsciiName);
-
+ TRACE("dlopen() found module %s\n", shortAsciiName);
#if !RETURNS_NEW_HANDLES_ON_REPEAT_DLOPEN
/* search module list for a match. */
@@ -1471,7 +1394,7 @@ static HMODULE LOADLoadLibrary(LPCSTR ShortAsciiName, BOOL fDynamic)
/* found the handle. increment the refcount and return the
existing module structure */
TRACE("Found matching module %p for module name %s\n",
- module, ShortAsciiName);
+ module, shortAsciiName);
if (module->refcount != -1)
module->refcount++;
dlclose(dl_handle);
@@ -1481,8 +1404,8 @@ static HMODULE LOADLoadLibrary(LPCSTR ShortAsciiName, BOOL fDynamic)
} while (module != &exe_module);
#endif
- TRACE("Module doesn't exist : creating %s.\n", ShortAsciiName);
- module = LOADAllocModule(dl_handle, ShortAsciiName);
+ TRACE("Module doesn't exist : creating %s.\n", shortAsciiName);
+ module = LOADAllocModule(dl_handle, shortAsciiName);
if(NULL == module)
{
@@ -1527,7 +1450,7 @@ static HMODULE LOADLoadLibrary(LPCSTR ShortAsciiName, BOOL fDynamic)
PREGISTER_MODULE registerModule = (PREGISTER_MODULE)dlsym(module->dl_handle, "PAL_RegisterModule");
if (registerModule)
{
- module->hinstance = registerModule(ShortAsciiName);
+ module->hinstance = registerModule(shortAsciiName);
}
else
{
@@ -1764,185 +1687,6 @@ BOOL PAL_LOADUnloadPEFile(void * ptr)
}
/*++
-Function:
- FindLibrary
-
-Abstract
- Search LD_LIBRARY_PATH/DYLD_LIBRARY_PATH for a file named pszRelName
-
-Parameter
- pszRelName: The relative name of the file sought
- ppszFullName: A pointer that will be filled in with the full filename if
- we find it
-
-Return
- 0 if completed successfully, even if library not found
- -1 on error
---*/
-INT FindLibrary(CHAR* pszRelName, CHAR** ppszFullName)
-{
- CPalThread *pThread = NULL;
- CHAR* pszLibPath = NULL;
- CHAR* pszNext = NULL;
- CHAR** rgpLibDirSeparators = NULL;
- UINT cSeparators = 0;
- UINT iSeparator = 0;
- UINT iStringLen = 0;
- INT iRetVal = 0;
- CHAR* pszSearchPath = NULL;
- BOOL fSearchPathNeedsFreeing = FALSE;
-
- if (!ppszFullName)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- iRetVal = -1;
- goto Done;
- }
- *ppszFullName = NULL;
-
- // First, get the LD_LIBRARY_PATH to figure out where to look
- // Note that pszLibPath points to system memory -- don't free.
- pszLibPath = MiscGetenv(LIBSEARCHPATH);
- if (!pszLibPath)
- {
- TRACE("FindLibrary: " LIBSEARCHPATH " not set\n");
- pszLibPath = (char*)".";
- }
- else
- {
- TRACE("FindLibrary: " LIBSEARCHPATH " is %s\n", pszLibPath);
- }
-
- pThread = InternalGetCurrentThread();
- iStringLen = strlen(pszLibPath);
-
- // We want to make sure that we always search the current directory,
- // regardless of whether LD_LIBRARY_PATH includes it (this mimics
- // Windows behavior)
- if ( (!(strstr(pszLibPath, ":.:"))) && // if you don't find '.' in the middle
- (!(iStringLen == 1 && pszLibPath[0] == '.')) && // if it's not just equal to '.'
- (!(iStringLen >= 2 && pszLibPath[0] == '.'
- && pszLibPath[1] == ':')) && // if it doesn't start with ".:"
- (!(iStringLen >= 2 && pszLibPath[iStringLen-2] == ':'
- && pszLibPath[iStringLen-1] == '.')) ) // if it doesn't end with ":."
- {
- // 3 is hardcoded here for :. and null
- int iLen = sizeof(pszSearchPath[0]) * (iStringLen + 3);
- pszSearchPath = (char*) InternalMalloc (pThread, iLen);
- if (!pszSearchPath)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- iRetVal = -1;
- goto Done;
- }
- iStringLen += 3; // This 3 is hard coded for :. and null
- fSearchPathNeedsFreeing = TRUE;
- if (strcpy_s(pszSearchPath, iLen, pszLibPath) != SAFECRT_SUCCESS)
- {
- ERROR("strcpy_s failed!\n");
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- goto Done;
- }
-
- if (strcat_s(pszSearchPath, iLen, ":.") != SAFECRT_SUCCESS)
- {
- ERROR("strcat_s failed!\n");
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- goto Done;
- }
- }
- // If LD_LIBRARY_PATH already includes a reference to the current
- // directory, we'll search it in the right order.
- else
- {
- pszSearchPath = pszLibPath;
- }
-
- _ASSERTE(strchr(pszSearchPath, '.'));
-
- // Allocate an array for pointers to separators -- there can't be more than
- // the length of LD_LIBRARY_PATH - 1 separators (since we always have atleast a '.' in it )
- // + 2 implicit seperators...
- rgpLibDirSeparators = (char **)
- InternalMalloc(pThread, sizeof(rgpLibDirSeparators[0]) * (iStringLen+1));
- if (!rgpLibDirSeparators)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- iRetVal = -1;
- goto Done;
- }
-
- // Now, find the separators in LD_LIBRARY_PATH. Set a pointer to each :
- pszNext = pszSearchPath;
- // There's an implicit separator at the start...
- rgpLibDirSeparators[0] = pszNext - 1;
- cSeparators = 1;
- while (*pszNext != '\0')
- {
- if (*pszNext == ':')
- {
- _ASSERTE(cSeparators < iStringLen);
- rgpLibDirSeparators[cSeparators] = pszNext;
- cSeparators++;
- }
- pszNext++;
- }
-
- _ASSERTE(cSeparators <= iStringLen);
- // And there's an implicit separator at the end.
- rgpLibDirSeparators[cSeparators] = pszNext;
- cSeparators++;
-
- // Now, check each path for the File
- // Note that cSeparators is always >= 2, so the < -1 check is safe
- for (iSeparator = 0; iSeparator < (cSeparators-1); iSeparator++)
- {
- CHAR szFileName[MAX_PATH + 1];
- CHAR szDirName[MAX_PATH + 1];
- struct stat stat_buf;
- UINT cchDirName = 0;
-
- // length of DirName is number of chars between the first char after
- // the colon and the next colon
- cchDirName = rgpLibDirSeparators[iSeparator + 1] -
- (rgpLibDirSeparators[iSeparator] + 1);
- memcpy(szDirName, rgpLibDirSeparators[iSeparator] + 1, cchDirName);
- szDirName[cchDirName] = '\0';
- snprintf(szFileName, MAX_PATH, "%s/%s", szDirName, pszRelName);
- if (0 == stat(szFileName, &stat_buf))
- {
- // First, make sure we've got the canonical path
- CHAR szRealPath[PATH_MAX + 1];
-
- if(!realpath(szFileName, szRealPath))
- {
- ASSERT("realpath() failed! problem path is %s\n", szFileName);
- SetLastError(ERROR_INTERNAL_ERROR);
- goto Done;
- }
- // We've found it. Rejoice!
- TRACE("FindLibrary: found file: %s\n", szRealPath);
- *ppszFullName = InternalStrdup(pThread, szRealPath);
- if (!*ppszFullName)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- iRetVal = -1;
- }
- goto Done;
- }
- }
-
-Done:
- if (rgpLibDirSeparators)
- InternalFree(pThread, rgpLibDirSeparators);
- if (fSearchPathNeedsFreeing)
- InternalFree(pThread, pszSearchPath);
- // Don't treat it as an error if the library's not found -- just set
- // *ppszFullName to NULL.
- return iRetVal;
-}
-
-/*++
LOADInitCoreCLRModules
Run the initialization methods for CoreCLR modules that used to be standalone dynamic libraries (PALRT and
@@ -2015,5 +1759,5 @@ PAL_GetSymbolModuleBase(void *symbol)
LOGEXIT("PAL_GetPalModuleBase returns %p\n", retval);
PERF_EXIT(PAL_GetPalModuleBase);
return retval;
-
}
+
diff --git a/src/pal/src/thread/process.cpp b/src/pal/src/thread/process.cpp
index 7097e093b5..498d05fc7d 100644
--- a/src/pal/src/thread/process.cpp
+++ b/src/pal/src/thread/process.cpp
@@ -23,6 +23,7 @@ Abstract:
#include "pal/thread.hpp"
#include "pal/file.hpp"
#include "pal/handlemgr.hpp"
+#include "pal/module.h"
#include "procprivate.hpp"
#include "pal/palinternal.h"
#include "pal/process.h"
@@ -172,7 +173,18 @@ static int checkFileType(char *lpFileName);
static BOOL PROCEndProcess(HANDLE hProcess, UINT uExitCode,
BOOL bTerminateUnconditionally);
+//
+// Struct for temporary process module list
+//
+struct ProcessModules
+{
+ ProcessModules *Next;
+ PVOID BaseAddress;
+ CHAR Name[0];
+};
+ProcessModules *CreateProcessModules(IN HANDLE hProcess, OUT LPDWORD lpCount);
+void DestroyProcessModules(IN ProcessModules *listHead);
/*++
Function:
@@ -1758,6 +1770,233 @@ OpenProcessExit:
/*++
Function:
+ EnumProcessModules
+
+Abstract
+ Returns a process's module list
+
+Return
+ TRUE if it succeeded, FALSE otherwise
+
+Notes
+ This API is tricky because the module handles are never closed/freed so there can't be any
+ allocations for the module handle or name strings, etc. The "handles" are actually the base
+ addresses of the modules. The module handles should only be used by GetModuleFileNameExW
+ below.
+--*/
+BOOL
+PALAPI
+EnumProcessModules(
+ IN HANDLE hProcess,
+ OUT HMODULE *lphModule,
+ IN DWORD cb,
+ OUT LPDWORD lpcbNeeded)
+{
+ PERF_ENTRY(EnumProcessModules);
+ ENTRY("EnumProcessModules(hProcess=0x%08x, cb=%d)\n", hProcess, cb);
+
+ BOOL result = TRUE;
+ DWORD count = 0;
+
+ ProcessModules *listHead = CreateProcessModules(hProcess, &count);
+ if (listHead != NULL)
+ {
+ for (ProcessModules *entry = listHead; entry != NULL; entry = entry->Next)
+ {
+ if (cb <= 0)
+ {
+ break;
+ }
+ cb -= sizeof(HMODULE);
+ *lphModule = (HMODULE)entry->BaseAddress;
+ lphModule++;
+ }
+ }
+ else
+ {
+ result = FALSE;
+ }
+
+ DestroyProcessModules(listHead);
+
+ if (lpcbNeeded)
+ {
+ // This return value isn't exactly up to spec because it should return the actual
+ // number of modules in the process even if "cb" isn't big enough but for our use
+ // it works just fine.
+ (*lpcbNeeded) = count * sizeof(HMODULE);
+ }
+
+ LOGEXIT("EnumProcessModules returns %d\n", result);
+ PERF_EXIT(EnumProcessModules);
+ return result;
+}
+
+/*++
+Function:
+ GetModuleFileNameExW
+
+ Used only with module handles returned from EnumProcessModule (for dbgshim).
+
+--*/
+DWORD
+PALAPI
+GetModuleFileNameExW(
+ IN HANDLE hProcess,
+ IN HMODULE hModule,
+ OUT LPWSTR lpFilename,
+ IN DWORD nSize
+)
+{
+ DWORD result = 0;
+ DWORD count = 0;
+
+ ProcessModules *listHead = CreateProcessModules(hProcess, &count);
+ if (listHead != NULL)
+ {
+ for (ProcessModules *entry = listHead; entry != NULL; entry = entry->Next)
+ {
+ if ((HMODULE)entry->BaseAddress == hModule)
+ {
+ // Convert CHAR string into WCHAR string
+ result = MultiByteToWideChar(CP_ACP, 0, entry->Name, -1, lpFilename, nSize);
+ break;
+ }
+ }
+ }
+
+ DestroyProcessModules(listHead);
+
+ return result;
+}
+
+/*++
+Function:
+ CreateProcessModules
+
+Abstract
+ Returns a process's module list
+
+Return
+ ProcessModules * list
+
+--*/
+ProcessModules *
+CreateProcessModules(
+ IN HANDLE hProcess,
+ OUT LPDWORD lpCount)
+{
+ DWORD dwProcessId = PROCGetProcessIDFromHandle(hProcess);
+ if (dwProcessId == 0)
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return NULL;
+ }
+
+#ifdef HAVE_PROCFS_CTL
+ // Here we read /proc/<pid>/maps file in order to parse it and figure out what it says
+ // about a library we are looking for. This file looks something like this:
+ //
+ // [address] [perms] [offset] [dev] [inode] [pathname] - HEADER is not preset in an actual file
+ //
+ // 35b1800000-35b1820000 r-xp 00000000 08:02 135522 /usr/lib64/ld-2.15.so
+ // 35b1a1f000-35b1a20000 r--p 0001f000 08:02 135522 /usr/lib64/ld-2.15.so
+ // 35b1a20000-35b1a21000 rw-p 00020000 08:02 135522 /usr/lib64/ld-2.15.so
+ // 35b1a21000-35b1a22000 rw-p 00000000 00:00 0 [heap]
+ // 35b1c00000-35b1dac000 r-xp 00000000 08:02 135870 /usr/lib64/libc-2.15.so
+ // 35b1dac000-35b1fac000 ---p 001ac000 08:02 135870 /usr/lib64/libc-2.15.so
+ // 35b1fac000-35b1fb0000 r--p 001ac000 08:02 135870 /usr/lib64/libc-2.15.so
+ // 35b1fb0000-35b1fb2000 rw-p 001b0000 08:02 135870 /usr/lib64/libc-2.15.so
+
+ // Making something like: /proc/123/maps
+ char mapFileName[100];
+ int chars = snprintf(mapFileName, sizeof(mapFileName), "/proc/%d/maps", dwProcessId);
+ _ASSERTE(chars > 0 && chars <= sizeof(mapFileName));
+
+ FILE *mapsFile = fopen(mapFileName, "r");
+ if (mapsFile == NULL)
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return NULL;
+ }
+
+ CPalThread* pThread = InternalGetCurrentThread();
+ ProcessModules *listHead = NULL;
+ char *line = NULL;
+ size_t lineLen = 0;
+ int count = 0;
+ ssize_t read;
+
+ // Reading maps file line by line
+ while ((read = getline(&line, &lineLen, mapsFile)) != -1)
+ {
+ void *startAddress, *endAddress, *offset;
+ int devHi, devLo, inode;
+ char moduleName[PATH_MAX];
+
+ if (sscanf(line, "%p-%p %*[-rwxsp] %p %x:%x %d %s\n", &startAddress, &endAddress, &offset, &devHi, &devLo, &inode, moduleName) == 7)
+ {
+ if (inode != 0)
+ {
+ bool dup = false;
+ for (ProcessModules *entry = listHead; entry != NULL; entry = entry->Next)
+ {
+ if (strcmp(moduleName, entry->Name) == 0)
+ {
+ dup = true;
+ break;
+ }
+ }
+
+ if (!dup)
+ {
+ int cbModuleName = strlen(moduleName) + 1;
+ ProcessModules *entry = (ProcessModules *)InternalMalloc(pThread, sizeof(ProcessModules) + cbModuleName);
+ if (entry == NULL)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ DestroyProcessModules(listHead);
+ listHead = NULL;
+ count = 0;
+ break;
+ }
+ strcpy_s(entry->Name, cbModuleName, moduleName);
+ entry->BaseAddress = startAddress;
+ entry->Next = listHead;
+ listHead = entry;
+ count++;
+ }
+ }
+ }
+ }
+
+ *lpCount = count;
+
+ free(line); // We didn't allocate line, but as per contract of getline we should free it
+ fclose(mapsFile);
+
+ return listHead;
+#else
+ _ASSERTE(!"Not implemented on this platform");
+ return NULL;
+#endif
+}
+
+void
+DestroyProcessModules(IN ProcessModules *listHead)
+{
+ CPalThread* pThread = InternalGetCurrentThread();
+
+ for (ProcessModules *entry = listHead; entry != NULL; )
+ {
+ ProcessModules *next = entry->Next;
+ InternalFree(pThread, entry);
+ entry = next;
+ }
+}
+
+/*++
+Function:
InitializeFlushProcessWriteBuffers
Abstract