Make allocatePinned use local storage, and other refactorings
[ghc-hetmet.git] / rts / Linker.c
index 4fcfade..2412864 100644 (file)
 #endif
 
 #include "Rts.h"
-#include "RtsFlags.h"
 #include "HsFFI.h"
+
+#include "sm/Storage.h"
 #include "Hash.h"
-#include "Linker.h"
 #include "LinkerInternals.h"
 #include "RtsUtils.h"
-#include "Schedule.h"
-#include "Sparks.h"
-#include "RtsTypeable.h"
-#include "Timer.h"
 #include "Trace.h"
+#include "StgPrimFloat.h" // for __int_encodeFloat etc.
+#include "Stable.h"
+
+#if !defined(mingw32_HOST_OS)
+#include "posix/Signals.h"
+#endif
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #include <sys/wait.h>
 #endif
 
-#if defined(ia64_HOST_ARCH) || defined(linux_HOST_OS) || defined(freebsd_HOST_OS) || defined(netbsd_HOST_OS) || defined(openbsd_HOST_OS)
+#if defined(ia64_HOST_ARCH) || defined(linux_HOST_OS) || defined(freebsd_HOST_OS) || defined(dragonfly_HOST_OS) || defined(netbsd_HOST_OS) || defined(openbsd_HOST_OS)
 #define USE_MMAP
 #include <fcntl.h>
 #include <sys/mman.h>
 
-#if defined(linux_HOST_OS) || defined(freebsd_HOST_OS) || defined(netbsd_HOST_OS) || defined(openbsd_HOST_OS)
+#if defined(linux_HOST_OS) || defined(freebsd_HOST_OS) || defined(dragonfly_HOST_OS) || defined(netbsd_HOST_OS) || defined(openbsd_HOST_OS)
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
@@ -74,7 +76,7 @@
 
 #endif
 
-#if defined(linux_HOST_OS) || defined(solaris2_HOST_OS) || defined(freebsd_HOST_OS) || defined(netbsd_HOST_OS) || defined(openbsd_HOST_OS)
+#if defined(linux_HOST_OS) || defined(solaris2_HOST_OS) || defined(freebsd_HOST_OS) || defined(dragonfly_HOST_OS) || defined(netbsd_HOST_OS) || defined(openbsd_HOST_OS)
 #  define OBJFORMAT_ELF
 #elif defined(cygwin32_HOST_OS) || defined (mingw32_HOST_OS)
 #  define OBJFORMAT_PEi386
@@ -205,7 +207,7 @@ static void machoInitSymbolsWithoutUnderscore( void );
 #define MMAP_32BIT_BASE_DEFAULT 0x40000000
 #endif
 
-static void *mmap_32bit_base = MMAP_32BIT_BASE_DEFAULT;
+static void *mmap_32bit_base = (void *)MMAP_32BIT_BASE_DEFAULT;
 #endif
 
 /* MAP_ANONYMOUS is MAP_ANON on some systems, e.g. OpenBSD */
@@ -222,20 +224,18 @@ typedef struct _RtsSymbolVal {
     void   *addr;
 } RtsSymbolVal;
 
-#if !defined(PAR)
-#define Maybe_Stable_Names      SymI_HasProto(mkWeakzh_fast)                   \
-                               SymI_HasProto(makeStableNamezh_fast)            \
-                               SymI_HasProto(finalizzeWeakzh_fast)
-#else
-/* These are not available in GUM!!! -- HWL */
-#define Maybe_Stable_Names
-#endif
+#define Maybe_Stable_Names      SymI_HasProto(stg_mkWeakzh)                    \
+                               SymI_HasProto(stg_mkWeakForeignEnvzh)           \
+                               SymI_HasProto(stg_makeStableNamezh)             \
+                               SymI_HasProto(stg_finalizzeWeakzh)
 
 #if !defined (mingw32_HOST_OS)
 #define RTS_POSIX_ONLY_SYMBOLS                  \
+      SymI_HasProto(__hscore_get_saved_termios)        \
+      SymI_HasProto(__hscore_set_saved_termios)        \
       SymI_HasProto(shutdownHaskellAndSignal)  \
-      SymI_NeedsProto(lockFile)                 \
-      SymI_NeedsProto(unlockFile)               \
+      SymI_HasProto(lockFile)                   \
+      SymI_HasProto(unlockFile)                 \
       SymI_HasProto(signal_handlers)           \
       SymI_HasProto(stg_sig_install)           \
       SymI_NeedsProto(nocldstop)
