merge upstream HEAD
[ghc-hetmet.git] / rts / Linker.c
index d2fb4f7..c840857 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 ) && !defined(powerpc_HOST_ARCH) ) || \
-    defined(kfreebsdgnu_HOST_OS)
-/* Don't use mmap on powerpc-apple-darwin as mmap doesn't support
+#if !defined(powerpc_HOST_ARCH) && \
+    (   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(kfreebsdgnu_HOST_OS) )
+/* Don't use mmap on powerpc_HOST_ARCH 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.
 #elif defined(darwin_HOST_OS)
 #  define OBJFORMAT_MACHO
 #  include <regex.h>
+#  include <mach/machine.h>
+#  include <mach-o/fat.h>
 #  include <mach-o/loader.h>
 #  include <mach-o/nlist.h>
 #  include <mach-o/reloc.h>
@@ -830,6 +832,7 @@ typedef struct _RtsSymbolVal {
       SymI_HasProto(stg_newTVarzh)                      \
       SymI_HasProto(stg_noDuplicatezh)                  \
       SymI_HasProto(stg_atomicModifyMutVarzh)           \
+      SymI_HasProto(stg_casMutVarzh)                    \
       SymI_HasProto(stg_newPinnedByteArrayzh)           \
       SymI_HasProto(stg_newAlignedPinnedByteArrayzh)    \
       SymI_HasProto(newSpark)                           \
@@ -1701,12 +1704,31 @@ loadArchive( char *path )
     char *fileName;
     size_t fileNameSize;
     int isObject, isGnuIndex;
-    char tmp[12];
+    char tmp[20];
     char *gnuFileIndex;
     int gnuFileIndexSize;
-#if !defined(USE_MMAP) && defined(darwin_HOST_OS)
+#if defined(darwin_HOST_OS)
+    int i;
+    uint32_t nfat_arch, nfat_offset, cputype, cpusubtype;
+#if defined(i386_HOST_ARCH)
+    const uint32_t mycputype = CPU_TYPE_X86;
+    const uint32_t mycpusubtype = CPU_SUBTYPE_X86_ALL;
+#elif defined(x86_64_HOST_ARCH)
+    const uint32_t mycputype = CPU_TYPE_X86_64;
+    const uint32_t mycpusubtype = CPU_SUBTYPE_X86_64_ALL;
+#elif defined(powerpc_HOST_ARCH)
+    const uint32_t mycputype = CPU_TYPE_POWERPC;
+    const uint32_t mycpusubtype = CPU_SUBTYPE_POWERPC_ALL;
+#elif defined(powerpc64_HOST_ARCH)
+    const uint32_t mycputype = CPU_TYPE_POWERPC64;
+    const uint32_t mycpusubtype = CPU_SUBTYPE_POWERPC_ALL;
+#else
+#error Unknown Darwin architecture
+#endif
+#if !defined(USE_MMAP)
     int misalignment;
 #endif
+#endif
 
     IF_DEBUG(linker, debugBelch("loadArchive: start\n"));
     IF_DEBUG(linker, debugBelch("loadArchive: Loading archive `%s'\n", path));
@@ -1721,9 +1743,74 @@ loadArchive( char *path )
     if (!f)
         barf("loadObj: can't read `%s'", path);
 
+    /* Check if this is an archive by looking for the magic "!<arch>\n"
+     * string.  Usually, if this fails, we barf and quit.  On Darwin however,
+     * we may have a fat archive, which contains archives for more than
+     * one architecture.  Fat archives start with the magic number 0xcafebabe,
+     * always stored big endian.  If we find a fat_header, we scan through
+     * the fat_arch structs, searching through for one for our host
+     * architecture.  If a matching struct is found, we read the offset
+     * of our archive data (nfat_offset) and seek forward nfat_offset bytes
+     * from the start of the file.
+     *
+     * A subtlety is that all of the members of the fat_header and fat_arch
+     * structs are stored big endian, so we need to call byte order
+     * conversion functions.
+     *
+     * If we find the appropriate architecture in a fat archive, we gobble
+     * its magic "!<arch>\n" string and continue processing just as if
+     * we had a single architecture archive.
+     */
+
     n = fread ( tmp, 1, 8, f );
