[project @ 2004-09-09 21:33:07 by simonpj]
[ghc-hetmet.git] / ghc / rts / Linker.c
index 41e90ca..7b1e4e9 100644 (file)
@@ -1,7 +1,6 @@
 /* -----------------------------------------------------------------------------
 /* -----------------------------------------------------------------------------
- * $Id: Linker.c,v 1.142 2003/12/18 09:32:07 simonmar Exp $
  *
  *
- * (c) The GHC Team, 2000-2003
+ * (c) The GHC Team, 2000-2004
  *
  * RTS Object Linker
  *
  *
  * RTS Object Linker
  *
@@ -10,6 +9,12 @@
 #if 0
 #include "PosixSource.h"
 #endif
 #if 0
 #include "PosixSource.h"
 #endif
+
+//  Linux needs _GNU_SOURCE to get RTLD_DEFAULT from <dlfcn.h>.
+#ifdef __linux__
+#define _GNU_SOURCE
+#endif
+
 #include "Rts.h"
 #include "RtsFlags.h"
 #include "HsFFI.h"
 #include "Rts.h"
 #include "RtsFlags.h"
 #include "HsFFI.h"
@@ -17,8 +22,8 @@
 #include "Linker.h"
 #include "LinkerInternals.h"
 #include "RtsUtils.h"
 #include "Linker.h"
 #include "LinkerInternals.h"
 #include "RtsUtils.h"
-#include "StoragePriv.h"
 #include "Schedule.h"
 #include "Schedule.h"
+#include "Storage.h"
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #include <sys/wait.h>
 #endif
 
 #include <sys/wait.h>
 #endif
 
-#if defined(ia64_TARGET_ARCH)
+#if defined(ia64_TARGET_ARCH) || defined(openbsd_TARGET_OS)
 #define USE_MMAP
 #include <fcntl.h>
 #include <sys/mman.h>
 #define USE_MMAP
 #include <fcntl.h>
 #include <sys/mman.h>
+
+#if defined(openbsd_TARGET_OS) 
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#endif
+
 #endif
 
 #if defined(linux_TARGET_OS) || defined(solaris2_TARGET_OS) || defined(freebsd_TARGET_OS) || defined(netbsd_TARGET_OS) || defined(openbsd_TARGET_OS)
 #endif
 
 #if defined(linux_TARGET_OS) || defined(solaris2_TARGET_OS) || defined(freebsd_TARGET_OS) || defined(netbsd_TARGET_OS) || defined(openbsd_TARGET_OS)
@@ -129,7 +141,7 @@ typedef struct _RtsSymbolVal {
 #define RTS_MINGW_ONLY_SYMBOLS /**/
 /* Don't have the ability to read import libs / archives, so
  * we have to stupidly list a lot of what libcygwin.a
 #define RTS_MINGW_ONLY_SYMBOLS /**/
 /* Don't have the ability to read import libs / archives, so
  * we have to stupidly list a lot of what libcygwin.a
- * exports; sigh. 
+ * exports; sigh.
  */
 #define RTS_CYGWIN_ONLY_SYMBOLS                 \
       SymX(regfree)                             \
  */
 #define RTS_CYGWIN_ONLY_SYMBOLS                 \
       SymX(regfree)                             \
