X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FLinker.c;h=cd6e03d8e90beb4248b36d75ab439e42c0acb828;hb=ab3d1f285cef784138d99e70f7359ea6e67f6c25;hp=4fb0ed6d9e768a7cf4f96f83d1e8a7e1ffa179c6;hpb=04e294bda9f5127d3d5f09d20491e52b7f796d7a;p=ghc-hetmet.git diff --git a/ghc/rts/Linker.c b/ghc/rts/Linker.c index 4fb0ed6..cd6e03d 100644 --- a/ghc/rts/Linker.c +++ b/ghc/rts/Linker.c @@ -38,9 +38,7 @@ #include #endif -#if defined(HAVE_FRAMEWORK_HASKELLSUPPORT) -#include -#elif defined(HAVE_DLFCN_H) +#if defined(HAVE_DLFCN_H) #include #endif @@ -298,11 +296,13 @@ typedef struct _RtsSymbolVal { SymX(log) \ SymX(sqrt) \ SymX(memcpy) \ - SymX(stg_InstallConsoleEvent) \ + SymX(rts_InstallConsoleEvent) \ + SymX(rts_ConsoleHandlerDone) \ Sym(mktime) \ Sym(_imp___timezone) \ Sym(_imp___tzname) \ Sym(_imp___iob) \ + Sym(_imp___osver) \ Sym(localtime) \ Sym(gmtime) \ Sym(opendir) \ @@ -318,6 +318,14 @@ typedef struct _RtsSymbolVal { # define MAIN_CAP_SYM #endif +#if !defined(mingw32_HOST_OS) +#define RTS_USER_SIGNALS_SYMBOLS \ + SymX(startSignalHandler) \ + SymX(setIOManagerPipe) +#else +#define RTS_USER_SIGNALS_SYMBOLS /* nothing */ +#endif + #ifdef TABLES_NEXT_TO_CODE #define RTS_RET_SYMBOLS /* nothing */ #else @@ -530,7 +538,6 @@ typedef struct _RtsSymbolVal { SymX(stable_ptr_table) \ SymX(stackOverflow) \ SymX(stg_CAF_BLACKHOLE_info) \ - SymX(stg_BLACKHOLE_BQ_info) \ SymX(awakenBlockedQueue) \ SymX(stg_CHARLIKE_closure) \ SymX(stg_EMPTY_MVAR_info) \ @@ -592,7 +599,8 @@ typedef struct _RtsSymbolVal { SymX(word2Integerzh_fast) \ SymX(writeTVarzh_fast) \ SymX(xorIntegerzh_fast) \ - SymX(yieldzh_fast) + SymX(yieldzh_fast) \ + RTS_USER_SIGNALS_SYMBOLS #ifdef SUPPORT_LONG_LONGS #define RTS_LONG_LONG_SYMS \ @@ -758,7 +766,7 @@ initLinker( void ) # if defined(openbsd_HOST_OS) dl_libc_handle = dlopen("libc.so", RTLD_LAZY); # endif -# endif // RTLD_DEFAULT +# endif /* RTLD_DEFAULT */ # endif } @@ -1096,7 +1104,19 @@ loadObj( char *path ) #endif n = ROUND_UP(oc->fileSize, pagesize); - oc->image = mmap(map_addr, n, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); + + /* Link objects into the lower 2Gb on x86_64. GHC assumes the + * small memory model on this architecture (see gcc docs, + * -mcmodel=small). + */ +#ifdef x86_64_HOST_ARCH +#define EXTRA_MAP_FLAGS MAP_32BIT +#else +#define EXTRA_MAP_FLAGS 0 +#endif + + oc->image = mmap(map_addr, n, PROT_EXEC|PROT_READ|PROT_WRITE, + MAP_PRIVATE|EXTRA_MAP_FLAGS, fd, 0); if (oc->image == MAP_FAILED) barf("loadObj: can't map `%s'", path); @@ -1943,6 +1963,7 @@ ocGetNames_PEi386 ( ObjectCode* oc ) # endif if (0==strcmp(".text",sectab_i->Name) || + 0==strcmp(".rdata",sectab_i->Name)|| 0==strcmp(".rodata",sectab_i->Name)) kind = SECTIONKIND_CODE_OR_RODATA; if (0==strcmp(".data",sectab_i->Name) || @@ -1961,8 +1982,10 @@ ocGetNames_PEi386 ( ObjectCode* oc ) information. */ && 0 != strcmp(".stab", sectab_i->Name) && 0 != strcmp(".stabstr", sectab_i->Name) + /* ignore constructor section for now */ + && 0 != strcmp(".ctors", sectab_i->Name) ) { - errorBelch("Unknown PEi386 section name `%s'", sectab_i->Name); + errorBelch("Unknown PEi386 section name `%s' (while processing: %s)", sectab_i->Name, oc->fileName); return 0; } @@ -2104,7 +2127,8 @@ ocResolve_PEi386 ( ObjectCode* oc ) /* Ignore sections called which contain stabs debugging information. */ if (0 == strcmp(".stab", sectab_i->Name) - || 0 == strcmp(".stabstr", sectab_i->Name)) + || 0 == strcmp(".stabstr", sectab_i->Name) + || 0 == strcmp(".ctors", sectab_i->Name)) continue; if ( sectab_i->Characteristics & MYIMAGE_SCN_LNK_NRELOC_OVFL ) { @@ -2183,7 +2207,7 @@ ocResolve_PEi386 ( ObjectCode* oc ) /* Newline first because the interactive linker has printed "linking..." */ errorBelch("\n%s: unknown symbol `%s'", oc->fileName, symbol); return 0; - foundit: + foundit:; } checkProddableBlock(oc, pP); switch (reltab_j->Type) { @@ -2201,9 +2225,22 @@ ocResolve_PEi386 ( ObjectCode* oc ) -- hence the constant 4. Also I don't know if A should be added, but so far it has always been zero. + + SOF 05/2005: 'A' (old contents of *pP) have been observed + to contain values other than zero (the 'wx' object file + that came with wxhaskell-0.9.4; dunno how it was compiled..). + So, add displacement to old value instead of asserting + A to be zero. Fixes wxhaskell-related crashes, and no other + ill effects have been observed. + + Update: the reason why we're seeing these more elaborate + relocations is due to a switch in how the NCG compiles SRTs + and offsets to them from info tables. SRTs live in .(ro)data, + while info tables live in .text, causing GAS to emit REL32/DISP32 + relocations with non-zero values. Adding the displacement is + the right thing to do. */ - ASSERT(A==0); - *pP = S - ((UInt32)pP) - 4; + *pP = S - ((UInt32)pP) - 4 + A; break; default: debugBelch("%s: unhandled PEi386 relocation type %d", @@ -2516,6 +2553,9 @@ ocVerifyImage_ELF ( ObjectCode* oc ) case EM_IA_64: IF_DEBUG(linker,debugBelch( "ia64" )); break; #endif case EM_PPC: IF_DEBUG(linker,debugBelch( "powerpc32" )); break; +#ifdef EM_X86_64 + case EM_X86_64: IF_DEBUG(linker,debugBelch( "x86_64" )); break; +#endif default: IF_DEBUG(linker,debugBelch( "unknown" )); errorBelch("%s: unknown architecture", oc->fileName); return 0; @@ -2929,7 +2969,7 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC, target_shndx, symtab_shndx )); for (j = 0; j < nent; j++) { -#if defined(DEBUG) || defined(sparc_HOST_ARCH) || defined(ia64_HOST_ARCH) || defined(powerpc_HOST_ARCH) +#if defined(DEBUG) || defined(sparc_HOST_ARCH) || defined(ia64_HOST_ARCH) || defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH) /* This #ifdef only serves to avoid unused-var warnings. */ Elf_Addr offset = rtab[j].r_offset; Elf_Addr P = targ + offset; @@ -3105,6 +3145,25 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC, | (delta & 0x3fffffc); break; # endif + +#if x86_64_HOST_OS + case R_X86_64_64: + *(Elf64_Xword *)P = value; + break; + + case R_X86_64_PC32: + *(Elf64_Word *)P = (Elf64_Word) (value - P); + break; + + case R_X86_64_32: + *(Elf64_Word *)P = (Elf64_Word)value; + break; + + case R_X86_64_32S: + *(Elf64_Sword *)P = (Elf64_Sword)value; + break; +#endif + default: errorBelch("%s: unhandled ELF relocation(RelA) type %d\n", oc->fileName, ELF_R_TYPE(info)); @@ -3324,7 +3383,7 @@ static int ocAllocateJumpIslands_MachO(ObjectCode* oc) // symbol, so we don't have to allocate too many // jump islands. struct symtab_command *symLC = (struct symtab_command *) lc; - int min = symLC->nsyms, max = 0; + unsigned min = symLC->nsyms, max = 0; struct nlist *nlist = symLC ? (struct nlist*) ((char*) oc->image + symLC->symoff) : NULL; @@ -3355,7 +3414,7 @@ static int ocAllocateJumpIslands_MachO(ObjectCode* oc) return ocAllocateJumpIslands(oc,0,0); } -static int ocVerifyImage_MachO(ObjectCode* oc) +static int ocVerifyImage_MachO(ObjectCode* oc STG_UNUSED) { // FIXME: do some verifying here return 1; @@ -3398,7 +3457,7 @@ static int resolveImports( return 1; } -static char* relocateAddress( +static unsigned long relocateAddress( ObjectCode* oc, int nSections, struct section* sections, @@ -3410,12 +3469,13 @@ static char* relocateAddress( if(sections[i].addr <= address && address < sections[i].addr + sections[i].size) { - return oc->image + sections[i].offset + address - sections[i].addr; + return (unsigned long)oc->image + + sections[i].offset + address - sections[i].addr; } } barf("Invalid Mach-O file:" "Address out of bounds while relocating object file"); - return NULL; + return 0; } static int relocateSection( @@ -3551,7 +3611,9 @@ static int relocateSection( { unsigned long word = 0; unsigned long jumpIsland = 0; - long offsetToJumpIsland; + long offsetToJumpIsland = 0xBADBAD42; // initialise to bad value + // to avoid warning and to catch + // bugs. unsigned long* wordPtr = (unsigned long*) (image + sect->offset + reloc->r_address); checkProddableBlock(oc,wordPtr); @@ -3595,7 +3657,7 @@ static int relocateSection( { struct nlist *symbol = &nlist[reloc->r_symbolnum]; char *nm = image + symLC->stroff + symbol->n_un.n_strx; - unsigned long symbolAddress = (unsigned long) (lookupSymbol(nm)); + void *symbolAddress = lookupSymbol(nm); if(!symbolAddress) { errorBelch("\nunknown symbol `%s'", nm); @@ -3607,7 +3669,7 @@ static int relocateSection( // In the .o file, this should be a relative jump to NULL // and we'll change it to a jump to a relative jump to the symbol ASSERT(-word == reloc->r_address); - word = symbolAddress; + word = (unsigned long) symbolAddress; jumpIsland = makeJumpIsland(oc,reloc->r_symbolnum,word); word -= ((long)image) + sect->offset + reloc->r_address; if(jumpIsland != 0) @@ -3618,7 +3680,7 @@ static int relocateSection( } else { - word += symbolAddress; + word += (unsigned long) symbolAddress; } } @@ -3676,7 +3738,7 @@ static int ocGetNames_MachO(ObjectCode* oc) char *image = (char*) oc->image; struct mach_header *header = (struct mach_header*) image; struct load_command *lc = (struct load_command*) (image + sizeof(struct mach_header)); - unsigned i,curSymbol; + unsigned i,curSymbol = 0; struct segment_command *segLC = NULL; struct section *sections; struct symtab_command *symLC = NULL; @@ -3758,7 +3820,6 @@ static int ocGetNames_MachO(ObjectCode* oc) if(symLC) { - curSymbol = 0; for(i=0;insyms;i++) { if(nlist[i].n_type & N_STAB) @@ -3891,7 +3952,7 @@ static void machoInitSymbolsWithoutUnderscore() { extern void* symbolsWithoutUnderscore[]; void **p = symbolsWithoutUnderscore; - __asm__ volatile(".data\n_symbolsWithoutUnderscore:"); + __asm__ volatile(".globl _symbolsWithoutUnderscore\n.data\n_symbolsWithoutUnderscore:"); #undef Sym #define Sym(x) \