diff --git a/lib/Support/DynamicLinker.cpp b/lib/Support/DynamicLinker.cpp index cf00bea2db8..4ac58c1bbc0 100644 --- a/lib/Support/DynamicLinker.cpp +++ b/lib/Support/DynamicLinker.cpp @@ -12,8 +12,7 @@ // provides it. // // Possible future extensions include support for the HPUX shl_load() -// interface, the Mac OS X NSLinkModule() interface, and the Windows -// LoadLibrary() interface. +// interface, and the Mac OS X NSLinkModule() interface. // // Note that we assume that if dlopen() is available, then dlsym() is too. // @@ -23,18 +22,36 @@ #include "Config/dlfcn.h" #include "Config/windows.h" #include +#include using namespace llvm; -bool llvm::LinkDynamicObject (const char *filename, std::string *ErrorMessage) { -#if defined (HAVE_DLOPEN) - if (dlopen (filename, RTLD_NOW | RTLD_GLOBAL) == 0) { - if (ErrorMessage) *ErrorMessage = dlerror (); - return true; +#if defined(HAVE_WINDOWS_H) +// getLoadedLibs - Keep track of the shared objects that are loaded into the +// process address space, as the windows GetProcAddress function does not +// automatically search an entire address space, it only searches a specific +// object. +static std::vector &getLoadedLibHandles() { + static std::vector *LoadedLibHandles = 0; + if (LoadedLibHandles == 0) { + LoadedLibHandles = new std::vector(); + if (HMODULE H = GetModuleHandle(NULL)) // JIT symbols + LoadedLibHandles->push_back(H); + if (HMODULE MH = GetModuleHandle("cygwin1.dll")) // Cygwin symbols OR + LoadedLibHandles->push_back(MH); + else if (HMODULE MH = GetModuleHandle("msvcr80.dll")) // VC++ symbols + LoadedLibHandles->push_back(MH); } - return false; -#elif defined(HAVE_WINDOWS_H) - if (LoadLibrary(filename)) + return *LoadedLibHandles; +} +#endif + +bool llvm::LinkDynamicObject(const char *filename, std::string *ErrorMessage) { +#if defined(HAVE_WINDOWS_H) + if (HMODULE Handle = LoadLibrary(filename)) { + // Allow GetProcAddress in this module + getLoadedLibHandles().push_back(Handle); return false; + } if (ErrorMessage) { char Buffer[100]; // FIXME: This should use FormatMessage @@ -42,23 +59,31 @@ bool llvm::LinkDynamicObject (const char *filename, std::string *ErrorMessage) { *ErrorMessage = Buffer; } return true; +#elif defined (HAVE_DLOPEN) + if (dlopen (filename, RTLD_NOW | RTLD_GLOBAL) == 0) { + if (ErrorMessage) *ErrorMessage = dlerror (); + return true; + } + return false; #else assert (0 && "Dynamic object linking not implemented for this platform"); #endif } -void *llvm::GetAddressOfSymbol (const char *symbolName) { -#if defined (HAVE_DLOPEN) +void *llvm::GetAddressOfSymbol(const char *symbolName) { +#if defined(HAVE_WINDOWS_H) + std::vector &LH = getLoadedLibHandles(); + for (unsigned i = 0, e = LH.size(); i != e; ++i) + if (void *Val = (void*)GetProcAddress(LH[i], symbolName)) + return Val; + return 0; +#elif defined(HAVE_DLOPEN) # ifdef RTLD_DEFAULT return dlsym (RTLD_DEFAULT, symbolName); # else static void* CurHandle = dlopen(0, RTLD_LAZY); return dlsym(CurHandle, symbolName); # endif -#elif defined(HAVE_WINDOWS_H) - static HMODULE ModHandle = NULL; - if (ModHandle == 0) ModHandle = GetModuleHandle(NULL); - return (void*)GetProcAddress(ModHandle, symbolName); #else assert (0 && "Dynamic symbol lookup not implemented for this platform"); #endif