[project @ 2005-07-09 00:13:14 by igloo]
[ghc-hetmet.git] / ghc / rts / Linker.c
index 5693bd2..cb68522 100644 (file)
 #  include <windows.h>
 #  include <math.h>
 #elif defined(darwin_HOST_OS)
-#  include <mach-o/ppc/reloc.h>
 #  define OBJFORMAT_MACHO
 #  include <mach-o/loader.h>
 #  include <mach-o/nlist.h>
 #  include <mach-o/reloc.h>
 #  include <mach-o/dyld.h>
+#if defined(powerpc_HOST_ARCH)
+#  include <mach-o/ppc/reloc.h>
+#endif
 #endif
 
 /* Hash table mapping symbol names to Symbol */
@@ -104,13 +106,16 @@ static int ocVerifyImage_PEi386 ( ObjectCode* oc );
 static int ocGetNames_PEi386    ( ObjectCode* oc );
 static int ocResolve_PEi386     ( ObjectCode* oc );
 #elif defined(OBJFORMAT_MACHO)
-static int ocAllocateJumpIslands_MachO ( ObjectCode* oc );
 static int ocVerifyImage_MachO    ( ObjectCode* oc );
 static int ocGetNames_MachO       ( ObjectCode* oc );
 static int ocResolve_MachO        ( ObjectCode* oc );
 
+static int machoGetMisalignment( FILE * );
+#ifdef powerpc_HOST_ARCH
+static int ocAllocateJumpIslands_MachO ( ObjectCode* oc );
 static void machoInitSymbolsWithoutUnderscore( void );
 #endif
+#endif
 
 /* -----------------------------------------------------------------------------
  * Built-in symbols from the RTS
@@ -296,11 +301,13 @@ typedef struct _RtsSymbolVal {
       SymX(log)                                 \
       SymX(sqrt)                                \
       SymX(memcpy)                              \
-      SymX(stg_InstallConsoleEvent)             \
+      SymX(rts_InstallConsoleEvent)             \
+      SymX(rts_ConsoleHandlerDone)              \
       Sym(mktime)                               \
       Sym(_imp___timezone)                      \
       Sym(_imp___tzname)                        \
       Sym(_imp___iob)                           \
+      Sym(_imp___osver)                         \
       Sym(localtime)                            \
       Sym(gmtime)                               \
       Sym(opendir)                              \
@@ -316,6 +323,14 @@ typedef struct _RtsSymbolVal {
 # define MAIN_CAP_SYM
 #endif
 
+#if !defined(mingw32_HOST_OS)
+#define RTS_USER_SIGNALS_SYMBOLS \
+   SymX(startSignalHandler) \
+   SymX(setIOManagerPipe)
+#else
+#define RTS_USER_SIGNALS_SYMBOLS /* nothing */
+#endif
+
 #ifdef TABLES_NEXT_TO_CODE
 #define RTS_RET_SYMBOLS /* nothing */
 #else