+    if (n != 8)
+        barf("loadArchive: Failed reading header from `%s'", path);
     if (strncmp(tmp, "!<arch>\n", 8) != 0) {
+
+#if defined(darwin_HOST_OS)
+        /* Not a standard archive, look for a fat archive magic number: */
+        if (ntohl(*(uint32_t *)tmp) == FAT_MAGIC) {
+            nfat_arch = ntohl(*(uint32_t *)(tmp + 4));
+            IF_DEBUG(linker, debugBelch("loadArchive: found a fat archive containing %d architectures\n", nfat_arch));
+            nfat_offset = 0;
+
+            for (i = 0; i < (int)nfat_arch; i++) {
+                /* search for the right arch */
+                n = fread( tmp, 1, 20, f );
+                if (n != 8)
+                    barf("loadArchive: Failed reading arch from `%s'", path);
+                cputype = ntohl(*(uint32_t *)tmp);
+                cpusubtype = ntohl(*(uint32_t *)(tmp + 4));
+
+                if (cputype == mycputype && cpusubtype == mycpusubtype) {
+                    IF_DEBUG(linker, debugBelch("loadArchive: found my archive in a fat archive\n"));
+                    nfat_offset = ntohl(*(uint32_t *)(tmp + 8));
+                    break;
+                }
+            }
+
+            if (nfat_offset == 0) {
+               barf ("loadArchive: searched %d architectures, but no host arch found", (int)nfat_arch);
+            }
+            else {
+                n = fseek( f, nfat_offset, SEEK_SET );
+                if (n != 0)
+                    barf("loadArchive: Failed to seek to arch in `%s'", path);
+                n = fread ( tmp, 1, 8, f );
+                if (n != 8)
+                    barf("loadArchive: Failed reading header from `%s'", path);
+                if (strncmp(tmp, "!<arch>\n", 8) != 0) {
+                    barf("loadArchive: couldn't find archive in `%s' at offset %d", path, nfat_offset);
+                }
+            }
+        }
+        else {
+            barf("loadArchive: Neither an archive, nor a fat archive: `%s'", path);
+        }
+
+#else
         barf("loadArchive: Not an archive: `%s'", path);
+#endif
     }
 
     IF_DEBUG(linker, debugBelch("loadArchive: loading archive contents\n"));
@@ -1739,12 +1826,11 @@ loadArchive( char *path )
                 barf("loadArchive: Failed reading file name from `%s'", path);
             }
         }
+
 #if defined(darwin_HOST_OS)
