#include "RtsUtils.h"
#include "Schedule.h"
#include "Sparks.h"
-#include "RtsTypeable.h"
+#include "RtsGlobals.h"
#include "Timer.h"
+#include "Trace.h"
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
static int ocVerifyImage_PEi386 ( ObjectCode* oc );
static int ocGetNames_PEi386 ( ObjectCode* oc );
static int ocResolve_PEi386 ( ObjectCode* oc );
-static void zapTrailingAtSign ( unsigned char* sym );
+static void *lookupSymbolInDLLs ( unsigned char *lbl );
+static void zapTrailingAtSign ( unsigned char *sym );
#elif defined(OBJFORMAT_MACHO)
static int ocVerifyImage_MachO ( ObjectCode* oc );
static int ocGetNames_MachO ( ObjectCode* oc );
*/
#define X86_64_ELF_NONPIC_HACK 1
+/* Link objects into the lower 2Gb on x86_64. GHC assumes the
+ * small memory model on this architecture (see gcc docs,
+ * -mcmodel=small).
+ *
+ * MAP_32BIT not available on OpenBSD/amd64
+ */
+#if defined(x86_64_HOST_ARCH) && defined(MAP_32BIT)
+#define TRY_MAP_32BIT MAP_32BIT
+#else
+#define TRY_MAP_32BIT 0
+#endif
+
+/*
+ * Due to the small memory model (see above), on x86_64 we have to map
+ * all our non-PIC object files into the low 2Gb of the address space
+ * (why 2Gb and not 4Gb? Because all addresses must be reachable
+ * using a 32-bit signed PC-relative offset). On Linux we can do this
+ * using the MAP_32BIT flag to mmap(), however on other OSs
+ * (e.g. *BSD, see #2063, and also on Linux inside Xen, see #2512), we
+ * can't do this. So on these systems, we have to pick a base address
+ * in the low 2Gb of the address space and try to allocate memory from
+ * there.
+ *
+ * We pick a default address based on the OS, but also make this
+ * configurable via an RTS flag (+RTS -xm)
+ */
+#if defined(x86_64_HOST_ARCH)
+
+#if defined(MAP_32BIT)
+// Try to use MAP_32BIT
+#define MMAP_32BIT_BASE_DEFAULT 0
+#else
+// A guess: 1Gb.
+#define MMAP_32BIT_BASE_DEFAULT 0x40000000
+#endif
+
+static void *mmap_32bit_base = (void *)MMAP_32BIT_BASE_DEFAULT;
+#endif
+
+/* MAP_ANONYMOUS is MAP_ANON on some systems, e.g. OpenBSD */
+#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
/* -----------------------------------------------------------------------------
* Built-in symbols from the RTS
*/
void *addr;
} RtsSymbolVal;
-#if !defined(PAR)
#define Maybe_Stable_Names SymI_HasProto(mkWeakzh_fast) \
+ SymI_HasProto(mkWeakForeignEnvzh_fast) \
SymI_HasProto(makeStableNamezh_fast) \
SymI_HasProto(finalizzeWeakzh_fast)
-#else
-/* These are not available in GUM!!! -- HWL */
-#define Maybe_Stable_Names
-#endif
#if !defined (mingw32_HOST_OS)
#define RTS_POSIX_ONLY_SYMBOLS \
#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_NeedsProto(iscntrl) \
SymI_NeedsProto(isalpha) \
SymI_NeedsProto(isalnum) \
+ SymI_NeedsProto(isascii) \
+ RTS___MINGW_VFPRINTF_SYM \
SymI_HasProto(strcmp) \
SymI_HasProto(memmove) \
SymI_HasProto(realloc) \
#if !defined(mingw32_HOST_OS)
#define RTS_USER_SIGNALS_SYMBOLS \
- SymI_HasProto(setIOManagerPipe)
+ SymI_HasProto(setIOManagerPipe) \
+ SymI_NeedsProto(blockUserSignals) \
+ SymI_NeedsProto(unblockUserSignals)
#else
#define RTS_USER_SIGNALS_SYMBOLS \
SymI_HasProto(sendIOManagerEvent) \
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)
-#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)
-#endif
-
#define RTS_SYMBOLS \
Maybe_Stable_Names \
SymI_HasProto(StgReturn) \
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(barf) \
SymI_HasProto(debugBelch) \
SymI_HasProto(errorBelch) \
+ SymI_HasProto(sysErrorBelch) \
SymI_HasProto(asyncExceptionsBlockedzh_fast) \
SymI_HasProto(blockAsyncExceptionszh_fast) \
SymI_HasProto(catchzh_fast) \
SymI_HasProto(checkzh_fast) \
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(defaultsHook) \
SymI_HasProto(deRefWeakzh_fast) \
SymI_HasProto(deRefStablePtrzh_fast) \
SymI_HasProto(dirty_MUT_VAR) \
- SymI_HasProto(divExactIntegerzh_fast) \
- SymI_HasProto(divModIntegerzh_fast) \
SymI_HasProto(forkzh_fast) \
SymI_HasProto(forkOnzh_fast) \
SymI_HasProto(forkProcess) \
SymI_HasProto(freeHaskellFunctionPtr) \
SymI_HasProto(freeStablePtr) \
SymI_HasProto(getOrSetTypeableStore) \
- SymI_HasProto(gcdIntegerzh_fast) \
- SymI_HasProto(gcdIntegerIntzh_fast) \
- SymI_HasProto(gcdIntzh_fast) \
+ SymI_HasProto(getOrSetSignalHandlerStore) \
SymI_HasProto(genSymZh) \
SymI_HasProto(genericRaise) \
SymI_HasProto(getProgArgv) \
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(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(noDuplicatezh_fast) \
SymI_HasProto(atomicModifyMutVarzh_fast) \
SymI_HasProto(newPinnedByteArrayzh_fast) \
+ SymI_HasProto(newAlignedPinnedByteArrayzh_fast) \
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(resumeThread) \
SymI_HasProto(resolveObjs) \
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(stable_ptr_table) \
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_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) \
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(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_NeedsProto(stg_interp_constr_entry) \
+ SymI_HasProto(alloc_blocks) \
+ SymI_HasProto(alloc_blocks_lim) \
+ SymI_HasProto(allocateLocal) \
SymI_HasProto(allocateExec) \
SymI_HasProto(freeExec) \
SymI_HasProto(getAllocations) \
SymI_NeedsProto(rts_stop_on_exception) \
SymI_HasProto(stopTimer) \
SymI_HasProto(n_capabilities) \
+ SymI_HasProto(traceCcszh_fast) \
RTS_USER_SIGNALS_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
#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
static RtsSymbolVal rtsSyms[] = {
RTS_SYMBOLS
RTS_RET_SYMBOLS
- RTS_LONG_LONG_SYMS
RTS_POSIX_ONLY_SYMBOLS
RTS_MINGW_ONLY_SYMBOLS
RTS_CYGWIN_ONLY_SYMBOLS
dl_prog_handle = dlopen(NULL, RTLD_LAZY);
# endif /* RTLD_DEFAULT */
# endif
+
+#if defined(x86_64_HOST_ARCH)
+ if (RtsFlags.MiscFlags.linkerMemBase != 0) {
+ // User-override for mmap_32bit_base
+ 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
}
/* -----------------------------------------------------------------------------
}
# endif /* HAVE_DLFCN_H */
# elif defined(OBJFORMAT_PEi386)
- OpenedDLL* o_dll;
void* sym;
- zapTrailingAtSign ( lbl );
+ sym = lookupSymbolInDLLs(lbl);
+ if (sym != NULL) { return sym; };
- for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) {
- /* 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
- a Rule that governs whether an initial '_' *should always* be
- stripped off when mapping from import lib name to the DLL name.
- */
- sym = GetProcAddress(o_dll->instance, (lbl+1));
- if (sym != NULL) {
- /*debugBelch("found %s in %s\n", lbl+1,o_dll->name);*/
- return sym;
- }
- }
- sym = GetProcAddress(o_dll->instance, lbl);
- if (sym != NULL) {
- /*debugBelch("found %s in %s\n", lbl,o_dll->name);*/
- return sym;
- }
- }
+ // Also try looking up the symbol without the @N suffix. Some
+ // DLLs have the suffixes on their symbols, some don't.
+ zapTrailingAtSign ( lbl );
+ sym = lookupSymbolInDLLs(lbl);
+ if (sym != NULL) { return sym; };
return NULL;
+
# else
ASSERT(2+2 == 5);
return NULL;
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:
+
+ if (mmap_32bit_base != 0) {
+ map_addr = mmap_32bit_base;
+ }
+#endif
+
+ 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 %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 + size;
+ } else {
+ if ((W_)result > 0x80000000) {
+ // oops, we were given memory over 2Gb
+#if defined(freebsd_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 + size;
+ }
+ }
+ } else {
+ if ((W_)result > 0x80000000) {
+ // 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, size);
+
+ // Set a base address and try again... (guess: 1Gb)
+ mmap_32bit_base = (void*)0x40000000;
+ goto mmap_again;
+ }
+ }
+#endif
+
+ return result;
+}
+#endif // USE_MMAP
+
/* -----------------------------------------------------------------------------
* Load an obj (populate the global symbol table, but don't resolve yet)
*
{
ObjectCode* oc;
struct stat st;
- int r, n;
+ int r;
#ifdef USE_MMAP
- int fd, pagesize;
- void *map_addr = NULL;
+ int fd;
#else
FILE *f;
#endif
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)
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 */
+ {
+ int pagesize, n;
+ pagesize = getpagesize();
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)
oc->pltIndex = 0;
map_addr = oc->plt + n;
-#endif
n = ROUND_UP(oc->fileSize, pagesize);
-
- /* Link objects into the lower 2Gb on x86_64. GHC assumes the
- * small memory model on this architecture (see gcc docs,
- * -mcmodel=small).
- *
- * MAP_32BIT not available on OpenBSD/amd64
- */
-#if defined(x86_64_HOST_ARCH) && defined(MAP_32BIT)
-#define EXTRA_MAP_FLAGS MAP_32BIT
-#else
-#define EXTRA_MAP_FLAGS 0
-#endif
-
- /* MAP_ANONYMOUS is MAP_ANON on some systems, e.g. OpenBSD */
-#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
-#define MAP_ANONYMOUS MAP_ANON
-#endif
-
oc->image = mmap(map_addr, n, PROT_EXEC|PROT_READ|PROT_WRITE,
- MAP_PRIVATE|EXTRA_MAP_FLAGS, fd, 0);
+ MAP_PRIVATE|TRY_MAP_32BIT, fd, 0);
if (oc->image == MAP_FAILED)
barf("loadObj: can't map `%s'", path);
+ }
+#else
+ oc->image = mmapForLinker(oc->fileSize, 0, fd);
+#endif
close(fd);
#else /* !USE_MMAP */
-
/* load the image into memory */
f = fopen(path, "rb");
if (!f)
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 */
*/
if( m > n ) // we need to allocate more pages
{
- oc->symbol_extras = mmap (NULL, sizeof(SymbolExtra) * count,
- PROT_EXEC|PROT_READ|PROT_WRITE,
- MAP_PRIVATE|MAP_ANONYMOUS|EXTRA_MAP_FLAGS,
- 0, 0);
- if (oc->symbol_extras == MAP_FAILED)
- {
- errorBelch( "Unable to mmap() for jump islands\n" );
- return 0;
- }
-#ifdef x86_64_HOST_ARCH
- if ((StgWord)oc->symbol_extras > 0x80000000)
- {
- barf("mmap() returned memory outside 2Gb");
- }
-#endif
+ oc->symbol_extras = mmapForLinker(sizeof(SymbolExtra) * count,
+ MAP_ANONYMOUS, -1);
}
else
{
# undef my_isdigit
}
+static void *
+lookupSymbolInDLLs ( UChar *lbl )
+{
+ OpenedDLL* o_dll;
+ void *sym;
+
+ for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) {
+ /* 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
+ a Rule that governs whether an initial '_' *should always* be
+ stripped off when mapping from import lib name to the DLL name.
+ */
+ sym = GetProcAddress(o_dll->instance, (lbl+1));
+ if (sym != NULL) {
+ /*debugBelch("found %s in %s\n", lbl+1,o_dll->name);*/
+ return sym;
+ }
+ }
+ sym = GetProcAddress(o_dll->instance, lbl);
+ if (sym != NULL) {
+ /*debugBelch("found %s in %s\n", lbl,o_dll->name);*/
+ return sym;
+ }
+ }
+ return NULL;
+}
+
static int
ocVerifyImage_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:;
}
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;
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;
void **p = symbolsWithoutUnderscore;
__asm__ volatile(".globl _symbolsWithoutUnderscore\n.data\n_symbolsWithoutUnderscore:");
-#undef Sym
+#undef SymI_NeedsProto
#define SymI_NeedsProto(x) \
__asm__ volatile(".long " # x);
__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