X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FLinker.c;h=e09a1151a86b12f72b64f299cefc1ffe36406fe1;hb=04089f99f55e719afd0c967be35e8bbb8691dbed;hp=71654435b9e0709bdb483ddc6ad5573eadfce812;hpb=03a9ff01812afc81eb5236fd3063cbec44cf469e;p=ghc-hetmet.git diff --git a/ghc/rts/Linker.c b/ghc/rts/Linker.c index 7165443..e09a115 100644 --- a/ghc/rts/Linker.c +++ b/ghc/rts/Linker.c @@ -26,6 +26,7 @@ #include "RtsUtils.h" #include "Schedule.h" #include "Storage.h" +#include "Sparks.h" #ifdef HAVE_SYS_TYPES_H #include @@ -142,6 +143,7 @@ typedef struct _RtsSymbolVal { #if !defined (mingw32_HOST_OS) #define RTS_POSIX_ONLY_SYMBOLS \ + SymX(signal_handlers) \ SymX(stg_sig_install) \ Sym(nocldstop) #endif @@ -301,6 +303,19 @@ typedef struct _RtsSymbolVal { SymX(exp) \ SymX(log) \ SymX(sqrt) \ + SymX(powf) \ + SymX(tanhf) \ + SymX(coshf) \ + SymX(sinhf) \ + SymX(atanf) \ + SymX(acosf) \ + SymX(asinf) \ + SymX(tanf) \ + SymX(cosf) \ + SymX(sinf) \ + SymX(expf) \ + SymX(logf) \ + SymX(sqrtf) \ SymX(memcpy) \ SymX(rts_InstallConsoleEvent) \ SymX(rts_ConsoleHandlerDone) \ @@ -387,7 +402,6 @@ typedef struct _RtsSymbolVal { #define RTS_RET_SYMBOLS \ SymX(stg_enter_ret) \ SymX(stg_gc_fun_ret) \ - SymX(stg_ap_0_ret) \ SymX(stg_ap_v_ret) \ SymX(stg_ap_f_ret) \ SymX(stg_ap_d_ret) \ @@ -473,6 +487,7 @@ typedef struct _RtsSymbolVal { SymX(delayzh_fast) \ SymX(deRefWeakzh_fast) \ SymX(deRefStablePtrzh_fast) \ + SymX(dirty_MUT_VAR) \ SymX(divExactIntegerzh_fast) \ SymX(divModIntegerzh_fast) \ SymX(forkzh_fast) \ @@ -525,6 +540,7 @@ typedef struct _RtsSymbolVal { SymX(newTVarzh_fast) \ SymX(atomicModifyMutVarzh_fast) \ SymX(newPinnedByteArrayzh_fast) \ + SymX(newSpark) \ SymX(orIntegerzh_fast) \ SymX(performGC) \ SymX(performMajorGC) \ @@ -596,10 +612,10 @@ typedef struct _RtsSymbolVal { SymX(stg_EMPTY_MVAR_info) \ SymX(stg_IND_STATIC_info) \ SymX(stg_INTLIKE_closure) \ + SymX(stg_MUT_ARR_PTRS_DIRTY_info) \ SymX(stg_MUT_ARR_PTRS_FROZEN_info) \ SymX(stg_MUT_ARR_PTRS_FROZEN0_info) \ SymX(stg_WEAK_info) \ - SymX(stg_ap_0_info) \ SymX(stg_ap_v_info) \ SymX(stg_ap_f_info) \ SymX(stg_ap_d_info) \ @@ -614,6 +630,21 @@ typedef struct _RtsSymbolVal { SymX(stg_ap_pppp_info) \ SymX(stg_ap_ppppp_info) \ SymX(stg_ap_pppppp_info) \ + SymX(stg_ap_0_fast) \ + SymX(stg_ap_v_fast) \ + SymX(stg_ap_f_fast) \ + SymX(stg_ap_d_fast) \ + SymX(stg_ap_l_fast) \ + SymX(stg_ap_n_fast) \ + SymX(stg_ap_p_fast) \ + SymX(stg_ap_pv_fast) \ + SymX(stg_ap_pp_fast) \ + SymX(stg_ap_ppv_fast) \ + SymX(stg_ap_ppp_fast) \ + SymX(stg_ap_pppv_fast) \ + SymX(stg_ap_pppp_fast) \ + SymX(stg_ap_ppppp_fast) \ + SymX(stg_ap_pppppp_fast) \ SymX(stg_ap_1_upd_info) \ SymX(stg_ap_2_upd_info) \ SymX(stg_ap_3_upd_info) \ @@ -653,6 +684,19 @@ typedef struct _RtsSymbolVal { SymX(writeTVarzh_fast) \ SymX(xorIntegerzh_fast) \ SymX(yieldzh_fast) \ + SymX(stg_interp_constr_entry) \ + SymX(stg_interp_constr1_entry) \ + SymX(stg_interp_constr2_entry) \ + SymX(stg_interp_constr3_entry) \ + SymX(stg_interp_constr4_entry) \ + SymX(stg_interp_constr5_entry) \ + SymX(stg_interp_constr6_entry) \ + SymX(stg_interp_constr7_entry) \ + SymX(stg_interp_constr8_entry) \ + SymX(stgMallocBytesRWX) \ + SymX(getAllocations) \ + SymX(revertCAFs) \ + SymX(RtsFlags) \ RTS_USER_SIGNALS_SYMBOLS #ifdef SUPPORT_LONG_LONGS @@ -1446,22 +1490,37 @@ static int ocAllocateJumpIslands( ObjectCode* oc, int count, int first ) n = ROUND_UP( oc->fileSize, pagesize ); m = ROUND_UP( aligned + sizeof (ppcJumpIsland) * count, pagesize ); - /* The effect of this mremap() call is only the ensure that we have - * a sufficient number of virtually contiguous pages. As returned from - * mremap, the pages past the end of the file are not backed. We give - * them a backing by using MAP_FIXED to map in anonymous pages. + /* If we have a half-page-size file and map one page of it then + * the part of the page after the size of the file remains accessible. + * If, however, we map in 2 pages, the 2nd page is not accessible + * and will give a "Bus Error" on access. To get around this, we check + * if we need any extra pages for the jump islands and map them in + * anonymously. We must check that we actually require extra pages + * otherwise the attempt to mmap 0 pages of anonymous memory will + * fail -EINVAL. */ - if( (oc->image = mremap( oc->image, n, m, MREMAP_MAYMOVE )) == MAP_FAILED ) - { - errorBelch( "Unable to mremap for Jump Islands\n" ); - return 0; - } - if( mmap( oc->image + n, m - n, PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, 0, 0 ) == MAP_FAILED ) + if( m > n ) { - errorBelch( "Unable to mmap( MAP_FIXED ) for Jump Islands\n" ); - return 0; + /* The effect of this mremap() call is only the ensure that we have + * a sufficient number of virtually contiguous pages. As returned from + * mremap, the pages past the end of the file are not backed. We give + * them a backing by using MAP_FIXED to map in anonymous pages. + */ + oc->image = mremap( oc->image, n, m, MREMAP_MAYMOVE ); + + if( oc->image == MAP_FAILED ) + { + errorBelch( "Unable to mremap for Jump Islands\n" ); + return 0; + } + + if( mmap( oc->image + n, m - n, PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, 0, 0 ) == MAP_FAILED ) + { + errorBelch( "Unable to mmap( MAP_FIXED ) for Jump Islands\n" ); + return 0; + } } #else @@ -2047,7 +2106,7 @@ ocGetNames_PEi386 ( ObjectCode* oc ) if ( bss_sz < sectab_i->SizeOfRawData) { bss_sz = sectab_i->SizeOfRawData; } zspace = stgCallocBytes(1, bss_sz, "ocGetNames_PEi386(anonymous bss)"); sectab_i->PointerToRawData = ((UChar*)zspace) - ((UChar*)(oc->image)); - addProddableBlock(oc, zspace, sectab_i->VirtualSize); + addProddableBlock(oc, zspace, bss_sz); /* debugBelch("BSS anon section at 0x%x\n", zspace); */ } @@ -2258,8 +2317,14 @@ ocResolve_PEi386 ( ObjectCode* oc ) COFF_reloc* rel = (COFF_reloc*) myindex ( sizeof_COFF_reloc, reltab, 0 ); noRelocs = rel->VirtualAddress; + + /* 10/05: we now assume (and check for) a GNU ld that is capable + * of handling object files with (>2^16) of relocs. + */ +#if 0 debugBelch("WARNING: Overflown relocation field (# relocs found: %u)\n", noRelocs); +#endif j = 1; } else { noRelocs = sectab_i->NumberOfRelocations; @@ -2734,7 +2799,7 @@ ocVerifyImage_ELF ( ObjectCode* oc ) IF_DEBUG(linker,debugBelch( "\nSection header table: start %ld, n_entries %d, ent_size %d\n", - ehdr->e_shoff, ehdr->e_shnum, ehdr->e_shentsize )); + (long)ehdr->e_shoff, ehdr->e_shnum, ehdr->e_shentsize )); ASSERT (ehdr->e_shentsize == sizeof(Elf_Shdr)); @@ -2801,7 +2866,7 @@ ocVerifyImage_ELF ( ObjectCode* oc ) nent = shdr[i].sh_size / sizeof(Elf_Sym); IF_DEBUG(linker,debugBelch( " number of entries is apparently %d (%ld rem)\n", nent, - shdr[i].sh_size % sizeof(Elf_Sym) + (long)shdr[i].sh_size % sizeof(Elf_Sym) )); if (0 != shdr[i].sh_size % sizeof(Elf_Sym)) { errorBelch("%s: non-integral number of symbol table entries", oc->fileName); @@ -3110,8 +3175,8 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC, case R_386_PC32: *pP = value - P; break; # endif default: - errorBelch("%s: unhandled ELF relocation(Rel) type %ld\n", - oc->fileName, ELF_R_TYPE(info)); + errorBelch("%s: unhandled ELF relocation(Rel) type %lu\n", + oc->fileName, (lnat)ELF_R_TYPE(info)); return 0; } @@ -3351,8 +3416,8 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC, #endif default: - errorBelch("%s: unhandled ELF relocation(RelA) type %ld\n", - oc->fileName, ELF_R_TYPE(info)); + errorBelch("%s: unhandled ELF relocation(RelA) type %lu\n", + oc->fileName, (lnat)ELF_R_TYPE(info)); return 0; } @@ -3617,8 +3682,19 @@ static int resolveImports( struct nlist *nlist) { unsigned i; + size_t itemSize = 4; + +#if i386_HOST_ARCH + int isJumpTable = 0; + if(!strcmp(sect->sectname,"__jump_table")) + { + isJumpTable = 1; + itemSize = 5; + ASSERT(sect->reserved2 == itemSize); + } +#endif - for(i=0;i*4size;i++) + for(i=0; i*itemSize < sect->size;i++) { // according to otool, reserved1 contains the first index into the indirect symbol table struct nlist *symbol = &nlist[indirectSyms[sect->reserved1+i]]; @@ -3638,8 +3714,21 @@ static int resolveImports( return 0; } ASSERT(addr); - checkProddableBlock(oc,((void**)(image + sect->offset)) + i); - ((void**)(image + sect->offset))[i] = addr; + +#if i386_HOST_ARCH + if(isJumpTable) + { + checkProddableBlock(oc,image + sect->offset + i*itemSize); + *(image + sect->offset + i*itemSize) = 0xe9; // jmp + *(unsigned*)(image + sect->offset + i*itemSize + 1) + = (char*)addr - (image + sect->offset + i*itemSize + 5); + } + else +#endif + { + checkProddableBlock(oc,((void**)(image + sect->offset)) + i); + ((void**)(image + sect->offset))[i] = addr; + } } return 1; @@ -4102,7 +4191,7 @@ static int ocResolve_MachO(ObjectCode* oc) struct load_command *lc = (struct load_command*) (image + sizeof(struct mach_header)); unsigned i; struct segment_command *segLC = NULL; - struct section *sections, *la_ptrs = NULL, *nl_ptrs = NULL; + struct section *sections; struct symtab_command *symLC = NULL; struct dysymtab_command *dsymLC = NULL; struct nlist *nlist; @@ -4122,29 +4211,32 @@ static int ocResolve_MachO(ObjectCode* oc) nlist = symLC ? (struct nlist*) (image + symLC->symoff) : NULL; - for(i=0;insects;i++) - { - if(!strcmp(sections[i].sectname,"__la_symbol_ptr")) - la_ptrs = §ions[i]; - else if(!strcmp(sections[i].sectname,"__nl_symbol_ptr")) - nl_ptrs = §ions[i]; - else if(!strcmp(sections[i].sectname,"__la_sym_ptr2")) - la_ptrs = §ions[i]; - else if(!strcmp(sections[i].sectname,"__la_sym_ptr3")) - la_ptrs = §ions[i]; - } - if(dsymLC) { unsigned long *indirectSyms = (unsigned long*) (image + dsymLC->indirectsymoff); - if(la_ptrs) - if(!resolveImports(oc,image,symLC,la_ptrs,indirectSyms,nlist)) - return 0; - if(nl_ptrs) - if(!resolveImports(oc,image,symLC,nl_ptrs,indirectSyms,nlist)) - return 0; + for(i=0;insects;i++) + { + if( !strcmp(sections[i].sectname,"__la_symbol_ptr") + || !strcmp(sections[i].sectname,"__la_sym_ptr2") + || !strcmp(sections[i].sectname,"__la_sym_ptr3")) + { + if(!resolveImports(oc,image,symLC,§ions[i],indirectSyms,nlist)) + return 0; + } + else if(!strcmp(sections[i].sectname,"__nl_symbol_ptr") + || !strcmp(sections[i].sectname,"__pointers")) + { + if(!resolveImports(oc,image,symLC,§ions[i],indirectSyms,nlist)) + return 0; + } + else if(!strcmp(sections[i].sectname,"__jump_table")) + { + if(!resolveImports(oc,image,symLC,§ions[i],indirectSyms,nlist)) + return 0; + } + } } for(i=0;insects;i++)