@@ -220,7 +232,7 @@ typedef struct _RtsSymbolVal {
 #if __GNUC__>=3
 #define RTS_MINGW_EXTRA_SYMS                    \
       Sym(_imp____mb_cur_max)                   \
 #if __GNUC__>=3
 #define RTS_MINGW_EXTRA_SYMS                    \
       Sym(_imp____mb_cur_max)                   \
-      Sym(_imp___pctype)            
+      Sym(_imp___pctype)
 #else
 #define RTS_MINGW_EXTRA_SYMS
 #endif
 #else
 #define RTS_MINGW_EXTRA_SYMS
 #endif
@@ -300,12 +312,34 @@ typedef struct _RtsSymbolVal {
 # define MAIN_CAP_SYM
 #endif
 
 # define MAIN_CAP_SYM
 #endif
 
+#ifdef TABLES_NEXT_TO_CODE
+#define RTS_RET_SYMBOLS /* nothing */
+#else
+#define RTS_RET_SYMBOLS                        \
+      SymX(stg_enter_ret)                      \
+      SymX(stg_gc_fun_ret)                     \
+      SymX(stg_ap_0_ret)                       \
+      SymX(stg_ap_v_ret)                       \
+      SymX(stg_ap_f_ret)                       \
+      SymX(stg_ap_d_ret)                       \
+      SymX(stg_ap_l_ret)                       \
+      SymX(stg_ap_n_ret)                       \
+      SymX(stg_ap_p_ret)                       \
+      SymX(stg_ap_pv_ret)                      \
+      SymX(stg_ap_pp_ret)                      \
+      SymX(stg_ap_ppv_ret)                     \
+      SymX(stg_ap_ppp_ret)                     \
+      SymX(stg_ap_pppv_ret)                    \
+      SymX(stg_ap_pppp_ret)                    \
+      SymX(stg_ap_ppppp_ret)                   \
+      SymX(stg_ap_pppppp_ret)
+#endif
+
 #define RTS_SYMBOLS                            \
       Maybe_ForeignObj                         \
       Maybe_Stable_Names                       \
       Sym(StgReturn)                           \
       SymX(stg_enter_info)                     \
 #define RTS_SYMBOLS                            \
       Maybe_ForeignObj                         \
       Maybe_Stable_Names                       \
       Sym(StgReturn)                           \
       SymX(stg_enter_info)                     \
-      SymX(stg_enter_ret)                      \
       SymX(stg_gc_void_info)                   \
       SymX(__stg_gc_enter_1)                   \
       SymX(stg_gc_noregs)                      \
       SymX(stg_gc_void_info)                   \
       SymX(__stg_gc_enter_1)                   \
       SymX(stg_gc_noregs)                      \
@@ -321,7 +355,6 @@ typedef struct _RtsSymbolVal {
       SymX(stg_gc_l1)                          \
       SymX(__stg_gc_fun)                       \
       SymX(stg_gc_fun_info)                    \
       SymX(stg_gc_l1)                          \
       SymX(__stg_gc_fun)                       \
       SymX(stg_gc_fun_info)                    \
-      SymX(stg_gc_fun_ret)                     \
       SymX(stg_gc_gen)                         \
       SymX(stg_gc_gen_info)                    \
       SymX(stg_gc_gen_hp)                      \
       SymX(stg_gc_gen)                         \
       SymX(stg_gc_gen_info)                    \
       SymX(stg_gc_gen_hp)                      \
@@ -335,17 +368,14 @@ typedef struct _RtsSymbolVal {
       SymX(stg_block_takemvar)                 \
       SymX(stg_block_putmvar)                  \
       SymX(stg_seq_frame_info)                 \
       SymX(stg_block_takemvar)                 \
       SymX(stg_block_putmvar)                  \
       SymX(stg_seq_frame_info)                 \
-      SymX(ErrorHdrHook)                       \
       MAIN_CAP_SYM                              \
       SymX(MallocFailHook)                     \
       SymX(OnExitHook)                         \
       SymX(OutOfHeapHook)                      \
       MAIN_CAP_SYM                              \
       SymX(MallocFailHook)                     \
       SymX(OnExitHook)                         \
       SymX(OutOfHeapHook)                      \
-      SymX(PatErrorHdrHook)                    \
-      SymX(PostTraceHook)                      \
-      SymX(PreTraceHook)                       \
       SymX(StackOverflowHook)                  \
       SymX(__encodeDouble)                     \
       SymX(__encodeFloat)                      \
       SymX(StackOverflowHook)                  \
       SymX(__encodeDouble)                     \
       SymX(__encodeFloat)                      \
+      SymX(addDLL)                             \
       SymX(__gmpn_gcd_1)                       \
       SymX(__gmpz_cmp)                         \
       SymX(__gmpz_cmp_si)                      \
       SymX(__gmpn_gcd_1)                       \
       SymX(__gmpz_cmp)                         \
       SymX(__gmpz_cmp_si)                      \
@@ -355,12 +385,14 @@ typedef struct _RtsSymbolVal {
       SymX(__int_encodeDouble)                 \
       SymX(__int_encodeFloat)                  \
       SymX(andIntegerzh_fast)                  \
       SymX(__int_encodeDouble)                 \
       SymX(__int_encodeFloat)                  \
       SymX(andIntegerzh_fast)                  \
+      SymX(barf)                               \
       SymX(blockAsyncExceptionszh_fast)                \
       SymX(catchzh_fast)                       \
       SymX(blockAsyncExceptionszh_fast)                \
       SymX(catchzh_fast)                       \
+      SymX(closure_flags)                       \
       SymX(cmp_thread)                         \
       SymX(cmp_thread)                         \
-      SymX(complementIntegerzh_fast)           \
       SymX(cmpIntegerzh_fast)                  \
       SymX(cmpIntegerIntzh_fast)               \
       SymX(cmpIntegerzh_fast)                  \
       SymX(cmpIntegerIntzh_fast)               \
+      SymX(complementIntegerzh_fast)           \
       SymX(createAdjustor)                     \
       SymX(decodeDoublezh_fast)                        \
       SymX(decodeFloatzh_fast)                 \
       SymX(createAdjustor)                     \
       SymX(decodeDoublezh_fast)                        \
       SymX(decodeFloatzh_fast)                 \
@@ -381,6 +413,7 @@ typedef struct _RtsSymbolVal {
       SymX(genSymZh)                           \
       SymX(getProgArgv)                                \
       SymX(getStablePtr)                       \
       SymX(genSymZh)                           \
       SymX(getProgArgv)                                \
       SymX(getStablePtr)                       \
+      SymX(initLinker)                         \
       SymX(int2Integerzh_fast)                 \
       SymX(integer2Intzh_fast)                 \
       SymX(integer2Wordzh_fast)                        \
       SymX(int2Integerzh_fast)                 \
       SymX(integer2Intzh_fast)                 \
       SymX(integer2Wordzh_fast)                        \
@@ -395,6 +428,8 @@ typedef struct _RtsSymbolVal {
       SymX(isFloatNaN)                         \
       SymX(isFloatNegativeZero)                        \
       SymX(killThreadzh_fast)                  \
       SymX(isFloatNaN)                         \
       SymX(isFloatNegativeZero)                        \
       SymX(killThreadzh_fast)                  \
+      SymX(loadObj)                            \
+      SymX(lookupSymbol)                       \
       SymX(makeStablePtrzh_fast)               \
       SymX(minusIntegerzh_fast)                        \
       SymX(mkApUpd0zh_fast)                    \
       SymX(makeStablePtrzh_fast)               \
       SymX(minusIntegerzh_fast)                        \
       SymX(mkApUpd0zh_fast)                    \
@@ -410,6 +445,7 @@ typedef struct _RtsSymbolVal {
       SymX(newPinnedByteArrayzh_fast)          \
       SymX(orIntegerzh_fast)                   \
       SymX(performGC)                          \
       SymX(newPinnedByteArrayzh_fast)          \
       SymX(orIntegerzh_fast)                   \
       SymX(performGC)                          \
+      SymX(performMajorGC)                     \
       SymX(plusIntegerzh_fast)                 \
       SymX(prog_argc)                          \
       SymX(prog_argv)                          \
       SymX(plusIntegerzh_fast)                 \
       SymX(prog_argc)                          \
       SymX(prog_argv)                          \
@@ -421,6 +457,7 @@ typedef struct _RtsSymbolVal {
       SymX(remIntegerzh_fast)                  \
       SymX(resetNonBlockingFd)                 \
       SymX(resumeThread)                       \
       SymX(remIntegerzh_fast)                  \
       SymX(resetNonBlockingFd)                 \
       SymX(resumeThread)                       \
+      SymX(resolveObjs)                         \
       SymX(rts_apply)                          \
       SymX(rts_checkSchedStatus)               \
       SymX(rts_eval)                           \
       SymX(rts_apply)                          \
       SymX(rts_checkSchedStatus)               \
       SymX(rts_eval)                           \
@@ -479,6 +516,7 @@ typedef struct _RtsSymbolVal {
       SymX(stg_INTLIKE_closure)                        \
       SymX(stg_MUT_ARR_PTRS_FROZEN_info)       \
       SymX(stg_WEAK_info)                       \
       SymX(stg_INTLIKE_closure)                        \
       SymX(stg_MUT_ARR_PTRS_FROZEN_info)       \
       SymX(stg_WEAK_info)                       \
+      SymX(stg_ap_0_info)                      \
       SymX(stg_ap_v_info)                      \
       SymX(stg_ap_f_info)                      \
       SymX(stg_ap_d_info)                      \
       SymX(stg_ap_v_info)                      \
       SymX(stg_ap_f_info)                      \
       SymX(stg_ap_d_info)                      \
@@ -489,25 +527,10 @@ typedef struct _RtsSymbolVal {
       SymX(stg_ap_pp_info)                     \
       SymX(stg_ap_ppv_info)                    \
       SymX(stg_ap_ppp_info)                    \
       SymX(stg_ap_pp_info)                     \
       SymX(stg_ap_ppv_info)                    \
       SymX(stg_ap_ppp_info)                    \
+      SymX(stg_ap_pppv_info)                   \
       SymX(stg_ap_pppp_info)                   \
       SymX(stg_ap_ppppp_info)                  \
       SymX(stg_ap_pppppp_info)                 \
       SymX(stg_ap_pppp_info)                   \
       SymX(stg_ap_ppppp_info)                  \
       SymX(stg_ap_pppppp_info)                 \
-      SymX(stg_ap_ppppppp_info)                        \
-      SymX(stg_ap_0_ret)                       \
-      SymX(stg_ap_v_ret)                       \
-      SymX(stg_ap_f_ret)                       \
-      SymX(stg_ap_d_ret)                       \
-      SymX(stg_ap_l_ret)                       \
-      SymX(stg_ap_n_ret)                       \
-      SymX(stg_ap_p_ret)                       \
-      SymX(stg_ap_pv_ret)                      \
-      SymX(stg_ap_pp_ret)                      \
-      SymX(stg_ap_ppv_ret)                     \
-      SymX(stg_ap_ppp_ret)                     \
-      SymX(stg_ap_pppp_ret)                    \
-      SymX(stg_ap_ppppp_ret)                   \
-      SymX(stg_ap_pppppp_ret)                  \
-      SymX(stg_ap_ppppppp_ret)                 \
       SymX(stg_ap_1_upd_info)                  \
       SymX(stg_ap_2_upd_info)                  \
       SymX(stg_ap_3_upd_info)                  \
       SymX(stg_ap_1_upd_info)                  \
       SymX(stg_ap_2_upd_info)                  \
       SymX(stg_ap_3_upd_info)                  \
@@ -515,7 +538,6 @@ typedef struct _RtsSymbolVal {
       SymX(stg_ap_5_upd_info)                  \
       SymX(stg_ap_6_upd_info)                  \
       SymX(stg_ap_7_upd_info)                  \
       SymX(stg_ap_5_upd_info)                  \
       SymX(stg_ap_6_upd_info)                  \
       SymX(stg_ap_7_upd_info)                  \
-      SymX(stg_ap_8_upd_info)                  \
       SymX(stg_exit)                           \
       SymX(stg_sel_0_upd_info)                 \
       SymX(stg_sel_10_upd_info)                        \
       SymX(stg_exit)                           \
       SymX(stg_sel_0_upd_info)                 \
       SymX(stg_sel_10_upd_info)                        \
@@ -540,6 +562,7 @@ typedef struct _RtsSymbolVal {
       SymX(tryPutMVarzh_fast)                  \
       SymX(tryTakeMVarzh_fast)                 \
       SymX(unblockAsyncExceptionszh_fast)      \
       SymX(tryPutMVarzh_fast)                  \
       SymX(tryTakeMVarzh_fast)                 \
       SymX(unblockAsyncExceptionszh_fast)      \
+      SymX(unloadObj)                           \
       SymX(unsafeThawArrayzh_fast)             \
       SymX(waitReadzh_fast)                    \
       SymX(waitWritezh_fast)                   \
       SymX(unsafeThawArrayzh_fast)             \
       SymX(waitReadzh_fast)                    \
       SymX(waitWritezh_fast)                   \
@@ -592,6 +615,7 @@ typedef struct _RtsSymbolVal {
 #define SymX(vvv) /**/
 #define SymX_redirect(vvv,xxx) /**/
 RTS_SYMBOLS
 #define SymX(vvv) /**/
 #define SymX_redirect(vvv,xxx) /**/
 RTS_SYMBOLS
+RTS_RET_SYMBOLS
 RTS_LONG_LONG_SYMS
 RTS_POSIX_ONLY_SYMBOLS
 RTS_MINGW_ONLY_SYMBOLS
 RTS_LONG_LONG_SYMS
 RTS_POSIX_ONLY_SYMBOLS
 RTS_MINGW_ONLY_SYMBOLS
@@ -619,6 +643,7 @@ RTS_LIBGCC_SYMBOLS
 
 static RtsSymbolVal rtsSyms[] = {
       RTS_SYMBOLS
 
 static RtsSymbolVal rtsSyms[] = {
       RTS_SYMBOLS
+      RTS_RET_SYMBOLS
       RTS_LONG_LONG_SYMS
       RTS_POSIX_ONLY_SYMBOLS
       RTS_MINGW_ONLY_SYMBOLS
       RTS_LONG_LONG_SYMS
       RTS_POSIX_ONLY_SYMBOLS
       RTS_MINGW_ONLY_SYMBOLS
@@ -641,7 +666,7 @@ static void ghciInsertStrHashTable ( char* obj_name,
       insertStrHashTable(table, (StgWord)key, data);
       return;
    }
       insertStrHashTable(table, (StgWord)key, data);
       return;
    }
-   fprintf(stderr,
+   debugBelch(
       "\n\n"
       "GHCi runtime linker: fatal error: I found a duplicate definition for symbol\n"
       "   %s\n"
       "\n\n"
       "GHCi runtime linker: fatal error: I found a duplicate definition for symbol\n"
       "   %s\n"
@@ -672,6 +697,11 @@ static int linker_init_done = 0 ;
 static void *dl_prog_handle;
 #endif
 
 static void *dl_prog_handle;
 #endif
 
+/* dlopen(NULL,..) doesn't work so we grab libc explicitly */
+#if defined(openbsd_TARGET_OS)
+static void *dl_libc_handle;
+#endif
+
 void
 initLinker( void )
 {
 void
 initLinker( void )
 {
@@ -696,7 +726,14 @@ initLinker( void )
 #   endif
 
 #   if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)
 #   endif
 
 #   if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)
+#   if defined(RTLD_DEFAULT)
+    dl_prog_handle = RTLD_DEFAULT;
+#   else
     dl_prog_handle = dlopen(NULL, RTLD_LAZY);
     dl_prog_handle = dlopen(NULL, RTLD_LAZY);
+#   if defined(openbsd_TARGET_OS)
+    dl_libc_handle = dlopen("libc.so", RTLD_LAZY);
+#   endif
+#   endif // RTLD_DEFAULT
 #   endif
 }
 
 #   endif
 }
 
@@ -717,7 +754,7 @@ initLinker( void )
  * to give to loadSymbol, so that we can find the symbols.  For such
  * libraries, the LoadLibrary call should be a no-op except for returning
  * the handle.
  * to give to loadSymbol, so that we can find the symbols.  For such
  * libraries, the LoadLibrary call should be a no-op except for returning
  * the handle.
- * 
+ *
  */
 
 #if defined(OBJFORMAT_PEi386)
  */
 
 #if defined(OBJFORMAT_PEi386)
@@ -766,7 +803,7 @@ addDLL( char *dll_name )
 
    initLinker();
 
 
    initLinker();
 
-   /* fprintf(stderr, "\naddDLL; dll_name = `%s'\n", dll_name); */
+   /* debugBelch("\naddDLL; dll_name = `%s'\n", dll_name); */
 
    /* See if we've already got it, and ignore if so. */
    for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) {
 
    /* See if we've already got it, and ignore if so. */
    for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) {
@@ -826,7 +863,12 @@ lookupSymbol( char *lbl )
 
     if (val == NULL) {
 #       if defined(OBJFORMAT_ELF)
 
     if (val == NULL) {
 #       if defined(OBJFORMAT_ELF)
+#      if defined(openbsd_TARGET_OS)
+       val = dlsym(dl_prog_handle, lbl);
+       return (val != NULL) ? val : dlsym(dl_libc_handle,lbl);
+#      else /* not openbsd */
        return dlsym(dl_prog_handle, lbl);
        return dlsym(dl_prog_handle, lbl);
+#      endif
 #       elif defined(OBJFORMAT_MACHO)
        if(NSIsSymbolNameDefined(lbl)) {
            NSSymbol symbol = NSLookupAndBindSymbol(lbl);
 #       elif defined(OBJFORMAT_MACHO)
        if(NSIsSymbolNameDefined(lbl)) {
            NSSymbol symbol = NSLookupAndBindSymbol(lbl);
@@ -838,7 +880,7 @@ lookupSymbol( char *lbl )
         OpenedDLL* o_dll;
         void* sym;
         for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) {
         OpenedDLL* o_dll;
         void* sym;
         for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) {
-         /* fprintf(stderr, "look in %s for %s\n", o_dll->name, lbl); */
+         /* debugBelch("look in %s for %s\n", o_dll->name, lbl); */
            if (lbl[0] == '_') {
               /* HACK: if the name has an initial underscore, try stripping
                  it off & look that up first. I've yet to verify whether there's
            if (lbl[0] == '_') {
               /* HACK: if the name has an initial underscore, try stripping
                  it off & look that up first. I've yet to verify whether there's
@@ -847,13 +889,13 @@ lookupSymbol( char *lbl )
               */
               sym = GetProcAddress(o_dll->instance, (lbl+1));
               if (sym != NULL) {
               */
               sym = GetProcAddress(o_dll->instance, (lbl+1));
               if (sym != NULL) {
-               /*fprintf(stderr, "found %s in %s\n", lbl+1,o_dll->name); fflush(stderr);*/
+               /*debugBelch("found %s in %s\n", lbl+1,o_dll->name);*/
                return sym;
              }
            }
            sym = GetProcAddress(o_dll->instance, lbl);
            if (sym != NULL) {
                return sym;
              }
            }
            sym = GetProcAddress(o_dll->instance, lbl);
            if (sym != NULL) {
-            /*fprintf(stderr, "found %s in %s\n", lbl,o_dll->name); fflush(stderr);*/
+            /*debugBelch("found %s in %s\n", lbl,o_dll->name);*/
             return sym;
           }
         }
             return sym;
           }
         }
@@ -905,7 +947,7 @@ void ghci_enquire ( char* addr )
       for (i = 0; i < oc->n_symbols; i++) {
          sym = oc->symbols[i];
          if (sym == NULL) continue;
       for (i = 0; i < oc->n_symbols; i++) {
          sym = oc->symbols[i];
          if (sym == NULL) continue;
-         // fprintf(stderr, "enquire %p %p\n", sym, oc->lochash);
+         // debugBelch("enquire %p %p\n", sym, oc->lochash);
          a = NULL;
          if (oc->lochash != NULL) {
             a = lookupStrHashTable(oc->lochash, sym);
          a = NULL;
          if (oc->lochash != NULL) {
             a = lookupStrHashTable(oc->lochash, sym);
@@ -914,10 +956,10 @@ void ghci_enquire ( char* addr )
             a = lookupStrHashTable(symhash, sym);
         }
          if (a == NULL) {
             a = lookupStrHashTable(symhash, sym);
         }
          if (a == NULL) {
-            // fprintf(stderr, "ghci_enquire: can't find %s\n", sym);
+            // debugBelch("ghci_enquire: can't find %s\n", sym);
          }
          else if (addr-DELTA <= a && a <= addr+DELTA) {
          }
          else if (addr-DELTA <= a && a <= addr+DELTA) {
-            fprintf(stderr, "%p + %3d  ==  `%s'\n", addr, a - addr, sym);
+            debugBelch("%p + %3d  ==  `%s'\n", addr, a - addr, sym);
          }
       }
    }
          }
       }
    }
@@ -941,33 +983,34 @@ loadObj( char *path )
    int r, n;
 #ifdef USE_MMAP
    int fd, pagesize;
    int r, n;
 #ifdef USE_MMAP
    int fd, pagesize;
-   void *map_addr;
+   void *map_addr = NULL;
 #else
    FILE *f;
 #endif
 
    initLinker();
 
 #else
    FILE *f;
 #endif
 
    initLinker();
 
-   /* fprintf(stderr, "loadObj %s\n", path ); */
+   /* debugBelch("loadObj %s\n", path ); */
 
 
-   /* Check that we haven't already loaded this object.  Don't give up
-      at this stage; ocGetNames_* will barf later. */
+   /* Check that we haven't already loaded this object. 
+      Ignore requests to load multiple times */
    {
        ObjectCode *o;
        int is_dup = 0;
        for (o = objects; o; o = o->next) {
    {
        ObjectCode *o;
        int is_dup = 0;
        for (o = objects; o; o = o->next) {
-          if (0 == strcmp(o->fileName, path))
+          if (0 == strcmp(o->fileName, path)) {
              is_dup = 1;
              is_dup = 1;
+             break; /* don't need to search further */
+          }
        }
        if (is_dup) {
        }
        if (is_dup) {
-        fprintf(stderr,
-            "\n\n"
+          IF_DEBUG(linker, debugBelch(
             "GHCi runtime linker: warning: looks like you're trying to load the\n"
             "same object file twice:\n"
             "   %s\n"
             "GHCi runtime linker: warning: looks like you're trying to load the\n"
             "same object file twice:\n"
             "   %s\n"
-            "GHCi will continue, but a duplicate-symbol error may shortly follow.\n"
-            "\n"
-            , path);
+            "GHCi will ignore this, but be warned.\n"
+            , path));
+          return 1; /* success */
        }
    }
 
        }
    }
 
@@ -1006,7 +1049,11 @@ loadObj( char *path )
 
    /* On many architectures malloc'd memory isn't executable, so we need to use mmap. */
 
 
    /* On many architectures malloc'd memory isn't executable, so we need to use mmap. */
 
+#if defined(openbsd_TARGET_OS)
+   fd = open(path, O_RDONLY, S_IRUSR);
+#else
    fd = open(path, O_RDONLY);
    fd = open(path, O_RDONLY);
+#endif
    if (fd == -1)
       barf("loadObj: can't open `%s'", path);
 
    if (fd == -1)
       barf("loadObj: can't open `%s'", path);
 
@@ -1124,7 +1171,7 @@ unloadObj( char *path )
     ASSERT(symhash != NULL);
     ASSERT(objects != NULL);
 
     ASSERT(symhash != NULL);
     ASSERT(objects != NULL);
 
-    initLinker(); 
+    initLinker();
 
     prev = NULL;
     for (oc = objects; oc; prev = oc, oc = oc->next) {
 
     prev = NULL;
     for (oc = objects; oc; prev = oc, oc = oc->next) {
@@ -1162,7 +1209,7 @@ unloadObj( char *path )
        }
     }
 
        }
     }
 
-    belch("unloadObj: can't find `%s' to unload", path);
+    errorBelch("unloadObj: can't find `%s' to unload", path);
     return 0;
 }
 
     return 0;
 }
 
@@ -1175,7 +1222,7 @@ static void addProddableBlock ( ObjectCode* oc, void* start, int size )
 {
    ProddableBlock* pb
       = stgMallocBytes(sizeof(ProddableBlock), "addProddableBlock");
 {
    ProddableBlock* pb
       = stgMallocBytes(sizeof(ProddableBlock), "addProddableBlock");
-   /* fprintf(stderr, "aPB %p %p %d\n", oc, start, size); */
+   /* debugBelch("aPB %p %p %d\n", oc, start, size); */
    ASSERT(size > 0);
    pb->start      = start;
    pb->size       = size;
    ASSERT(size > 0);
    pb->start      = start;
    pb->size       = size;
@@ -1211,7 +1258,7 @@ static void addSection ( ObjectCode* oc, SectionKind kind,
    s->next      = oc->sections;
    oc->sections = s;
    /*
    s->next      = oc->sections;
    oc->sections = s;
    /*
-   fprintf(stderr, "addSection: %p-%p (size %d), kind %d\n",
+   debugBelch("addSection: %p-%p (size %d), kind %d\n",
                    start, ((char*)end)-1, end - start + 1, kind );
    */
 }
                    start, ((char*)end)-1, end - start + 1, kind );
    */
 }
@@ -1373,12 +1420,12 @@ printName ( UChar* name, UChar* strtab )
 {
    if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
       UInt32 strtab_offset = * (UInt32*)(name+4);
 {
    if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
       UInt32 strtab_offset = * (UInt32*)(name+4);
-      fprintf ( stderr, "%s", strtab + strtab_offset );
+      debugBelch("%s", strtab + strtab_offset );
    } else {
       int i;
       for (i = 0; i < 8; i++) {
          if (name[i] == 0) break;
    } else {
       int i;
       for (i = 0; i < 8; i++) {
          if (name[i] == 0) break;
-         fprintf ( stderr, "%c", name[i] );
+         debugBelch("%c", name[i] );
       }
    }
 }
       }
    }
 }
@@ -1485,7 +1532,7 @@ ocVerifyImage_PEi386 ( ObjectCode* oc )
    COFF_section* sectab;
    COFF_symbol*  symtab;
    UChar*        strtab;
    COFF_section* sectab;
    COFF_symbol*  symtab;
    UChar*        strtab;
-   /* fprintf(stderr, "\nLOADING %s\n", oc->fileName); */
+   /* debugBelch("\nLOADING %s\n", oc->fileName); */
    hdr = (COFF_header*)(oc->image);
    sectab = (COFF_section*) (
                ((UChar*)(oc->image))
    hdr = (COFF_header*)(oc->image);
    sectab = (COFF_section*) (
                ((UChar*)(oc->image))
@@ -1499,36 +1546,36 @@ ocVerifyImage_PEi386 ( ObjectCode* oc )
             + hdr->NumberOfSymbols * sizeof_COFF_symbol;
 
    if (hdr->Machine != 0x14c) {
             + hdr->NumberOfSymbols * sizeof_COFF_symbol;
 
    if (hdr->Machine != 0x14c) {
-      belch("Not x86 PEi386");
+      errorBelch("Not x86 PEi386");
       return 0;
    }
    if (hdr->SizeOfOptionalHeader != 0) {
       return 0;
    }
    if (hdr->SizeOfOptionalHeader != 0) {
-      belch("PEi386 with nonempty optional header");
+      errorBelch("PEi386 with nonempty optional header");
       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) ) {
       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) ) {
-      belch("Not a PEi386 object file");
+      errorBelch("Not a PEi386 object file");
       return 0;
    }
    if ( (hdr->Characteristics & MYIMAGE_FILE_BYTES_REVERSED_HI)
         /* || !(hdr->Characteristics & MYIMAGE_FILE_32BIT_MACHINE) */ ) {
       return 0;
    }
    if ( (hdr->Characteristics & MYIMAGE_FILE_BYTES_REVERSED_HI)
         /* || !(hdr->Characteristics & MYIMAGE_FILE_32BIT_MACHINE) */ ) {
-      belch("Invalid PEi386 word size or endiannness: %d",
+      errorBelch("Invalid PEi386 word size or endiannness: %d",
             (int)(hdr->Characteristics));
       return 0;
    }
    /* If the string table size is way crazy, this might indicate that
       there are more than 64k relocations, despite claims to the
       contrary.  Hence this test. */
             (int)(hdr->Characteristics));
       return 0;
    }
    /* If the string table size is way crazy, this might indicate that
       there are more than 64k relocations, despite claims to the
       contrary.  Hence this test. */
-   /* fprintf(stderr, "strtab size %d\n", * (UInt32*)strtab); */
+   /* debugBelch("strtab size %d\n", * (UInt32*)strtab); */
 #if 0
    if ( (*(UInt32*)strtab) > 600000 ) {
       /* Note that 600k has no special significance other than being
          big enough to handle the almost-2MB-sized lumps that
          constitute HSwin32*.o. */
 #if 0
    if ( (*(UInt32*)strtab) > 600000 ) {
       /* Note that 600k has no special significance other than being
          big enough to handle the almost-2MB-sized lumps that
          constitute HSwin32*.o. */
-      belch("PEi386 object has suspiciously large string table; > 64k relocs?");
+      debugBelch("PEi386 object has suspiciously large string table; > 64k relocs?");
       return 0;
    }
 #endif
       return 0;
    }
 #endif
@@ -1538,44 +1585,34 @@ ocVerifyImage_PEi386 ( ObjectCode* oc )
    IF_DEBUG(linker, i=1);
    if (i == 0) return 1;
 
    IF_DEBUG(linker, i=1);
    if (i == 0) return 1;
 
-   fprintf ( stderr,
-             "sectab offset = %d\n", ((UChar*)sectab) - ((UChar*)hdr) );
-   fprintf ( stderr,
-             "symtab offset = %d\n", ((UChar*)symtab) - ((UChar*)hdr) );
-   fprintf ( stderr,
-             "strtab offset = %d\n", ((UChar*)strtab) - ((UChar*)hdr) );
-
-   fprintf ( stderr, "\n" );
-   fprintf ( stderr,
-             "Machine:           0x%x\n", (UInt32)(hdr->Machine) );
-   fprintf ( stderr,
-             "# sections:        %d\n",   (UInt32)(hdr->NumberOfSections) );
-   fprintf ( stderr,
-             "time/date:         0x%x\n", (UInt32)(hdr->TimeDateStamp) );
-   fprintf ( stderr,
-             "symtab offset:     %d\n",   (UInt32)(hdr->PointerToSymbolTable) );
-   fprintf ( stderr,
-             "# symbols:         %d\n",   (UInt32)(hdr->NumberOfSymbols) );
-   fprintf ( stderr,
-             "sz of opt hdr:     %d\n",   (UInt32)(hdr->SizeOfOptionalHeader) );
-   fprintf ( stderr,
-             "characteristics:   0x%x\n", (UInt32)(hdr->Characteristics) );
+   debugBelch( "sectab offset = %d\n", ((UChar*)sectab) - ((UChar*)hdr) );
+   debugBelch( "symtab offset = %d\n", ((UChar*)symtab) - ((UChar*)hdr) );
+   debugBelch( "strtab offset = %d\n", ((UChar*)strtab) - ((UChar*)hdr) );
+
+   debugBelch("\n" );
+   debugBelch( "Machine:           0x%x\n", (UInt32)(hdr->Machine) );
+   debugBelch( "# sections:        %d\n",   (UInt32)(hdr->NumberOfSections) );
+   debugBelch( "time/date:         0x%x\n", (UInt32)(hdr->TimeDateStamp) );
+   debugBelch( "symtab offset:     %d\n",   (UInt32)(hdr->PointerToSymbolTable) );
+   debugBelch( "# symbols:         %d\n",   (UInt32)(hdr->NumberOfSymbols) );
+   debugBelch( "sz of opt hdr:     %d\n",   (UInt32)(hdr->SizeOfOptionalHeader) );
+   debugBelch( "characteristics:   0x%x\n", (UInt32)(hdr->Characteristics) );
 
    /* Print the section table. */
 
    /* Print the section table. */
-   fprintf ( stderr, "\n" );
+   debugBelch("\n" );
    for (i = 0; i < hdr->NumberOfSections; i++) {
       COFF_reloc* reltab;
       COFF_section* sectab_i
          = (COFF_section*)
            myindex ( sizeof_COFF_section, sectab, i );
    for (i = 0; i < hdr->NumberOfSections; i++) {
       COFF_reloc* reltab;
       COFF_section* sectab_i
          = (COFF_section*)
            myindex ( sizeof_COFF_section, sectab, i );
-      fprintf ( stderr,
+      debugBelch(
                 "\n"
                 "section %d\n"
                 "     name `",
                 i
               );
       printName ( sectab_i->Name, strtab );
                 "\n"
                 "section %d\n"
                 "     name `",
                 i
               );
       printName ( sectab_i->Name, strtab );
-      fprintf ( stderr,
+      debugBelch(
                 "'\n"
                 "    vsize %d\n"
                 "    vaddr %d\n"
                 "'\n"
                 "    vsize %d\n"
                 "    vaddr %d\n"
@@ -1615,7 +1652,7 @@ ocVerifyImage_PEi386 ( ObjectCode* oc )
          COFF_symbol* sym;
          COFF_reloc* rel = (COFF_reloc*)
                            myindex ( sizeof_COFF_reloc, reltab, j );
          COFF_symbol* sym;
          COFF_reloc* rel = (COFF_reloc*)
                            myindex ( sizeof_COFF_reloc, reltab, j );
-         fprintf ( stderr,
+         debugBelch(
                    "        type 0x%-4x   vaddr 0x%-8x   name `",
                    (UInt32)rel->Type,
                    rel->VirtualAddress );
                    "        type 0x%-4x   vaddr 0x%-8x   name `",
                    (UInt32)rel->Type,
                    rel->VirtualAddress );
@@ -1623,35 +1660,35 @@ ocVerifyImage_PEi386 ( ObjectCode* oc )
                myindex ( sizeof_COFF_symbol, symtab, rel->SymbolTableIndex );
         /* Hmm..mysterious looking offset - what's it for? SOF */
          printName ( sym->Name, strtab -10 );
                myindex ( sizeof_COFF_symbol, symtab, rel->SymbolTableIndex );
         /* Hmm..mysterious looking offset - what's it for? SOF */
          printName ( sym->Name, strtab -10 );
-         fprintf ( stderr, "'\n" );
+         debugBelch("'\n" );
       }
 
       }
 
-      fprintf ( stderr, "\n" );
+      debugBelch("\n" );
    }
    }
-   fprintf ( stderr, "\n" );
-   fprintf ( stderr, "string table has size 0x%x\n", * (UInt32*)strtab );
-   fprintf ( stderr, "---START of string table---\n");
+   debugBelch("\n" );
+   debugBelch("string table has size 0x%x\n", * (UInt32*)strtab );
+   debugBelch("---START of string table---\n");
    for (i = 4; i < *(Int32*)strtab; i++) {
       if (strtab[i] == 0)
    for (i = 4; i < *(Int32*)strtab; i++) {
       if (strtab[i] == 0)
-         fprintf ( stderr, "\n"); else
-         fprintf( stderr, "%c", strtab[i] );
+         debugBelch("\n"); else
+         debugBelch("%c", strtab[i] );
    }
    }
-   fprintf ( stderr, "--- END  of string table---\n");
+   debugBelch("--- END  of string table---\n");
 
 
-   fprintf ( stderr, "\n" );
+   debugBelch("\n" );
    i = 0;
    while (1) {
       COFF_symbol* symtab_i;
       if (i >= (Int32)(hdr->NumberOfSymbols)) break;
       symtab_i = (COFF_symbol*)
                  myindex ( sizeof_COFF_symbol, symtab, i );
    i = 0;
    while (1) {
       COFF_symbol* symtab_i;
       if (i >= (Int32)(hdr->NumberOfSymbols)) break;
       symtab_i = (COFF_symbol*)
                  myindex ( sizeof_COFF_symbol, symtab, i );
-      fprintf ( stderr,
+      debugBelch(
                 "symbol %d\n"
                 "     name `",
                 i
               );
       printName ( symtab_i->Name, strtab );
                 "symbol %d\n"
                 "     name `",
                 i
               );
       printName ( symtab_i->Name, strtab );
-      fprintf ( stderr,
+      debugBelch(
                 "'\n"
                 "    value 0x%x\n"
                 "   1+sec# %d\n"
                 "'\n"
                 "    value 0x%x\n"
                 "   1+sec# %d\n"
@@ -1668,7 +1705,7 @@ ocVerifyImage_PEi386 ( ObjectCode* oc )
       i++;
    }
 
       i++;
    }
 
-   fprintf ( stderr, "\n" );
+   debugBelch("\n" );
    return 1;
 }
 
    return 1;
 }
 
@@ -1714,7 +1751,7 @@ ocGetNames_PEi386 ( ObjectCode* oc )
                               "ocGetNames_PEi386(anonymous bss)");
       sectab_i->PointerToRawData = ((UChar*)zspace) - ((UChar*)(oc->image));
       addProddableBlock(oc, zspace, sectab_i->VirtualSize);
                               "ocGetNames_PEi386(anonymous bss)");
       sectab_i->PointerToRawData = ((UChar*)zspace) - ((UChar*)(oc->image));
       addProddableBlock(oc, zspace, sectab_i->VirtualSize);
-      /* fprintf(stderr, "BSS anon section at 0x%x\n", zspace); */
+      /* debugBelch("BSS anon section at 0x%x\n", zspace); */
    }
 
    /* Copy section information into the ObjectCode. */
    }
 
    /* Copy section information into the ObjectCode. */
@@ -1729,7 +1766,7 @@ ocGetNames_PEi386 ( ObjectCode* oc )
       COFF_section* sectab_i
          = (COFF_section*)
            myindex ( sizeof_COFF_section, sectab, i );
       COFF_section* sectab_i
          = (COFF_section*)
            myindex ( sizeof_COFF_section, sectab, i );
-      IF_DEBUG(linker, belch("section name = %s\n", sectab_i->Name ));
+      IF_DEBUG(linker, debugBelch("section name = %s\n", sectab_i->Name ));
 
 #     if 0
       /* I'm sure this is the Right Way to do it.  However, the
 
 #     if 0
       /* I'm sure this is the Right Way to do it.  However, the
@@ -1761,7 +1798,7 @@ ocGetNames_PEi386 ( ObjectCode* oc )
           && 0 != strcmp(".stab", sectab_i->Name)
           && 0 != strcmp(".stabstr", sectab_i->Name)
          ) {
           && 0 != strcmp(".stab", sectab_i->Name)
           && 0 != strcmp(".stabstr", sectab_i->Name)
          ) {
-         belch("Unknown PEi386 section name `%s'", sectab_i->Name);
+         errorBelch("Unknown PEi386 section name `%s'", sectab_i->Name);
          return 0;
       }
 
          return 0;
       }
 
@@ -1815,26 +1852,26 @@ ocGetNames_PEi386 ( ObjectCode* oc )
          addSection(oc, SECTIONKIND_RWDATA, addr,
                         ((UChar*)addr) + symtab_i->Value - 1);
          addProddableBlock(oc, addr, symtab_i->Value);
          addSection(oc, SECTIONKIND_RWDATA, addr,
                         ((UChar*)addr) + symtab_i->Value - 1);
          addProddableBlock(oc, addr, symtab_i->Value);
-         /* fprintf(stderr, "BSS      section at 0x%x\n", addr); */
+         /* debugBelch("BSS      section at 0x%x\n", addr); */
       }
 
       if (addr != NULL ) {
          sname = cstring_from_COFF_symbol_name ( symtab_i->Name, strtab );
       }
 
       if (addr != NULL ) {
          sname = cstring_from_COFF_symbol_name ( symtab_i->Name, strtab );
-         /* fprintf(stderr,"addSymbol %p `%s \n", addr,sname);  */
-         IF_DEBUG(linker, belch("addSymbol %p `%s'\n", addr,sname);)
+         /* debugBelch("addSymbol %p `%s \n", addr,sname);  */
+         IF_DEBUG(linker, debugBelch("addSymbol %p `%s'\n", addr,sname);)
          ASSERT(i >= 0 && i < oc->n_symbols);
          /* cstring_from_COFF_symbol_name always succeeds. */
          oc->symbols[i] = sname;
          ghciInsertStrHashTable(oc->fileName, symhash, sname, addr);
       } else {
 #        if 0
          ASSERT(i >= 0 && i < oc->n_symbols);
          /* cstring_from_COFF_symbol_name always succeeds. */
          oc->symbols[i] = sname;
          ghciInsertStrHashTable(oc->fileName, symhash, sname, addr);
       } else {
 #        if 0
-         fprintf ( stderr,
+         debugBelch(
                    "IGNORING symbol %d\n"
                    "     name `",
                    i
                  );
          printName ( symtab_i->Name, strtab );
                    "IGNORING symbol %d\n"
                    "     name `",
                    i
                  );
          printName ( symtab_i->Name, strtab );
-         fprintf ( stderr,
+         debugBelch(
                    "'\n"
                    "    value 0x%x\n"
                    "   1+sec# %d\n"
                    "'\n"
                    "    value 0x%x\n"
                    "   1+sec# %d\n"
@@ -1876,7 +1913,7 @@ ocResolve_PEi386 ( ObjectCode* oc )
    /* ToDo: should be variable-sized?  But is at least safe in the
       sense of buffer-overrun-proof. */
    char symbol[1000];
    /* ToDo: should be variable-sized?  But is at least safe in the
       sense of buffer-overrun-proof. */
    char symbol[1000];
-   /* fprintf(stderr, "resolving for %s\n", oc->fileName); */
+   /* debugBelch("resolving for %s\n", oc->fileName); */
 
    hdr = (COFF_header*)(oc->image);
    sectab = (COFF_section*) (
 
    hdr = (COFF_header*)(oc->image);
    sectab = (COFF_section*) (
@@ -1912,15 +1949,16 @@ ocResolve_PEi386 ( ObjectCode* oc )
          *
         * See Section 4.1 (last para) of the PE spec (rev6.0).
         *
          *
         * See Section 4.1 (last para) of the PE spec (rev6.0).
         *
-        * Nov2003 update: the GNU linker still doesn't correctly 
-        * handle the generation of relocatable object files with 
-        * overflown relocations. Hence the output to warn of potential 
+        * Nov2003 update: the GNU linker still doesn't correctly
+        * handle the generation of relocatable object files with
+        * overflown relocations. Hence the output to warn of potential
         * troubles.
         */
         COFF_reloc* rel = (COFF_reloc*)
                            myindex ( sizeof_COFF_reloc, reltab, 0 );
        noRelocs = rel->VirtualAddress;
         * troubles.
         */
         COFF_reloc* rel = (COFF_reloc*)
                            myindex ( sizeof_COFF_reloc, reltab, 0 );
        noRelocs = rel->VirtualAddress;
-       fprintf(stderr, "WARNING: Overflown relocation field (# relocs found: %u)\n", noRelocs); fflush(stderr);
+       debugBelch("WARNING: Overflown relocation field (# relocs found: %u)\n",
+                  noRelocs);
        j = 1;
       } else {
        noRelocs = sectab_i->NumberOfRelocations;
        j = 1;
       } else {
        noRelocs = sectab_i->NumberOfRelocations;
@@ -1948,20 +1986,20 @@ ocResolve_PEi386 ( ObjectCode* oc )
                myindex ( sizeof_COFF_symbol,
                          symtab, reltab_j->SymbolTableIndex );
          IF_DEBUG(linker,
                myindex ( sizeof_COFF_symbol,
                          symtab, reltab_j->SymbolTableIndex );
          IF_DEBUG(linker,
-                  fprintf ( stderr,
+                  debugBelch(
                             "reloc sec %2d num %3d:  type 0x%-4x   "
                             "vaddr 0x%-8x   name `",
                             i, j,
                             (UInt32)reltab_j->Type,
                             reltab_j->VirtualAddress );
                             printName ( sym->Name, strtab );
                             "reloc sec %2d num %3d:  type 0x%-4x   "
                             "vaddr 0x%-8x   name `",
                             i, j,
                             (UInt32)reltab_j->Type,
                             reltab_j->VirtualAddress );
                             printName ( sym->Name, strtab );
-                            fprintf ( stderr, "'\n" ));
+                            debugBelch("'\n" ));
 
          if (sym->StorageClass == MYIMAGE_SYM_CLASS_STATIC) {
             COFF_section* section_sym
                = findPEi386SectionCalled ( oc, sym->Name );
             if (!section_sym) {
 
          if (sym->StorageClass == MYIMAGE_SYM_CLASS_STATIC) {
             COFF_section* section_sym
                = findPEi386SectionCalled ( oc, sym->Name );
             if (!section_sym) {
-               belch("%s: can't find section `%s'", oc->fileName, sym->Name);
+               errorBelch("%s: can't find section `%s'", oc->fileName, sym->Name);
                return 0;
             }
             S = ((UInt32)(oc->image))
                return 0;
             }
             S = ((UInt32)(oc->image))
@@ -1979,7 +2017,7 @@ ocResolve_PEi386 ( ObjectCode* oc )
             (void*)S = lookupSymbol( symbol );
             if ((void*)S != NULL) goto foundit;
            /* Newline first because the interactive linker has printed "linking..." */
             (void*)S = lookupSymbol( symbol );
             if ((void*)S != NULL) goto foundit;
            /* Newline first because the interactive linker has printed "linking..." */
-            belch("\n%s: unknown symbol `%s'", oc->fileName, symbol);
+            errorBelch("\n%s: unknown symbol `%s'", oc->fileName, symbol);
             return 0;
            foundit:
          }
             return 0;
            foundit:
          }
@@ -2004,7 +2042,7 @@ ocResolve_PEi386 ( ObjectCode* oc )
                *pP = S - ((UInt32)pP) - 4;
                break;
             default:
                *pP = S - ((UInt32)pP) - 4;
                break;
             default:
-               belch("%s: unhandled PEi386 relocation type %d",
+               debugBelch("%s: unhandled PEi386 relocation type %d",
                     oc->fileName, reltab_j->Type);
                return 0;
          }
                     oc->fileName, reltab_j->Type);
                return 0;
          }
@@ -2012,7 +2050,7 @@ ocResolve_PEi386 ( ObjectCode* oc )
       }
    }
 
       }
    }
 
-   IF_DEBUG(linker, belch("completed %s", oc->fileName));
+   IF_DEBUG(linker, debugBelch("completed %s", oc->fileName));
    return 1;
 }
 
    return 1;
 }
 
@@ -2281,44 +2319,44 @@ ocVerifyImage_ELF ( ObjectCode* oc )
        ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
        ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
        ehdr->e_ident[EI_MAG3] != ELFMAG3) {
        ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
        ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
        ehdr->e_ident[EI_MAG3] != ELFMAG3) {
-      belch("%s: not an ELF object", oc->fileName);
+      errorBelch("%s: not an ELF object", oc->fileName);
       return 0;
    }
 
    if (ehdr->e_ident[EI_CLASS] != ELFCLASS) {
       return 0;
    }
 
    if (ehdr->e_ident[EI_CLASS] != ELFCLASS) {
-      belch("%s: unsupported ELF format", oc->fileName);
+      errorBelch("%s: unsupported ELF format", oc->fileName);
       return 0;
    }
 
    if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB) {
       return 0;
    }
 
    if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB) {
-       IF_DEBUG(linker,belch( "Is little-endian" ));
+       IF_DEBUG(linker,debugBelch( "Is little-endian" ));
    } else
    if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) {
    } else
    if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) {
-       IF_DEBUG(linker,belch( "Is big-endian" ));
+       IF_DEBUG(linker,debugBelch( "Is big-endian" ));
    } else {
    } else {
-       belch("%s: unknown endiannness", oc->fileName);
+       errorBelch("%s: unknown endiannness", oc->fileName);
        return 0;
    }
 
    if (ehdr->e_type != ET_REL) {
        return 0;
    }
 
    if (ehdr->e_type != ET_REL) {
-      belch("%s: not a relocatable object (.o) file", oc->fileName);
+      errorBelch("%s: not a relocatable object (.o) file", oc->fileName);
       return 0;
    }
       return 0;
    }
