Commit be497c20 authored by ian@well-typed.com's avatar ian@well-typed.com

Keep the list of DLLs that we dlopen

Unfortunately, dlsym finds the first symbol loaded, while when we reload
a compiled module in GHCi it's the last symbol that we want. Therefore
we remember the list of loaded DLLs ourselves and go through them in
order.
parent 76410f7f
......@@ -1588,9 +1588,32 @@ static OpenedDLL* opened_dlls = NULL;
# if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)
/* Suppose in ghci we load a temporary SO for a module containing
f = 1
and then modify the module, recompile, and load another temporary
SO with
f = 2
Then as we don't unload the first SO, dlsym will find the
f = 1
symbol whereas we want the
f = 2
symbol. We therefore need to keep our own SO handle list, and
try SOs in the right order. */
typedef
struct _OpenedSO {
struct _OpenedSO* next;
void *handle;
}
OpenedSO;
/* A list thereof. */
static OpenedSO* openedSOs = NULL;
static const char *
internal_dlopen(const char *dll_name)
{
OpenedSO* o_so;
void *hdl;
const char *errmsg;
char *errmsg_copy;
......@@ -1618,11 +1641,36 @@ internal_dlopen(const char *dll_name)
strcpy(errmsg_copy, errmsg);
errmsg = errmsg_copy;
}
o_so = stgMallocBytes(sizeof(OpenedSO), "addDLL");
o_so->handle = hdl;
o_so->next = openedSOs;
openedSOs = o_so;
RELEASE_LOCK(&dl_mutex);
//--------------- End critical section -------------------
return errmsg;
}
static void *
internal_dlsym(void *hdl, const char *symbol) {
OpenedSO* o_so;
void *v;
// We acquire dl_mutex as concurrent dl* calls may alter dlerror
ACQUIRE_LOCK(&dl_mutex);
dlerror();
for (o_so = openedSOs; o_so != NULL; o_so = o_so->next) {
v = dlsym(o_so->handle, symbol);
if (dlerror() == NULL) {
RELEASE_LOCK(&dl_mutex);
return v;
}
}
v = dlsym(hdl, symbol)
RELEASE_LOCK(&dl_mutex);
return v;
}
# endif
const char *
......@@ -1798,7 +1846,7 @@ lookupSymbol( char *lbl )
if (val == NULL) {
IF_DEBUG(linker, debugBelch("lookupSymbol: symbol not found\n"));
# if defined(OBJFORMAT_ELF)
return dlsym(dl_prog_handle, lbl);
return internal_dlsym(dl_prog_handle, lbl);
# elif defined(OBJFORMAT_MACHO)
# if HAVE_DLFCN_H
/* On OS X 10.3 and later, we use dlsym instead of the old legacy
......@@ -1812,7 +1860,7 @@ lookupSymbol( char *lbl )
*/
IF_DEBUG(linker, debugBelch("lookupSymbol: looking up %s with dlsym\n", lbl));
ASSERT(lbl[0] == '_');
return dlsym(dl_prog_handle, lbl + 1);
return internal_dlsym(dl_prog_handle, lbl + 1);
# else
if (NSIsSymbolNameDefined(lbl)) {
NSSymbol symbol = NSLookupAndBindSymbol(lbl);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment