Add a proper write barrier for MVars
[ghc-hetmet.git] / rts / Linker.c
index 72f2f7e..e86efd3 100644 (file)
@@ -83,7 +83,9 @@
 #  include <mach-o/loader.h>
 #  include <mach-o/nlist.h>
 #  include <mach-o/reloc.h>
+#if !defined(HAVE_DLFCN_H)
 #  include <mach-o/dyld.h>
+#endif
 #if defined(powerpc_HOST_ARCH)
 #  include <mach-o/ppc/reloc.h>
 #endif
@@ -599,32 +601,38 @@ typedef struct _RtsSymbolVal {
       SymX(rts_getDouble)                      \
       SymX(rts_getFloat)                       \
       SymX(rts_getInt)                         \
+      SymX(rts_getInt8)                                \
+      SymX(rts_getInt16)                       \
       SymX(rts_getInt32)                       \
+      SymX(rts_getInt64)                       \
       SymX(rts_getPtr)                         \
       SymX(rts_getFunPtr)                      \
       SymX(rts_getStablePtr)                   \
       SymX(rts_getThreadId)                    \
       SymX(rts_getWord)                                \
+      SymX(rts_getWord8)                       \
+      SymX(rts_getWord16)                      \
       SymX(rts_getWord32)                      \
+      SymX(rts_getWord64)                      \
       SymX(rts_lock)                           \
       SymX(rts_mkBool)                         \
       SymX(rts_mkChar)                         \
       SymX(rts_mkDouble)                       \
       SymX(rts_mkFloat)                                \
       SymX(rts_mkInt)                          \
+      SymX(rts_mkInt8)                         \
       SymX(rts_mkInt16)                                \
       SymX(rts_mkInt32)                                \
       SymX(rts_mkInt64)                                \
-      SymX(rts_mkInt8)                         \
       SymX(rts_mkPtr)                          \
       SymX(rts_mkFunPtr)                       \
       SymX(rts_mkStablePtr)                    \
       SymX(rts_mkString)                       \
       SymX(rts_mkWord)                         \
+      SymX(rts_mkWord8)                                \
       SymX(rts_mkWord16)                       \
       SymX(rts_mkWord32)                       \
       SymX(rts_mkWord64)                       \
-      SymX(rts_mkWord8)                                \
       SymX(rts_unlock)                         \
       SymX(rtsSupportsBoundThreads)            \
       SymX(__hscore_get_saved_termios)         \
@@ -638,7 +646,8 @@ typedef struct _RtsSymbolVal {
       SymX(stg_CAF_BLACKHOLE_info)             \
       SymX(awakenBlockedQueue)                 \
       SymX(stg_CHARLIKE_closure)               \
-      SymX(stg_EMPTY_MVAR_info)                        \
+      SymX(stg_MVAR_CLEAN_info)                        \
+      SymX(stg_MVAR_DIRTY_info)                        \
       SymX(stg_IND_STATIC_info)                        \
       SymX(stg_INTLIKE_closure)                        \
       SymX(stg_MUT_ARR_PTRS_DIRTY_info)                \
@@ -722,6 +731,8 @@ typedef struct _RtsSymbolVal {
       SymX(rts_breakpoint_io_action)           \
       SymX(rts_stop_next_breakpoint)           \
       SymX(rts_stop_on_exception)              \
+      SymX(stopTimer)                          \
+      SymX(n_capabilities)                     \
       RTS_USER_SIGNALS_SYMBOLS
 
 #ifdef SUPPORT_LONG_LONGS
@@ -937,13 +948,13 @@ typedef
 static OpenedDLL* opened_dlls = NULL;
 #endif
 
-char *
+const char *
 addDLL( char *dll_name )
 {
 #  if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)
    /* ------------------- ELF DLL loader ------------------- */
    void *hdl;
-   char *errmsg;
+   const char *errmsg;
 
    initLinker();
 
@@ -1062,12 +1073,25 @@ lookupSymbol( char *lbl )
        return dlsym(dl_prog_handle, lbl);
 #      endif
 #       elif defined(OBJFORMAT_MACHO)
+#       if HAVE_DLFCN_H
+        /* On OS X 10.3 and later, we use dlsym instead of the old legacy
+           interface.
+
+           HACK: On OS X, global symbols are prefixed with an underscore.
+                 However, dlsym wants us to omit the leading underscore from the
+                 symbol name. For now, we simply strip it off here (and ONLY
+                 here).
+        */
+        ASSERT(lbl[0] == '_');
+        return dlsym(dl_prog_handle, lbl+1);
+#       else
        if(NSIsSymbolNameDefined(lbl)) {
            NSSymbol symbol = NSLookupAndBindSymbol(lbl);
            return NSAddressOfSymbol(symbol);
        } else {
            return NULL;
        }
+#       endif /* HAVE_DLFCN_H */
 #       elif defined(OBJFORMAT_PEi386)
         OpenedDLL* o_dll;
         void* sym;
@@ -1266,13 +1290,20 @@ loadObj( char *path )
    /* Link objects into the lower 2Gb on x86_64.  GHC assumes the
     * small memory model on this architecture (see gcc docs,
     * -mcmodel=small).
+    *
+    * MAP_32BIT not available on OpenBSD/amd64
     */
-#ifdef x86_64_HOST_ARCH
+#if defined(x86_64_HOST_ARCH) && defined(MAP_32BIT)
 #define EXTRA_MAP_FLAGS MAP_32BIT
 #else
 #define EXTRA_MAP_FLAGS 0
 #endif
 
+   /* MAP_ANONYMOUS is MAP_ANON on some systems, e.g. OpenBSD */
+#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
    oc->image = mmap(map_addr, n, PROT_EXEC|PROT_READ|PROT_WRITE,
                    MAP_PRIVATE|EXTRA_MAP_FLAGS, fd, 0);
    if (oc->image == MAP_FAILED)
@@ -2536,9 +2567,6 @@ ocResolve_PEi386 ( ObjectCode* oc )
 
 #if !defined(openbsd_HOST_OS)
 #  include <elf.h>
-#  ifndef R_X86_64_PC64     /* If elf.h doesn't define it */
-#    define R_X86_64_PC64 24
-#  endif
 #else
 /* openbsd elf has things in different places, with diff names */
 #  include <elf_abi.h>
@@ -2547,6 +2575,11 @@ ocResolve_PEi386 ( ObjectCode* oc )
 #  define R_386_PC32  RELOC_PC32
 #endif
 
+/* If elf.h doesn't define it */
+#  ifndef R_X86_64_PC64     
+#    define R_X86_64_PC64 24
+#  endif
+
 /*
  * Define a set of types which can be used for both ELF32 and ELF64
  */
@@ -2744,7 +2777,7 @@ x86_64_high_symbol( char *lbl, void *addr )
        x86_64_bounce_buffer = 
            mmap(NULL, X86_64_BB_SIZE * sizeof(x86_64_bounce), 
                 PROT_EXEC|PROT_READ|PROT_WRITE, 
-                MAP_PRIVATE|MAP_32BIT|MAP_ANONYMOUS, -1, 0);
+                MAP_PRIVATE|EXTRA_MAP_FLAGS|MAP_ANONYMOUS, -1, 0);
        if (x86_64_bounce_buffer == MAP_FAILED) {
            barf("x86_64_high_symbol: mmap failed");
        }
@@ -2872,8 +2905,12 @@ ocVerifyImage_ELF ( ObjectCode* oc )
 #ifdef EM_X86_64
       case EM_X86_64: IF_DEBUG(linker,debugBelch( "x86_64" )); break;
 #endif
+#ifdef EM_AMD64
+      case EM_AMD64: IF_DEBUG(linker,debugBelch( "amd64" )); break;
+#endif
       default:       IF_DEBUG(linker,debugBelch( "unknown" ));
-                     errorBelch("%s: unknown architecture", oc->fileName);
+                     errorBelch("%s: unknown architecture (e_machine == %d)"
+                                , oc->fileName, ehdr->e_machine);
                      return 0;
    }
 
@@ -4214,7 +4251,7 @@ static int relocateSection(
 #ifdef powerpc_HOST_ARCH
                             // In the .o file, this should be a relative jump to NULL
                             // and we'll change it to a relative jump to the symbol
-                        ASSERT(-word == reloc->r_address);
+                        ASSERT(word + reloc->r_address == 0);
                         jumpIsland = (unsigned long)
                                         &makeSymbolExtra(oc,
                                                          reloc->r_symbolnum,