-   IF_DEBUG(linker, belch( "Is a relocatable object (.o) file" ));
+   IF_DEBUG(linker, debugBelch( "Is a relocatable object (.o) file" ));
 
 
-   IF_DEBUG(linker,belch( "Architecture is " ));
+   IF_DEBUG(linker,debugBelch( "Architecture is " ));
    switch (ehdr->e_machine) {
    switch (ehdr->e_machine) {
-      case EM_386:   IF_DEBUG(linker,belch( "x86" )); break;
-      case EM_SPARC: IF_DEBUG(linker,belch( "sparc" )); break;
+      case EM_386:   IF_DEBUG(linker,debugBelch( "x86" )); break;
+      case EM_SPARC: IF_DEBUG(linker,debugBelch( "sparc" )); break;
 #ifdef EM_IA_64
 #ifdef EM_IA_64
-      case EM_IA_64: IF_DEBUG(linker,belch( "ia64" )); break;
+      case EM_IA_64: IF_DEBUG(linker,debugBelch( "ia64" )); break;
 #endif
 #endif
-      default:       IF_DEBUG(linker,belch( "unknown" ));
-                     belch("%s: unknown architecture", oc->fileName);
+      default:       IF_DEBUG(linker,debugBelch( "unknown" ));
+                     errorBelch("%s: unknown architecture", oc->fileName);
                      return 0;
    }
 
                      return 0;
    }
 
