X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FLinker.c;h=901e0896f36eff0dce6376140bda2339dceab024;hb=0fcf892d28f9d70770717352019bd6a98b3b4651;hp=66057f744e36d37d8edb29ec66f89c0e1e4781d0;hpb=badd5d76687dc28c063cdd539ca89c9fa44a0e9e;p=ghc-hetmet.git diff --git a/ghc/rts/Linker.c b/ghc/rts/Linker.c index 66057f7..901e089 100644 --- a/ghc/rts/Linker.c +++ b/ghc/rts/Linker.c @@ -402,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) \ @@ -617,7 +616,6 @@ typedef struct _RtsSymbolVal { 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) \ @@ -632,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) \ @@ -3669,8 +3682,19 @@ static int resolveImports( struct nlist *nlist) { unsigned i; + size_t itemSize = 4; - for(i=0;i*4size;i++) +#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*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]]; @@ -3690,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; @@ -4154,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, *la_ptrs = NULL, *nl_ptrs = NULL, *jump_table = NULL; struct symtab_command *symLC = NULL; struct dysymtab_command *dsymLC = NULL; struct nlist *nlist; @@ -4184,6 +4221,10 @@ static int ocResolve_MachO(ObjectCode* oc) la_ptrs = §ions[i]; else if(!strcmp(sections[i].sectname,"__la_sym_ptr3")) la_ptrs = §ions[i]; + else if(!strcmp(sections[i].sectname,"__pointers")) + nl_ptrs = §ions[i]; + else if(!strcmp(sections[i].sectname,"__jump_table")) + jump_table = §ions[i]; } if(dsymLC) @@ -4197,6 +4238,9 @@ static int ocResolve_MachO(ObjectCode* oc) if(nl_ptrs) if(!resolveImports(oc,image,symLC,nl_ptrs,indirectSyms,nlist)) return 0; + if(jump_table) + if(!resolveImports(oc,image,symLC,jump_table,indirectSyms,nlist)) + return 0; } for(i=0;insects;i++)