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
This commit is contained in:
Chris Lattner 2004-05-28 23:54:07 +00:00
parent 1c457b89bb
commit aafb1c16b4

View File

@ -12,8 +12,7 @@
// provides it. // provides it.
// //
// Possible future extensions include support for the HPUX shl_load() // Possible future extensions include support for the HPUX shl_load()
// interface, the Mac OS X NSLinkModule() interface, and the Windows // interface, and the Mac OS X NSLinkModule() interface.
// LoadLibrary() interface.
// //
// Note that we assume that if dlopen() is available, then dlsym() is too. // Note that we assume that if dlopen() is available, then dlsym() is too.
// //
@ -23,18 +22,36 @@
#include "Config/dlfcn.h" #include "Config/dlfcn.h"
#include "Config/windows.h" #include "Config/windows.h"
#include <cassert> #include <cassert>
#include <vector>
using namespace llvm; using namespace llvm;
bool llvm::LinkDynamicObject (const char *filename, std::string *ErrorMessage) { #if defined(HAVE_WINDOWS_H)
#if defined (HAVE_DLOPEN) // getLoadedLibs - Keep track of the shared objects that are loaded into the
if (dlopen (filename, RTLD_NOW | RTLD_GLOBAL) == 0) { // process address space, as the windows GetProcAddress function does not
if (ErrorMessage) *ErrorMessage = dlerror (); // automatically search an entire address space, it only searches a specific
return true; // 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 *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; return false;
#elif defined(HAVE_WINDOWS_H) }
if (LoadLibrary(filename))
return false;
if (ErrorMessage) { if (ErrorMessage) {
char Buffer[100]; char Buffer[100];
// FIXME: This should use FormatMessage // FIXME: This should use FormatMessage
@ -42,23 +59,31 @@ bool llvm::LinkDynamicObject (const char *filename, std::string *ErrorMessage) {
*ErrorMessage = Buffer; *ErrorMessage = Buffer;
} }
return true; return true;
#elif defined (HAVE_DLOPEN)
if (dlopen (filename, RTLD_NOW | RTLD_GLOBAL) == 0) {
if (ErrorMessage) *ErrorMessage = dlerror ();
return true;
}
return false;
#else #else
assert (0 && "Dynamic object linking not implemented for this platform"); assert (0 && "Dynamic object linking not implemented for this platform");
#endif #endif
} }
void *llvm::GetAddressOfSymbol(const char *symbolName) { void *llvm::GetAddressOfSymbol(const char *symbolName) {
#if defined (HAVE_DLOPEN) #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 # ifdef RTLD_DEFAULT
return dlsym (RTLD_DEFAULT, symbolName); return dlsym (RTLD_DEFAULT, symbolName);
# else # else
static void* CurHandle = dlopen(0, RTLD_LAZY); static void* CurHandle = dlopen(0, RTLD_LAZY);
return dlsym(CurHandle, symbolName); return dlsym(CurHandle, symbolName);
# endif # endif
#elif defined(HAVE_WINDOWS_H)
static HMODULE ModHandle = NULL;
if (ModHandle == 0) ModHandle = GetModuleHandle(NULL);
return (void*)GetProcAddress(ModHandle, symbolName);
#else #else
assert (0 && "Dynamic symbol lookup not implemented for this platform"); assert (0 && "Dynamic symbol lookup not implemented for this platform");
#endif #endif