-   IF_DEBUG(linker,belch(
+   IF_DEBUG(linker,debugBelch(
              "\nSection header table: start %d, n_entries %d, ent_size %d",
              ehdr->e_shoff, ehdr->e_shnum, ehdr->e_shentsize  ));
 
              "\nSection header table: start %d, n_entries %d, ent_size %d",
              ehdr->e_shoff, ehdr->e_shnum, ehdr->e_shentsize  ));
 
@@ -2327,36 +2365,36 @@ ocVerifyImage_ELF ( ObjectCode* oc )
    shdr = (Elf_Shdr*) (ehdrC + ehdr->e_shoff);
 
    if (ehdr->e_shstrndx == SHN_UNDEF) {
    shdr = (Elf_Shdr*) (ehdrC + ehdr->e_shoff);
 
    if (ehdr->e_shstrndx == SHN_UNDEF) {
-      belch("%s: no section header string table", oc->fileName);
+      errorBelch("%s: no section header string table", oc->fileName);
       return 0;
    } else {
       return 0;
    } else {
-      IF_DEBUG(linker,belch( "Section header string table is section %d",
+      IF_DEBUG(linker,debugBelch( "Section header string table is section %d",
                           ehdr->e_shstrndx));
       sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
    }
 
    for (i = 0; i < ehdr->e_shnum; i++) {
                           ehdr->e_shstrndx));
       sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
    }
 
    for (i = 0; i < ehdr->e_shnum; i++) {
-      IF_DEBUG(linker,fprintf(stderr, "%2d:  ", i ));
-      IF_DEBUG(linker,fprintf(stderr, "type=%2d  ", (int)shdr[i].sh_type ));
-      IF_DEBUG(linker,fprintf(stderr, "size=%4d  ", (int)shdr[i].sh_size ));
-      IF_DEBUG(linker,fprintf(stderr, "offs=%4d  ", (int)shdr[i].sh_offset ));
-      IF_DEBUG(linker,fprintf(stderr, "  (%p .. %p)  ",
+      IF_DEBUG(linker,debugBelch("%2d:  ", i ));
+      IF_DEBUG(linker,debugBelch("type=%2d  ", (int)shdr[i].sh_type ));
+      IF_DEBUG(linker,debugBelch("size=%4d  ", (int)shdr[i].sh_size ));
+      IF_DEBUG(linker,debugBelch("offs=%4d  ", (int)shdr[i].sh_offset ));
+      IF_DEBUG(linker,debugBelch("  (%p .. %p)  ",
                ehdrC + shdr[i].sh_offset,
                      ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1));
 
       if (shdr[i].sh_type == SHT_REL) {
                ehdrC + shdr[i].sh_offset,
                      ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1));
 
       if (shdr[i].sh_type == SHT_REL) {
-         IF_DEBUG(linker,fprintf(stderr, "Rel  " ));
+         IF_DEBUG(linker,debugBelch("Rel  " ));
       } else if (shdr[i].sh_type == SHT_RELA) {
       } else if (shdr[i].sh_type == SHT_RELA) {
-         IF_DEBUG(linker,fprintf(stderr, "RelA " ));
+         IF_DEBUG(linker,debugBelch("RelA " ));
       } else {
       } else {
-         IF_DEBUG(linker,fprintf(stderr,"     "));
+         IF_DEBUG(linker,debugBelch("     "));
       }
       if (sh_strtab) {
       }
       if (sh_strtab) {
-         IF_DEBUG(linker,fprintf(stderr, "sname=%s\n", sh_strtab + shdr[i].sh_name ));
+         IF_DEBUG(linker,debugBelch("sname=%s\n", sh_strtab + shdr[i].sh_name ));
       }
    }
 
       }
    }
 
