X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=rts%2FLinker.c;h=283103fdd2ed46d3090020210fd17b187b22034a;hp=4fcfadead5ad3ac18feca15f2026ad1294a46632;hb=2016964946f0bff4753295bd4918f98cc1195a7c;hpb=01014815a071a8ffd2fa1225c0f196a3e76fdb74 diff --git a/rts/Linker.c b/rts/Linker.c index 4fcfade..283103f 100644 --- a/rts/Linker.c +++ b/rts/Linker.c @@ -26,7 +26,7 @@ #include "RtsUtils.h" #include "Schedule.h" #include "Sparks.h" -#include "RtsTypeable.h" +#include "RtsGlobals.h" #include "Timer.h" #include "Trace.h" @@ -205,7 +205,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,14 +222,10 @@ typedef struct _RtsSymbolVal { 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 \ @@ -492,7 +488,9 @@ typedef struct _RtsSymbolVal { #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) \ @@ -592,8 +590,6 @@ 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) \ @@ -606,6 +602,7 @@ typedef struct _RtsSymbolVal { SymI_HasProto(barf) \ SymI_HasProto(debugBelch) \ SymI_HasProto(errorBelch) \ + SymI_HasProto(sysErrorBelch) \ SymI_HasProto(asyncExceptionsBlockedzh_fast) \ SymI_HasProto(blockAsyncExceptionszh_fast) \ SymI_HasProto(catchzh_fast) \ @@ -619,7 +616,6 @@ typedef struct _RtsSymbolVal { 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) \ @@ -636,6 +632,7 @@ typedef struct _RtsSymbolVal { SymI_HasProto(freeHaskellFunctionPtr) \ SymI_HasProto(freeStablePtr) \ SymI_HasProto(getOrSetTypeableStore) \ + SymI_HasProto(getOrSetSignalHandlerStore) \ SymI_HasProto(gcdIntegerzh_fast) \ SymI_HasProto(gcdIntegerIntzh_fast) \ SymI_HasProto(gcdIntzh_fast) \ @@ -652,6 +649,7 @@ 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) \ @@ -689,6 +687,7 @@ typedef struct _RtsSymbolVal { 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) \ @@ -855,6 +854,7 @@ typedef struct _RtsSymbolVal { 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 @@ -1047,6 +1047,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 } /* ----------------------------------------------------------------------------- @@ -1294,11 +1304,18 @@ 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 +1325,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 -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 = 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 -RTS", bytes, map_addr, result); +#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 -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 = (void*)result + size; } } } else { @@ -1337,7 +1363,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 +1386,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 +1448,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,10 +1458,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 */ + { + 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) @@ -1445,23 +1470,20 @@ loadObj( char *path ) 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); + oc->image = mmapForLinker(oc->fileSize, 0, fd); #endif close(fd); #else /* !USE_MMAP */ - /* load the image into memory */ f = fopen(path, "rb"); if (!f) @@ -1489,10 +1511,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 +1753,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 +2660,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:; } @@ -3513,17 +3536,26 @@ 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; @@ -4078,7 +4110,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; @@ -4670,7 +4704,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 +4712,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