[project @ 2001-02-13 13:11:07 by sewardj]
[ghc-hetmet.git] / ghc / rts / Linker.c
index 02be005..5316f46 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: Linker.c,v 1.25 2001/02/12 13:30:15 sewardj Exp $
+ * $Id: Linker.c,v 1.27 2001/02/13 13:11:07 sewardj Exp $
  *
  * (c) The GHC Team, 2000
  *
@@ -47,6 +47,35 @@ static int ocGetNames_PEi386    ( ObjectCode* oc );
 static int ocResolve_PEi386     ( ObjectCode* oc );
 #endif
 
+int ocAddDLL ( char* dll_name );
+
+
+/* -----------------------------------------------------------------------------
+ * 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 0 if fail, 1 if success.
+ */
+int ocAddDLL ( char* dll_name )
+{
+#  if defined(OBJFORMAT_ELF)
+   void* hdl;
+   char  buf[100];
+   if (strlen(dll_name) > 50)
+      barf("ocAddDLL: excessively long .so/.DLL name `%s'", dll_name);
+   sprintf(buf, "lib%s.so", dll_name);
+   hdl = dlopen(buf, RTLD_NOW | RTLD_GLOBAL);
+   return (hdl == NULL) ? 0 : 1;
+#  elif defined(OBJFORMAT_PEi386)
+   barf("ocAddDLL: not implemented on PEi386 yet");
+   return 0;
+#  else
+   barf("ocAddDLL: not implemented on this platform");
+#  endif
+}
+
+
 /* -----------------------------------------------------------------------------
  * Built-in symbols from the RTS
  */
@@ -463,7 +492,9 @@ unloadObj( char *path )
            free(oc->fileName);
            free(oc->symbols);
            free(oc->sections);
-            freeHashTable(oc->lochash, NULL);
+           /* The local hash table should have been freed at the end
+               of the ocResolve_ call on it. */
+            ASSERT(oc->lochash == NULL);
            free(oc);
            return 1;
        }
@@ -1611,6 +1642,10 @@ ocResolve_ELF ( ObjectCode* oc )
       }
    }
 
+   /* Free the local symbol table; we won't need it again. */
+   freeHashTable(oc->lochash, NULL);
+   oc->lochash = NULL;
+
    return 1;
 }