@@ -528,7 +543,6 @@ typedef struct _RtsSymbolVal {
       SymX(stable_ptr_table)                   \
       SymX(stackOverflow)                      \
       SymX(stg_CAF_BLACKHOLE_info)             \
-      SymX(stg_BLACKHOLE_BQ_info)              \
       SymX(awakenBlockedQueue)                 \
       SymX(stg_CHARLIKE_closure)               \
       SymX(stg_EMPTY_MVAR_info)                        \
@@ -590,7 +604,8 @@ typedef struct _RtsSymbolVal {
       SymX(word2Integerzh_fast)                        \
       SymX(writeTVarzh_fast)                   \
       SymX(xorIntegerzh_fast)                  \
-      SymX(yieldzh_fast)
+      SymX(yieldzh_fast)                        \
+      RTS_USER_SIGNALS_SYMBOLS
 
 #ifdef SUPPORT_LONG_LONGS
 #define RTS_LONG_LONG_SYMS                     \
@@ -624,7 +639,7 @@ typedef struct _RtsSymbolVal {
 #define RTS_LIBGCC_SYMBOLS
 #endif
 
-#ifdef darwin_HOST_OS
+#if defined(darwin_HOST_OS) && defined(powerpc_HOST_ARCH)
       // Symbols that don't have a leading underscore
       // on Mac OS X. They have to receive special treatment,
       // see machoInitSymbolsWithoutUnderscore()
@@ -672,6 +687,12 @@ static RtsSymbolVal rtsSyms[] = {
       RTS_MINGW_ONLY_SYMBOLS
       RTS_CYGWIN_ONLY_SYMBOLS
       RTS_LIBGCC_SYMBOLS
+#if defined(darwin_HOST_OS) && defined(i386_HOST_ARCH)
+      // dyld stub code contains references to this,
+      // but it should never be called because we treat
+      // lazy pointers as nonlazy.
+      { "dyld_stub_binding_helper", (void*)0xDEADBEEF },
+#endif
       { 0, 0 } /* sentinel */
 };
 
@@ -744,7 +765,7 @@ initLinker( void )
        ghciInsertStrHashTable("(GHCi built-in symbols)",
                                symhash, sym->lbl, sym->addr);
     }
-#   if defined(OBJFORMAT_MACHO)
+#   if defined(OBJFORMAT_MACHO) && defined(powerpc_HOST_ARCH)
     machoInitSymbolsWithoutUnderscore();
 #   endif
 
@@ -756,7 +777,7 @@ initLinker( void )
 #   if defined(openbsd_HOST_OS)
     dl_libc_handle = dlopen("libc.so", RTLD_LAZY);
 #   endif
-#   endif // RTLD_DEFAULT
+#   endif /* RTLD_DEFAULT */
 #   endif
 }
 
@@ -803,24 +824,6 @@ addDLL( char *dll_name )
    void *hdl;
    char *errmsg;
 
-   // *** HACK
-   // If we load libHSbase_cbits_dyn.[so|dylib],
-   // then we know that we need to activate another newCAF
-   // related hack in Storage.c because we can't redirect
-   // newCAF to newDynCAF with the system dynamic linker.
-#ifdef OBJFORMAT_MACHO
-   const char *hsbase = "/libHSbase_cbits_dyn.dylib";
-#else
-   const char *hsbase = "/libHSbase_cbits_dyn.so";
-#endif
-   int namelen = strlen(dll_name);
-   int baselen = strlen(hsbase);
-   if(namelen > baselen && !strcmp(dll_name + namelen - baselen, hsbase))
-   {
-      keepCAFs = rtsTrue;
-   }
-   // *** END HACK.
-
    initLinker();
 
    hdl= dlopen(dll_name, RTLD_NOW | RTLD_GLOBAL);
@@ -1027,8 +1030,8 @@ loadObj( char *path )
    void *map_addr = NULL;
 #else
    FILE *f;
+   int misalignment;
 #endif
-
    initLinker();
 
    /* debugBelch("loadObj %s\n", path ); */
@@ -1112,7 +1115,19 @@ loadObj( char *path )
 #endif
 
    n = ROUND_UP(oc->fileSize, pagesize);
-   oc->image = mmap(map_addr, n, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
+
+   /* Link objects into the lower 2Gb on x86_64.  GHC assumes the
+    * small memory model on this architecture (see gcc docs,
+    * -mcmodel=small).
+    */
+#ifdef x86_64_HOST_ARCH
+#define EXTRA_MAP_FLAGS MAP_32BIT
+#else
+#define EXTRA_MAP_FLAGS 0
+#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)
       barf("loadObj: can't map `%s'", path);
 
@@ -1120,13 +1135,29 @@ loadObj( char *path )
 
 #else /* !USE_MMAP */
 
-   oc->image = stgMallocBytes(oc->fileSize, "loadObj(image)");
-
    /* load the image into memory */
    f = fopen(path, "rb");
    if (!f)
        barf("loadObj: can't read `%s'", path);
 
+#ifdef darwin_HOST_OS
+    // In a Mach-O .o file, all sections can and will be misaligned
+    // if the total size of the headers is not a multiple of the
+    // desired alignment. This is fine for .o files that only serve
+    // as input for the static linker, but it's not fine for us,
+    // as SSE (used by gcc for floating point) and Altivec require
+    // 16-byte alignment.
+    // We calculate the correct alignment from the header before
+    // reading the file, and then we misalign oc->image on purpose so
+    // that the actual sections end up aligned again.
+   misalignment = machoGetMisalignment(f);
+#else
+   misalignment = 0;
+#endif
+
+   oc->image = stgMallocBytes(oc->fileSize + misalignment, "loadObj(image)");
+   oc->image += misalignment;
+   
    n = fread ( oc->image, 1, oc->fileSize, f );
    if (n != oc->fileSize)
       barf("loadObj: error whilst reading `%s'", path);
@@ -1135,7 +1166,7 @@ loadObj( char *path )
 
 #endif /* USE_MMAP */
 
-#  if defined(OBJFORMAT_MACHO)
+#  if defined(OBJFORMAT_MACHO) && defined(powerpc_HOST_ARCH)
    r = ocAllocateJumpIslands_MachO ( oc );
    if (!r) { return r; }
 #  elif defined(OBJFORMAT_ELF) && defined(powerpc_HOST_ARCH)
@@ -1726,24 +1757,25 @@ ocVerifyImage_PEi386 ( ObjectCode* oc )
             + hdr->NumberOfSymbols * sizeof_COFF_symbol;
 
    if (hdr->Machine != 0x14c) {
-      errorBelch("Not x86 PEi386");
+      errorBelch("%s: Not x86 PEi386", oc->fileName);
       return 0;
    }
    if (hdr->SizeOfOptionalHeader != 0) {
-      errorBelch("PEi386 with nonempty optional header");
+      errorBelch("%s: PEi386 with nonempty optional header", oc->fileName);
       return 0;
    }
    if ( /* (hdr->Characteristics & MYIMAGE_FILE_RELOCS_STRIPPED) || */
         (hdr->Characteristics & MYIMAGE_FILE_EXECUTABLE_IMAGE) ||
         (hdr->Characteristics & MYIMAGE_FILE_DLL) ||
         (hdr->Characteristics & MYIMAGE_FILE_SYSTEM) ) {
-      errorBelch("Not a PEi386 object file");
+      errorBelch("%s: Not a PEi386 object file", oc->fileName);
       return 0;
    }
    if ( (hdr->Characteristics & MYIMAGE_FILE_BYTES_REVERSED_HI)
         /* || !(hdr->Characteristics & MYIMAGE_FILE_32BIT_MACHINE) */ ) {
-      errorBelch("Invalid PEi386 word size or endiannness: %d",
-            (int)(hdr->Characteristics));
+      errorBelch("%s: Invalid PEi386 word size or endiannness: %d",
+                oc->fileName,
+                (int)(hdr->Characteristics));
       return 0;
    }
    /* If the string table size is way crazy, this might indicate that
@@ -1959,6 +1991,7 @@ ocGetNames_PEi386 ( ObjectCode* oc )
 #     endif
 
       if (0==strcmp(".text",sectab_i->Name) ||
+          0==strcmp(".rdata",sectab_i->Name)||
           0==strcmp(".rodata",sectab_i->Name))
          kind = SECTIONKIND_CODE_OR_RODATA;
       if (0==strcmp(".data",sectab_i->Name) ||
@@ -1977,8 +2010,10 @@ ocGetNames_PEi386 ( ObjectCode* oc )
              information. */
           && 0 != strcmp(".stab", sectab_i->Name)
           && 0 != strcmp(".stabstr", sectab_i->Name)
+          /* ignore constructor section for now */
+          && 0 != strcmp(".ctors", sectab_i->Name)
          ) {
-         errorBelch("Unknown PEi386 section name `%s'", sectab_i->Name);
+         errorBelch("Unknown PEi386 section name `%s' (while processing: %s)", sectab_i->Name, oc->fileName);
          return 0;
       }
 
@@ -2120,7 +2155,8 @@ ocResolve_PEi386 ( ObjectCode* oc )
       /* Ignore sections called which contain stabs debugging
          information. */
       if (0 == strcmp(".stab", sectab_i->Name)
-          || 0 == strcmp(".stabstr", sectab_i->Name))
+          || 0 == strcmp(".stabstr", sectab_i->Name)
+          || 0 == strcmp(".ctors", sectab_i->Name))
          continue;
 
       if ( sectab_i->Characteristics & MYIMAGE_SCN_LNK_NRELOC_OVFL ) {
@@ -2217,9 +2253,22 @@ ocResolve_PEi386 ( ObjectCode* oc )
                   -- hence the constant 4.
                   Also I don't know if A should be added, but so
                   far it has always been zero.
+
+                 SOF 05/2005: 'A' (old contents of *pP) have been observed
+                 to contain values other than zero (the 'wx' object file
+                 that came with wxhaskell-0.9.4; dunno how it was compiled..).
+                 So, add displacement to old value instead of asserting
+                 A to be zero. Fixes wxhaskell-related crashes, and no other
+                 ill effects have been observed.
+                 
+                 Update: the reason why we're seeing these more elaborate
+                 relocations is due to a switch in how the NCG compiles SRTs 
+                 and offsets to them from info tables. SRTs live in .(ro)data, 
+                 while info tables live in .text, causing GAS to emit REL32/DISP32 
+                 relocations with non-zero values. Adding the displacement is
+                 the right thing to do.
               */
-               ASSERT(A==0);
-               *pP = S - ((UInt32)pP) - 4;
+               *pP = S - ((UInt32)pP) - 4 + A;
                break;
             default:
                debugBelch("%s: unhandled PEi386 relocation type %d",
@@ -2532,6 +2581,9 @@ ocVerifyImage_ELF ( ObjectCode* oc )
       case EM_IA_64: IF_DEBUG(linker,debugBelch( "ia64" )); break;
 #endif
       case EM_PPC:   IF_DEBUG(linker,debugBelch( "powerpc32" )); break;
+#ifdef EM_X86_64
+      case EM_X86_64: IF_DEBUG(linker,debugBelch( "x86_64" )); break;
+#endif
       default:       IF_DEBUG(linker,debugBelch( "unknown" ));
                      errorBelch("%s: unknown architecture", oc->fileName);
                      return 0;
@@ -2945,7 +2997,7 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
                           target_shndx, symtab_shndx ));
 
    for (j = 0; j < nent; j++) {
-#if defined(DEBUG) || defined(sparc_HOST_ARCH) || defined(ia64_HOST_ARCH) || defined(powerpc_HOST_ARCH)
+#if defined(DEBUG) || defined(sparc_HOST_ARCH) || defined(ia64_HOST_ARCH) || defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH)
       /* This #ifdef only serves to avoid unused-var warnings. */
       Elf_Addr  offset = rtab[j].r_offset;
       Elf_Addr  P      = targ + offset;
@@ -3121,6 +3173,25 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
                                           | (delta & 0x3fffffc);
             break;
 #        endif
+
+#if x86_64_HOST_OS
+      case R_X86_64_64:
+         *(Elf64_Xword *)P = value;
+         break;
+
+      case R_X86_64_PC32:
+         *(Elf64_Word *)P = (Elf64_Word) (value - P);
+         break;
+
+      case R_X86_64_32:
+         *(Elf64_Word *)P = (Elf64_Word)value;
+         break;
+
+      case R_X86_64_32S:
+         *(Elf64_Sword *)P = (Elf64_Sword)value;
+         break;
+#endif
+
          default:
             errorBelch("%s: unhandled ELF relocation(RelA) type %d\n",
                  oc->fileName, ELF_R_TYPE(info));
@@ -3192,7 +3263,7 @@ ia64_extract_instruction(Elf64_Xword *target)
 {
    Elf64_Xword w1, w2;
    int slot = (Elf_Addr)target & 3;
-   (Elf_Addr)target &= ~3;
+   target = (Elf_Addr)target & ~3;
 
    w1 = *target;
    w2 = *(target+1);
@@ -3214,7 +3285,7 @@ static void
 ia64_deposit_instruction(Elf64_Xword *target, Elf64_Xword value)
 {
    int slot = (Elf_Addr)target & 3;
-   (Elf_Addr)target &= ~3;
+   target = (Elf_Addr)target & ~3;
 
    switch (slot)
    {
@@ -3317,7 +3388,7 @@ static int ocAllocateJumpIslands_ELF( ObjectCode *oc )
 #if defined(OBJFORMAT_MACHO)
 
 /*
-  Support for MachO linking on Darwin/MacOS X on PowerPC chips
+  Support for MachO linking on Darwin/MacOS X
   by Wolfgang Thaller (wolfgang.thaller@gmx.net)
 
   I hereby formally apologize for the hackish nature of this code.
@@ -3326,6 +3397,7 @@ static int ocAllocateJumpIslands_ELF( ObjectCode *oc )
   *) add still more sanity checks.
 */
 
+#ifdef powerpc_HOST_ARCH
 static int ocAllocateJumpIslands_MachO(ObjectCode* oc)
 {
     struct mach_header *header = (struct mach_header *) oc->image;
@@ -3370,6 +3442,7 @@ static int ocAllocateJumpIslands_MachO(ObjectCode* oc)
     }
     return ocAllocateJumpIslands(oc,0,0);
 }
+#endif
 
 static int ocVerifyImage_MachO(ObjectCode* oc STG_UNUSED)
 {
@@ -3448,6 +3521,10 @@ static int relocateSection(
        return 1;
     else if(!strcmp(sect->sectname,"__nl_symbol_ptr"))
        return 1;
+    else if(!strcmp(sect->sectname,"__la_sym_ptr2"))
+       return 1;
+    else if(!strcmp(sect->sectname,"__la_sym_ptr3"))
+       return 1;
 
     n = sect->nreloc;
     relocs = (struct relocation_info*) (image + sect->reloff);
@@ -3467,6 +3544,15 @@ static int relocateSection(
                    unsigned long* wordPtr = (unsigned long*) (image + sect->offset + scat->r_address);
                    checkProddableBlock(oc,wordPtr);
 
+                    // Note on relocation types:
+                    // i386 uses the GENERIC_RELOC_* types,
+                    // while ppc uses special PPC_RELOC_* types.
+                    // *_RELOC_VANILLA and *_RELOC_PAIR have the same value
+                    // in both cases, all others are different.
+                    // Therefore, we use GENERIC_RELOC_VANILLA
+                    // and GENERIC_RELOC_PAIR instead of the PPC variants,
+                    // and use #ifdefs for the other types.
+                    
                    // Step 1: Figure out what the relocated value should be
                    if(scat->r_type == GENERIC_RELOC_VANILLA)
                    {
@@ -3477,23 +3563,28 @@ static int relocateSection(
                                                                 scat->r_value)
                                         - scat->r_value;
                    }
+#ifdef powerpc_HOST_ARCH
                    else if(scat->r_type == PPC_RELOC_SECTDIFF
                        || scat->r_type == PPC_RELOC_LO16_SECTDIFF
                        || scat->r_type == PPC_RELOC_HI16_SECTDIFF
                        || scat->r_type == PPC_RELOC_HA16_SECTDIFF)
+#else
+                    else if(scat->r_type == GENERIC_RELOC_SECTDIFF)
+#endif
                    {
                        struct scattered_relocation_info *pair =
                                (struct scattered_relocation_info*) &relocs[i+1];
 
-                       if(!pair->r_scattered || pair->r_type != PPC_RELOC_PAIR)
+                       if(!pair->r_scattered || pair->r_type != GENERIC_RELOC_PAIR)
                            barf("Invalid Mach-O file: "
-                                "PPC_RELOC_*_SECTDIFF not followed by PPC_RELOC_PAIR");
+                                "RELOC_*_SECTDIFF not followed by RELOC_PAIR");
 
                        word = (unsigned long)
                               (relocateAddress(oc, nSections, sections, scat->r_value)
                              - relocateAddress(oc, nSections, sections, pair->r_value));
                        i++;
                    }
+#ifdef powerpc_HOST_ARCH
                    else if(scat->r_type == PPC_RELOC_HI16
                          || scat->r_type == PPC_RELOC_LO16
                          || scat->r_type == PPC_RELOC_HA16
@@ -3532,14 +3623,21 @@ static int relocateSection(
                         
                         i++;
                     }
+ #endif
                     else
                        continue;  // ignore the others
 
+#ifdef powerpc_HOST_ARCH
                     if(scat->r_type == GENERIC_RELOC_VANILLA
                         || scat->r_type == PPC_RELOC_SECTDIFF)
+#else
+                    if(scat->r_type == GENERIC_RELOC_VANILLA
+                        || scat->r_type == GENERIC_RELOC_SECTDIFF)
+#endif
                     {
                         *wordPtr = word;
                     }
+#ifdef powerpc_HOST_ARCH
                     else if(scat->r_type == PPC_RELOC_LO16_SECTDIFF || scat->r_type == PPC_RELOC_LO16)
                     {
                         ((unsigned short*) wordPtr)[1] = word & 0xFFFF;
@@ -3553,6 +3651,7 @@ static int relocateSection(
                         ((unsigned short*) wordPtr)[1] = ((word >> 16) & 0xFFFF)
                             + ((word & (1<<15)) ? 1 : 0);
                     }
+#endif
                }
            }
 
@@ -3567,10 +3666,12 @@ static int relocateSection(
            if(reloc->r_length == 2)
            {
                unsigned long word = 0;
+#ifdef powerpc_HOST_ARCH
                 unsigned long jumpIsland = 0;
                 long offsetToJumpIsland = 0xBADBAD42; // initialise to bad value
                                                       // to avoid warning and to catch
                                                       // bugs.
+#endif
 
                unsigned long* wordPtr = (unsigned long*) (image + sect->offset + reloc->r_address);
                checkProddableBlock(oc,wordPtr);
@@ -3579,6 +3680,7 @@ static int relocateSection(
                {
                    word = *wordPtr;
                }
+#ifdef powerpc_HOST_ARCH
                else if(reloc->r_type == PPC_RELOC_LO16)
                {
                    word = ((unsigned short*) wordPtr)[1];
@@ -3599,7 +3701,7 @@ static int relocateSection(
                    word = *wordPtr;
                    word = (word & 0x03FFFFFC) | ((word & 0x02000000) ? 0xFC000000 : 0);
                }
-
+#endif
 
                if(!reloc->r_extern)
                {
@@ -3623,17 +3725,19 @@ static int relocateSection(
 
                    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 jump to a relative jump to the symbol
+                            // and we'll change it to a relative jump to the symbol
                         ASSERT(-word == reloc->r_address);
-                        word = (unsigned long) symbolAddress;
-                        jumpIsland = makeJumpIsland(oc,reloc->r_symbolnum,word);
-                       word -= ((long)image) + sect->offset + reloc->r_address;
+                        jumpIsland = makeJumpIsland(oc,reloc->r_symbolnum,(unsigned long) symbolAddress);
                         if(jumpIsland != 0)
                         {
-                            offsetToJumpIsland = jumpIsland
-                                - (((long)image) + sect->offset + reloc->r_address);
+                            offsetToJumpIsland = word + jumpIsland
+                                - (((long)image) + sect->offset - sect->addr);
                         }
+#endif
+                       word += (unsigned long) symbolAddress
+                                - (((long)image) + sect->offset - sect->addr);
                     }
                     else
                     {
@@ -3646,6 +3750,7 @@ static int relocateSection(
                    *wordPtr = word;
                    continue;
                }
+#ifdef powerpc_HOST_ARCH
                else if(reloc->r_type == PPC_RELOC_LO16)
                {
                    ((unsigned short*) wordPtr)[1] = word & 0xFFFF;
@@ -3682,7 +3787,8 @@ static int relocateSection(
                    *wordPtr = (*wordPtr & 0xFC000003) | (word & 0x03FFFFFC);
                    continue;
                }
-           }
+#endif
+            }
            barf("\nunknown relocation %d",reloc->r_type);
            return 0;
        }
@@ -3864,6 +3970,10 @@ static int ocResolve_MachO(ObjectCode* oc)
            la_ptrs = &sections[i];
        else if(!strcmp(sections[i].sectname,"__nl_symbol_ptr"))
            nl_ptrs = &sections[i];
+        else if(!strcmp(sections[i].sectname,"__la_sym_ptr2"))
+           la_ptrs = &sections[i];
+        else if(!strcmp(sections[i].sectname,"__la_sym_ptr3"))
+           la_ptrs = &sections[i];
     }
 
     if(dsymLC)
@@ -3896,6 +4006,7 @@ static int ocResolve_MachO(ObjectCode* oc)
     return 1;
 }
 
+#ifdef powerpc_HOST_ARCH
 /*
  * The Mach-O object format uses leading underscores. But not everywhere.
  * There is a small number of runtime support functions defined in
@@ -3909,7 +4020,7 @@ static void machoInitSymbolsWithoutUnderscore()
 {
     extern void* symbolsWithoutUnderscore[];
     void **p = symbolsWithoutUnderscore;
-    __asm__ volatile(".data\n_symbolsWithoutUnderscore:");
+    __asm__ volatile(".globl _symbolsWithoutUnderscore\n.data\n_symbolsWithoutUnderscore:");
 
 #undef Sym
 #define Sym(x)  \
@@ -3928,3 +4039,26 @@ static void machoInitSymbolsWithoutUnderscore()
 #undef Sym
 }
 #endif
+
+/*
+ * 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 )
+{
+    struct mach_header header;
+    int misalignment;
+    
+    fread(&header, sizeof(header), 1, f);
+    rewind(f);
+
+    if(header.magic != MH_MAGIC)
+        return 0;
+    
+    misalignment = (header.sizeofcmds + sizeof(header))
+                    & 0xF;
+
+    return misalignment ? (16 - misalignment) : 0;
+}
+
+#endif