Add some casts to fix warnings; patch from Greg Wright
[ghc-hetmet.git] / rts / Linker.c
index 5f8ce13..3cd7fef 100644 (file)
 #include <sys/wait.h>
 #endif
 
-#if defined(linux_HOST_OS) || defined(freebsd_HOST_OS) || defined(dragonfly_HOST_OS) || defined(netbsd_HOST_OS) || defined(openbsd_HOST_OS) || defined(darwin_HOST_OS)
+#if defined(linux_HOST_OS    ) || defined(freebsd_HOST_OS) || \
+    defined(dragonfly_HOST_OS) || defined(netbsd_HOST_OS ) || \
+    defined(openbsd_HOST_OS  ) || \
+    ( defined(darwin_HOST_OS ) && !defined(powerpc_HOST_ARCH) )
+/* Don't use mmap on powerpc-apple-darwin as mmap doesn't support
+ * reallocating but we need to allocate jump islands just after each
+ * object images. Otherwise relative branches to jump islands can fail
+ * due to 24-bits displacement overflow.
+ */
 #define USE_MMAP
 #include <fcntl.h>
 #include <sys/mman.h>
@@ -261,6 +269,7 @@ typedef struct _RtsSymbolVal {
       SymI_HasProto(unlockFile)                 \
       SymI_HasProto(signal_handlers)           \
       SymI_HasProto(stg_sig_install)           \
+      SymI_HasProto(rtsTimerSignal)             \
       SymI_NeedsProto(nocldstop)
 #endif
 
@@ -880,7 +889,7 @@ typedef struct _RtsSymbolVal {
       SymI_HasProto(rts_unlock)                                \
       SymI_HasProto(rts_unsafeGetMyCapability)          \
       SymI_HasProto(rtsSupportsBoundThreads)           \
-      SymI_HasProto(rts_isProfiled)                    \
+      SymI_HasProto(rts_isProfiled)                     \
       SymI_HasProto(setProgArgv)                       \
       SymI_HasProto(startupHaskell)                    \
       SymI_HasProto(shutdownHaskell)                   \
@@ -1685,6 +1694,9 @@ loadArchive( char *path )
     char tmp[12];
     char *gnuFileIndex;
     int gnuFileIndexSize;
+#if !defined(USE_MMAP) && defined(darwin_HOST_OS)
+    int misalignment;
+#endif
 
     IF_DEBUG(linker, debugBelch("loadArchive: Loading archive `%s'\n", path));
 
@@ -1854,8 +1866,13 @@ loadArchive( char *path )
                we use malloc then we can be given memory above 2^32.
                In the mmap case we're probably wasting lots of space;
                we could do better. */
-#ifdef USE_MMAP
+#if defined(USE_MMAP)
             image = mmapForLinker(memberSize, MAP_ANONYMOUS, -1);
+#elif defined(darwin_HOST_OS)
+            /* See loadObj() */
+            misalignment = machoGetMisalignment(f);
+            image = stgMallocBytes(memberSize + misalignment, "loadArchive(image)");
+            image += misalignment;
 #else
             image = stgMallocBytes(memberSize, "loadArchive(image)");
 #endif
@@ -1872,7 +1889,7 @@ loadArchive( char *path )
             oc = mkOc(path, image, memberSize, archiveMemberName
 #ifndef USE_MMAP
 #ifdef darwin_HOST_OS
-                     , 0
+                     , misalignment
 #endif
 #endif
                      );
@@ -1952,6 +1969,9 @@ loadObj( char *path )
    int fd;
 #else
    FILE *f;
+#  if defined(darwin_HOST_OS)
+   int misalignment;
+#  endif
 #endif
    IF_DEBUG(linker, debugBelch("loadObj %s\n", path));
 
@@ -4655,15 +4675,15 @@ static int relocateSection(
            IF_DEBUG(linker, debugBelch("               : type  = %d\n", symbol->n_type));
            IF_DEBUG(linker, debugBelch("               : sect  = %d\n", symbol->n_sect));
            IF_DEBUG(linker, debugBelch("               : desc  = %d\n", symbol->n_desc));
-           IF_DEBUG(linker, debugBelch("               : value = %d\n", symbol->n_value));
+           IF_DEBUG(linker, debugBelch("               : value = %p\n", (void *)symbol->n_value));
             if ((symbol->n_type & N_TYPE) == N_SECT) {
                 value = relocateAddress(oc, nSections, sections,
                                         symbol->n_value);
-               IF_DEBUG(linker, debugBelch("relocateSection, defined external symbol %s, relocated address %p\n", nm, value));
+               IF_DEBUG(linker, debugBelch("relocateSection, defined external symbol %s, relocated address %p\n", nm, (void *)value));
            }
             else {
                 value = (uint64_t) lookupSymbol(nm);
-               IF_DEBUG(linker, debugBelch("relocateSection: external symbol %s, address %p\n", nm, value));
+               IF_DEBUG(linker, debugBelch("relocateSection: external symbol %s, address %p\n", nm, (void *)value));
            }
         }
         else
@@ -4673,7 +4693,7 @@ static int relocateSection(
                  + (uint64_t) image;
         }
       
-       IF_DEBUG(linker, debugBelch("relocateSection: value = %p\n", value));
+       IF_DEBUG(linker, debugBelch("relocateSection: value = %p\n", (void *)value));
 
         if (type == X86_64_RELOC_BRANCH)
         {
@@ -5328,21 +5348,24 @@ static int machoGetMisalignment( FILE * f )
 {
     struct mach_header header;
     int misalignment;
-    
-    fread(&header, sizeof(header), 1, f);
-    rewind(f);
+
+    {
+        int n = fread(&header, sizeof(header), 1, f);
+        if (n != 1) {
+            barf("machoGetMisalignment: can't read the Mach-O header");
+        }
+    }
+    fseek(f, -sizeof(header), SEEK_CUR);
 
 #if x86_64_HOST_ARCH || powerpc64_HOST_ARCH
     if(header.magic != MH_MAGIC_64) {
-        errorBelch("Bad magic. Expected: %08x, got: %08x.\n",
-                   MH_MAGIC_64, header->magic);
-        return 0;
+        barf("Bad magic. Expected: %08x, got: %08x.",
+             MH_MAGIC_64, header.magic);
     }
 #else
     if(header.magic != MH_MAGIC) {
-        errorBelch("Bad magic. Expected: %08x, got: %08x.\n",
-                   MH_MAGIC, header->magic);
-        return 0;
+        barf("Bad magic. Expected: %08x, got: %08x.",
+             MH_MAGIC, header.magic);
     }
 #endif