-   IF_DEBUG(linker,belch( "\nString tables" ));
+   IF_DEBUG(linker,debugBelch( "\nString tables" ));
    strtab = NULL;
    nstrtab = 0;
    for (i = 0; i < ehdr->e_shnum; i++) {
    strtab = NULL;
    nstrtab = 0;
    for (i = 0; i < ehdr->e_shnum; i++) {
@@ -2367,65 +2405,65 @@ ocVerifyImage_ELF ( ObjectCode* oc )
              debugging info. */
           && 0 != memcmp(".stabstr", sh_strtab + shdr[i].sh_name, 8)
          ) {
              debugging info. */
           && 0 != memcmp(".stabstr", sh_strtab + shdr[i].sh_name, 8)
          ) {
-         IF_DEBUG(linker,belch("   section %d is a normal string table", i ));
+         IF_DEBUG(linker,debugBelch("   section %d is a normal string table", i ));
          strtab = ehdrC + shdr[i].sh_offset;
          nstrtab++;
       }
    }
    if (nstrtab != 1) {
          strtab = ehdrC + shdr[i].sh_offset;
          nstrtab++;
       }
    }
    if (nstrtab != 1) {
-      belch("%s: no string tables, or too many", oc->fileName);
+      errorBelch("%s: no string tables, or too many", oc->fileName);
       return 0;
    }
 
    nsymtabs = 0;
       return 0;
    }
 
    nsymtabs = 0;
-   IF_DEBUG(linker,belch( "\nSymbol tables" ));
+   IF_DEBUG(linker,debugBelch( "\nSymbol tables" ));
    for (i = 0; i < ehdr->e_shnum; i++) {
       if (shdr[i].sh_type != SHT_SYMTAB) continue;
    for (i = 0; i < ehdr->e_shnum; i++) {
       if (shdr[i].sh_type != SHT_SYMTAB) continue;
-      IF_DEBUG(linker,belch( "section %d is a symbol table", i ));
+      IF_DEBUG(linker,debugBelch( "section %d is a symbol table", i ));
       nsymtabs++;
       stab = (Elf_Sym*) (ehdrC + shdr[i].sh_offset);
       nent = shdr[i].sh_size / sizeof(Elf_Sym);
       nsymtabs++;
       stab = (Elf_Sym*) (ehdrC + shdr[i].sh_offset);
       nent = shdr[i].sh_size / sizeof(Elf_Sym);
-      IF_DEBUG(linker,belch( "   number of entries is apparently %d (%d rem)",
+      IF_DEBUG(linker,debugBelch( "   number of entries is apparently %d (%d rem)",
                nent,
                shdr[i].sh_size % sizeof(Elf_Sym)
              ));
       if (0 != shdr[i].sh_size % sizeof(Elf_Sym)) {
                nent,
                shdr[i].sh_size % sizeof(Elf_Sym)
              ));
       if (0 != shdr[i].sh_size % sizeof(Elf_Sym)) {
-         belch("%s: non-integral number of symbol table entries", oc->fileName);
+         errorBelch("%s: non-integral number of symbol table entries", oc->fileName);
          return 0;
       }
       for (j = 0; j < nent; j++) {
          return 0;
       }
       for (j = 0; j < nent; j++) {
-         IF_DEBUG(linker,fprintf(stderr, "   %2d  ", j ));
-         IF_DEBUG(linker,fprintf(stderr, "  sec=%-5d  size=%-3d  val=%5p  ",
+         IF_DEBUG(linker,debugBelch("   %2d  ", j ));
+         IF_DEBUG(linker,debugBelch("  sec=%-5d  size=%-3d  val=%5p  ",
                              (int)stab[j].st_shndx,
                              (int)stab[j].st_size,
                              (char*)stab[j].st_value ));
 
                              (int)stab[j].st_shndx,
                              (int)stab[j].st_size,
                              (char*)stab[j].st_value ));
 
-         IF_DEBUG(linker,fprintf(stderr, "type=" ));
+         IF_DEBUG(linker,debugBelch("type=" ));
          switch (ELF_ST_TYPE(stab[j].st_info)) {
          switch (ELF_ST_TYPE(stab[j].st_info)) {
-            case STT_NOTYPE:  IF_DEBUG(linker,fprintf(stderr, "notype " )); break;
-            case STT_OBJECT:  IF_DEBUG(linker,fprintf(stderr, "object " )); break;
-            case STT_FUNC  :  IF_DEBUG(linker,fprintf(stderr, "func   " )); break;
-            case STT_SECTION: IF_DEBUG(linker,fprintf(stderr, "section" )); break;
-            case STT_FILE:    IF_DEBUG(linker,fprintf(stderr, "file   " )); break;
-            default:          IF_DEBUG(linker,fprintf(stderr, "?      " )); break;
+            case STT_NOTYPE:  IF_DEBUG(linker,debugBelch("notype " )); break;
+            case STT_OBJECT:  IF_DEBUG(linker,debugBelch("object " )); break;
+            case STT_FUNC  :  IF_DEBUG(linker,debugBelch("func   " )); break;
+            case STT_SECTION: IF_DEBUG(linker,debugBelch("section" )); break;
+            case STT_FILE:    IF_DEBUG(linker,debugBelch("file   " )); break;
+            default:          IF_DEBUG(linker,debugBelch("?      " )); break;
          }
          }
-         IF_DEBUG(linker,fprintf(stderr, "  " ));
+         IF_DEBUG(linker,debugBelch("  " ));
 
 
-         IF_DEBUG(linker,fprintf(stderr, "bind=" ));
+         IF_DEBUG(linker,debugBelch("bind=" ));
          switch (ELF_ST_BIND(stab[j].st_info)) {
          switch (ELF_ST_BIND(stab[j].st_info)) {
-            case STB_LOCAL :  IF_DEBUG(linker,fprintf(stderr, "local " )); break;
-            case STB_GLOBAL:  IF_DEBUG(linker,fprintf(stderr, "global" )); break;
-            case STB_WEAK  :  IF_DEBUG(linker,fprintf(stderr, "weak  " )); break;
-            default:          IF_DEBUG(linker,fprintf(stderr, "?     " )); break;
+            case STB_LOCAL :  IF_DEBUG(linker,debugBelch("local " )); break;
+            case STB_GLOBAL:  IF_DEBUG(linker,debugBelch("global" )); break;
+            case STB_WEAK  :  IF_DEBUG(linker,debugBelch("weak  " )); break;
+            default:          IF_DEBUG(linker,debugBelch("?     " )); break;
          }
          }
-         IF_DEBUG(linker,fprintf(stderr, "  " ));
+         IF_DEBUG(linker,debugBelch("  " ));
 
 
-         IF_DEBUG(linker,fprintf(stderr, "name=%s\n", strtab + stab[j].st_name ));
+         IF_DEBUG(linker,debugBelch("name=%s\n", strtab + stab[j].st_name ));
       }
    }
 
    if (nsymtabs == 0) {
       }
    }
 
    if (nsymtabs == 0) {
-      belch("%s: didn't find any symbol tables", oc->fileName);
+      errorBelch("%s: didn't find any symbol tables", oc->fileName);
       return 0;
    }
 
       return 0;
    }
 
@@ -2447,7 +2485,7 @@ ocGetNames_ELF ( ObjectCode* oc )
    ASSERT(symhash != NULL);
 
    if (!strtab) {
    ASSERT(symhash != NULL);
 
    if (!strtab) {
-      belch("%s: no strtab", oc->fileName);
+      errorBelch("%s: no strtab", oc->fileName);
       return 0;
    }
 
       return 0;
    }
 
@@ -2493,7 +2531,7 @@ ocGetNames_ELF ( ObjectCode* oc )
                                        "ocGetNames_ELF(BSS)");
          shdr[i].sh_offset = ((char*)zspace) - ((char*)ehdrC);
         /*
                                        "ocGetNames_ELF(BSS)");
          shdr[i].sh_offset = ((char*)zspace) - ((char*)ehdrC);
         /*
-         fprintf(stderr, "BSS section at 0x%x, size %d\n",
+         debugBelch("BSS section at 0x%x, size %d\n",
                          zspace, shdr[i].sh_size);
         */
       }
                          zspace, shdr[i].sh_size);
         */
       }
@@ -2529,7 +2567,7 @@ ocGetNames_ELF ( ObjectCode* oc )
             isLocal = FALSE;
             ad = stgCallocBytes(1, stab[j].st_size, "ocGetNames_ELF(COMMON)");
            /*
             isLocal = FALSE;
             ad = stgCallocBytes(1, stab[j].st_size, "ocGetNames_ELF(COMMON)");
            /*
-            fprintf(stderr, "COMMON symbol, size %d name %s\n",
+            debugBelch("COMMON symbol, size %d name %s\n",
                             stab[j].st_size, nm);
            */
            /* Pointless to do addProddableBlock() for this area,
                             stab[j].st_size, nm);
            */
            /* Pointless to do addProddableBlock() for this area,
@@ -2554,7 +2592,7 @@ ocGetNames_ELF ( ObjectCode* oc )
             ASSERT(secno > 0 && secno < ehdr->e_shnum);
            /*
             if (shdr[secno].sh_type == SHT_NOBITS) {
             ASSERT(secno > 0 && secno < ehdr->e_shnum);
            /*
             if (shdr[secno].sh_type == SHT_NOBITS) {
-               fprintf(stderr, "   BSS symbol, size %d off %d name %s\n",
+               debugBelch("   BSS symbol, size %d off %d name %s\n",
                                stab[j].st_size, stab[j].st_value, nm);
             }
             */
                                stab[j].st_size, stab[j].st_value, nm);
             }
             */
