Do not link ghc stage1 using -threaded, only for stage2 or 3
[ghc-hetmet.git] / rts / Linker.c
index 84c69cb..6d7b66a 100644 (file)
@@ -26,7 +26,7 @@
 #include "RtsUtils.h"
 #include "Schedule.h"
 #include "Sparks.h"
-#include "RtsTypeable.h"
+#include "RtsGlobals.h"
 #include "Timer.h"
 #include "Trace.h"
 
@@ -224,6 +224,7 @@ typedef struct _RtsSymbolVal {
 
 #if !defined(PAR)
 #define Maybe_Stable_Names      SymI_HasProto(mkWeakzh_fast)                   \
+                               SymI_HasProto(mkWeakForeignEnvzh_fast)          \
                                SymI_HasProto(makeStableNamezh_fast)            \
                                SymI_HasProto(finalizzeWeakzh_fast)
 #else
@@ -492,7 +493,9 @@ typedef struct _RtsSymbolVal {
 
 #if !defined(mingw32_HOST_OS)
 #define RTS_USER_SIGNALS_SYMBOLS \
-   SymI_HasProto(setIOManagerPipe)
+   SymI_HasProto(setIOManagerPipe) \
+   SymI_NeedsProto(blockUserSignals) \
+   SymI_NeedsProto(unblockUserSignals)
 #else
 #define RTS_USER_SIGNALS_SYMBOLS     \
    SymI_HasProto(sendIOManagerEvent) \
@@ -636,6 +639,7 @@ typedef struct _RtsSymbolVal {
       SymI_HasProto(freeHaskellFunctionPtr)            \
       SymI_HasProto(freeStablePtr)                     \
       SymI_HasProto(getOrSetTypeableStore)             \
+      SymI_HasProto(getOrSetSignalHandlerStore)                \
       SymI_HasProto(gcdIntegerzh_fast)                 \
       SymI_HasProto(gcdIntegerIntzh_fast)              \
       SymI_HasProto(gcdIntzh_fast)                     \
@@ -652,6 +656,7 @@ typedef struct _RtsSymbolVal {
       SymI_HasProto(hs_free_stable_ptr)                        \
       SymI_HasProto(hs_free_fun_ptr)                   \
       SymI_HasProto(hs_hpc_rootModule)                 \
+      SymI_HasProto(hs_hpc_module)                     \
       SymI_HasProto(initLinker)                                \
       SymI_HasProto(unpackClosurezh_fast)               \
       SymI_HasProto(getApStackValzh_fast)               \
@@ -689,6 +694,7 @@ typedef struct _RtsSymbolVal {
       SymI_HasProto(noDuplicatezh_fast)                        \
       SymI_HasProto(atomicModifyMutVarzh_fast)         \
       SymI_HasProto(newPinnedByteArrayzh_fast)         \
+      SymI_HasProto(newAlignedPinnedByteArrayzh_fast)  \
       SymI_HasProto(newSpark)                          \
       SymI_HasProto(orIntegerzh_fast)                  \
       SymI_HasProto(performGC)                         \
@@ -855,6 +861,7 @@ typedef struct _RtsSymbolVal {
       SymI_NeedsProto(rts_stop_on_exception)           \
       SymI_HasProto(stopTimer)                         \
       SymI_HasProto(n_capabilities)                    \
+      SymI_HasProto(traceCcszh_fast)                    \
       RTS_USER_SIGNALS_SYMBOLS
 
 #ifdef SUPPORT_LONG_LONGS
@@ -1294,11 +1301,18 @@ static unsigned int PLTSize(void);
 #endif
 
 #ifdef USE_MMAP
+#define ROUND_UP(x,size) ((x + size - 1) & ~(size - 1))
+
 static void *
 mmapForLinker (size_t bytes, nat flags, int fd)
 {
    void *map_addr = NULL;
    void *result;
+   int pagesize, size;
+   static nat fixed = 0;
+
+   pagesize = getpagesize();
+   size = ROUND_UP(bytes, pagesize);
 
 #if defined(x86_64_HOST_ARCH)
 mmap_again:
@@ -1308,28 +1322,37 @@ mmap_again:
    }
 #endif
 
-   result = mmap(map_addr, bytes, PROT_EXEC|PROT_READ|PROT_WRITE,
-                   MAP_PRIVATE|TRY_MAP_32BIT|flags, fd, 0);
+   result = mmap(map_addr, size, PROT_EXEC|PROT_READ|PROT_WRITE,
+                   MAP_PRIVATE|TRY_MAP_32BIT|fixed|flags, fd, 0);
 
    if (result == MAP_FAILED) {
-       sysErrorBelch("mmap");
+       sysErrorBelch("mmap %lu bytes at %p",(lnat)size,map_addr);
+       errorBelch("Try specifying an address with +RTS -xm<addr> -RTS");
        stg_exit(EXIT_FAILURE);
    }
    
 #if defined(x86_64_HOST_ARCH)
    if (mmap_32bit_base != 0) {
        if (result == map_addr) {
-           mmap_32bit_base = map_addr + bytes;
+           mmap_32bit_base = map_addr + size;
        } else {
            if ((W_)result > 0x80000000) {
                // oops, we were given memory over 2Gb
-               // ... try allocating memory somewhere else?;
-               barf("loadObj: failed to mmap() memory below 2Gb; asked for %lu bytes at 0x%p, got 0x%p.  Try specifying an address with +RTS -xm<addr> -RTS", bytes, map_addr, result);
+#if defined(freebsd_HOST_OS)
+               // Some platforms require MAP_FIXED.  This is normally
+               // a bad idea, because MAP_FIXED will overwrite
+               // existing mappings.
+               munmap(result,size);
+               fixed = MAP_FIXED;
+               goto mmap_again;
+#else
+               barf("loadObj: failed to mmap() memory below 2Gb; asked for %lu bytes at %p.  Try specifying an address with +RTS -xm<addr> -RTS", size, map_addr, result);
+#endif
            } else {
                // hmm, we were given memory somewhere else, but it's
                // still under 2Gb so we can use it.  Next time, ask
                // for memory right after the place we just got some
-               mmap_32bit_base = (void*)result + bytes;
+               mmap_32bit_base = (void*)result + size;
            }
        }
    } else {
@@ -1337,7 +1360,7 @@ mmap_again:
            // oops, we were given memory over 2Gb
            // ... try allocating memory somewhere else?;
            debugTrace(DEBUG_linker,"MAP_32BIT didn't work; gave us %lu bytes at 0x%p", bytes, result);
-           munmap(result, bytes);
+           munmap(result, size);
            
            // Set a base address and try again... (guess: 1Gb)
            mmap_32bit_base = (void*)0x40000000;
@@ -1360,9 +1383,9 @@ loadObj( char *path )
 {
    ObjectCode* oc;
    struct stat st;
-   int r, n;
+   int r;
 #ifdef USE_MMAP
-   int fd, pagesize;
+   int fd;
 #else
    FILE *f;
 #endif
@@ -1422,8 +1445,6 @@ loadObj( char *path )
    objects               = oc;
 
 #ifdef USE_MMAP
-#define ROUND_UP(x,size) ((x + size - 1) & ~(size - 1))
-
    /* On many architectures malloc'd memory isn't executable, so we need to use mmap. */
 
 #if defined(openbsd_HOST_OS)
@@ -1434,10 +1455,11 @@ loadObj( char *path )
    if (fd == -1)
       barf("loadObj: can't open `%s'", path);
 
-   pagesize = getpagesize();
-
 #ifdef ia64_HOST_ARCH
    /* The PLT needs to be right before the object */
+   {
+   int pagesize, n;
+   pagesize = getpagesize();
    n = ROUND_UP(PLTSize(), pagesize);
    oc->plt = mmap(NULL, n, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
    if (oc->plt == MAP_FAILED)
@@ -1445,23 +1467,20 @@ loadObj( char *path )
 
    oc->pltIndex = 0;
    map_addr = oc->plt + n;
-#endif
 
    n = ROUND_UP(oc->fileSize, pagesize);
-
-#ifdef ia64_HOST_ARCH
    oc->image = mmap(map_addr, n, PROT_EXEC|PROT_READ|PROT_WRITE,
                    MAP_PRIVATE|TRY_MAP_32BIT, fd, 0);
    if (oc->image == MAP_FAILED)
       barf("loadObj: can't map `%s'", path);
+   }
 #else
-   oc->image = mmapForLinker(n, 0, fd);
+   oc->image = mmapForLinker(oc->fileSize, 0, fd);
 #endif
 
    close(fd);
 
 #else /* !USE_MMAP */
-
    /* load the image into memory */
    f = fopen(path, "rb");
    if (!f)
@@ -1489,10 +1508,12 @@ loadObj( char *path )
    oc->image = stgMallocBytes(oc->fileSize, "loadObj(image)");
 #  endif
 
-   n = fread ( oc->image, 1, oc->fileSize, f );
-   if (n != oc->fileSize)
-      barf("loadObj: error whilst reading `%s'", path);
-
+   {
+       int n;
+       n = fread ( oc->image, 1, oc->fileSize, f );
+       if (n != oc->fileSize)
+           barf("loadObj: error whilst reading `%s'", path);
+   }
    fclose(f);
 #endif /* USE_MMAP */
 
@@ -1729,7 +1750,7 @@ static int ocAllocateSymbolExtras( ObjectCode* oc, int count, int first )
     if( m > n ) // we need to allocate more pages
     {
         oc->symbol_extras = mmapForLinker(sizeof(SymbolExtra) * count, 
-                                          MAP_ANONYMOUS, 0);
+                                          MAP_ANONYMOUS, -1);
     }
     else
     {
@@ -2636,8 +2657,7 @@ ocResolve_PEi386 ( ObjectCode* oc )
             copyName ( sym->Name, strtab, symbol, 1000-1 );
             S = (UInt32) lookupSymbol( symbol );
             if ((void*)S != NULL) goto foundit;
-           /* Newline first because the interactive linker has printed "linking..." */
-            errorBelch("\n%s: unknown symbol `%s'", oc->fileName, symbol);
+            errorBelch("%s: unknown symbol `%s'", oc->fileName, symbol);
             return 0;
            foundit:;
          }
@@ -4670,7 +4690,7 @@ static void machoInitSymbolsWithoutUnderscore()
     void **p = symbolsWithoutUnderscore;
     __asm__ volatile(".globl _symbolsWithoutUnderscore\n.data\n_symbolsWithoutUnderscore:");
 
-#undef Sym
+#undef SymI_NeedsProto
 #define SymI_NeedsProto(x)  \
     __asm__ volatile(".long " # x);
 
@@ -4678,13 +4698,13 @@ static void machoInitSymbolsWithoutUnderscore()
 
     __asm__ volatile(".text");
     
-#undef Sym
+#undef SymI_NeedsProto
 #define SymI_NeedsProto(x)  \
     ghciInsertStrHashTable("(GHCi built-in symbols)", symhash, #x, *p++);
     
     RTS_MACHO_NOUNDERLINE_SYMBOLS
     
-#undef Sym
+#undef SymI_NeedsProto
 }
 #endif