@@ -347,12 +347,18 @@ typedef struct _RtsSymbolVal {
 #define RTS_MINGW_GETTIMEOFDAY_SYM /**/
 #endif
 
+#if HAVE___MINGW_VFPRINTF
+#define RTS___MINGW_VFPRINTF_SYM SymI_HasProto(__mingw_vfprintf)
+#else
+#define RTS___MINGW_VFPRINTF_SYM /**/
+#endif
+
 /* These are statically linked from the mingw libraries into the ghc
    executable, so we have to employ this hack. */
 #define RTS_MINGW_ONLY_SYMBOLS                           \
-      SymI_HasProto(asyncReadzh_fast)                   \
-      SymI_HasProto(asyncWritezh_fast)                  \
-      SymI_HasProto(asyncDoProczh_fast)                         \
+      SymI_HasProto(stg_asyncReadzh)                    \
+      SymI_HasProto(stg_asyncWritezh)                   \
+      SymI_HasProto(stg_asyncDoProczh)                  \
       SymI_HasProto(memset)                              \
       SymI_HasProto(inet_ntoa)                           \
       SymI_HasProto(inet_addr)                           \
@@ -385,6 +391,8 @@ typedef struct _RtsSymbolVal {
       SymI_NeedsProto(iscntrl)                           \
       SymI_NeedsProto(isalpha)                           \
       SymI_NeedsProto(isalnum)                           \
+      SymI_NeedsProto(isascii)                           \
+      RTS___MINGW_VFPRINTF_SYM                           \
       SymI_HasProto(strcmp)                              \
       SymI_HasProto(memmove)                             \
       SymI_HasProto(realloc)                             \
@@ -415,6 +423,10 @@ typedef struct _RtsSymbolVal {
       SymI_HasProto(expf)                                \
       SymI_HasProto(logf)                                \
       SymI_HasProto(sqrtf)                               \
+      SymI_HasProto(erf)                                \
+      SymI_HasProto(erfc)                                \
+      SymI_HasProto(erff)                                \
+      SymI_HasProto(erfcf)                               \
       SymI_HasProto(memcpy)                              \
       SymI_HasProto(rts_InstallConsoleEvent)             \
       SymI_HasProto(rts_ConsoleHandlerDone)              \
@@ -492,9 +504,14 @@ typedef struct _RtsSymbolVal {
 
 #if !defined(mingw32_HOST_OS)
 #define RTS_USER_SIGNALS_SYMBOLS \
-   SymI_HasProto(setIOManagerPipe)
+   SymI_HasProto(setIOManagerPipe) \
+   SymI_HasProto(ioManagerWakeup) \
+   SymI_HasProto(ioManagerSync) \
+   SymI_HasProto(blockUserSignals) \
+   SymI_HasProto(unblockUserSignals)
 #else
 #define RTS_USER_SIGNALS_SYMBOLS     \
+   SymI_HasProto(ioManagerWakeup) \
    SymI_HasProto(sendIOManagerEvent) \
    SymI_HasProto(readIOManagerEvent) \
    SymI_HasProto(getIOManagerEvent)  \
@@ -539,25 +556,137 @@ typedef struct _RtsSymbolVal {
       SymI_HasProto(stg_ap_pppppp_ret)
 #endif
 
-/* On Windows, we link libgmp.a statically into libHSrts.dll */
-#ifdef mingw32_HOST_OS
-#define GMP_SYMS                                       \
-      SymI_HasProto(__gmpz_cmp)                                \
-      SymI_HasProto(__gmpz_cmp_si)                     \
-      SymI_HasProto(__gmpz_cmp_ui)                     \
-      SymI_HasProto(__gmpz_get_si)                     \
-      SymI_HasProto(__gmpz_get_ui)
+/* Modules compiled with -ticky may mention ticky counters */
+/* This list should marry up with the one in $(TOP)/includes/stg/Ticky.h */
+#define RTS_TICKY_SYMBOLS                       \
+      SymI_NeedsProto(ticky_entry_ctrs)         \
+      SymI_NeedsProto(top_ct)                   \
+                                                \
+      SymI_HasProto(ENT_VIA_NODE_ctr)          \
+      SymI_HasProto(ENT_STATIC_THK_ctr)                \
+      SymI_HasProto(ENT_DYN_THK_ctr)           \
+      SymI_HasProto(ENT_STATIC_FUN_DIRECT_ctr) \
+      SymI_HasProto(ENT_DYN_FUN_DIRECT_ctr)    \
+      SymI_HasProto(ENT_STATIC_CON_ctr)                \
+      SymI_HasProto(ENT_DYN_CON_ctr)           \
+      SymI_HasProto(ENT_STATIC_IND_ctr)                \
+      SymI_HasProto(ENT_DYN_IND_ctr)           \
+      SymI_HasProto(ENT_PERM_IND_ctr)          \
+      SymI_HasProto(ENT_PAP_ctr)               \
+      SymI_HasProto(ENT_AP_ctr)                        \
+      SymI_HasProto(ENT_AP_STACK_ctr)          \
+      SymI_HasProto(ENT_BH_ctr)                        \
+      SymI_HasProto(UNKNOWN_CALL_ctr)          \
+      SymI_HasProto(SLOW_CALL_v_ctr)           \
+      SymI_HasProto(SLOW_CALL_f_ctr)           \
+      SymI_HasProto(SLOW_CALL_d_ctr)           \
+      SymI_HasProto(SLOW_CALL_l_ctr)           \
+      SymI_HasProto(SLOW_CALL_n_ctr)           \
+      SymI_HasProto(SLOW_CALL_p_ctr)           \
+      SymI_HasProto(SLOW_CALL_pv_ctr)          \
+      SymI_HasProto(SLOW_CALL_pp_ctr)          \
+      SymI_HasProto(SLOW_CALL_ppv_ctr)         \
+      SymI_HasProto(SLOW_CALL_ppp_ctr)         \
+      SymI_HasProto(SLOW_CALL_pppv_ctr)                \
+      SymI_HasProto(SLOW_CALL_pppp_ctr)                \
+      SymI_HasProto(SLOW_CALL_ppppp_ctr)               \
+      SymI_HasProto(SLOW_CALL_pppppp_ctr)              \
+      SymI_HasProto(SLOW_CALL_OTHER_ctr)               \
+      SymI_HasProto(ticky_slow_call_unevald)            \
+      SymI_HasProto(SLOW_CALL_ctr)                     \
+      SymI_HasProto(MULTI_CHUNK_SLOW_CALL_ctr)         \
+      SymI_HasProto(MULTI_CHUNK_SLOW_CALL_CHUNKS_ctr)  \
+      SymI_HasProto(KNOWN_CALL_ctr)                    \
+      SymI_HasProto(KNOWN_CALL_TOO_FEW_ARGS_ctr)       \
+      SymI_HasProto(KNOWN_CALL_EXTRA_ARGS_ctr)         \
+      SymI_HasProto(SLOW_CALL_FUN_TOO_FEW_ctr)         \
+      SymI_HasProto(SLOW_CALL_FUN_CORRECT_ctr)         \
+      SymI_HasProto(SLOW_CALL_FUN_TOO_MANY_ctr)                \
+      SymI_HasProto(SLOW_CALL_PAP_TOO_FEW_ctr)         \
+      SymI_HasProto(SLOW_CALL_PAP_CORRECT_ctr)         \
+      SymI_HasProto(SLOW_CALL_PAP_TOO_MANY_ctr)                \
+      SymI_HasProto(SLOW_CALL_UNEVALD_ctr)             \
+      SymI_HasProto(UPDF_OMITTED_ctr)          \
+      SymI_HasProto(UPDF_PUSHED_ctr)           \
+      SymI_HasProto(CATCHF_PUSHED_ctr)         \
+      SymI_HasProto(UPDF_RCC_PUSHED_ctr)       \
+      SymI_HasProto(UPDF_RCC_OMITTED_ctr)      \
+      SymI_HasProto(UPD_SQUEEZED_ctr)          \
+      SymI_HasProto(UPD_CON_IN_NEW_ctr)                \
+      SymI_HasProto(UPD_CON_IN_PLACE_ctr)      \
+      SymI_HasProto(UPD_PAP_IN_NEW_ctr)                \
+      SymI_HasProto(UPD_PAP_IN_PLACE_ctr)      \
+      SymI_HasProto(ALLOC_HEAP_ctr)            \
+      SymI_HasProto(ALLOC_HEAP_tot)             \
+      SymI_HasProto(ALLOC_FUN_ctr)             \
+      SymI_HasProto(ALLOC_FUN_adm)              \
+      SymI_HasProto(ALLOC_FUN_gds)              \
+      SymI_HasProto(ALLOC_FUN_slp)              \
+      SymI_HasProto(UPD_NEW_IND_ctr)           \
+      SymI_HasProto(UPD_NEW_PERM_IND_ctr)      \
+      SymI_HasProto(UPD_OLD_IND_ctr)           \
+      SymI_HasProto(UPD_OLD_PERM_IND_ctr)              \
+      SymI_HasProto(UPD_BH_UPDATABLE_ctr)              \
+      SymI_HasProto(UPD_BH_SINGLE_ENTRY_ctr)           \
+      SymI_HasProto(UPD_CAF_BH_UPDATABLE_ctr)          \
+      SymI_HasProto(UPD_CAF_BH_SINGLE_ENTRY_ctr)       \
+      SymI_HasProto(GC_SEL_ABANDONED_ctr)              \
+      SymI_HasProto(GC_SEL_MINOR_ctr)          \
+      SymI_HasProto(GC_SEL_MAJOR_ctr)          \
+      SymI_HasProto(GC_FAILED_PROMOTION_ctr)   \
+      SymI_HasProto(ALLOC_UP_THK_ctr)          \
+      SymI_HasProto(ALLOC_SE_THK_ctr)          \
+      SymI_HasProto(ALLOC_THK_adm)             \
+      SymI_HasProto(ALLOC_THK_gds)             \
+      SymI_HasProto(ALLOC_THK_slp)             \
+      SymI_HasProto(ALLOC_CON_ctr)             \
+      SymI_HasProto(ALLOC_CON_adm)             \
+      SymI_HasProto(ALLOC_CON_gds)             \
+      SymI_HasProto(ALLOC_CON_slp)             \
+      SymI_HasProto(ALLOC_TUP_ctr)             \
+      SymI_HasProto(ALLOC_TUP_adm)             \
+      SymI_HasProto(ALLOC_TUP_gds)             \
+      SymI_HasProto(ALLOC_TUP_slp)             \
+      SymI_HasProto(ALLOC_BH_ctr)              \
+      SymI_HasProto(ALLOC_BH_adm)              \
+      SymI_HasProto(ALLOC_BH_gds)              \
+      SymI_HasProto(ALLOC_BH_slp)              \
+      SymI_HasProto(ALLOC_PRIM_ctr)            \
+      SymI_HasProto(ALLOC_PRIM_adm)            \
+      SymI_HasProto(ALLOC_PRIM_gds)            \
+      SymI_HasProto(ALLOC_PRIM_slp)            \
+      SymI_HasProto(ALLOC_PAP_ctr)             \
+      SymI_HasProto(ALLOC_PAP_adm)             \
+      SymI_HasProto(ALLOC_PAP_gds)             \
+      SymI_HasProto(ALLOC_PAP_slp)             \
+      SymI_HasProto(ALLOC_TSO_ctr)             \
+      SymI_HasProto(ALLOC_TSO_adm)             \
+      SymI_HasProto(ALLOC_TSO_gds)             \
+      SymI_HasProto(ALLOC_TSO_slp)             \
+      SymI_HasProto(RET_NEW_ctr)               \
+      SymI_HasProto(RET_OLD_ctr)               \
+      SymI_HasProto(RET_UNBOXED_TUP_ctr)       \
+      SymI_HasProto(RET_SEMI_loads_avoided)
+
+
+// On most platforms, the garbage collector rewrites references
+//     to small integer and char objects to a set of common, shared ones.
+//
+// We don't do this when compiling to Windows DLLs at the moment because
+//     it doesn't support cross package data references well.
+//
+#if defined(__PIC__) && defined(mingw32_HOST_OS)
+#define RTS_INTCHAR_SYMBOLS
 #else
-#define GMP_SYMS                                       \
-      SymE_HasProto(__gmpz_cmp)                                \
-      SymE_HasProto(__gmpz_cmp_si)                     \
-      SymE_HasProto(__gmpz_cmp_ui)                     \
-      SymE_HasProto(__gmpz_get_si)                     \
-      SymE_HasProto(__gmpz_get_ui)
+#define RTS_INTCHAR_SYMBOLS                            \
+      SymI_HasProto(stg_CHARLIKE_closure)              \
+      SymI_HasProto(stg_INTLIKE_closure)               
 #endif
 
+
 #define RTS_SYMBOLS                                    \
       Maybe_Stable_Names                               \
+      RTS_TICKY_SYMBOLS                                 \
       SymI_HasProto(StgReturn)                         \
       SymI_HasProto(stg_enter_info)                    \
       SymI_HasProto(stg_gc_void_info)                  \
@@ -592,53 +721,44 @@ typedef struct _RtsSymbolVal {
       SymI_HasProto(OnExitHook)                                \
       SymI_HasProto(OutOfHeapHook)                     \
       SymI_HasProto(StackOverflowHook)                 \
-      SymI_HasProto(__encodeDouble)                    \
-      SymI_HasProto(__encodeFloat)                     \
       SymI_HasProto(addDLL)                            \
-      GMP_SYMS                                         \
       SymI_HasProto(__int_encodeDouble)                        \
       SymI_HasProto(__word_encodeDouble)               \
       SymI_HasProto(__2Int_encodeDouble)               \
       SymI_HasProto(__int_encodeFloat)                 \
       SymI_HasProto(__word_encodeFloat)                        \
-      SymI_HasProto(andIntegerzh_fast)                 \
-      SymI_HasProto(atomicallyzh_fast)                 \
+      SymI_HasProto(stg_atomicallyzh)                  \
       SymI_HasProto(barf)                              \
       SymI_HasProto(debugBelch)                                \
       SymI_HasProto(errorBelch)                                \
-      SymI_HasProto(asyncExceptionsBlockedzh_fast)     \
-      SymI_HasProto(blockAsyncExceptionszh_fast)       \
-      SymI_HasProto(catchzh_fast)                      \
-      SymI_HasProto(catchRetryzh_fast)                 \
-      SymI_HasProto(catchSTMzh_fast)                   \
-      SymI_HasProto(checkzh_fast)                       \
+      SymI_HasProto(sysErrorBelch)                      \
+      SymI_HasProto(stg_asyncExceptionsBlockedzh)      \
+      SymI_HasProto(stg_blockAsyncExceptionszh)                \
+      SymI_HasProto(stg_catchzh)                       \
+      SymI_HasProto(stg_catchRetryzh)                  \
+      SymI_HasProto(stg_catchSTMzh)                    \
+      SymI_HasProto(stg_checkzh)                        \
       SymI_HasProto(closure_flags)                      \
       SymI_HasProto(cmp_thread)                                \
-      SymI_HasProto(cmpIntegerzh_fast)                 \
-      SymI_HasProto(cmpIntegerIntzh_fast)              \
-      SymI_HasProto(complementIntegerzh_fast)          \
       SymI_HasProto(createAdjustor)                    \
-      SymI_HasProto(decodeDoublezh_fast)               \
-      SymI_HasProto(decodeFloatzh_fast)                        \
-      SymI_HasProto(decodeDoublezu2Intzh_fast)         \
-      SymI_HasProto(decodeFloatzuIntzh_fast)           \
+      SymI_HasProto(stg_decodeDoublezu2Intzh)          \
+      SymI_HasProto(stg_decodeFloatzuIntzh)            \
       SymI_HasProto(defaultsHook)                      \
-      SymI_HasProto(delayzh_fast)                      \
-      SymI_HasProto(deRefWeakzh_fast)                  \
-      SymI_HasProto(deRefStablePtrzh_fast)             \
+      SymI_HasProto(stg_delayzh)                       \
+      SymI_HasProto(stg_deRefWeakzh)                   \
+      SymI_HasProto(stg_deRefStablePtrzh)              \
       SymI_HasProto(dirty_MUT_VAR)                     \
-      SymI_HasProto(divExactIntegerzh_fast)            \
-      SymI_HasProto(divModIntegerzh_fast)              \
-      SymI_HasProto(forkzh_fast)                       \
-      SymI_HasProto(forkOnzh_fast)                     \
+      SymI_HasProto(stg_forkzh)                                \
+      SymI_HasProto(stg_forkOnzh)                      \
       SymI_HasProto(forkProcess)                       \
       SymI_HasProto(forkOS_createThread)               \
       SymI_HasProto(freeHaskellFunctionPtr)            \
-      SymI_HasProto(freeStablePtr)                     \
       SymI_HasProto(getOrSetTypeableStore)             \
-      SymI_HasProto(gcdIntegerzh_fast)                 \
-      SymI_HasProto(gcdIntegerIntzh_fast)              \
-      SymI_HasProto(gcdIntzh_fast)                     \
+      SymI_HasProto(getOrSetGHCConcSignalHandlerStore)         \
+      SymI_HasProto(getOrSetGHCConcPendingEventsStore)         \
+      SymI_HasProto(getOrSetGHCConcPendingDelaysStore)         \
+      SymI_HasProto(getOrSetGHCConcIOManagerThreadStore)       \
+      SymI_HasProto(getOrSetGHCConcProddingStore)              \
       SymI_HasProto(genSymZh)                          \
       SymI_HasProto(genericRaise)                      \
       SymI_HasProto(getProgArgv)                       \
@@ -652,62 +772,46 @@ typedef struct _RtsSymbolVal {
       SymI_HasProto(hs_free_stable_ptr)                        \
       SymI_HasProto(hs_free_fun_ptr)                   \
       SymI_HasProto(hs_hpc_rootModule)                 \
+      SymI_HasProto(hs_hpc_module)                     \
       SymI_HasProto(initLinker)                                \
-      SymI_HasProto(unpackClosurezh_fast)               \
-      SymI_HasProto(getApStackValzh_fast)               \
-      SymI_HasProto(getSparkzh_fast)                    \
-      SymI_HasProto(int2Integerzh_fast)                        \
-      SymI_HasProto(integer2Intzh_fast)                        \
-      SymI_HasProto(integer2Wordzh_fast)               \
-      SymI_HasProto(isCurrentThreadBoundzh_fast)       \
-      SymI_HasProto(isDoubleDenormalized)              \
-      SymI_HasProto(isDoubleInfinite)                  \
-      SymI_HasProto(isDoubleNaN)                       \
-      SymI_HasProto(isDoubleNegativeZero)              \
-      SymI_HasProto(isEmptyMVarzh_fast)                        \
-      SymI_HasProto(isFloatDenormalized)               \
-      SymI_HasProto(isFloatInfinite)                   \
-      SymI_HasProto(isFloatNaN)                                \
-      SymI_HasProto(isFloatNegativeZero)               \
-      SymI_HasProto(killThreadzh_fast)                 \
+      SymI_HasProto(stg_unpackClosurezh)                \
+      SymI_HasProto(stg_getApStackValzh)                \
+      SymI_HasProto(stg_getSparkzh)                     \
+      SymI_HasProto(stg_isCurrentThreadBoundzh)                \
+      SymI_HasProto(stg_isEmptyMVarzh)                 \
+      SymI_HasProto(stg_killThreadzh)                  \
       SymI_HasProto(loadObj)                           \
       SymI_HasProto(insertStableSymbol)                \
       SymI_HasProto(insertSymbol)                      \
       SymI_HasProto(lookupSymbol)                      \
-      SymI_HasProto(makeStablePtrzh_fast)              \
-      SymI_HasProto(minusIntegerzh_fast)               \
-      SymI_HasProto(mkApUpd0zh_fast)                   \
-      SymI_HasProto(myThreadIdzh_fast)                 \
-      SymI_HasProto(labelThreadzh_fast)                 \
-      SymI_HasProto(newArrayzh_fast)                   \
-      SymI_HasProto(newBCOzh_fast)                     \
-      SymI_HasProto(newByteArrayzh_fast)               \
+      SymI_HasProto(stg_makeStablePtrzh)               \
+      SymI_HasProto(stg_mkApUpd0zh)                    \
+      SymI_HasProto(stg_myThreadIdzh)                  \
+      SymI_HasProto(stg_labelThreadzh)                  \
+      SymI_HasProto(stg_newArrayzh)                    \
+      SymI_HasProto(stg_newBCOzh)                      \
+      SymI_HasProto(stg_newByteArrayzh)                \
       SymI_HasProto_redirect(newCAF, newDynCAF)                \
-      SymI_HasProto(newMVarzh_fast)                    \
-      SymI_HasProto(newMutVarzh_fast)                  \
-      SymI_HasProto(newTVarzh_fast)                    \
-      SymI_HasProto(noDuplicatezh_fast)                        \
-      SymI_HasProto(atomicModifyMutVarzh_fast)         \
-      SymI_HasProto(newPinnedByteArrayzh_fast)         \
+      SymI_HasProto(stg_newMVarzh)                     \
+      SymI_HasProto(stg_newMutVarzh)                   \
+      SymI_HasProto(stg_newTVarzh)                     \
+      SymI_HasProto(stg_noDuplicatezh)                 \
+      SymI_HasProto(stg_atomicModifyMutVarzh)          \
+      SymI_HasProto(stg_newPinnedByteArrayzh)          \
+      SymI_HasProto(stg_newAlignedPinnedByteArrayzh)   \
       SymI_HasProto(newSpark)                          \
-      SymI_HasProto(orIntegerzh_fast)                  \
       SymI_HasProto(performGC)                         \
       SymI_HasProto(performMajorGC)                    \
-      SymI_HasProto(plusIntegerzh_fast)                        \
       SymI_HasProto(prog_argc)                         \
       SymI_HasProto(prog_argv)                         \
-      SymI_HasProto(putMVarzh_fast)                    \
-      SymI_HasProto(quotIntegerzh_fast)                        \
-      SymI_HasProto(quotRemIntegerzh_fast)             \
-      SymI_HasProto(raisezh_fast)                      \
-      SymI_HasProto(raiseIOzh_fast)                    \
-      SymI_HasProto(readTVarzh_fast)                   \
-      SymI_HasProto(readTVarIOzh_fast)                 \
-      SymI_HasProto(remIntegerzh_fast)                 \
-      SymI_HasProto(resetNonBlockingFd)                        \
+      SymI_HasProto(stg_putMVarzh)                     \
+      SymI_HasProto(stg_raisezh)                       \
+      SymI_HasProto(stg_raiseIOzh)                     \
+      SymI_HasProto(stg_readTVarzh)                    \
+      SymI_HasProto(stg_readTVarIOzh)                  \
       SymI_HasProto(resumeThread)                      \
       SymI_HasProto(resolveObjs)                        \
-      SymI_HasProto(retryzh_fast)                       \
+      SymI_HasProto(stg_retryzh)                        \
       SymI_HasProto(rts_apply)                         \
       SymI_HasProto(rts_checkSchedStatus)              \
       SymI_HasProto(rts_eval)                          \
@@ -753,9 +857,8 @@ typedef struct _RtsSymbolVal {
       SymI_HasProto(rts_mkWord32)                      \
       SymI_HasProto(rts_mkWord64)                      \
       SymI_HasProto(rts_unlock)                                \
+      SymI_HasProto(rts_unsafeGetMyCapability)          \
       SymI_HasProto(rtsSupportsBoundThreads)           \
-      SymI_HasProto(__hscore_get_saved_termios)                \
-      SymI_HasProto(__hscore_set_saved_termios)                \
       SymI_HasProto(setProgArgv)                       \
       SymI_HasProto(startupHaskell)                    \
       SymI_HasProto(shutdownHaskell)                   \
@@ -764,13 +867,11 @@ typedef struct _RtsSymbolVal {
       SymI_HasProto(stackOverflow)                     \
       SymI_HasProto(stg_CAF_BLACKHOLE_info)            \
       SymI_HasProto(__stg_EAGER_BLACKHOLE_info)                \
-      SymI_HasProto(awakenBlockedQueue)                        \
       SymI_HasProto(startTimer)                         \
-      SymI_HasProto(stg_CHARLIKE_closure)              \
       SymI_HasProto(stg_MVAR_CLEAN_info)               \
       SymI_HasProto(stg_MVAR_DIRTY_info)               \
       SymI_HasProto(stg_IND_STATIC_info)               \
-      SymI_HasProto(stg_INTLIKE_closure)               \
+      SymI_HasProto(stg_ARR_WORDS_info)                 \
       SymI_HasProto(stg_MUT_ARR_PTRS_DIRTY_info)       \
       SymI_HasProto(stg_MUT_ARR_PTRS_FROZEN_info)      \
       SymI_HasProto(stg_MUT_ARR_PTRS_FROZEN0_info)     \
@@ -830,21 +931,20 @@ typedef struct _RtsSymbolVal {
       SymI_HasProto(stg_sel_9_upd_info)                        \
       SymI_HasProto(stg_upd_frame_info)                        \
       SymI_HasProto(suspendThread)                     \
-      SymI_HasProto(takeMVarzh_fast)                   \
-      SymI_HasProto(threadStatuszh_fast)               \
-      SymI_HasProto(timesIntegerzh_fast)               \
-      SymI_HasProto(tryPutMVarzh_fast)                 \
-      SymI_HasProto(tryTakeMVarzh_fast)                        \
-      SymI_HasProto(unblockAsyncExceptionszh_fast)     \
+      SymI_HasProto(stg_takeMVarzh)                    \
+      SymI_HasProto(stg_threadStatuszh)                        \
+      SymI_HasProto(stg_tryPutMVarzh)                  \
+      SymI_HasProto(stg_tryTakeMVarzh)                 \
+      SymI_HasProto(stg_unblockAsyncExceptionszh)      \
       SymI_HasProto(unloadObj)                          \
-      SymI_HasProto(unsafeThawArrayzh_fast)            \
-      SymI_HasProto(waitReadzh_fast)                   \
-      SymI_HasProto(waitWritezh_fast)                  \
-      SymI_HasProto(word2Integerzh_fast)               \
-      SymI_HasProto(writeTVarzh_fast)                  \
-      SymI_HasProto(xorIntegerzh_fast)                 \
-      SymI_HasProto(yieldzh_fast)                       \
+      SymI_HasProto(stg_unsafeThawArrayzh)             \
+      SymI_HasProto(stg_waitReadzh)                    \
+      SymI_HasProto(stg_waitWritezh)                   \
+      SymI_HasProto(stg_writeTVarzh)                   \
+      SymI_HasProto(stg_yieldzh)                        \
       SymI_NeedsProto(stg_interp_constr_entry)          \
+      SymI_HasProto(alloc_blocks_lim)                   \
+      SymI_HasProto(allocate)                           \
       SymI_HasProto(allocateExec)                      \
       SymI_HasProto(freeExec)                          \
       SymI_HasProto(getAllocations)                     \
@@ -855,15 +955,11 @@ typedef struct _RtsSymbolVal {
       SymI_NeedsProto(rts_stop_on_exception)           \
       SymI_HasProto(stopTimer)                         \
       SymI_HasProto(n_capabilities)                    \
-      RTS_USER_SIGNALS_SYMBOLS
+      SymI_HasProto(stg_traceCcszh)                     \
+      SymI_HasProto(stg_traceEventzh)                   \
+      RTS_USER_SIGNALS_SYMBOLS                         \
+      RTS_INTCHAR_SYMBOLS
 
-#ifdef SUPPORT_LONG_LONGS
-#define RTS_LONG_LONG_SYMS                             \
-      SymI_HasProto(int64ToIntegerzh_fast)             \
-      SymI_HasProto(word64ToIntegerzh_fast)
-#else
-#define RTS_LONG_LONG_SYMS /* nothing */
-#endif
 
 // 64-bit support functions in libgcc.a
 #if defined(__GNUC__) && SIZEOF_VOID_P <= 4
@@ -877,14 +973,6 @@ typedef struct _RtsSymbolVal {
       SymI_NeedsProto(__ashrdi3)                      \
       SymI_NeedsProto(__lshrdi3)                      \
       SymI_NeedsProto(__eprintf)
-#elif defined(ia64_HOST_ARCH)
-#define RTS_LIBGCC_SYMBOLS                             \
-      SymI_NeedsProto(__divdi3)                                \
-      SymI_NeedsProto(__udivdi3)                        \
-      SymI_NeedsProto(__moddi3)                                \
-      SymI_NeedsProto(__umoddi3)                       \
-      SymI_NeedsProto(__divsf3)                                \
-      SymI_NeedsProto(__divdf3)
 #else
 #define RTS_LIBGCC_SYMBOLS
 #endif
@@ -911,7 +999,6 @@ typedef struct _RtsSymbolVal {
 #define SymI_HasProto_redirect(vvv,xxx) /**/
 RTS_SYMBOLS
 RTS_RET_SYMBOLS
-RTS_LONG_LONG_SYMS
 RTS_POSIX_ONLY_SYMBOLS
 RTS_MINGW_ONLY_SYMBOLS
 RTS_CYGWIN_ONLY_SYMBOLS
@@ -947,7 +1034,6 @@ RTS_LIBFFI_SYMBOLS
 static RtsSymbolVal rtsSyms[] = {
       RTS_SYMBOLS
       RTS_RET_SYMBOLS
-      RTS_LONG_LONG_SYMS
       RTS_POSIX_ONLY_SYMBOLS
       RTS_MINGW_ONLY_SYMBOLS
       RTS_CYGWIN_ONLY_SYMBOLS
@@ -1047,6 +1133,16 @@ initLinker( void )
         mmap_32bit_base = (void*)RtsFlags.MiscFlags.linkerMemBase;
     }
 #endif
+
+#if defined(mingw32_HOST_OS)
+    /*
+     * These two libraries cause problems when added to the static link,
+     * but are necessary for resolving symbols in GHCi, hence we load
+     * them manually here.
+     */
+    addDLL("msvcrt");
+    addDLL("kernel32");
+#endif
 }
 
 /* -----------------------------------------------------------------------------
@@ -1289,16 +1385,19 @@ void ghci_enquire ( char* addr )
 }
 #endif
 
-#ifdef ia64_HOST_ARCH
-static unsigned int PLTSize(void);
-#endif
-
 #ifdef USE_MMAP
+#define ROUND_UP(x,size) ((x + size - 1) & ~(size - 1))
+
 static void *
 mmapForLinker (size_t bytes, nat flags, int fd)
 {
    void *map_addr = NULL;
    void *result;
+   int pagesize, size;
+   static nat fixed = 0;
+
+   pagesize = getpagesize();
+   size = ROUND_UP(bytes, pagesize);
 
 #if defined(x86_64_HOST_ARCH)
 mmap_again:
@@ -1308,28 +1407,37 @@ mmap_again:
    }
 #endif
 
-   result = mmap(map_addr, bytes, PROT_EXEC|PROT_READ|PROT_WRITE,
-                   MAP_PRIVATE|TRY_MAP_32BIT|flags, fd, 0);
+   result = mmap(map_addr, size, PROT_EXEC|PROT_READ|PROT_WRITE,
+                   MAP_PRIVATE|TRY_MAP_32BIT|fixed|flags, fd, 0);
 
    if (result == MAP_FAILED) {
-       sysErrorBelch("mmap");
+       sysErrorBelch("mmap %lu bytes at %p",(lnat)size,map_addr);
+       errorBelch("Try specifying an address with +RTS -xm<addr> -RTS");
        stg_exit(EXIT_FAILURE);
    }
    
 #if defined(x86_64_HOST_ARCH)
    if (mmap_32bit_base != 0) {
        if (result == map_addr) {
-           mmap_32bit_base = map_addr + bytes;
+           mmap_32bit_base = (StgWord8*)map_addr + size;
        } else {
            if ((W_)result > 0x80000000) {
                // oops, we were given memory over 2Gb
-               // ... try allocating memory somewhere else?;
-               barf("loadObj: failed to mmap() memory below 2Gb; asked for %lu bytes at %p, got %p.  Try specifying an address with +RTS -xm<addr> -RTS", bytes, map_addr, result);
+#if defined(freebsd_HOST_OS) || defined(dragonfly_HOST_OS)
+               // Some platforms require MAP_FIXED.  This is normally
+               // a bad idea, because MAP_FIXED will overwrite
+               // existing mappings.
+               munmap(result,size);
+               fixed = MAP_FIXED;
+               goto mmap_again;
+#else
+               barf("loadObj: failed to mmap() memory below 2Gb; asked for %lu bytes at %p.  Try specifying an address with +RTS -xm<addr> -RTS", size, map_addr, result);
+#endif
            } else {
                // hmm, we were given memory somewhere else, but it's
                // still under 2Gb so we can use it.  Next time, ask
                // for memory right after the place we just got some
-               mmap_32bit_base = (void*)result + bytes;
+               mmap_32bit_base = (StgWord8*)result + size;
            }
        }
    } else {
@@ -1337,7 +1445,7 @@ mmap_again:
            // oops, we were given memory over 2Gb
            // ... try allocating memory somewhere else?;
            debugTrace(DEBUG_linker,"MAP_32BIT didn't work; gave us %lu bytes at 0x%p", bytes, result);
-           munmap(result, bytes);
+           munmap(result, size);
            
            // Set a base address and try again... (guess: 1Gb)
            mmap_32bit_base = (void*)0x40000000;
@@ -1360,9 +1468,9 @@ loadObj( char *path )
 {
    ObjectCode* oc;
    struct stat st;
-   int r, n;
+   int r;
 #ifdef USE_MMAP
-   int fd, pagesize;
+   int fd;
 #else
    FILE *f;
 #endif
@@ -1422,8 +1530,6 @@ loadObj( char *path )
    objects               = oc;
 
 #ifdef USE_MMAP
-#define ROUND_UP(x,size) ((x + size - 1) & ~(size - 1))
-
    /* On many architectures malloc'd memory isn't executable, so we need to use mmap. */
 
 #if defined(openbsd_HOST_OS)
@@ -1434,34 +1540,11 @@ loadObj( char *path )
    if (fd == -1)
       barf("loadObj: can't open `%s'", path);
 
-   pagesize = getpagesize();
-
-#ifdef ia64_HOST_ARCH
-   /* The PLT needs to be right before the object */
-   n = ROUND_UP(PLTSize(), pagesize);
-   oc->plt = mmap(NULL, n, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
-   if (oc->plt == MAP_FAILED)
-      barf("loadObj: can't allocate PLT");
-
-   oc->pltIndex = 0;
-   map_addr = oc->plt + n;
-#endif
-
-   n = ROUND_UP(oc->fileSize, pagesize);
-
-#ifdef ia64_HOST_ARCH
-   oc->image = mmap(map_addr, n, PROT_EXEC|PROT_READ|PROT_WRITE,
-                   MAP_PRIVATE|TRY_MAP_32BIT, fd, 0);
-   if (oc->image == MAP_FAILED)
-      barf("loadObj: can't map `%s'", path);
-#else
-   oc->image = mmapForLinker(n, 0, fd);
-#endif
+   oc->image = mmapForLinker(oc->fileSize, 0, fd);
 
    close(fd);
 
 #else /* !USE_MMAP */
-
    /* load the image into memory */
    f = fopen(path, "rb");
    if (!f)
@@ -1489,10 +1572,12 @@ loadObj( char *path )
    oc->image = stgMallocBytes(oc->fileSize, "loadObj(image)");
 #  endif
 
-   n = fread ( oc->image, 1, oc->fileSize, f );
-   if (n != oc->fileSize)
-      barf("loadObj: error whilst reading `%s'", path);
-
+   {
+       int n;
+       n = fread ( oc->image, 1, oc->fileSize, f );
+       if (n != oc->fileSize)
+           barf("loadObj: error whilst reading `%s'", path);
+   }
    fclose(f);
 #endif /* USE_MMAP */
 
@@ -1729,7 +1814,7 @@ static int ocAllocateSymbolExtras( ObjectCode* oc, int count, int first )
     if( m > n ) // we need to allocate more pages
     {
         oc->symbol_extras = mmapForLinker(sizeof(SymbolExtra) * count, 
-                                          MAP_ANONYMOUS, 0);
+                                          MAP_ANONYMOUS, -1);
     }
     else
     {
@@ -2636,8 +2721,7 @@ ocResolve_PEi386 ( ObjectCode* oc )
             copyName ( sym->Name, strtab, symbol, 1000-1 );
             S = (UInt32) lookupSymbol( symbol );
             if ((void*)S != NULL) goto foundit;
-           /* Newline first because the interactive linker has printed "linking..." */
-            errorBelch("\n%s: unknown symbol `%s'", oc->fileName, symbol);
+            errorBelch("%s: unknown symbol `%s'", oc->fileName, symbol);
             return 0;
            foundit:;
          }
@@ -2706,12 +2790,6 @@ ocResolve_PEi386 ( ObjectCode* oc )
 #elif defined(x86_64_HOST_ARCH)
 #  define ELF_TARGET_X64_64
 #  define ELF_64BIT
-#elif defined (ia64_HOST_ARCH)
-#  define ELF_TARGET_IA64   /* Used inside <elf.h> */
-#  define ELF_64BIT
-#  define ELF_FUNCTION_DESC /* calling convention uses function descriptors */
-#  define ELF_NEED_GOT      /* needs Global Offset Table */
-#  define ELF_NEED_PLT      /* needs Procedure Linkage Tables */
 #endif
 
 #if !defined(openbsd_HOST_OS)
@@ -2841,30 +2919,6 @@ copyFunctionDesc(Elf_Addr target)
 #endif
 
 #ifdef ELF_NEED_PLT
-#ifdef ia64_HOST_ARCH
-static void ia64_reloc_gprel22(Elf_Addr target, Elf_Addr value);
-static void ia64_reloc_pcrel21(Elf_Addr target, Elf_Addr value, ObjectCode *oc);
-
-static unsigned char plt_code[] =
-{
-   /* taken from binutils bfd/elfxx-ia64.c */
-   0x0b, 0x78, 0x00, 0x02, 0x00, 0x24,  /*   [MMI]       addl r15=0,r1;;    */
-   0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0,  /*               ld8 r16=[r15],8    */
-   0x01, 0x08, 0x00, 0x84,              /*               mov r14=r1;;       */
-   0x11, 0x08, 0x00, 0x1e, 0x18, 0x10,  /*   [MIB]       ld8 r1=[r15]       */
-   0x60, 0x80, 0x04, 0x80, 0x03, 0x00,  /*               mov b6=r16         */
-   0x60, 0x00, 0x80, 0x00               /*               br.few b6;;        */
-};
-
-/* If we can't get to the function descriptor via gp, take a local copy of it */
-#define PLT_RELOC(code, target) { \
-   Elf64_Sxword rel_value = target - gp_val; \
-   if ((rel_value > 0x1fffff) || (rel_value < -0x1fffff)) \
-      ia64_reloc_gprel22((Elf_Addr)code, copyFunctionDesc(target)); \
-   else \
-      ia64_reloc_gprel22((Elf_Addr)code, target); \
-   }
-#endif
 
 typedef struct {
    unsigned char code[sizeof(plt_code)];
@@ -2922,25 +2976,6 @@ findElfSection ( void* objImage, Elf_Word sh_type )
    return ptr;
 }
 
-#if defined(ia64_HOST_ARCH)
-static Elf_Addr
-findElfSegment ( void* objImage, Elf_Addr vaddr )
-{
-   char* ehdrC = (char*)objImage;
-   Elf_Ehdr* ehdr = (Elf_Ehdr*)ehdrC;
-   Elf_Phdr* phdr = (Elf_Phdr*)(ehdrC + ehdr->e_phoff);
-   Elf_Addr segaddr = 0;
-   int i;
-
-   for (i = 0; i < ehdr->e_phnum; i++) {
-      segaddr = phdr[i].p_vaddr;
-      if ((vaddr >= segaddr) && (vaddr < segaddr + phdr[i].p_memsz))
-             break;
-   }
-   return segaddr;
-}
-#endif
-
 static int
 ocVerifyImage_ELF ( ObjectCode* oc )
 {
@@ -3434,9 +3469,6 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
 #     if defined(sparc_HOST_ARCH)
       Elf_Word* pP = (Elf_Word*)P;
       Elf_Word  w1, w2;
-#     elif defined(ia64_HOST_ARCH)
-      Elf64_Xword *pP = (Elf64_Xword *)P;
-      Elf_Addr addr;
 #     elif defined(powerpc_HOST_ARCH)
       Elf_Sword delta;
 #     endif
@@ -3513,49 +3545,30 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
             w1 |= w2;
             *pP = w1;
             break;
+
          /* According to the Sun documentation:
             R_SPARC_UA32
             This relocation type resembles R_SPARC_32, except it refers to an
             unaligned word. That is, the word to be relocated must be treated
             as four separate bytes with arbitrary alignment, not as a word
             aligned according to the architecture requirements.
-
-            (JRS: which means that freeloading on the R_SPARC_32 case
-            is probably wrong, but hey ...)
          */
          case R_SPARC_UA32:
+            w2 = (Elf_Word)value;
+
+            // SPARC doesn't do misaligned writes of 32 bit words,
+           //       so we have to do this one byte-at-a-time.
+           char *pPc   = (char*)pP;
+           pPc[0]      = (char) ((Elf_Word)(w2 & 0xff000000) >> 24);
+           pPc[1]      = (char) ((Elf_Word)(w2 & 0x00ff0000) >> 16);
+           pPc[2]      = (char) ((Elf_Word)(w2 & 0x0000ff00) >> 8);
+           pPc[3]      = (char) ((Elf_Word)(w2 & 0x000000ff));
+           break;
+
          case R_SPARC_32:
             w2 = (Elf_Word)value;
             *pP = w2;
             break;
-#        elif defined(ia64_HOST_ARCH)
-        case R_IA64_DIR64LSB:
-        case R_IA64_FPTR64LSB:
-           *pP = value;
-           break;
-        case R_IA64_PCREL64LSB:
-           *pP = value - P;
-           break;
-        case R_IA64_SEGREL64LSB:
-           addr = findElfSegment(ehdrC, value);
-           *pP = value - addr;
-           break;
-        case R_IA64_GPREL22:
-           ia64_reloc_gprel22(P, value);
-           break;
-        case R_IA64_LTOFF22:
-        case R_IA64_LTOFF22X:
-        case R_IA64_LTOFF_FPTR22:
-           addr = allocateGOTEntry(value);
-           ia64_reloc_gprel22(P, addr);
-           break;
-        case R_IA64_PCREL21B:
-           ia64_reloc_pcrel21(P, S, oc);
-           break;
-        case R_IA64_LDXMOV:
-           /* This goes with R_IA64_LTOFF22X and points to the load to
-            * convert into a move.  We don't implement relaxation. */
-           break;
 #        elif defined(powerpc_HOST_ARCH)
          case R_PPC_ADDR16_LO:
             *(Elf32_Half*) P = value;
@@ -3731,98 +3744,6 @@ ocResolve_ELF ( ObjectCode* oc )
 }
 
 /*
- * IA64 specifics
- * Instructions are 41 bits long, packed into 128 bit bundles with a 5-bit template
- * at the front.  The following utility functions pack and unpack instructions, and
- * take care of the most common relocations.
- */
-
-#ifdef ia64_HOST_ARCH
-
-static Elf64_Xword
-ia64_extract_instruction(Elf64_Xword *target)
-{
-   Elf64_Xword w1, w2;
-   int slot = (Elf_Addr)target & 3;
-   target = (Elf_Addr)target & ~3;
-
-   w1 = *target;
-   w2 = *(target+1);
-
-   switch (slot)
-   {
-      case 0:
-         return ((w1 >> 5) & 0x1ffffffffff);
-      case 1:
-         return (w1 >> 46) | ((w2 & 0x7fffff) << 18);
-      case 2:
-         return (w2 >> 23);
-      default:
-         barf("ia64_extract_instruction: invalid slot %p", target);
-   }
-}
-
-static void
-ia64_deposit_instruction(Elf64_Xword *target, Elf64_Xword value)
-{
-   int slot = (Elf_Addr)target & 3;
-   target = (Elf_Addr)target & ~3;
-
-   switch (slot)
-   {
-      case 0:
-         *target |= value << 5;
-         break;
-      case 1:
-         *target |= value << 46;
-         *(target+1) |= value >> 18;
-         break;
-      case 2:
-         *(target+1) |= value << 23;
-         break;
-   }
-}
-
-static void
-ia64_reloc_gprel22(Elf_Addr target, Elf_Addr value)
-{
-   Elf64_Xword instruction;
-   Elf64_Sxword rel_value;
-
-   rel_value = value - gp_val;
-   if ((rel_value > 0x1fffff) || (rel_value < -0x1fffff))
-      barf("GP-relative data out of range (address = 0x%lx, gp = 0x%lx)", value, gp_val);
-
-   instruction = ia64_extract_instruction((Elf64_Xword *)target);
-   instruction |= (((rel_value >> 0) & 0x07f) << 13)           /* imm7b */
-                   | (((rel_value >> 7) & 0x1ff) << 27)        /* imm9d */
-                   | (((rel_value >> 16) & 0x01f) << 22)       /* imm5c */
-                   | ((Elf64_Xword)(rel_value < 0) << 36);     /* s */
-   ia64_deposit_instruction((Elf64_Xword *)target, instruction);
-}
-
-static void
-ia64_reloc_pcrel21(Elf_Addr target, Elf_Addr value, ObjectCode *oc)
-{
-   Elf64_Xword instruction;
-   Elf64_Sxword rel_value;
-   Elf_Addr entry;
-
-   entry = allocatePLTEntry(value, oc);
-
-   rel_value = (entry >> 4) - (target >> 4);
-   if ((rel_value > 0xfffff) || (rel_value < -0xfffff))
-      barf("PLT entry too far away (entry = 0x%lx, target = 0x%lx)", entry, target);
-
-   instruction = ia64_extract_instruction((Elf64_Xword *)target);
-   instruction |= ((rel_value & 0xfffff) << 13)                /* imm20b */
-                   | ((Elf64_Xword)(rel_value < 0) << 36);     /* s */
-   ia64_deposit_instruction((Elf64_Xword *)target, instruction);
-}
-
-#endif /* ia64 */
-
-/*
  * PowerPC & X86_64 ELF specifics
  */
 
@@ -4078,7 +3999,9 @@ static int relocateSection(
         
         char    *thingPtr = image + sect->offset + reloc->r_address;
         uint64_t thing;
-        uint64_t value;
+        /* We shouldn't need to initialise this, but gcc on OS X 64 bit
+           complains that it may be used uninitialized if we don't */
+        uint64_t value = 0;
         uint64_t baseValue;
         int type = reloc->r_type;
         
@@ -4214,7 +4137,8 @@ static int relocateSection(
                        || scat->r_type == PPC_RELOC_HI16_SECTDIFF
                        || scat->r_type == PPC_RELOC_HA16_SECTDIFF)
 #else
-                    else if(scat->r_type == GENERIC_RELOC_SECTDIFF)
+                    else if(scat->r_type == GENERIC_RELOC_SECTDIFF
+                        || scat->r_type == GENERIC_RELOC_LOCAL_SECTDIFF)
 #endif
                    {
                        struct scattered_relocation_info *pair =
@@ -4269,15 +4193,23 @@ static int relocateSection(
                         i++;
                     }
  #endif
-                    else
-                       continue;  // ignore the others
-
+                    else 
+                    {
+                       barf ("Don't know how to handle this Mach-O "
+                             "scattered relocation entry: "
+                              "object file %s; entry type %ld; "
+                              "address %#lx\n", 
+                              oc->fileName, scat->r_type, scat->r_address);
+                        return 0;
+                     }
+                     
 #ifdef powerpc_HOST_ARCH
                     if(scat->r_type == GENERIC_RELOC_VANILLA
                         || scat->r_type == PPC_RELOC_SECTDIFF)
 #else
                     if(scat->r_type == GENERIC_RELOC_VANILLA
-                        || scat->r_type == GENERIC_RELOC_SECTDIFF)
+                        || scat->r_type == GENERIC_RELOC_SECTDIFF
+                        || scat->r_type == GENERIC_RELOC_LOCAL_SECTDIFF)
 #endif
                     {
                         *wordPtr = word;
@@ -4298,11 +4230,28 @@ static int relocateSection(
                     }
 #endif
                }
+               else
+               {
+                   barf("Can't handle Mach-O scattered relocation entry "
+                        "with this r_length tag: "
+                         "object file %s; entry type %ld; "
+                         "r_length tag %ld; address %#lx\n", 
+                         oc->fileName, scat->r_type, scat->r_length,
+                         scat->r_address);
+                    return 0;
+               }
            }
-
-           continue; // FIXME: I hope it's OK to ignore all the others.
+           else /* scat->r_pcrel */
+           {
+               barf("Don't know how to handle *PC-relative* Mach-O "
+                    "scattered relocation entry: "
+                     "object file %s; entry type %ld; address %#lx\n", 
+                     oc->fileName, scat->r_type, scat->r_address);
+               return 0;
+            }
+      
        }
-       else
+       else /* !(relocs[i].r_address & R_SCATTERED) */
        {
            struct relocation_info *reloc = &relocs[i];
            if(reloc->r_pcrel && !reloc->r_extern)
@@ -4347,6 +4296,14 @@ static int relocateSection(
                    word = (word & 0x03FFFFFC) | ((word & 0x02000000) ? 0xFC000000 : 0);
                }
 #endif
+                else
+                {
+                    barf("Can't handle this Mach-O relocation entry "
+                        "(not scattered): "
+                         "object file %s; entry type %ld; address %#lx\n", 
+                         oc->fileName, reloc->r_type, reloc->r_address);
+                    return 0;
+                }
 
                if(!reloc->r_extern)
                {
@@ -4438,8 +4395,16 @@ static int relocateSection(
                }
 #endif
             }
-           barf("\nunknown relocation %d",reloc->r_type);
-           return 0;
+            else
+            {
+                barf("Can't handle Mach-O relocation entry (not scattered) "
+                      "with this r_length tag: "
+                      "object file %s; entry type %ld; "
+                      "r_length tag %ld; address %#lx\n", 
+                      oc->fileName, reloc->r_type, reloc->r_length,
+                      reloc->r_address);
+                return 0;
+           }
        }
 #endif
     }
@@ -4670,7 +4635,7 @@ static void machoInitSymbolsWithoutUnderscore()
     void **p = symbolsWithoutUnderscore;
     __asm__ volatile(".globl _symbolsWithoutUnderscore\n.data\n_symbolsWithoutUnderscore:");
 
-#undef Sym
+#undef SymI_NeedsProto
 #define SymI_NeedsProto(x)  \
     __asm__ volatile(".long " # x);
 
@@ -4678,13 +4643,13 @@ static void machoInitSymbolsWithoutUnderscore()
 
     __asm__ volatile(".text");
     
-#undef Sym
+#undef SymI_NeedsProto
 #define SymI_NeedsProto(x)  \
     ghciInsertStrHashTable("(GHCi built-in symbols)", symhash, #x, *p++);
     
     RTS_MACHO_NOUNDERLINE_SYMBOLS
     
-#undef Sym
+#undef SymI_NeedsProto
 }
 #endif