Changeset 582
- Timestamp:
- 07/23/10 22:58:11 (14 years ago)
- Files:
-
- branches/dmd-1.x/src/backend/cod3.c (modified) (1 diff)
- branches/dmd-1.x/src/backend/elfobj.c (modified) (2 diffs)
- branches/dmd-1.x/src/backend/global.h (modified) (1 diff)
- trunk/src/backend/cod3.c (modified) (1 diff)
- trunk/src/backend/elfobj.c (modified) (2 diffs)
- trunk/src/backend/global.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/dmd-1.x/src/backend/cod3.c
r581 r582 2931 2931 #endif 2932 2932 2933 2933 if (b) 2934 2934 { bn = b->Bnext; 2935 2935 usespace = (config.flags4 & CFG4space && b->BC != BCasm); 2936 2936 useopsize = (I16 || (config.flags4 & CFG4space && b->BC != BCasm)); 2937 2937 } 2938 2938 else 2939 2939 { bn = NULL; 2940 2940 usespace = (config.flags4 & CFG4space); 2941 2941 useopsize = (I16 || config.flags4 & CFG4space); 2942 2942 } 2943 2943 for (; c; c = code_next(c)) 2944 2944 { 2945 2945 L1: 2946 2946 op = c->Iop; 2947 2947 if (op == 0x0F) 2948 2948 ins = inssize2[c->Iop2]; 2949 2949 else 2950 2950 ins = inssize[c->Iop]; 2951 if ( ins & M) // if modregrm byte2951 if (I32 && ins & M) // if modregrm byte 2952 2952 { int shortop = (c->Iflags & CFopsize) ? !I16 : I16; 2953 2953 int local_BPRM = BPRM; 2954 2954 2955 2955 if (c->Iflags & CFaddrsize) 2956 2956 local_BPRM ^= 5 ^ 6; // toggle between 5 and 6 2957 2957 2958 2958 unsigned rm = c->Irm; 2959 2959 unsigned reg = rm & modregrm(0,7,0); // isolate reg field 2960 2960 unsigned ereg = rm & 7; 2961 2961 //printf("c = %p, op = %02x rm = %02x\n", c, op, rm); 2962 2962 2963 2963 /* If immediate second operand */ 2964 2964 if ((ins & T || op == 0xF6 || op == 0xF7) && 2965 2965 c->IFL2 == FLconst) 2966 2966 { 2967 2967 int flags = c->Iflags & CFpsw; /* if want result in flags */ 2968 2968 targ_long u = c->IEV2.Vuns; 2969 2969 if (ins & E) 2970 2970 u = (signed char) u; 2971 2971 else if (shortop) branches/dmd-1.x/src/backend/elfobj.c
r581 r582 2230 2230 relsec->sh_link = SHI_SYMTAB; 2231 2231 relsec->sh_info = secidx; 2232 2232 relsec->sh_entsize = sizeof(Elf64_Rela); 2233 2233 relsec->sh_addralign = 8; 2234 2234 } 2235 2235 else 2236 2236 { 2237 2237 Elf32_Shdr *relsec = &SecHdrTab[relidx]; 2238 2238 relsec->sh_link = SHI_SYMTAB; 2239 2239 relsec->sh_info = secidx; 2240 2240 relsec->sh_entsize = sizeof(Elf32_Rel); 2241 2241 relsec->sh_addralign = 4; 2242 2242 } 2243 2243 } 2244 2244 2245 2245 if (I64) 2246 2246 { 2247 2247 Elf64_Rela rel; 2248 2248 rel.r_offset = offset; // build relocation information 2249 2249 rel.r_info = ELF64_R_INFO(symidx,type); 2250 rel.r_addend = 0;2250 rel.r_addend = val; 2251 2251 buf = segdata->SDrel; 2252 2252 buf->write(&rel,sizeof(rel)); 2253 2253 segdata->SDrelcnt++; 2254 2254 2255 2255 if (offset >= segdata->SDrelmaxoff) 2256 2256 segdata->SDrelmaxoff = offset; 2257 2257 else 2258 2258 { // insert numerically 2259 2259 Elf64_Rela *relbuf = (Elf64_Rela *)buf->buf; 2260 2260 int i = relbuf[segdata->SDrelindex].r_offset > offset ? 0 : segdata->SDrelindex; 2261 2261 while (i < segdata->SDrelcnt) 2262 2262 { 2263 2263 if (relbuf[i].r_offset > offset) 2264 2264 break; 2265 2265 i++; 2266 2266 } 2267 2267 assert(i != segdata->SDrelcnt); // slide greater offsets down 2268 2268 memmove(relbuf+i+1,relbuf+i,sizeof(Elf64_Rela) * (segdata->SDrelcnt - i - 1)); 2269 2269 *(relbuf+i) = rel; // copy to correct location 2270 2270 segdata->SDrelindex = i; // next entry usually greater … … 2504 2504 return retsize; 2505 2505 } 2506 2506 else 2507 2507 { 2508 2508 int save; 2509 2509 buf = SegData[seg]->SDbuf; 2510 2510 save = buf->size(); 2511 2511 buf->setsize(offset); 2512 2512 if (flags & CFselfrel) 2513 2513 { // only for function references within code segments 2514 2514 if (!external && // local definition found 2515 2515 s->Sseg == seg && // within same code segment 2516 2516 (!(config.flags3 & CFG3pic) || // not position indp code 2517 2517 s->Sclass == SCstatic)) // or is pic, but declared static 2518 2518 { // Can use PC relative 2519 2519 //dbg_printf("\tdoing PC relative\n"); 2520 2520 val = (s->Soffset+val) - (offset+4); 2521 2521 } 2522 2522 else 2523 2523 { 2524 val = (targ_size_t)-4;2525 2524 //dbg_printf("\tadding relocation\n"); 2526 2525 if (I64) 2527 relinfo = config.flags3 & CFG3pic ? R_X86_64_PLT32 : R_X86_64_PC32; 2526 { relinfo = config.flags3 & CFG3pic ? R_X86_64_PLT32 : R_X86_64_PC32; 2527 elf_addrel(seg,offset, relinfo, s->Sxtrnnum, -4); 2528 val = 0; 2529 } 2528 2530 else 2529 relinfo = config.flags3 & CFG3pic ? RI_TYPE_PLT32 : RI_TYPE_PC32;2530 elf_addrel(seg,offset,2531 relinfo,2532 s->Sxtrnnum,0);2531 { relinfo = config.flags3 & CFG3pic ? RI_TYPE_PLT32 : RI_TYPE_PC32; 2532 elf_addrel(seg,offset, relinfo, s->Sxtrnnum, 0); 2533 val = (targ_size_t)-4; 2534 } 2533 2535 } 2534 if (I64)2535 val += 4;2536 2536 } 2537 2537 else 2538 2538 { // code to code code to data, data to code, data to data refs 2539 2539 refseg = s->Sxtrnnum; // default to name symbol table entry 2540 2540 if (s->Sclass == SCstatic) 2541 2541 { // offset into .data or .bss seg 2542 2542 refseg = MAP_SEG2SYMIDX(s->Sseg); 2543 2543 // use segment symbol table entry 2544 2544 val += s->Soffset; 2545 2545 if (!(config.flags3 & CFG3pic) || // all static refs from normal code 2546 2546 segtyp == DATA) // or refs from data from posi indp 2547 2547 { 2548 2548 relinfo = I64 ? R_X86_64_32 : RI_TYPE_SYM32; 2549 2549 } 2550 2550 else 2551 2551 { 2552 2552 relinfo = I64 ? R_X86_64_PC32 : RI_TYPE_GOTOFF; 2553 2553 } 2554 2554 } 2555 2555 else if (config.flags3 & CFG3pic && s == GOTsym) branches/dmd-1.x/src/backend/global.h
r552 r582 534 534 #if MACHOBJ 535 535 int mach_getsegment(const char *sectname, const char *segname, 536 536 int align, int flags, int flags2 = 0); 537 537 void mach_addrel(int seg, targ_size_t offset, symbol *targsym, 538 538 unsigned targseg, int rtype); 539 539 #endif 540 540 void elf_func_start(Symbol *sfunc); 541 541 int elf_data_start(Symbol *sdata, targ_size_t datasize, int seg); 542 542 void elf_func_term(Symbol *sfunc); 543 543 unsigned elf_addstr(Outbuffer *strtab, const char *); 544 544 545 545 void dwarf_CFA_set_loc(size_t location); 546 546 void dwarf_CFA_set_reg_offset(int reg, int offset); 547 547 void dwarf_CFA_offset(int reg, int offset); 548 548 void dwarf_CFA_args_size(size_t sz); 549 549 #endif 550 550 551 551 #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 552 552 void elfobj_gotref(symbol *s); 553 553 symbol *elfobj_getGOTsym(); 554 void elfobj_refGOTsym(); 554 555 elem * exp_isconst(); 555 556 elem *lnx_builtin_next_arg(elem *efunc,list_t arglist); 556 557 char *lnx_redirect_funcname(const char *); 557 558 void lnx_funcdecl(symbol *,enum SC,enum_SC,int); 558 559 int lnx_attributes(int hinttype,const void *hint, type **ptyp, tym_t *ptym,int *pattrtype); 559 560 #endif 560 561 561 562 562 563 #if TARGET_MAC 563 564 #include "TGglobal.h" 564 565 #endif 565 566 566 567 #endif /* GLOBAL_H */ trunk/src/backend/cod3.c
r581 r582 2931 2931 #endif 2932 2932 2933 2933 if (b) 2934 2934 { bn = b->Bnext; 2935 2935 usespace = (config.flags4 & CFG4space && b->BC != BCasm); 2936 2936 useopsize = (I16 || (config.flags4 & CFG4space && b->BC != BCasm)); 2937 2937 } 2938 2938 else 2939 2939 { bn = NULL; 2940 2940 usespace = (config.flags4 & CFG4space); 2941 2941 useopsize = (I16 || config.flags4 & CFG4space); 2942 2942 } 2943 2943 for (; c; c = code_next(c)) 2944 2944 { 2945 2945 L1: 2946 2946 op = c->Iop; 2947 2947 if (op == 0x0F) 2948 2948 ins = inssize2[c->Iop2]; 2949 2949 else 2950 2950 ins = inssize[c->Iop]; 2951 if ( ins & M) // if modregrm byte2951 if (I32 && ins & M) // if modregrm byte 2952 2952 { int shortop = (c->Iflags & CFopsize) ? !I16 : I16; 2953 2953 int local_BPRM = BPRM; 2954 2954 2955 2955 if (c->Iflags & CFaddrsize) 2956 2956 local_BPRM ^= 5 ^ 6; // toggle between 5 and 6 2957 2957 2958 2958 unsigned rm = c->Irm; 2959 2959 unsigned reg = rm & modregrm(0,7,0); // isolate reg field 2960 2960 unsigned ereg = rm & 7; 2961 2961 //printf("c = %p, op = %02x rm = %02x\n", c, op, rm); 2962 2962 2963 2963 /* If immediate second operand */ 2964 2964 if ((ins & T || op == 0xF6 || op == 0xF7) && 2965 2965 c->IFL2 == FLconst) 2966 2966 { 2967 2967 int flags = c->Iflags & CFpsw; /* if want result in flags */ 2968 2968 targ_long u = c->IEV2.Vuns; 2969 2969 if (ins & E) 2970 2970 u = (signed char) u; 2971 2971 else if (shortop) trunk/src/backend/elfobj.c
r581 r582 2230 2230 relsec->sh_link = SHI_SYMTAB; 2231 2231 relsec->sh_info = secidx; 2232 2232 relsec->sh_entsize = sizeof(Elf64_Rela); 2233 2233 relsec->sh_addralign = 8; 2234 2234 } 2235 2235 else 2236 2236 { 2237 2237 Elf32_Shdr *relsec = &SecHdrTab[relidx]; 2238 2238 relsec->sh_link = SHI_SYMTAB; 2239 2239 relsec->sh_info = secidx; 2240 2240 relsec->sh_entsize = sizeof(Elf32_Rel); 2241 2241 relsec->sh_addralign = 4; 2242 2242 } 2243 2243 } 2244 2244 2245 2245 if (I64) 2246 2246 { 2247 2247 Elf64_Rela rel; 2248 2248 rel.r_offset = offset; // build relocation information 2249 2249 rel.r_info = ELF64_R_INFO(symidx,type); 2250 rel.r_addend = 0;2250 rel.r_addend = val; 2251 2251 buf = segdata->SDrel; 2252 2252 buf->write(&rel,sizeof(rel)); 2253 2253 segdata->SDrelcnt++; 2254 2254 2255 2255 if (offset >= segdata->SDrelmaxoff) 2256 2256 segdata->SDrelmaxoff = offset; 2257 2257 else 2258 2258 { // insert numerically 2259 2259 Elf64_Rela *relbuf = (Elf64_Rela *)buf->buf; 2260 2260 int i = relbuf[segdata->SDrelindex].r_offset > offset ? 0 : segdata->SDrelindex; 2261 2261 while (i < segdata->SDrelcnt) 2262 2262 { 2263 2263 if (relbuf[i].r_offset > offset) 2264 2264 break; 2265 2265 i++; 2266 2266 } 2267 2267 assert(i != segdata->SDrelcnt); // slide greater offsets down 2268 2268 memmove(relbuf+i+1,relbuf+i,sizeof(Elf64_Rela) * (segdata->SDrelcnt - i - 1)); 2269 2269 *(relbuf+i) = rel; // copy to correct location 2270 2270 segdata->SDrelindex = i; // next entry usually greater … … 2504 2504 return retsize; 2505 2505 } 2506 2506 else 2507 2507 { 2508 2508 int save; 2509 2509 buf = SegData[seg]->SDbuf; 2510 2510 save = buf->size(); 2511 2511 buf->setsize(offset); 2512 2512 if (flags & CFselfrel) 2513 2513 { // only for function references within code segments 2514 2514 if (!external && // local definition found 2515 2515 s->Sseg == seg && // within same code segment 2516 2516 (!(config.flags3 & CFG3pic) || // not position indp code 2517 2517 s->Sclass == SCstatic)) // or is pic, but declared static 2518 2518 { // Can use PC relative 2519 2519 //dbg_printf("\tdoing PC relative\n"); 2520 2520 val = (s->Soffset+val) - (offset+4); 2521 2521 } 2522 2522 else 2523 2523 { 2524 val = (targ_size_t)-4;2525 2524 //dbg_printf("\tadding relocation\n"); 2526 2525 if (I64) 2527 relinfo = config.flags3 & CFG3pic ? R_X86_64_PLT32 : R_X86_64_PC32; 2526 { relinfo = config.flags3 & CFG3pic ? R_X86_64_PLT32 : R_X86_64_PC32; 2527 elf_addrel(seg,offset, relinfo, s->Sxtrnnum, -4); 2528 val = 0; 2529 } 2528 2530 else 2529 relinfo = config.flags3 & CFG3pic ? RI_TYPE_PLT32 : RI_TYPE_PC32;2530 elf_addrel(seg,offset,2531 relinfo,2532 s->Sxtrnnum,0);2531 { relinfo = config.flags3 & CFG3pic ? RI_TYPE_PLT32 : RI_TYPE_PC32; 2532 elf_addrel(seg,offset, relinfo, s->Sxtrnnum, 0); 2533 val = (targ_size_t)-4; 2534 } 2533 2535 } 2534 if (I64)2535 val += 4;2536 2536 } 2537 2537 else 2538 2538 { // code to code code to data, data to code, data to data refs 2539 2539 refseg = s->Sxtrnnum; // default to name symbol table entry 2540 2540 if (s->Sclass == SCstatic) 2541 2541 { // offset into .data or .bss seg 2542 2542 refseg = MAP_SEG2SYMIDX(s->Sseg); 2543 2543 // use segment symbol table entry 2544 2544 val += s->Soffset; 2545 2545 if (!(config.flags3 & CFG3pic) || // all static refs from normal code 2546 2546 segtyp == DATA) // or refs from data from posi indp 2547 2547 { 2548 2548 relinfo = I64 ? R_X86_64_32 : RI_TYPE_SYM32; 2549 2549 } 2550 2550 else 2551 2551 { 2552 2552 relinfo = I64 ? R_X86_64_PC32 : RI_TYPE_GOTOFF; 2553 2553 } 2554 2554 } 2555 2555 else if (config.flags3 & CFG3pic && s == GOTsym) trunk/src/backend/global.h
r552 r582 534 534 #if MACHOBJ 535 535 int mach_getsegment(const char *sectname, const char *segname, 536 536 int align, int flags, int flags2 = 0); 537 537 void mach_addrel(int seg, targ_size_t offset, symbol *targsym, 538 538 unsigned targseg, int rtype); 539 539 #endif 540 540 void elf_func_start(Symbol *sfunc); 541 541 int elf_data_start(Symbol *sdata, targ_size_t datasize, int seg); 542 542 void elf_func_term(Symbol *sfunc); 543 543 unsigned elf_addstr(Outbuffer *strtab, const char *); 544 544 545 545 void dwarf_CFA_set_loc(size_t location); 546 546 void dwarf_CFA_set_reg_offset(int reg, int offset); 547 547 void dwarf_CFA_offset(int reg, int offset); 548 548 void dwarf_CFA_args_size(size_t sz); 549 549 #endif 550 550 551 551 #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 552 552 void elfobj_gotref(symbol *s); 553 553 symbol *elfobj_getGOTsym(); 554 void elfobj_refGOTsym(); 554 555 elem * exp_isconst(); 555 556 elem *lnx_builtin_next_arg(elem *efunc,list_t arglist); 556 557 char *lnx_redirect_funcname(const char *); 557 558 void lnx_funcdecl(symbol *,enum SC,enum_SC,int); 558 559 int lnx_attributes(int hinttype,const void *hint, type **ptyp, tym_t *ptym,int *pattrtype); 559 560 #endif 560 561 561 562 562 563 #if TARGET_MAC 563 564 #include "TGglobal.h" 564 565 #endif 565 566 566 567 #endif /* GLOBAL_H */
