+# endif
+}
+
+/* -----------------------------------------------------------------------------
+ * Add a DLL from which symbols may be found. In the ELF case, just
+ * do RTLD_GLOBAL-style add, so no further messing around needs to
+ * happen in order that symbols in the loaded .so are findable --
+ * lookupSymbol() will subsequently see them by dlsym on the program's
+ * dl-handle. Returns NULL if success, otherwise ptr to an err msg.
+ *
+ * In the PEi386 case, open the DLLs and put handles to them in a
+ * linked list. When looking for a symbol, try all handles in the
+ * list.
+ */
+
+#if defined(OBJFORMAT_PEi386)
+/* A record for storing handles into DLLs. */
+
+typedef
+ struct _OpenedDLL {
+ char* name;
+ struct _OpenedDLL* next;
+ HINSTANCE instance;
+ }
+ OpenedDLL;
+
+/* A list thereof. */
+static OpenedDLL* opened_dlls = NULL;
+#endif
+
+
+
+char*
+addDLL ( __attribute((unused)) char* path, char* dll_name )
+{
+# if defined(OBJFORMAT_ELF)
+ void *hdl;
+ char *buf;
+ char *errmsg;
+
+ if (path == NULL || strlen(path) == 0) {
+ buf = stgMallocBytes(strlen(dll_name) + 10, "addDll");
+ sprintf(buf, "lib%s.so", dll_name);
+ } else {
+ buf = stgMallocBytes(strlen(path) + 1 + strlen(dll_name) + 10, "addDll");
+ sprintf(buf, "%s/lib%s.so", path, dll_name);
+ }
+ hdl = dlopen(buf, RTLD_NOW | RTLD_GLOBAL );
+ free(buf);
+ if (hdl == NULL) {
+ /* dlopen failed; return a ptr to the error msg. */
+ errmsg = dlerror();
+ if (errmsg == NULL) errmsg = "addDLL: unknown error";
+ return errmsg;
+ } else {
+ return NULL;
+ }
+ /*NOTREACHED*/
+
+# elif defined(OBJFORMAT_PEi386)
+
+ /* Add this DLL to the list of DLLs in which to search for symbols.
+ The path argument is ignored. */
+ char* buf;
+ OpenedDLL* o_dll;
+ HINSTANCE instance;
+
+ /* fprintf(stderr, "\naddDLL; path=`%s', dll_name = `%s'\n", path, dll_name); */
+
+ /* See if we've already got it, and ignore if so. */
+ for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) {
+ if (0 == strcmp(o_dll->name, dll_name))
+ return NULL;
+ }
+
+ buf = stgMallocBytes(strlen(dll_name) + 10, "addDLL");
+ sprintf(buf, "%s.DLL", dll_name);
+ instance = LoadLibrary(buf);
+ free(buf);
+ if (instance == NULL) {
+ /* LoadLibrary failed; return a ptr to the error msg. */
+ return "addDLL: unknown error";
+ }
+
+ o_dll = stgMallocBytes( sizeof(OpenedDLL), "addDLL" );
+ o_dll->name = stgMallocBytes(1+strlen(dll_name), "addDLL");
+ strcpy(o_dll->name, dll_name);
+ o_dll->instance = instance;
+ o_dll->next = opened_dlls;
+ opened_dlls = o_dll;
+
+ return NULL;
+# else
+ barf("addDLL: not implemented on this platform");
+# endif