aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Support
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-05-28 23:54:07 +0000
committerChris Lattner <sabre@nondot.org>2004-05-28 23:54:07 +0000
commitaafb1c16b4de9aaa5e33c035dabcacdc3b66396f (patch)
tree4db3b7f667538ca6a54fb69efbb1141c1e84c788 /lib/Support
parent1c457b89bbe46e371e856bd559e0271c0fd7e175 (diff)
downloadexternal_llvm-aafb1c16b4de9aaa5e33c035dabcacdc3b66396f.zip
external_llvm-aafb1c16b4de9aaa5e33c035dabcacdc3b66396f.tar.gz
external_llvm-aafb1c16b4de9aaa5e33c035dabcacdc3b66396f.tar.bz2
Thoroughly rehack the dynamic linking mechanisms on Win32. The Win32
dynamic linker does not automatically search libraries when looking up symbols with GetProcAddress. Because of this we have to emulate it. The only detail is that there doesn't seem to be a way to enumerate the libraries loaded, so we have a gross hack (tm). This make the JIT functional on win32 under cygwin. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@13887 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support')
-rw-r--r--lib/Support/DynamicLinker.cpp57
1 files changed, 41 insertions, 16 deletions
diff --git a/lib/Support/DynamicLinker.cpp b/lib/Support/DynamicLinker.cpp
index cf00bea..4ac58c1 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 <cassert>
+#include <vector>
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<HMODULE> &getLoadedLibHandles() {
+ static std::vector<HMODULE> *LoadedLibHandles = 0;
+ if (LoadedLibHandles == 0) {
+ LoadedLibHandles = new std::vector<HMODULE>();
+ 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<HMODULE> &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