Windows: print an error message in addDLL
[ghc-hetmet.git] / rts / Linker.c
index 04f272c..26d671e 100644 (file)
@@ -27,6 +27,7 @@
 #include "Schedule.h"
 #include "Sparks.h"
 #include "RtsTypeable.h"
+#include "Timer.h"
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #include <sys/wait.h>
 #endif
 
-#if defined(ia64_HOST_ARCH) || defined(openbsd_HOST_OS) || defined(linux_HOST_OS) || defined(freebsd_HOST_OS)
+#if defined(ia64_HOST_ARCH) || defined(linux_HOST_OS) || defined(freebsd_HOST_OS) || defined(netbsd_HOST_OS) || defined(openbsd_HOST_OS)
 #define USE_MMAP
 #include <fcntl.h>
 #include <sys/mman.h>
 
-#if defined(openbsd_HOST_OS) || defined(linux_HOST_OS) || defined(freebsd_HOST_OS)
+#if defined(linux_HOST_OS) || defined(freebsd_HOST_OS) || defined(netbsd_HOST_OS) || defined(openbsd_HOST_OS)
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
@@ -174,6 +175,7 @@ typedef struct _RtsSymbolVal {
 
 #if !defined (mingw32_HOST_OS)
 #define RTS_POSIX_ONLY_SYMBOLS                  \
+      SymX(shutdownHaskellAndSignal)           \
       Sym(lockFile)                             \
       Sym(unlockFile)                           \
       SymX(signal_handlers)                    \
@@ -537,13 +539,16 @@ typedef struct _RtsSymbolVal {
       SymX(addDLL)                             \
       GMP_SYMS                                 \
       SymX(__int_encodeDouble)                 \
+      SymX(__word_encodeDouble)                        \
       SymX(__2Int_encodeDouble)                        \
       SymX(__int_encodeFloat)                  \
+      SymX(__word_encodeFloat)                 \
       SymX(andIntegerzh_fast)                  \
       SymX(atomicallyzh_fast)                  \
       SymX(barf)                               \
       SymX(debugBelch)                         \
       SymX(errorBelch)                         \
+      SymX(asyncExceptionsBlockedzh_fast)      \
       SymX(blockAsyncExceptionszh_fast)                \
       SymX(catchzh_fast)                       \
       SymX(catchRetryzh_fast)                  \
@@ -699,6 +704,7 @@ typedef struct _RtsSymbolVal {
       SymX(stackOverflow)                      \
       SymX(stg_CAF_BLACKHOLE_info)             \
       SymX(awakenBlockedQueue)                 \
+      SymX(startTimer)                          \
       SymX(stg_CHARLIKE_closure)               \
       SymX(stg_MVAR_CLEAN_info)                        \
       SymX(stg_MVAR_DIRTY_info)                        \
@@ -764,6 +770,7 @@ typedef struct _RtsSymbolVal {
       SymX(stg_upd_frame_info)                 \
       SymX(suspendThread)                      \
       SymX(takeMVarzh_fast)                    \
+      SymX(threadStatuszh_fast)                        \
       SymX(timesIntegerzh_fast)                        \
       SymX(tryPutMVarzh_fast)                  \
       SymX(tryTakeMVarzh_fast)                 \
@@ -1014,7 +1021,9 @@ addDLL( char *dll_name )
 
    initLinker();
 
-   hdl= dlopen(dll_name, RTLD_NOW | RTLD_GLOBAL);
+   // omitted: RTLD_NOW
+   // see http://www.haskell.org/pipermail/cvs-ghc/2007-September/038570.html
+   hdl= dlopen(dll_name, RTLD_LAZY | RTLD_GLOBAL);
 
    if (hdl == NULL) {
       /* dlopen failed; return a ptr to the error msg. */
@@ -1057,14 +1066,19 @@ addDLL( char *dll_name )
    sprintf(buf, "%s.DLL", dll_name);
    instance = LoadLibrary(buf);
    if (instance == NULL) {
-        sprintf(buf, "%s.DRV", dll_name);      // KAA: allow loading of drivers (like winspool.drv)
-        instance = LoadLibrary(buf);
-        if (instance == NULL) {
-               stgFree(buf);
-
-           /* LoadLibrary failed; return a ptr to the error msg. */
-           return "addDLL: unknown error";
-        }
+       if (GetLastError() != ERROR_MOD_NOT_FOUND) goto error;
+       // KAA: allow loading of drivers (like winspool.drv)
+       sprintf(buf, "%s.DRV", dll_name);
+       instance = LoadLibrary(buf);
+       if (instance == NULL) {
+           if (GetLastError() != ERROR_MOD_NOT_FOUND) goto error;
+           // #1883: allow loading of unix-style libfoo.dll DLLs
+           sprintf(buf, "lib%s.DLL", dll_name);
+           instance = LoadLibrary(buf);
+           if (instance == NULL) {
+               goto error;
+           }
+       }
    }
    stgFree(buf);
 
@@ -1080,6 +1094,13 @@ addDLL( char *dll_name )
 #  else
    barf("addDLL: not implemented on this platform");
 #  endif
+
+error:
+   stgFree(buf);
+   sysErrorBelch(dll_name);
+               
+   /* LoadLibrary failed; return a ptr to the error msg. */
+   return "addDLL: could not load DLL";
 }
 
 /* -----------------------------------------------------------------------------
@@ -1169,23 +1190,6 @@ lookupSymbol( char *lbl )
     }
 }
 
-static
-__attribute((unused))
-void *
-lookupLocalSymbol( ObjectCode* oc, char *lbl )
-{
-    void *val;
-    initLinker() ;
-    val = lookupStrHashTable(oc->lochash, lbl);
-
-    if (val == NULL) {
-        return NULL;
-    } else {
-       return val;
-    }
-}
-
-
 /* -----------------------------------------------------------------------------
  * Debugging aid: look in GHCi's object symbol tables for symbols
  * within DELTA bytes of the specified address, and show their names.
@@ -1207,11 +1211,7 @@ void ghci_enquire ( char* addr )
       for (i = 0; i < oc->n_symbols; i++) {
          sym = oc->symbols[i];
          if (sym == NULL) continue;
-         // debugBelch("enquire %p %p\n", sym, oc->lochash);
          a = NULL;
-         if (oc->lochash != NULL) {
-            a = lookupStrHashTable(oc->lochash, sym);
-        }
          if (a == NULL) {
             a = lookupStrHashTable(symhash, sym);
         }
@@ -1296,7 +1296,6 @@ loadObj( char *path )
    oc->fileSize          = st.st_size;
    oc->symbols           = NULL;
    oc->sections          = NULL;
-   oc->lochash           = allocStrHashTable();
    oc->proddables        = NULL;
 
    /* chain it onto the list of objects */
@@ -1505,9 +1504,6 @@ unloadObj( char *path )
            stgFree(oc->fileName);
            stgFree(oc->symbols);
            stgFree(oc->sections);
-           /* The local hash table should have been freed at the end
-               of the ocResolve_ call on it. */
-            ASSERT(oc->lochash == NULL);
            stgFree(oc);
            return 1;
        }
@@ -2306,6 +2302,8 @@ ocGetNames_PEi386 ( ObjectCode* oc )
           && 0 != strcmp(".ctors", sectab_i->Name)
           /* ignore section generated from .ident */
           && 0!= strcmp("/4", sectab_i->Name)
+         /* ignore unknown section that appeared in gcc 3.4.5(?) */
+          && 0!= strcmp(".reloc", sectab_i->Name)
          ) {
          errorBelch("Unknown PEi386 section name `%s' (while processing: %s)", sectab_i->Name, oc->fileName);
          return 0;
@@ -2523,13 +2521,9 @@ ocResolve_PEi386 ( ObjectCode* oc )
                    + sym->Value);
          } else {
             copyName ( sym->Name, strtab, symbol, 1000-1 );
-            S = (UInt32) lookupLocalSymbol( oc, symbol );
-            if ((void*)S != NULL) goto foundit;
             S = (UInt32) lookupSymbol( symbol );
             if ((void*)S != NULL) goto foundit;
             zapTrailingAtSign ( symbol );
-            S = (UInt32) lookupLocalSymbol( oc, symbol );
-            if ((void*)S != NULL) goto foundit;
             S = (UInt32) lookupSymbol( symbol );
             if ((void*)S != NULL) goto foundit;
            /* Newline first because the interactive linker has printed "linking..." */
@@ -3157,7 +3151,7 @@ ocGetNames_ELF ( ObjectCode* oc )
                if (ELF_ST_TYPE(stab[j].st_info) == STT_FUNC)
                    ad = (char *)allocateFunctionDesc((Elf_Addr)ad);
 #endif
-               IF_DEBUG(linker,debugBelch( "addOTabName(GLOB): %10p  %s %s",
+               IF_DEBUG(linker,debugBelch( "addOTabName(GLOB): %10p  %s %s\n",
                                       ad, oc->fileName, nm ));
                isLocal = FALSE;
             }
@@ -3619,10 +3613,6 @@ ocResolve_ELF ( ObjectCode* oc )
       }
    }
 
-   /* Free the local symbol table; we won't need it again. */
-   freeHashTable(oc->lochash, NULL);
-   oc->lochash = NULL;
-
 #if defined(powerpc_HOST_ARCH)
    ocFlushInstructionCache( oc );
 #endif
@@ -3901,8 +3891,6 @@ static int resolveImports(
        if((symbol->n_type & N_TYPE) == N_UNDF
            && (symbol->n_type & N_EXT) && (symbol->n_value != 0))
            addr = (void*) (symbol->n_value);
-       else if((addr = lookupLocalSymbol(oc,nm)) != NULL)
-           ;
        else
            addr = lookupSymbol(nm);
        if(!addr)
@@ -4549,10 +4537,6 @@ static int ocResolve_MachO(ObjectCode* oc)
            return 0;
     }
 
-    /* Free the local symbol table; we won't need it again. */
-    freeHashTable(oc->lochash, NULL);
-    oc->lochash = NULL;
-
 #if defined (powerpc_HOST_ARCH)
     ocFlushInstructionCache( oc );
 #endif