@@ -2569,7 +2607,7 @@ ocGetNames_ELF ( ObjectCode* oc )
                if (ELF_ST_TYPE(stab[j].st_info) == STT_FUNC)
                    ad = (char *)allocateFunctionDesc((Elf_Addr)ad);
 #endif
                if (ELF_ST_TYPE(stab[j].st_info) == STT_FUNC)
                    ad = (char *)allocateFunctionDesc((Elf_Addr)ad);
 #endif
-               IF_DEBUG(linker,belch( "addOTabName(GLOB): %10p  %s %s",
+               IF_DEBUG(linker,debugBelch( "addOTabName(GLOB): %10p  %s %s",
                                       ad, oc->fileName, nm ));
                isLocal = FALSE;
             }
                                       ad, oc->fileName, nm ));
                isLocal = FALSE;
             }
@@ -2588,10 +2626,10 @@ ocGetNames_ELF ( ObjectCode* oc )
             }
          } else {
             /* Skip. */
             }
          } else {
             /* Skip. */
-            IF_DEBUG(linker,belch( "skipping `%s'",
+            IF_DEBUG(linker,debugBelch( "skipping `%s'",
                                    strtab + stab[j].st_name ));
             /*
                                    strtab + stab[j].st_name ));
             /*
-            fprintf(stderr,
+            debugBelch(
                     "skipping   bind = %d,  type = %d,  shndx = %d   `%s'\n",
                     (int)ELF_ST_BIND(stab[j].st_info),
                     (int)ELF_ST_TYPE(stab[j].st_info),
                     "skipping   bind = %d,  type = %d,  shndx = %d   `%s'\n",
                     (int)ELF_ST_BIND(stab[j].st_info),
                     (int)ELF_ST_TYPE(stab[j].st_info),
@@ -2625,7 +2663,7 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC,
 
    stab  = (Elf_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
    targ  = (Elf_Word*)(ehdrC + shdr[ target_shndx ].sh_offset);
 
    stab  = (Elf_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
    targ  = (Elf_Word*)(ehdrC + shdr[ target_shndx ].sh_offset);
-   IF_DEBUG(linker,belch( "relocations for section %d using symtab %d",
+   IF_DEBUG(linker,debugBelch( "relocations for section %d using symtab %d",
                           target_shndx, symtab_shndx ));
 
    for (j = 0; j < nent; j++) {
                           target_shndx, symtab_shndx ));
 
    for (j = 0; j < nent; j++) {
@@ -2636,12 +2674,13 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC,
       Elf_Word* pP = (Elf_Word*)P;
       Elf_Addr  A  = *pP;
       Elf_Addr  S;
       Elf_Word* pP = (Elf_Word*)P;
       Elf_Addr  A  = *pP;
       Elf_Addr  S;
+      void*     S_tmp;
       Elf_Addr  value;
 
       Elf_Addr  value;
 
-      IF_DEBUG(linker,belch( "Rel entry %3d is raw(%6p %6p)",
+      IF_DEBUG(linker,debugBelch( "Rel entry %3d is raw(%6p %6p)",
                              j, (void*)offset, (void*)info ));
       if (!info) {
                              j, (void*)offset, (void*)info ));
       if (!info) {
-         IF_DEBUG(linker,belch( " ZERO" ));
+         IF_DEBUG(linker,debugBelch( " ZERO" ));
          S = 0;
       } else {
          Elf_Sym sym = stab[ELF_R_SYM(info)];
          S = 0;
       } else {
          Elf_Sym sym = stab[ELF_R_SYM(info)];
@@ -2657,16 +2696,17 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC,
         } else {
             /* No, so look up the name in our global table. */
             symbol = strtab + sym.st_name;
         } else {
             /* No, so look up the name in our global table. */
             symbol = strtab + sym.st_name;
-            (void*)S = lookupSymbol( symbol );
+            S_tmp = lookupSymbol( symbol );
+            S = (Elf_Addr)S_tmp;
         }
          if (!S) {
         }
          if (!S) {
-            belch("%s: unknown symbol `%s'", oc->fileName, symbol);
+            errorBelch("%s: unknown symbol `%s'", oc->fileName, symbol);
            return 0;
          }
            return 0;
          }
-         IF_DEBUG(linker,belch( "`%s' resolves to %p", symbol, (void*)S ));
+         IF_DEBUG(linker,debugBelch( "`%s' resolves to %p", symbol, (void*)S ));
       }
 
       }
 
-      IF_DEBUG(linker,belch( "Reloc: P = %p   S = %p   A = %p",
+      IF_DEBUG(linker,debugBelch( "Reloc: P = %p   S = %p   A = %p",
                             (void*)P, (void*)S, (void*)A ));
       checkProddableBlock ( oc, pP );
 
                             (void*)P, (void*)S, (void*)A ));
       checkProddableBlock ( oc, pP );
 
@@ -2678,7 +2718,7 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC,
          case R_386_PC32: *pP = value - P; break;
 #        endif
          default:
          case R_386_PC32: *pP = value - P; break;
 #        endif
          default:
-            belch("%s: unhandled ELF relocation(Rel) type %d\n",
+            errorBelch("%s: unhandled ELF relocation(Rel) type %d\n",
                  oc->fileName, ELF_R_TYPE(info));
             return 0;
       }
                  oc->fileName, ELF_R_TYPE(info));
             return 0;
       }
@@ -2704,7 +2744,7 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
 
    stab  = (Elf_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
    targ  = (Elf_Addr) (ehdrC + shdr[ target_shndx ].sh_offset);
 
    stab  = (Elf_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
    targ  = (Elf_Addr) (ehdrC + shdr[ target_shndx ].sh_offset);
-   IF_DEBUG(linker,belch( "relocations for section %d using symtab %d",
+   IF_DEBUG(linker,debugBelch( "relocations for section %d using symtab %d",
                           target_shndx, symtab_shndx ));
 
    for (j = 0; j < nent; j++) {
                           target_shndx, symtab_shndx ));
 
    for (j = 0; j < nent; j++) {
@@ -2716,6 +2756,7 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
       Elf_Addr  info   = rtab[j].r_info;
       Elf_Addr  A      = rtab[j].r_addend;
       Elf_Addr  S;
       Elf_Addr  info   = rtab[j].r_info;
       Elf_Addr  A      = rtab[j].r_addend;
       Elf_Addr  S;
+      void*     S_tmp;
       Elf_Addr  value;
 #     if defined(sparc_TARGET_ARCH)
       Elf_Word* pP = (Elf_Word*)P;
       Elf_Addr  value;
 #     if defined(sparc_TARGET_ARCH)
       Elf_Word* pP = (Elf_Word*)P;
@@ -2725,11 +2766,11 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
       Elf_Addr addr;
 #     endif
 
       Elf_Addr addr;
 #     endif
 
-      IF_DEBUG(linker,belch( "Rel entry %3d is raw(%6p %6p %6p)   ",
+      IF_DEBUG(linker,debugBelch( "Rel entry %3d is raw(%6p %6p %6p)   ",
                              j, (void*)offset, (void*)info,
                                 (void*)A ));
       if (!info) {
                              j, (void*)offset, (void*)info,
                                 (void*)A ));
       if (!info) {
-         IF_DEBUG(linker,belch( " ZERO" ));
+         IF_DEBUG(linker,debugBelch( " ZERO" ));
          S = 0;
       } else {
          Elf_Sym sym = stab[ELF_R_SYM(info)];
          S = 0;
       } else {
          Elf_Sym sym = stab[ELF_R_SYM(info)];
@@ -2751,23 +2792,24 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
         } else {
             /* No, so look up the name in our global table. */
             symbol = strtab + sym.st_name;
         } else {
             /* No, so look up the name in our global table. */
             symbol = strtab + sym.st_name;
-            (void*)S = lookupSymbol( symbol );
+            S_tmp = lookupSymbol( symbol );
+            S = (Elf_Addr)S_tmp;
 
 #ifdef ELF_FUNCTION_DESC
            /* If a function, already a function descriptor - we would
               have to copy it to add an offset. */
             if (S && (ELF_ST_TYPE(sym.st_info) == STT_FUNC) && (A != 0))
 
 #ifdef ELF_FUNCTION_DESC
            /* If a function, already a function descriptor - we would
               have to copy it to add an offset. */
             if (S && (ELF_ST_TYPE(sym.st_info) == STT_FUNC) && (A != 0))
-               belch("%s: function %s with addend %p", oc->fileName, symbol, (void *)A);
+               errorBelch("%s: function %s with addend %p", oc->fileName, symbol, (void *)A);
 #endif
         }
          if (!S) {
 #endif
         }
          if (!S) {
-          belch("%s: unknown symbol `%s'", oc->fileName, symbol);
+          errorBelch("%s: unknown symbol `%s'", oc->fileName, symbol);
           return 0;
          }
           return 0;
          }
-         IF_DEBUG(linker,belch( "`%s' resolves to %p", symbol, (void*)S ));
+         IF_DEBUG(linker,debugBelch( "`%s' resolves to %p", symbol, (void*)S ));
       }
 
       }
 
-      IF_DEBUG(linker,fprintf ( stderr, "Reloc: P = %p   S = %p   A = %p\n",
+      IF_DEBUG(linker,debugBelch("Reloc: P = %p   S = %p   A = %p\n",
                                         (void*)P, (void*)S, (void*)A ));
       /* checkProddableBlock ( oc, (void*)P ); */
 
                                         (void*)P, (void*)S, (void*)A ));
       /* checkProddableBlock ( oc, (void*)P ); */
 
@@ -2841,7 +2883,7 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
            break;
 #        endif
          default:
            break;
 #        endif
          default:
-            belch("%s: unhandled ELF relocation(RelA) type %d\n",
+            errorBelch("%s: unhandled ELF relocation(RelA) type %d\n",
                  oc->fileName, ELF_R_TYPE(info));
             return 0;
       }
                  oc->fileName, ELF_R_TYPE(info));
             return 0;
       }
@@ -2868,7 +2910,7 @@ ocResolve_ELF ( ObjectCode* oc )
    strtab = findElfSection ( ehdrC, SHT_STRTAB );
 
    if (stab == NULL || strtab == NULL) {
    strtab = findElfSection ( ehdrC, SHT_STRTAB );
 
    if (stab == NULL || strtab == NULL) {
-      belch("%s: can't find string or symbol table", oc->fileName);
+      errorBelch("%s: can't find string or symbol table", oc->fileName);
       return 0;
    }
 
       return 0;
    }
 
