diff options
author | Konstantin Baladurin <k.baladurin@samsung.com> | 2019-07-05 19:36:28 +0300 |
---|---|---|
committer | Gleb Balykov <g.balykov@samsung.com> | 2020-03-25 15:29:41 +0300 |
commit | adf89f8ad08eaf477b768d76d3902d123fd916e2 (patch) | |
tree | a0551deaf0b3d1f996b40366ef72ea7b11d8207b /src/pal/src/loader/module.cpp | |
parent | c6b150319647712f3bd1340fcc051336fbabb424 (diff) | |
download | coreclr-adf89f8ad08eaf477b768d76d3902d123fd916e2.tar.gz coreclr-adf89f8ad08eaf477b768d76d3902d123fd916e2.tar.bz2 coreclr-adf89f8ad08eaf477b768d76d3902d123fd916e2.zip |
[Tizen] Add coreclr_preload_assembly to CoreCLR host API
Diffstat (limited to 'src/pal/src/loader/module.cpp')
-rw-r--r-- | src/pal/src/loader/module.cpp | 188 |
1 files changed, 184 insertions, 4 deletions
diff --git a/src/pal/src/loader/module.cpp b/src/pal/src/loader/module.cpp index 74156fd215..78069b8875 100644 --- a/src/pal/src/loader/module.cpp +++ b/src/pal/src/loader/module.cpp @@ -85,8 +85,98 @@ using namespace CorUnix; #define LIBC_NAME_WITHOUT_EXTENSION "libc" +struct PreloadedImageListNode +{ + PreloadedImageListNode *next; + LPSTR szPath; + LPWSTR wszPath; + LPVOID lpMappedImage; + SIZE_T virtualSize; + bool isLoaded; +}; + +class PreloadedImageList +{ + PreloadedImageListNode *m_start; + +public: + + PreloadedImageList() + : m_start(NULL) {} + + void addNew(LPCSTR szPath, LPVOID lpImage, SIZE_T size) + { + PreloadedImageListNode *node = (PreloadedImageListNode *) InternalMalloc(sizeof(PreloadedImageListNode)); + node->szPath = (LPSTR) InternalMalloc(strlen(szPath) + 1); + strcpy(node->szPath, szPath); + node->wszPath = NULL; + node->lpMappedImage = lpImage; + node->virtualSize = size; + node->isLoaded = false; + node->next = m_start; + m_start = node; + } + + bool freeAll() + { + PreloadedImageListNode *node = m_start; + while (node != NULL) + { + PreloadedImageListNode *nextNode = node->next; + if (!node->isLoaded) + { + MAPUnmapPreloadedPEFile(node->lpMappedImage, node->virtualSize); + } + + if (node->wszPath != NULL) + { + free(node->wszPath); + } + free(node->szPath); + free(node); + node = nextNode; + } + + return true; + } + + PreloadedImageListNode *find(LPCWSTR wszPath) + { + PreloadedImageListNode *node = m_start; + while (node != NULL) + { + if (node->wszPath == NULL) + { + // MultiByteToWideChar requires PAL initialization + if (!PALIsInitialized()) + break; + + int length = MultiByteToWideChar(CP_UTF8, 0, node->szPath, -1, NULL, 0); + _ASSERTE(length != 0); + + node->wszPath = (LPWSTR) InternalMalloc(length * sizeof(WCHAR)); + _ASSERTE(node->wszPath != NULL); + + length = MultiByteToWideChar(CP_UTF8, 0, node->szPath, -1, node->wszPath, length); + _ASSERTE(length != 0); + } + + if (PAL_wcscmp(node->wszPath, wszPath) == 0) + { + return node; + } + + node = node->next; + } + + return NULL; + } +}; + /* static variables ***********************************************************/ +PreloadedImageList preloadedAssemblies; + /* critical section that regulates access to the module list */ CRITICAL_SECTION module_critsec; @@ -779,6 +869,8 @@ PAL_UnregisterModule( Parameters: IN hFile - file to map + IN wszPath - File path + OUT isPreloaded - Flag whether pefile was preloaded Return value: non-NULL - the base address of the mapped image @@ -786,11 +878,14 @@ Return value: --*/ PVOID PALAPI -PAL_LOADLoadPEFile(HANDLE hFile) +PAL_LOADLoadPEFile(HANDLE hFile, LPCWSTR wszPath, BOOL *isPreloaded) { ENTRY("PAL_LOADLoadPEFile (hFile=%p)\n", hFile); - void * loadedBase = MAPMapPEFile(hFile); + void * preloadedBase = LOADFindPreloadedPEFile(wszPath); + *isPreloaded = preloadedBase != NULL; + + void * loadedBase = MAPMapPEFile(hFile, NULL, 0, preloadedBase); #ifdef _DEBUG if (loadedBase != nullptr) @@ -801,8 +896,11 @@ PAL_LOADLoadPEFile(HANDLE hFile) if (strlen(envVar) > 0) { TRACE("Forcing failure of PE file map, and retry\n"); - PAL_LOADUnloadPEFile(loadedBase); // unload it - loadedBase = MAPMapPEFile(hFile); // load it again + if (preloadedBase == NULL) + { + PAL_LOADUnloadPEFile(loadedBase); // unload it + } + loadedBase = MAPMapPEFile(hFile, NULL, 0, preloadedBase); // load it again } free(envVar); @@ -815,6 +913,60 @@ PAL_LOADLoadPEFile(HANDLE hFile) } /*++ +Function: + PAL_LOADPreloadPEFile + +Abstract + Preloads a PE file into memory. Properly maps all of the sections in the PE file. Returns a pointer to the + loaded base. + +Parameters: + IN szPath - path of file to load + +Return value: + A valid base address if successful. + 0 if failure +--*/ +void * +PALAPI +PAL_LOADPreloadPEFile(LPCSTR szPath) +{ + size_t size; + void *addr = MAPMapPEFile(NULL, szPath, &size, NULL); + + if (addr == NULL) + { + return NULL; + } + + if (!MAPApplyBaseRelocationsPreloadedPEFile(addr, size)) + { + MAPUnmapPreloadedPEFile(addr, size); + return NULL; + } + + preloadedAssemblies.addNew(szPath, addr, size); + + return addr; +} + +/*++ + PAL_LOADUnloadPreloadedPEFiles + + Unload all PE files that were loaded by PAL_LOADPreloadPEFile(). + +Return value: + TRUE - success + FALSE - failure +--*/ +BOOL +PALAPI +PAL_LOADUnloadPreloadedPEFiles() +{ + return preloadedAssemblies.freeAll(); +} + +/*++ PAL_LOADUnloadPEFile Unload a PE file that was loaded by PAL_LOADLoadPEFile(). @@ -921,6 +1073,34 @@ PAL_GetLoadLibraryError() /* Internal PAL functions *****************************************************/ /*++ + LOADFindPreloadedPEFile - + + Find image in list of preloaded + +Parameters: + IN wszPath - path to mapped file + +Return value: + non-NULL - the base address of the mapped image + NULL - image is not in the list of preloaded. +--*/ + +void * LOADFindPreloadedPEFile(LPCWSTR wszPath) +{ + void * preloadedBase = NULL; + + PreloadedImageListNode *node = preloadedAssemblies.find(wszPath); + if (node != NULL) + { + preloadedBase = node->lpMappedImage; + _ASSERTE(!node->isLoaded); + node->isLoaded = true; + } + + return preloadedBase; +} + +/*++ Function : LOADInitializeModules |