-        else {
-            if (strncmp(fileName, "!<arch>\n", 8) == 0) {
-                IF_DEBUG(linker, debugBelch("loadArchive: found the start of another archive, breaking\n"));
-                break;
-            }
+        if (strncmp(fileName, "!<arch>\n", 8) == 0) {
+            IF_DEBUG(linker, debugBelch("loadArchive: found the start of another archive, breaking\n"));
+            break;
         }
 #endif
 
@@ -1770,6 +1856,8 @@ loadArchive( char *path )
 
         IF_DEBUG(linker, debugBelch("loadArchive: size of this archive member is %d\n", memberSize));
         n = fread ( tmp, 1, 2, f );
+        if (n != 2)
+            barf("loadArchive: Failed reading magic from `%s'", path);
         if (strncmp(tmp, "\x60\x0A", 2) != 0)
             barf("loadArchive: Failed reading magic from `%s' at %ld. Got %c%c",
                  path, ftell(f), tmp[0], tmp[1]);
@@ -2484,7 +2572,11 @@ static void
 ocFlushInstructionCache( ObjectCode *oc )
 {
     /* The main object code */
-    ocFlushInstructionCacheFrom(oc->image + oc->misalignment, oc->fileSize);
+    ocFlushInstructionCacheFrom(oc->image
+#ifdef darwin_HOST_OS
+            + oc->misalignment
+#endif
+            , oc->fileSize);
 
     /* Jump Islands */
     ocFlushInstructionCacheFrom(oc->symbol_extras, sizeof(SymbolExtra) * oc->n_symbol_extras);
@@ -4846,10 +4938,9 @@ static int relocateSection(
                     // and use #ifdefs for the other types.
 
                     // Step 1: Figure out what the relocated value should be
-                    if(scat->r_type == GENERIC_RELOC_VANILLA)
-                    {
-                        word = *wordPtr + (unsigned long) relocateAddress(
-                                                                oc,
+                    if (scat->r_type == GENERIC_RELOC_VANILLA) {
+                        word = *wordPtr
+                             + (unsigned long) relocateAddress(oc,
                                                                 nSections,
                                                                 sections,
                                                                 scat->r_value)
@@ -4869,9 +4960,10 @@ static int relocateSection(
                         struct scattered_relocation_info *pair =
                                 (struct scattered_relocation_info*) &relocs[i+1];
 
-                        if(!pair->r_scattered || pair->r_type != GENERIC_RELOC_PAIR)
+                        if (!pair->r_scattered || pair->r_type != GENERIC_RELOC_PAIR) {
                             barf("Invalid Mach-O file: "
                                  "RELOC_*_SECTDIFF not followed by RELOC_PAIR");
+                        }
 
                         word = (unsigned long)
                                (relocateAddress(oc, nSections, sections, scat->r_value)
@@ -4885,9 +4977,11 @@ static int relocateSection(
                          || scat->r_type == PPC_RELOC_LO14)
                     {   // these are generated by label+offset things
                         struct relocation_info *pair = &relocs[i+1];
-                        if((pair->r_address & R_SCATTERED) || pair->r_type != PPC_RELOC_PAIR)
+
+                        if ((pair->r_address & R_SCATTERED) || pair->r_type != PPC_RELOC_PAIR) {
                             barf("Invalid Mach-O file: "
                                  "PPC_RELOC_* not followed by PPC_RELOC_PAIR");
+                        }
 
                         if(scat->r_type == PPC_RELOC_LO16)
                         {
@@ -4918,8 +5012,7 @@ static int relocateSection(
                         i++;
                     }
  #endif
-                    else
-                    {
+                    else {
                         barf ("Don't know how to handle this Mach-O "
                               "scattered relocation entry: "
                               "object file %s; entry type %ld; "
@@ -4942,15 +5035,18 @@ static int relocateSection(
                         *wordPtr = word;
                     }
 #ifdef powerpc_HOST_ARCH
-                    else if(scat->r_type == PPC_RELOC_LO16_SECTDIFF || scat->r_type == PPC_RELOC_LO16)
+                    else if (scat->r_type == PPC_RELOC_LO16_SECTDIFF
+                          || scat->r_type == PPC_RELOC_LO16)
                     {
                         ((unsigned short*) wordPtr)[1] = word & 0xFFFF;
                     }
-                    else if(scat->r_type == PPC_RELOC_HI16_SECTDIFF || scat->r_type == PPC_RELOC_HI16)
+                    else if (scat->r_type == PPC_RELOC_HI16_SECTDIFF
+                          || scat->r_type == PPC_RELOC_HI16)
                     {
                         ((unsigned short*) wordPtr)[1] = (word >> 16) & 0xFFFF;
                     }
-                    else if(scat->r_type == PPC_RELOC_HA16_SECTDIFF || scat->r_type == PPC_RELOC_HA16)
+                    else if (scat->r_type == PPC_RELOC_HA16_SECTDIFF
+                          || scat->r_type == PPC_RELOC_HA16)
                     {
                         ((unsigned short*) wordPtr)[1] = ((word >> 16) & 0xFFFF)
                             + ((word & (1<<15)) ? 1 : 0);
@@ -4985,11 +5081,12 @@ static int relocateSection(
         else /* !(relocs[i].r_address & R_SCATTERED) */
         {
             struct relocation_info *reloc = &relocs[i];
-            if(reloc->r_pcrel && !reloc->r_extern)
+            if (reloc->r_pcrel && !reloc->r_extern) {
+                IF_DEBUG(linker, debugBelch("relocateSection: pc relative but not external, skipping\n"));
                 continue;
+            }
 
-            if(reloc->r_length == 2)
-            {
+            if (reloc->r_length == 2) {
                 unsigned long word = 0;
 #ifdef powerpc_HOST_ARCH
                 unsigned long jumpIsland = 0;
@@ -5001,34 +5098,28 @@ static int relocateSection(
                 unsigned long* wordPtr = (unsigned long*) (image + sect->offset + reloc->r_address);
                 checkProddableBlock(oc,wordPtr);
 
-                if(reloc->r_type == GENERIC_RELOC_VANILLA)
-                {
+                if (reloc->r_type == GENERIC_RELOC_VANILLA) {
                     word = *wordPtr;
                 }
 #ifdef powerpc_HOST_ARCH
-                else if(reloc->r_type == PPC_RELOC_LO16)
-                {
+                else if (reloc->r_type == PPC_RELOC_LO16) {
                     word = ((unsigned short*) wordPtr)[1];
                     word |= ((unsigned long) relocs[i+1].r_address & 0xFFFF) << 16;
                 }
-                else if(reloc->r_type == PPC_RELOC_HI16)
-                {
+                else if (reloc->r_type == PPC_RELOC_HI16) {
                     word = ((unsigned short*) wordPtr)[1] << 16;
                     word |= ((unsigned long) relocs[i+1].r_address & 0xFFFF);
                 }
-                else if(reloc->r_type == PPC_RELOC_HA16)
-                {
+                else if (reloc->r_type == PPC_RELOC_HA16) {
                     word = ((unsigned short*) wordPtr)[1] << 16;
                     word += ((short)relocs[i+1].r_address & (short)0xFFFF);
                 }
-                else if(reloc->r_type == PPC_RELOC_BR24)
-                {
+                else if (reloc->r_type == PPC_RELOC_BR24) {
                     word = *wordPtr;
                     word = (word & 0x03FFFFFC) | ((word & 0x02000000) ? 0xFC000000 : 0);
                 }
 #endif
-                else
-                {
+                else {
                     barf("Can't handle this Mach-O relocation entry "
                          "(not scattered): "
                          "object file %s; entry type %ld; address %#lx\n",
@@ -5038,28 +5129,24 @@ static int relocateSection(
                     return 0;
                 }
 
-                if(!reloc->r_extern)
-                {
-                    long delta =
-                        sections[reloc->r_symbolnum-1].offset
+                if (!reloc->r_extern) {
+                    long delta = sections[reloc->r_symbolnum-1].offset
                         - sections[reloc->r_symbolnum-1].addr
                         + ((long) image);
 
                     word += delta;
                 }
-                else
-                {
+                else {
                     struct nlist *symbol = &nlist[reloc->r_symbolnum];
                     char *nm = image + symLC->stroff + symbol->n_un.n_strx;
                     void *symbolAddress = lookupSymbol(nm);
-                    if(!symbolAddress)
-                    {
+
+                    if (!symbolAddress) {
                         errorBelch("\nunknown symbol `%s'", nm);
                         return 0;
                     }
 
-                    if(reloc->r_pcrel)
-                    {
+                    if (reloc->r_pcrel) {  
 #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
@@ -5069,8 +5156,7 @@ static int relocateSection(
                                                          reloc->r_symbolnum,
                                                          (unsigned long) symbolAddress)
                                          -> jumpIsland;
-                        if(jumpIsland != 0)
-                        {
+                        if (jumpIsland != 0) {
                             offsetToJumpIsland = word + jumpIsland
                                 - (((long)image) + sect->offset - sect->addr);
                         }
@@ -5078,14 +5164,12 @@ static int relocateSection(
                         word += (unsigned long) symbolAddress
                                 - (((long)image) + sect->offset - sect->addr);
                     }
-                    else
-                    {
+                    else {
                         word += (unsigned long) symbolAddress;
                     }
                 }
 
-                if(reloc->r_type == GENERIC_RELOC_VANILLA)
-                {
+                if (reloc->r_type == GENERIC_RELOC_VANILLA) {
                     *wordPtr = word;
                     continue;
                 }
@@ -5093,34 +5177,36 @@ static int relocateSection(
                 else if(reloc->r_type == PPC_RELOC_LO16)
                 {
                     ((unsigned short*) wordPtr)[1] = word & 0xFFFF;
-                    i++; continue;
+                    i++;
+                    continue;
                 }
                 else if(reloc->r_type == PPC_RELOC_HI16)
                 {
                     ((unsigned short*) wordPtr)[1] = (word >> 16) & 0xFFFF;
-                    i++; continue;
+                    i++;
+                    continue;
                 }
                 else if(reloc->r_type == PPC_RELOC_HA16)
                 {
                     ((unsigned short*) wordPtr)[1] = ((word >> 16) & 0xFFFF)
                         + ((word & (1<<15)) ? 1 : 0);
-                    i++; continue;
+                    i++;
+                    continue;
                 }
                 else if(reloc->r_type == PPC_RELOC_BR24)
                 {
-                    if((word & 0x03) != 0)
+                    if ((word & 0x03) != 0) {
                         barf("%s: unconditional relative branch with a displacement "
                              "which isn't a multiple of 4 bytes: %#lx",
                              OC_INFORMATIVE_FILENAME(oc),
                              word);
+                    }
 
                     if((word & 0xFE000000) != 0xFE000000 &&
-                       (word & 0xFE000000) != 0x00000000)
-                    {
+                        (word & 0xFE000000) != 0x00000000) {
                         // The branch offset is too large.
                         // Therefore, we try to use a jump island.
-                        if(jumpIsland == 0)
-                        {
+                        if (jumpIsland == 0) {
                             barf("%s: unconditional relative branch out of range: "
                                  "no jump island available: %#lx",
                                  OC_INFORMATIVE_FILENAME(oc),
@@ -5128,13 +5214,15 @@ static int relocateSection(
                         }
 
                         word = offsetToJumpIsland;
+
                         if((word & 0xFE000000) != 0xFE000000 &&
-                           (word & 0xFE000000) != 0x00000000)
+                            (word & 0xFE000000) != 0x00000000) {
                             barf("%s: unconditional relative branch out of range: "
                                  "jump island out of range: %#lx",
                                  OC_INFORMATIVE_FILENAME(oc),
                                  word);
                     }
+                    }
                     *wordPtr = (*wordPtr & 0xFC000003) | (word & 0x03FFFFFC);
                     continue;
                 }
@@ -5155,11 +5243,13 @@ static int relocateSection(
         }
 #endif
     }
+
     IF_DEBUG(linker, debugBelch("relocateSection: done\n"));
     return 1;
 }
 
-static int ocGetNames_MachO(ObjectCode* oc)
+static int
+ocGetNames_MachO(ObjectCode* oc)
 {
     char *image = (char*) oc->image;
     struct mach_header *header = (struct mach_header*) image;
@@ -5177,10 +5267,13 @@ static int ocGetNames_MachO(ObjectCode* oc)
 
     for(i=0;i<header->ncmds;i++)
     {
-        if(lc->cmd == LC_SEGMENT || lc->cmd == LC_SEGMENT_64)
+        if (lc->cmd == LC_SEGMENT || lc->cmd == LC_SEGMENT_64) {
             segLC = (struct segment_command*) lc;
-        else if(lc->cmd == LC_SYMTAB)
+        }
+        else if (lc->cmd == LC_SYMTAB) {
             symLC = (struct symtab_command*) lc;
+        }
+
         lc = (struct load_command *) ( ((char*)lc) + lc->cmdsize );
     }
 
@@ -5188,14 +5281,19 @@ static int ocGetNames_MachO(ObjectCode* oc)
     nlist = symLC ? (struct nlist*) (image + symLC->symoff)
                   : NULL;
 
-    if(!segLC)
+    if (!segLC) {
         barf("ocGetNames_MachO: no segment load command");
+    }
 
+    IF_DEBUG(linker, debugBelch("ocGetNames_MachO: will load %d sections\n", segLC->nsects));
     for(i=0;i<segLC->nsects;i++)
     {
-        IF_DEBUG(linker, debugBelch("ocGetNames_MachO: segment %d\n", i));
-        if (sections[i].size == 0)
+        IF_DEBUG(linker, debugBelch("ocGetNames_MachO: section %d\n", i));
+
+        if (sections[i].size == 0) {
+            IF_DEBUG(linker, debugBelch("ocGetNames_MachO: found a zero length section, skipping\n"));
             continue;
+        }
 
         if((sections[i].flags & SECTION_TYPE) == S_ZEROFILL)
         {
@@ -5204,36 +5302,47 @@ static int ocGetNames_MachO(ObjectCode* oc)
             sections[i].offset = zeroFillArea - image;
         }
 
-        if(!strcmp(sections[i].sectname,"__text"))
+        if (!strcmp(sections[i].sectname,"__text")) {
+
+            IF_DEBUG(linker, debugBelch("ocGetNames_MachO: adding __text section\n"));
             addSection(oc, SECTIONKIND_CODE_OR_RODATA,
                 (void*) (image + sections[i].offset),
                 (void*) (image + sections[i].offset + sections[i].size));
-        else if(!strcmp(sections[i].sectname,"__const"))
+        }
+        else if (!strcmp(sections[i].sectname,"__const")) {
+
+            IF_DEBUG(linker, debugBelch("ocGetNames_MachO: adding __const section\n"));
             addSection(oc, SECTIONKIND_RWDATA,
                 (void*) (image + sections[i].offset),
                 (void*) (image + sections[i].offset + sections[i].size));
-        else if(!strcmp(sections[i].sectname,"__data"))
+        }    
+        else if (!strcmp(sections[i].sectname,"__data")) {
+
+            IF_DEBUG(linker, debugBelch("ocGetNames_MachO: adding __data section\n"));
             addSection(oc, SECTIONKIND_RWDATA,
                 (void*) (image + sections[i].offset),
                 (void*) (image + sections[i].offset + sections[i].size));
+        }
         else if(!strcmp(sections[i].sectname,"__bss")
-                || !strcmp(sections[i].sectname,"__common"))
+                || !strcmp(sections[i].sectname,"__common")) {
+
+            IF_DEBUG(linker, debugBelch("ocGetNames_MachO: adding __bss section\n"));
             addSection(oc, SECTIONKIND_RWDATA,
                 (void*) (image + sections[i].offset),
                 (void*) (image + sections[i].offset + sections[i].size));
-
-        addProddableBlock(oc, (void*) (image + sections[i].offset),
+        }
+        addProddableBlock(oc,
+                          (void *) (image + sections[i].offset),
                                         sections[i].size);
     }
 
         // count external symbols defined here
     oc->n_symbols = 0;
-    if(symLC)
-    {
-        for(i=0;i<symLC->nsyms;i++)
-        {
-            if(nlist[i].n_type & N_STAB)
+    if (symLC) {
+        for (i = 0; i < symLC->nsyms; i++) {
+            if (nlist[i].n_type & N_STAB) {
                 ;
+            }
             else if(nlist[i].n_type & N_EXT)
             {
                 if((nlist[i].n_type & N_TYPE) == N_UNDF
@@ -5277,19 +5386,27 @@ static int ocGetNames_MachO(ObjectCode* oc)
                             oc->symbols[curSymbol++] = nm;
                     }
                 }
+                else
+                {
+                    IF_DEBUG(linker, debugBelch("ocGetNames_MachO: \t...not external, skipping\n"));
+                }
+            }
+            else
+            {
+                IF_DEBUG(linker, debugBelch("ocGetNames_MachO: \t...not defined in this section, skipping\n"));
             }
         }
     }
 
     commonStorage = stgCallocBytes(1,commonSize,"ocGetNames_MachO(common symbols)");
     commonCounter = (unsigned long)commonStorage;
-    if(symLC)
-    {
-        for(i=0;i<symLC->nsyms;i++)
-        {
+
+    if (symLC) {
+        for (i = 0; i < symLC->nsyms; i++) {
             if((nlist[i].n_type & N_TYPE) == N_UNDF
-                    && (nlist[i].n_type & N_EXT) && (nlist[i].n_value != 0))
-            {
+             && (nlist[i].n_type & N_EXT)
+             && (nlist[i].n_value != 0)) {
+
                 char *nm = image + symLC->stroff + nlist[i].n_un.n_strx;
                 unsigned long sz = nlist[i].n_value;
 
@@ -5304,10 +5421,13 @@ static int ocGetNames_MachO(ObjectCode* oc)
             }
         }
     }
+
+    IF_DEBUG(linker, debugBelch("ocGetNames_MachO: done\n"));
     return 1;
 }
 
-static int ocResolve_MachO(ObjectCode* oc)
+static int
+ocResolve_MachO(ObjectCode* oc)
 {
     char *image = (char*) oc->image;
     struct mach_header *header = (struct mach_header*) image;
@@ -5322,12 +5442,19 @@ static int ocResolve_MachO(ObjectCode* oc)
     IF_DEBUG(linker, debugBelch("ocResolve_MachO: start\n"));
     for (i = 0; i < header->ncmds; i++)
     {
-        if(lc->cmd == LC_SEGMENT || lc->cmd == LC_SEGMENT_64)
+        if (lc->cmd == LC_SEGMENT || lc->cmd == LC_SEGMENT_64) {
             segLC = (struct segment_command*) lc;
-        else if(lc->cmd == LC_SYMTAB)
+            IF_DEBUG(linker, debugBelch("ocResolve_MachO: found a 32 or 64 bit segment load command\n"));
+        }
+        else if (lc->cmd == LC_SYMTAB) {
             symLC = (struct symtab_command*) lc;
-        else if(lc->cmd == LC_DYSYMTAB)
+            IF_DEBUG(linker, debugBelch("ocResolve_MachO: found a symbol table load command\n"));
+        }
+        else if (lc->cmd == LC_DYSYMTAB) {
             dsymLC = (struct dysymtab_command*) lc;
+            IF_DEBUG(linker, debugBelch("ocResolve_MachO: found a dynamic symbol table load command\n"));
+        }
+
         lc = (struct load_command *) ( ((char*)lc) + lc->cmdsize );
     }
 
@@ -5395,7 +5522,8 @@ static int ocResolve_MachO(ObjectCode* oc)
 
 extern void* symbolsWithoutUnderscore[];
 
-static void machoInitSymbolsWithoutUnderscore()
+static void
+machoInitSymbolsWithoutUnderscore(void)
 {
     void **p = symbolsWithoutUnderscore;
     __asm__ volatile(".globl _symbolsWithoutUnderscore\n.data\n_symbolsWithoutUnderscore:");
@@ -5423,7 +5551,8 @@ static void machoInitSymbolsWithoutUnderscore()
  * Figure out by how much to shift the entire Mach-O file in memory
  * when loading so that its single segment ends up 16-byte-aligned
  */
-static int machoGetMisalignment( FILE * f )
+static int
+machoGetMisalignment( FILE * f )
 {
     struct mach_header header;
     int misalignment;