#include "HsFFI.h"
#include "sm/Storage.h"
+#include "Stats.h"
#include "Hash.h"
#include "LinkerInternals.h"
#include "RtsUtils.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
#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
#if !defined(mingw32_HOST_OS)
#define RTS_USER_SIGNALS_SYMBOLS \
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) \
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 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(forkOS_createThread) \
SymI_HasProto(freeHaskellFunctionPtr) \
SymI_HasProto(getOrSetTypeableStore) \
- SymI_HasProto(getOrSetSignalHandlerStore) \
+ SymI_HasProto(getOrSetGHCConcSignalHandlerStore) \
+ SymI_HasProto(getOrSetGHCConcPendingEventsStore) \
+ SymI_HasProto(getOrSetGHCConcPendingDelaysStore) \
+ SymI_HasProto(getOrSetGHCConcIOManagerThreadStore) \
+ SymI_HasProto(getOrSetGHCConcProddingStore) \
SymI_HasProto(genSymZh) \
SymI_HasProto(genericRaise) \
SymI_HasProto(getProgArgv) \
SymI_HasProto(stg_CAF_BLACKHOLE_info) \
SymI_HasProto(__stg_EAGER_BLACKHOLE_info) \
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_writeTVarzh) \
SymI_HasProto(stg_yieldzh) \
SymI_NeedsProto(stg_interp_constr_entry) \
- SymI_HasProto(alloc_blocks) \
SymI_HasProto(alloc_blocks_lim) \
- SymI_HasProto(allocateLocal) \
+ SymI_HasProto(g0) \
+ SymI_HasProto(allocate) \
SymI_HasProto(allocateExec) \
SymI_HasProto(freeExec) \
SymI_HasProto(getAllocations) \
SymI_HasProto(n_capabilities) \
SymI_HasProto(stg_traceCcszh) \
SymI_HasProto(stg_traceEventzh) \
- RTS_USER_SIGNALS_SYMBOLS
+ RTS_USER_SIGNALS_SYMBOLS \
+ RTS_INTCHAR_SYMBOLS
// 64-bit support functions in libgcc.a
#define RTS_LIBGCC_SYMBOLS
#endif
-/* NOTE [io-manager-ghci]
-
- When GHCi loads the base package, it gets another copy of the CAFs
- in GHC.Conc that record the IO manager's ThreadId, and the blocking
- queues, so we get another IO manager. This is bad enough, but what
- is worse is that GHCi by default reverts all CAFs on every :load,
- so we'll get *another* IO manager thread (and an associated pipe)
- every time the user does :load. Miraculously, this actually
- manages to just about work in GHC 6.10 and earlier, but broke when
- I tried to fix #1185 (restarting the IO manager after a fork()).
-
- To work around it and ensure that we only have a single IO manager,
- we map the CAFs in the dynamically-loaded GHC.Conc to the
- statically-linked GHC.Conc. This is an ugly hack, but it's the
- least ugly hack that I could think of (SDM 3/11/2009)
-*/
-
-#define RTS_GHC_CONC_SYMBOLS \
- SymI_NeedsProto(base_GHCziConc_pendingDelays_closure) \
- SymI_NeedsProto(base_GHCziConc_pendingEvents_closure) \
- SymI_NeedsProto(base_GHCziConc_ioManagerThread_closure)
-
-#ifdef mingw32_HOST_OS
-#define RTS_GHC_CONC_OS_SYMBOLS /* empty */
-#else
-#define RTS_GHC_CONC_OS_SYMBOLS \
- SymI_NeedsProto(base_GHCziConc_prodding_closure) \
- SymI_NeedsProto(base_GHCziConc_sync_closure) \
- SymI_NeedsProto(base_GHCziConc_stick_closure)
-#endif
-
#if defined(darwin_HOST_OS) && defined(powerpc_HOST_ARCH)
// Symbols that don't have a leading underscore
// on Mac OS X. They have to receive special treatment,
RTS_DARWIN_ONLY_SYMBOLS
RTS_LIBGCC_SYMBOLS
RTS_LIBFFI_SYMBOLS
-RTS_GHC_CONC_SYMBOLS
-RTS_GHC_CONC_OS_SYMBOLS
#undef SymI_NeedsProto
#undef SymI_HasProto
#undef SymI_HasProto_redirect
RTS_DARWIN_ONLY_SYMBOLS
RTS_LIBGCC_SYMBOLS
RTS_LIBFFI_SYMBOLS
- RTS_GHC_CONC_SYMBOLS
- RTS_GHC_CONC_OS_SYMBOLS
#if defined(darwin_HOST_OS) && defined(i386_HOST_ARCH)
// dyld stub code contains references to this,
// but it should never be called because we treat
void *data
)
{
-#define GHC_CONC MAYBE_LEADING_UNDERSCORE_STR("base_GHCziConc")
-
- if (lookupHashTable(table, (StgWord)key) == NULL)
- {
+ if (lookupHashTable(table, (StgWord)key) == NULL)
+ {
insertStrHashTable(table, (StgWord)key, data);
return;
- }
- if (strncmp(key, GHC_CONC, strlen(GHC_CONC)) == 0) {
- /* see NOTE [io-manager-ghci] */
- return;
- }
- debugBelch(
+ }
+ debugBelch(
"\n\n"
"GHCi runtime linker: fatal error: I found a duplicate definition for symbol\n"
" %s\n"
"\n",
(char*)key,
obj_name
- );
- exit(1);
+ );
+ exit(1);
}
/* -----------------------------------------------------------------------------
* initialize the object linker
} else {
if ((W_)result > 0x80000000) {
// oops, we were given memory over 2Gb
-#if defined(freebsd_HOST_OS)
+#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.
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)
}
#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)
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)
{
}
#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
}