@@ -3005,7 +3047,7 @@ ia64_reloc_pcrel21(Elf_Addr target, Elf_Addr value, ObjectCode *oc)
 /*
   Support for MachO linking on Darwin/MacOS X on PowerPC chips
   by Wolfgang Thaller (wolfgang.thaller@gmx.net)
 /*
   Support for MachO linking on Darwin/MacOS X on PowerPC chips
   by Wolfgang Thaller (wolfgang.thaller@gmx.net)
-  
+
   I hereby formally apologize for the hackish nature of this code.
   Things that need to be done:
   *) implement ocVerifyImage_MachO
   I hereby formally apologize for the hackish nature of this code.
   Things that need to be done:
   *) implement ocVerifyImage_MachO
@@ -3015,10 +3057,10 @@ ia64_reloc_pcrel21(Elf_Addr target, Elf_Addr value, ObjectCode *oc)
 
 /*
   ocAllocateJumpIslands_MachO
 
 /*
   ocAllocateJumpIslands_MachO
-  
+
   Allocate additional space at the end of the object file image to make room
   for jump islands.
   Allocate additional space at the end of the object file image to make room
   for jump islands.
-  
+
   PowerPC relative branch instructions have a 24 bit displacement field.
   As PPC code is always 4-byte-aligned, this yields a +-32MB range.
   If a particular imported symbol is outside this range, we have to redirect
   PowerPC relative branch instructions have a 24 bit displacement field.
   As PPC code is always 4-byte-aligned, this yields a +-32MB range.
   If a particular imported symbol is outside this range, we have to redirect
@@ -3046,7 +3088,7 @@ static int ocAllocateJumpIslands_MachO(ObjectCode* oc)
             unsigned long nundefsym = dsymLC->nundefsym;
             oc->island_start_symbol = dsymLC->iundefsym;
             oc->n_islands = nundefsym;
             unsigned long nundefsym = dsymLC->nundefsym;
             oc->island_start_symbol = dsymLC->iundefsym;
             oc->n_islands = nundefsym;
-            
+
             if(nundefsym > 0)
             {
 #ifdef USE_MMAP
             if(nundefsym > 0)
             {
 #ifdef USE_MMAP
@@ -3055,11 +3097,11 @@ static int ocAllocateJumpIslands_MachO(ObjectCode* oc)
                 oc->image = stgReallocBytes(
                     image, oc->fileSize + islandSize * nundefsym,
                     "ocAllocateJumpIslands_MachO");
                 oc->image = stgReallocBytes(
                     image, oc->fileSize + islandSize * nundefsym,
                     "ocAllocateJumpIslands_MachO");
-#endif                    
+#endif
                 oc->jump_islands = oc->image + oc->fileSize;
                 memset(oc->jump_islands, 0, islandSize * nundefsym);
             }
                 oc->jump_islands = oc->image + oc->fileSize;
                 memset(oc->jump_islands, 0, islandSize * nundefsym);
             }
-            
+
             break;  // there can be only one LC_DSYMTAB
         }
        lc = (struct load_command *) ( ((char*)lc) + lc->cmdsize );
             break;  // there can be only one LC_DSYMTAB
         }
        lc = (struct load_command *) ( ((char*)lc) + lc->cmdsize );
@@ -3082,14 +3124,14 @@ static int resolveImports(
     struct nlist *nlist)
 {
     unsigned i;
     struct nlist *nlist)
 {
     unsigned i;
-    
+
     for(i=0;i*4<sect->size;i++)
     {
        // according to otool, reserved1 contains the first index into the indirect symbol table
        struct nlist *symbol = &nlist[indirectSyms[sect->reserved1+i]];
        char *nm = image + symLC->stroff + symbol->n_un.n_strx;
        void *addr = NULL;
     for(i=0;i*4<sect->size;i++)
     {
        // according to otool, reserved1 contains the first index into the indirect symbol table
        struct nlist *symbol = &nlist[indirectSyms[sect->reserved1+i]];
        char *nm = image + symLC->stroff + symbol->n_un.n_strx;
        void *addr = NULL;
-       
+
        if((symbol->n_type & N_TYPE) == N_UNDF
            && (symbol->n_type & N_EXT) && (symbol->n_value != 0))
            addr = (void*) (symbol->n_value);
        if((symbol->n_type & N_TYPE) == N_UNDF
            && (symbol->n_type & N_EXT) && (symbol->n_value != 0))
            addr = (void*) (symbol->n_value);
@@ -3099,14 +3141,14 @@ static int resolveImports(
            addr = lookupSymbol(nm);
        if(!addr)
        {
            addr = lookupSymbol(nm);
        if(!addr)
        {
-           belch("\n%s: unknown symbol `%s'", oc->fileName, nm);
+           errorBelch("\n%s: unknown symbol `%s'", oc->fileName, nm);
            return 0;
        }
        ASSERT(addr);
        checkProddableBlock(oc,((void**)(image + sect->offset)) + i);
        ((void**)(image + sect->offset))[i] = addr;
     }
            return 0;
        }
        ASSERT(addr);
        checkProddableBlock(oc,((void**)(image + sect->offset)) + i);
        ((void**)(image + sect->offset))[i] = addr;
     }
-    
+
     return 1;
 }
 
     return 1;
 }
 
@@ -3119,19 +3161,19 @@ static void* makeJumpIsland(
         symbolNumber - oc->island_start_symbol > oc->n_islands)
         return NULL;
     symbolNumber -= oc->island_start_symbol;
         symbolNumber - oc->island_start_symbol > oc->n_islands)
         return NULL;
     symbolNumber -= oc->island_start_symbol;
-    
+
     void *island = (void*) ((char*)oc->jump_islands + islandSize * symbolNumber);
     unsigned long *p = (unsigned long*) island;
     void *island = (void*) ((char*)oc->jump_islands + islandSize * symbolNumber);
     unsigned long *p = (unsigned long*) island;
-    
+
         // lis r12, hi16(target)
     *p++ = 0x3d800000 | ( ((unsigned long) target) >> 16 );
         // ori r12, r12, lo16(target)
         // lis r12, hi16(target)
     *p++ = 0x3d800000 | ( ((unsigned long) target) >> 16 );
         // ori r12, r12, lo16(target)
-    *p++ = 0x618c0000 | ( ((unsigned long) target) & 0xFFFF ); 
+    *p++ = 0x618c0000 | ( ((unsigned long) target) & 0xFFFF );
         // mtctr r12
     *p++ = 0x7d8903a6;
         // bctr
     *p++ = 0x4e800420;
         // mtctr r12
     *p++ = 0x7d8903a6;
         // bctr
     *p++ = 0x4e800420;
-    
+
     return (void*) island;
 }
 
     return (void*) island;
 }
 
@@ -3140,7 +3182,7 @@ static char* relocateAddress(
     int nSections,
     struct section* sections,
     unsigned long address)
     int nSections,
     struct section* sections,
     unsigned long address)
-{  
+{
     int i;
     for(i = 0; i < nSections; i++)
     {
     int i;
     for(i = 0; i < nSections; i++)
     {
@@ -3157,13 +3199,13 @@ static char* relocateAddress(
 
 static int relocateSection(
     ObjectCode* oc,
 
 static int relocateSection(
     ObjectCode* oc,
-    char *image, 
+    char *image,
     struct symtab_command *symLC, struct nlist *nlist,
     int nSections, struct section* sections, struct section *sect)
 {
     struct relocation_info *relocs;
     int i,n;
     struct symtab_command *symLC, struct nlist *nlist,
     int nSections, struct section* sections, struct section *sect)
 {
     struct relocation_info *relocs;
     int i,n;
-    
+
     if(!strcmp(sect->sectname,"__la_symbol_ptr"))
        return 1;
     else if(!strcmp(sect->sectname,"__nl_symbol_ptr"))
     if(!strcmp(sect->sectname,"__la_symbol_ptr"))
        return 1;
     else if(!strcmp(sect->sectname,"__nl_symbol_ptr"))
@@ -3171,14 +3213,14 @@ static int relocateSection(
 
     n = sect->nreloc;
     relocs = (struct relocation_info*) (image + sect->reloff);
 
     n = sect->nreloc;
     relocs = (struct relocation_info*) (image + sect->reloff);
-    
+
     for(i=0;i<n;i++)
     {
        if(relocs[i].r_address & R_SCATTERED)
        {
            struct scattered_relocation_info *scat =
                (struct scattered_relocation_info*) &relocs[i];
     for(i=0;i<n;i++)
     {
        if(relocs[i].r_address & R_SCATTERED)
        {
            struct scattered_relocation_info *scat =
                (struct scattered_relocation_info*) &relocs[i];
-           
+
            if(!scat->r_pcrel)
            {
                if(scat->r_length == 2)
            if(!scat->r_pcrel)
            {
                if(scat->r_length == 2)
@@ -3186,7 +3228,7 @@ static int relocateSection(
                    unsigned long word = 0;
                    unsigned long* wordPtr = (unsigned long*) (image + sect->offset + scat->r_address);
                    checkProddableBlock(oc,wordPtr);
                    unsigned long word = 0;
                    unsigned long* wordPtr = (unsigned long*) (image + sect->offset + scat->r_address);
                    checkProddableBlock(oc,wordPtr);
-                   
+
                    // Step 1: Figure out what the relocated value should be
                    if(scat->r_type == GENERIC_RELOC_VANILLA)
                    {
                    // Step 1: Figure out what the relocated value should be
                    if(scat->r_type == GENERIC_RELOC_VANILLA)
                    {
@@ -3199,17 +3241,55 @@ static int relocateSection(
                    {
                        struct scattered_relocation_info *pair =
                                (struct scattered_relocation_info*) &relocs[i+1];
                    {
                        struct scattered_relocation_info *pair =
                                (struct scattered_relocation_info*) &relocs[i+1];
-                               
+
                        if(!pair->r_scattered || pair->r_type != PPC_RELOC_PAIR)
                            barf("Invalid Mach-O file: "
                                 "PPC_RELOC_*_SECTDIFF not followed by PPC_RELOC_PAIR");
                        if(!pair->r_scattered || pair->r_type != PPC_RELOC_PAIR)
                            barf("Invalid Mach-O file: "
                                 "PPC_RELOC_*_SECTDIFF not followed by PPC_RELOC_PAIR");
-                       
+
                        word = (unsigned long)
                               (relocateAddress(oc, nSections, sections, scat->r_value)
                              - relocateAddress(oc, nSections, sections, pair->r_value));
                        i++;
                    }
                        word = (unsigned long)
                               (relocateAddress(oc, nSections, sections, scat->r_value)
                              - relocateAddress(oc, nSections, sections, pair->r_value));
                        i++;
                    }
-                   else
+                   else if(scat->r_type == PPC_RELOC_HI16
+                         || scat->r_type == PPC_RELOC_LO16
+                         || scat->r_type == PPC_RELOC_HA16
+                         || 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)
+                           barf("Invalid Mach-O file: "
+                                "PPC_RELOC_* not followed by PPC_RELOC_PAIR");
+                        
+                        if(scat->r_type == PPC_RELOC_LO16)
+                        {
+                            word = ((unsigned short*) wordPtr)[1];
+                            word |= ((unsigned long) relocs[i+1].r_address & 0xFFFF) << 16;
+                        }
+                        else if(scat->r_type == PPC_RELOC_LO14)
+                        {
+                            barf("Unsupported Relocation: PPC_RELOC_LO14");
+                            word = ((unsigned short*) wordPtr)[1] & 0xFFFC;
+                            word |= ((unsigned long) relocs[i+1].r_address & 0xFFFF) << 16;
+                        }
+                        else if(scat->r_type == PPC_RELOC_HI16)
+                        {
+                            word = ((unsigned short*) wordPtr)[1] << 16;
+                            word |= ((unsigned long) relocs[i+1].r_address & 0xFFFF);
+                        }
+                        else if(scat->r_type == PPC_RELOC_HA16)
+                        {
+                            word = ((unsigned short*) wordPtr)[1] << 16;
+                            word += ((short)relocs[i+1].r_address & (short)0xFFFF);
+                        }
+                       
+                        
+                        word += (unsigned long) relocateAddress(oc, nSections, sections, scat->r_value)
+                                                - scat->r_value;
+                        
+                        i++;
+                    }
+                    else
                        continue;  // ignore the others
 
                     if(scat->r_type == GENERIC_RELOC_VANILLA
                        continue;  // ignore the others
 
                     if(scat->r_type == GENERIC_RELOC_VANILLA
@@ -3217,22 +3297,22 @@ static int relocateSection(
                     {
                         *wordPtr = word;
                     }
                     {
                         *wordPtr = word;
                     }
-                    else if(scat->r_type == PPC_RELOC_LO16_SECTDIFF)
+                    else if(scat->r_type == PPC_RELOC_LO16_SECTDIFF || scat->r_type == PPC_RELOC_LO16)
                     {
                         ((unsigned short*) wordPtr)[1] = word & 0xFFFF;
                     }
                     {
                         ((unsigned short*) wordPtr)[1] = word & 0xFFFF;
                     }
-                    else if(scat->r_type == PPC_RELOC_HI16_SECTDIFF)
+                    else if(scat->r_type == PPC_RELOC_HI16_SECTDIFF || scat->r_type == PPC_RELOC_HI16)
                     {
                         ((unsigned short*) wordPtr)[1] = (word >> 16) & 0xFFFF;
                     }
                     {
                         ((unsigned short*) wordPtr)[1] = (word >> 16) & 0xFFFF;
                     }
-                    else if(scat->r_type == PPC_RELOC_HA16_SECTDIFF)
+                    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);
                     }
                }
            }
                     {
                         ((unsigned short*) wordPtr)[1] = ((word >> 16) & 0xFFFF)
                             + ((word & (1<<15)) ? 1 : 0);
                     }
                }
            }
-           
+
            continue; // FIXME: I hope it's OK to ignore all the others.
        }
        else
            continue; // FIXME: I hope it's OK to ignore all the others.
        }
        else
@@ -3240,16 +3320,16 @@ static int relocateSection(
            struct relocation_info *reloc = &relocs[i];
            if(reloc->r_pcrel && !reloc->r_extern)
                continue;
            struct relocation_info *reloc = &relocs[i];
            if(reloc->r_pcrel && !reloc->r_extern)
                continue;
-               
+
            if(reloc->r_length == 2)
            {
                unsigned long word = 0;
                 unsigned long jumpIsland = 0;
                 long offsetToJumpIsland;
            if(reloc->r_length == 2)
            {
                unsigned long word = 0;
                 unsigned long jumpIsland = 0;
                 long offsetToJumpIsland;
-                
+
                unsigned long* wordPtr = (unsigned long*) (image + sect->offset + reloc->r_address);
                checkProddableBlock(oc,wordPtr);
                unsigned long* wordPtr = (unsigned long*) (image + sect->offset + reloc->r_address);
                checkProddableBlock(oc,wordPtr);
-               
+
                if(reloc->r_type == GENERIC_RELOC_VANILLA)
                {
                    word = *wordPtr;
                if(reloc->r_type == GENERIC_RELOC_VANILLA)
                {
                    word = *wordPtr;
@@ -3278,26 +3358,28 @@ static int relocateSection(
 
                if(!reloc->r_extern)
                {
 
                if(!reloc->r_extern)
                {
-                   long delta = 
+                   long delta =
                        sections[reloc->r_symbolnum-1].offset
                        - sections[reloc->r_symbolnum-1].addr
                        + ((long) image);
                        sections[reloc->r_symbolnum-1].offset
                        - sections[reloc->r_symbolnum-1].addr
                        + ((long) image);
-                   
+
                    word += delta;
                }
                else
                {
                    struct nlist *symbol = &nlist[reloc->r_symbolnum];
                    char *nm = image + symLC->stroff + symbol->n_un.n_strx;
                    word += delta;
                }
                else
                {
                    struct nlist *symbol = &nlist[reloc->r_symbolnum];
                    char *nm = image + symLC->stroff + symbol->n_un.n_strx;
-                   word = (unsigned long) (lookupSymbol(nm));
-                   if(!word)
+                   unsigned long symbolAddress = (unsigned long) (lookupSymbol(nm));
+                   if(!symbolAddress)
                    {
                    {
-                       belch("\nunknown symbol `%s'", nm);
+                       errorBelch("\nunknown symbol `%s'", nm);
                        return 0;
                    }
                        return 0;
                    }
-                   
+
                    if(reloc->r_pcrel)
                    if(reloc->r_pcrel)
-                    {
+                    {  
+                        ASSERT(word == 0);
+                        word = symbolAddress;
                         jumpIsland = (long) makeJumpIsland(oc,reloc->r_symbolnum,(void*)word);
                        word -= ((long)image) + sect->offset + reloc->r_address;
                         if(jumpIsland != 0)
                         jumpIsland = (long) makeJumpIsland(oc,reloc->r_symbolnum,(void*)word);
                        word -= ((long)image) + sect->offset + reloc->r_address;
                         if(jumpIsland != 0)
@@ -3306,8 +3388,12 @@ static int relocateSection(
                                 - (((long)image) + sect->offset + reloc->r_address);
                         }
                     }
                                 - (((long)image) + sect->offset + reloc->r_address);
                         }
                     }
+                    else
+                    {
+                        word += symbolAddress;
+                    }
                }
                }
-               
+
                if(reloc->r_type == GENERIC_RELOC_VANILLA)
                {
                    *wordPtr = word;
                if(reloc->r_type == GENERIC_RELOC_VANILLA)
                {
                    *wordPtr = word;
@@ -3338,7 +3424,7 @@ static int relocateSection(
                         if(jumpIsland == 0)
                             barf("unconditional relative branch out of range: "
                                  "no jump island available");
                         if(jumpIsland == 0)
                             barf("unconditional relative branch out of range: "
                                  "no jump island available");
-                            
+
                         word = offsetToJumpIsland;
                         if((long)word > (long)0x01FFFFFF || (long)word < (long)0xFFE00000)
                             barf("unconditional relative branch out of range: "
                         word = offsetToJumpIsland;
                         if((long)word > (long)0x01FFFFFF || (long)word < (long)0xFFE00000)
                             barf("unconditional relative branch out of range: "
@@ -3381,36 +3467,36 @@ static int ocGetNames_MachO(ObjectCode* oc)
        lc = (struct load_command *) ( ((char*)lc) + lc->cmdsize );
     }
 
        lc = (struct load_command *) ( ((char*)lc) + lc->cmdsize );
     }
 
-    sections = (struct section*) (segLC+1); 
+    sections = (struct section*) (segLC+1);
     nlist = (struct nlist*) (image + symLC->symoff);
 
     for(i=0;i<segLC->nsects;i++)
     {
         if(sections[i].size == 0)
             continue;
     nlist = (struct nlist*) (image + symLC->symoff);
 
     for(i=0;i<segLC->nsects;i++)
     {
         if(sections[i].size == 0)
             continue;
-        
+
         if((sections[i].flags & SECTION_TYPE) == S_ZEROFILL)
         {
             char * zeroFillArea = stgCallocBytes(1,sections[i].size,
                                       "ocGetNames_MachO(common symbols)");
             sections[i].offset = zeroFillArea - image;
         }
         if((sections[i].flags & SECTION_TYPE) == S_ZEROFILL)
         {
             char * zeroFillArea = stgCallocBytes(1,sections[i].size,
                                       "ocGetNames_MachO(common symbols)");
             sections[i].offset = zeroFillArea - image;
         }
-    
+
        if(!strcmp(sections[i].sectname,"__text"))
        if(!strcmp(sections[i].sectname,"__text"))
-           addSection(oc, SECTIONKIND_CODE_OR_RODATA, 
+           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"))
                (void*) (image + sections[i].offset),
                (void*) (image + sections[i].offset + sections[i].size));
        else if(!strcmp(sections[i].sectname,"__const"))
-           addSection(oc, SECTIONKIND_RWDATA, 
+           addSection(oc, SECTIONKIND_RWDATA,
                (void*) (image + sections[i].offset),
                (void*) (image + sections[i].offset + sections[i].size));
        else if(!strcmp(sections[i].sectname,"__data"))
                (void*) (image + sections[i].offset),
                (void*) (image + sections[i].offset + sections[i].size));
        else if(!strcmp(sections[i].sectname,"__data"))
-           addSection(oc, SECTIONKIND_RWDATA, 
+           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"))
                (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"))
-           addSection(oc, SECTIONKIND_RWDATA, 
+           addSection(oc, SECTIONKIND_RWDATA,
                (void*) (image + sections[i].offset),
                (void*) (image + sections[i].offset + sections[i].size));
 
                (void*) (image + sections[i].offset),
                (void*) (image + sections[i].offset + sections[i].size));
 
@@ -3436,35 +3522,35 @@ static int ocGetNames_MachO(ObjectCode* oc)
     }
     oc->symbols = stgMallocBytes(oc->n_symbols * sizeof(char*),
                                   "ocGetNames_MachO(oc->symbols)");
     }
     oc->symbols = stgMallocBytes(oc->n_symbols * sizeof(char*),
                                   "ocGetNames_MachO(oc->symbols)");
-    
+
        // insert symbols into hash table
     for(i=dsymLC->iextdefsym,curSymbol=0;i<dsymLC->iextdefsym+dsymLC->nextdefsym;i++)
     {
        if((nlist[i].n_type & N_TYPE) == N_SECT)
        {
            char *nm = image + symLC->stroff + nlist[i].n_un.n_strx;
        // insert symbols into hash table
     for(i=dsymLC->iextdefsym,curSymbol=0;i<dsymLC->iextdefsym+dsymLC->nextdefsym;i++)
     {
        if((nlist[i].n_type & N_TYPE) == N_SECT)
        {
            char *nm = image + symLC->stroff + nlist[i].n_un.n_strx;
-           ghciInsertStrHashTable(oc->fileName, symhash, nm, image + 
+           ghciInsertStrHashTable(oc->fileName, symhash, nm, image +
                sections[nlist[i].n_sect-1].offset
                - sections[nlist[i].n_sect-1].addr
                + nlist[i].n_value);
            oc->symbols[curSymbol++] = nm;
        }
     }
                sections[nlist[i].n_sect-1].offset
                - sections[nlist[i].n_sect-1].addr
                + nlist[i].n_value);
            oc->symbols[curSymbol++] = nm;
        }
     }
-    
+
        // insert local symbols into lochash
     for(i=dsymLC->ilocalsym;i<dsymLC->ilocalsym+dsymLC->nlocalsym;i++)
     {
        if((nlist[i].n_type & N_TYPE) == N_SECT)
        {
            char *nm = image + symLC->stroff + nlist[i].n_un.n_strx;
        // insert local symbols into lochash
     for(i=dsymLC->ilocalsym;i<dsymLC->ilocalsym+dsymLC->nlocalsym;i++)
     {
        if((nlist[i].n_type & N_TYPE) == N_SECT)
        {
            char *nm = image + symLC->stroff + nlist[i].n_un.n_strx;
-           ghciInsertStrHashTable(oc->fileName, oc->lochash, nm, image + 
+           ghciInsertStrHashTable(oc->fileName, oc->lochash, nm, image +
                sections[nlist[i].n_sect-1].offset
                - sections[nlist[i].n_sect-1].addr
                + nlist[i].n_value);
        }
     }
 
                sections[nlist[i].n_sect-1].offset
                - sections[nlist[i].n_sect-1].addr
                + nlist[i].n_value);
        }
     }
 
-    
+
     commonStorage = stgCallocBytes(1,commonSize,"ocGetNames_MachO(common symbols)");
     commonCounter = (unsigned long)commonStorage;
     for(i=0;i<symLC->nsyms;i++)
     commonStorage = stgCallocBytes(1,commonSize,"ocGetNames_MachO(common symbols)");
     commonCounter = (unsigned long)commonStorage;
     for(i=0;i<symLC->nsyms;i++)
@@ -3474,12 +3560,12 @@ static int ocGetNames_MachO(ObjectCode* oc)
        {
            char *nm = image + symLC->stroff + nlist[i].n_un.n_strx;
            unsigned long sz = nlist[i].n_value;
        {
            char *nm = image + symLC->stroff + nlist[i].n_un.n_strx;
            unsigned long sz = nlist[i].n_value;
-           
+
            nlist[i].n_value = commonCounter;
            nlist[i].n_value = commonCounter;
-           
+
            ghciInsertStrHashTable(oc->fileName, symhash, nm, (void*)commonCounter);
            oc->symbols[curSymbol++] = nm;
            ghciInsertStrHashTable(oc->fileName, symhash, nm, (void*)commonCounter);
            oc->symbols[curSymbol++] = nm;
-           
+
            commonCounter += sz;
        }
     }
            commonCounter += sz;
        }
     }
@@ -3509,8 +3595,8 @@ static int ocResolve_MachO(ObjectCode* oc)
            dsymLC = (struct dysymtab_command*) lc;
        lc = (struct load_command *) ( ((char*)lc) + lc->cmdsize );
     }
            dsymLC = (struct dysymtab_command*) lc;
        lc = (struct load_command *) ( ((char*)lc) + lc->cmdsize );
     }
-    
-    sections = (struct section*) (segLC+1); 
+
+    sections = (struct section*) (segLC+1);
     nlist = (struct nlist*) (image + symLC->symoff);
 
     for(i=0;i<segLC->nsects;i++)
     nlist = (struct nlist*) (image + symLC->symoff);
 
     for(i=0;i<segLC->nsects;i++)
@@ -3520,7 +3606,7 @@ static int ocResolve_MachO(ObjectCode* oc)
        else if(!strcmp(sections[i].sectname,"__nl_symbol_ptr"))
            nl_ptrs = &sections[i];
     }
        else if(!strcmp(sections[i].sectname,"__nl_symbol_ptr"))
            nl_ptrs = &sections[i];
     }
-    
+
     indirectSyms = (unsigned long*) (image + dsymLC->indirectsymoff);
 
     if(la_ptrs)
     indirectSyms = (unsigned long*) (image + dsymLC->indirectsymoff);
 
     if(la_ptrs)
@@ -3529,7 +3615,7 @@ static int ocResolve_MachO(ObjectCode* oc)
     if(nl_ptrs)
        if(!resolveImports(oc,image,symLC,nl_ptrs,indirectSyms,nlist))
            return 0;
     if(nl_ptrs)
        if(!resolveImports(oc,image,symLC,nl_ptrs,indirectSyms,nlist))
            return 0;
-    
+
     for(i=0;i<segLC->nsects;i++)
     {
        if(!relocateSection(oc,image,symLC,nlist,segLC->nsects,sections,&sections[i]))
     for(i=0;i<segLC->nsects;i++)
     {
        if(!relocateSection(oc,image,symLC,nlist,segLC->nsects,sections,&sections[i]))
@@ -3539,7 +3625,7 @@ static int ocResolve_MachO(ObjectCode* oc)
     /* Free the local symbol table; we won't need it again. */
     freeHashTable(oc->lochash, NULL);
     oc->lochash = NULL;
     /* Free the local symbol table; we won't need it again. */
     freeHashTable(oc->lochash, NULL);
     oc->lochash = NULL;
-    
+
     /*
         Flush the data & instruction caches.
         Because the PPC has split data/instruction caches, we have to
     /*
         Flush the data & instruction caches.
         Because the PPC has split data/instruction caches, we have to
@@ -3572,11 +3658,11 @@ static void machoInitSymbolsWithoutUnderscore()
 {
     void *p;
 
 {
     void *p;
 
-#undef Sym    
+#undef Sym
 #define Sym(x)                                         \
     __asm__ ("lis %0,hi16(" #x ")\n\tori %0,%0,lo16(" #x ")" : "=r" (p));      \
     ghciInsertStrHashTable("(GHCi built-in symbols)", symhash, #x, p);
 #define Sym(x)                                         \
     __asm__ ("lis %0,hi16(" #x ")\n\tori %0,%0,lo16(" #x ")" : "=r" (p));      \
     ghciInsertStrHashTable("(GHCi built-in symbols)", symhash, #x, p);
-    
+
     RTS_MACHO_NOUNDERLINE_SYMBOLS
 
 }
     RTS_MACHO_NOUNDERLINE_SYMBOLS
 
 }