From 0bce85fbfacec97255337d12fc0ab193f03f21c3 Mon Sep 17 00:00:00 2001 From: Jordy Rose Date: Wed, 17 Aug 2011 00:29:32 +0000 Subject: Use DynamicLibrary instances as a way to get symbols from a specific library. Preparation for upcoming (preliminary) support for plugins for the static analyzer. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137791 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Support/Windows/DynamicLibrary.inc | 78 ++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 26 deletions(-) (limited to 'lib/Support/Windows/DynamicLibrary.inc') diff --git a/lib/Support/Windows/DynamicLibrary.inc b/lib/Support/Windows/DynamicLibrary.inc index fc5f580..6724fbc 100644 --- a/lib/Support/Windows/DynamicLibrary.inc +++ b/lib/Support/Windows/DynamicLibrary.inc @@ -39,7 +39,7 @@ using namespace sys; //=== and must not be UNIX code. //===----------------------------------------------------------------------===// -static std::vector OpenedHandles; +static DenseSet *OpenedHandles; extern "C" { @@ -63,30 +63,43 @@ extern "C" { #endif stricmp(ModuleName, "msvcrt20") != 0 && stricmp(ModuleName, "msvcrt40") != 0) { - OpenedHandles.push_back((HMODULE)ModuleBase); + OpenedHandles->push_back((HMODULE)ModuleBase); } return TRUE; } } -bool DynamicLibrary::LoadLibraryPermanently(const char *filename, - std::string *ErrMsg) { - if (filename) { - HMODULE a_handle = LoadLibrary(filename); +DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename, + std::string *errMsg) { + if (!filename) { + // When no file is specified, enumerate all DLLs and EXEs in the process. + SmartScopedLock lock(getMutex()); + if (OpenedHandles == 0) + OpenedHandles = new DenseSet(); - if (a_handle == 0) - return MakeErrMsg(ErrMsg, std::string(filename) + ": Can't open : "); - - OpenedHandles.push_back(a_handle); - } else { - // When no file is specified, enumerate all DLLs and EXEs in the - // process. EnumerateLoadedModules(GetCurrentProcess(), ELM_Callback, 0); + // Dummy library that represents "search all handles". + // This is mostly to ensure that the return value still shows up as "valid". + return DynamicLibrary(&OpenedHandles); + } + + HMODULE a_handle = LoadLibrary(filename); + + if (a_handle == 0) { + MakeErrMsg(ErrMsg, std::string(filename) + ": Can't open : "); + return DynamicLibrary(); } - // Because we don't remember the handle, we will never free it; hence, - // it is loaded permanently. - return false; + SmartScopedLock lock(getMutex()); + if (OpenedHandles == 0) + OpenedHandles = new DenseSet(); + + // If we've already loaded this library, FreeLibrary() the handle in order to + // keep the internal refcount at +1. + if (!OpenedHandles->insert(a_handle).second) + FreeLibrary(a_handle); + + return DynamicLibrary(a_handle); } // Stack probing routines are in the support library (e.g. libgcc), but we don't @@ -101,21 +114,24 @@ bool DynamicLibrary::LoadLibraryPermanently(const char *filename, #undef EXPLICIT_SYMBOL2 void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) { + SmartScopedLock Lock(getMutex()); + // First check symbols added via AddSymbol(). if (ExplicitSymbols) { - std::map::iterator I = - ExplicitSymbols->find(symbolName); - std::map::iterator E = ExplicitSymbols->end(); - if (I != E) - return I->second; + StringMap::iterator i = ExplicitSymbols->find(symbolName); + + if (i != ExplicitSymbols->end()) + return i->second; } // Now search the libraries. - for (std::vector::iterator I = OpenedHandles.begin(), - E = OpenedHandles.end(); I != E; ++I) { - FARPROC ptr = GetProcAddress((HMODULE)*I, symbolName); - if (ptr) { - return (void *)(intptr_t)ptr; + if (OpenedHandles) { + for (DenseSet::iterator I = OpenedHandles->begin(), + E = OpenedHandles->end(); I != E; ++I) { + FARPROC ptr = GetProcAddress((HMODULE)*I, symbolName); + if (ptr) { + return (void *)(intptr_t)ptr; + } } } @@ -134,4 +150,14 @@ void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) { return 0; } + +void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) { + if (!isValid()) + return NULL; + if (Data == &OpenedHandles) + return SearchForAddressOfSymbol(symbolName); + return (void *)(intptr_t)GetProcAddress((HMODULE)Data, symbolName); +} + + } -- cgit v1.1 From f0813ceeaf33ab77fbc8b0196ebb612544e67579 Mon Sep 17 00:00:00 2001 From: Jordy Rose Date: Wed, 17 Aug 2011 00:59:50 +0000 Subject: Unbork Windows build. Thanks, Francois. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137798 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Support/Windows/DynamicLibrary.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/Support/Windows/DynamicLibrary.inc') diff --git a/lib/Support/Windows/DynamicLibrary.inc b/lib/Support/Windows/DynamicLibrary.inc index 6724fbc..5a0b249 100644 --- a/lib/Support/Windows/DynamicLibrary.inc +++ b/lib/Support/Windows/DynamicLibrary.inc @@ -63,7 +63,7 @@ extern "C" { #endif stricmp(ModuleName, "msvcrt20") != 0 && stricmp(ModuleName, "msvcrt40") != 0) { - OpenedHandles->push_back((HMODULE)ModuleBase); + OpenedHandles->insert((HMODULE)ModuleBase); } return TRUE; } @@ -86,7 +86,7 @@ DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename, HMODULE a_handle = LoadLibrary(filename); if (a_handle == 0) { - MakeErrMsg(ErrMsg, std::string(filename) + ": Can't open : "); + MakeErrMsg(errMsg, std::string(filename) + ": Can't open : "); return DynamicLibrary(); } -- cgit v1.1 From eeb37f1a568185c46f600fb34769ec376bf5bfaf Mon Sep 17 00:00:00 2001 From: Jordy Rose Date: Mon, 22 Aug 2011 19:01:52 +0000 Subject: Make DynamicLibrary thread-safe w/r/t call to dlerror() after dlopen(). PR10718 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@138260 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Support/Windows/DynamicLibrary.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/Support/Windows/DynamicLibrary.inc') diff --git a/lib/Support/Windows/DynamicLibrary.inc b/lib/Support/Windows/DynamicLibrary.inc index 5a0b249..83da82a 100644 --- a/lib/Support/Windows/DynamicLibrary.inc +++ b/lib/Support/Windows/DynamicLibrary.inc @@ -71,9 +71,10 @@ extern "C" { DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename, std::string *errMsg) { + SmartScopedLock lock(getMutex()); + if (!filename) { // When no file is specified, enumerate all DLLs and EXEs in the process. - SmartScopedLock lock(getMutex()); if (OpenedHandles == 0) OpenedHandles = new DenseSet(); @@ -90,7 +91,6 @@ DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename, return DynamicLibrary(); } - SmartScopedLock lock(getMutex()); if (OpenedHandles == 0) OpenedHandles = new DenseSet(); -- cgit v1.1