[RFC] binutils support for x86-64 medium model shared libraries
Jan Hubicka
jh@suse.cz
Sat Aug 28 13:53:00 GMT 2004
More information about the Binutils mailing list
Sat Aug 28 13:53:00 GMT 2004
- Previous message (by thread): [PATCH] Update opcodes to autoconf 2.59
- Next message (by thread): [RFC] binutils support for x86-64 medium model shared libraries
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Hi, this patch adds neccesary binutils support for x86-64 medium PIC model (libraries whose text+PLT+GOT size is limited to 2GB, but data section size is unlimited). This is implemented by adding new 64bit PC relative relocation (PC64) and relocations allowing 64bit GOT pointer relative access to static variables (GOTPC32 to read GOT address and GOTOFF64 to compute offsets). The compiler is supposed to freely use 32bit IP relative addressing for everything except for data section and use the GOT pointer relative way within it. The 64bit PC relative is usefull for jumptables and EH tables. The incarnation of this patch for earlier binutils has been in use for a while within SUSE distro and appears to work. It also has been tested on some libraries really requiring the medium model. GOT and PLT are still accessed via IP relative way as 32bit PIC is. This brings few issues I would like to discuss here. 1) Currently the GOT/PLT sections are placed after data section, I need to have thse before for medium model PIC libraries. Please see the changes to linker scripts at the end of patch; I would like to ask for proper sollution to this especially because I was told that this is in conflict with optimization Jakub implements (ie it would be nice to use "normal" ordering for small libraries and reversed for big. IP relative access to GOT/PLT is very important for perfomrance... 2) In the function relocate_section is magic number 3 I have no idea from where is comming. I was discussing this with Andreas Schwab previously and he told me that I've messed up the computation of the relocation (that is copied from other port that appeared to do the same), but his suggestion didn't work for me either and I unfortunately lost the email, so I can't re-check. I will try to dig into this deeper but it makes me nervous and perhaps proper fix is obvious to everyone except me. 3) I would like to implement small data area as simple followup patch. This should make medium model performance mostly identical with small model with exception of very large static datastructures. This however hits another problem - in order to access sdata/sbss/friends in IP relative way they must appear before the data section. Does it seem to be in conflict with something to reorder thse in linker script? Except for these points I hope this is quite easy addition, so I would like to commit it once these issues are resolved. I also have companion patch for GCC and x86-64 ABI and few extra additions for large model are in preparation too. thanks, Honza 2004-08-28 Jan Hubicka <jh@suse.cz> * bfd-in2.h (BFD_RELOAD_X86_64_GOTOFF64): New relocation. (BFD_RELOAD_X86_64_GOTPC32): New relocation. * elf64-x86-64.c (x86_64_elf_howto): Add entries for R_X86_64_PC64, R_X86_64_GOTOFF64 and R_X86_64_GOTPC32. * elf64-x86-64.c (x86_64_elf_reloc_map): Add entries for R_X86_64_PC64, R_X86_64_GOTOFF64 and R_X86_64_GOTPC32. (elf64_x86_64_check_relocs): Deal with new relocs. (elf64_x86_64_gc_sweep_hook): Deal with PC64 reloc. (x86_64_rlocate_section): Deal with new relocs. * libbfd.h (bfd_reloc_code_): Add BFD_RELOC_X86_64_GOTOFF64. * reloc.c (BFD_RELOC_X86_64_GOTOFF64, BFD_RELOC_X86_64_GOTPC32): New. * config/tc-i386.c (reloc): Add BFD_RELOC_64_PCREL. (tc_i386_fix_adjustable): Add GOTOFF64. (output_disp): Allow new types. (output_imm): Likewise. (lex_got): Add new keywords. (i386_displacement): Likewise. (md_apply_fix3): Handle 64bit PC relative relocastion. (md_validate_fix): Likewise. (tc_get_reloc): Deal with GOTPC32 and GOTOFF64. * x86-64.h (R_X86_64_PC64, R_X86_64_GOTOFF64, R_X86_64_GOTPC32): New relocations. * emulparams/elf_x86_64.sh: Add EARLY_GOT section. * scripttempl/elf.sc: Support EARLY_GOT section. Index: bfd/bfd-in2.h =================================================================== RCS file: /cvs/src/src/bfd/bfd-in2.h,v retrieving revision 1.297 diff -c -3 -p -r1.297 bfd-in2.h *** bfd/bfd-in2.h 25 Aug 2004 12:54:13 -0000 1.297 --- bfd/bfd-in2.h 28 Aug 2004 10:25:03 -0000 *************** in the instruction. */ *** 2463,2468 **** --- 2463,2470 ---- BFD_RELOC_X86_64_DTPOFF32, BFD_RELOC_X86_64_GOTTPOFF, BFD_RELOC_X86_64_TPOFF32, + BFD_RELOC_X86_64_GOTOFF64, + BFD_RELOC_X86_64_GOTPC32, /* ns32k relocations */ BFD_RELOC_NS32K_IMM_8, Index: bfd/elf64-x86-64.c =================================================================== RCS file: /cvs/src/src/bfd/elf64-x86-64.c,v retrieving revision 1.83 diff -c -3 -p -r1.83 elf64-x86-64.c *** bfd/elf64-x86-64.c 13 Aug 2004 03:15:59 -0000 1.83 --- bfd/elf64-x86-64.c 28 Aug 2004 10:25:03 -0000 *************** static reloc_howto_type x86_64_elf_howto *** 102,107 **** --- 102,116 ---- HOWTO(R_X86_64_TPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_X86_64_TPOFF32", FALSE, 0xffffffff, 0xffffffff, FALSE), + HOWTO(R_X86_64_PC64, 0, 4, 64, TRUE, 0, complain_overflow_signed, + bfd_elf_generic_reloc, "R_X86_64_PC64", FALSE, MINUS_ONE, MINUS_ONE, + TRUE), + HOWTO(R_X86_64_GOTOFF64, 0, 4, 64, FALSE, 0, complain_overflow_signed, + bfd_elf_generic_reloc, "R_X86_64_GOTOFF64", + FALSE, MINUS_ONE, MINUS_ONE, FALSE), + HOWTO(R_X86_64_GOTPC32, 0, 2, 32, TRUE, 0, complain_overflow_signed, + bfd_elf_generic_reloc, "R_X86_64_GOTPC32", + FALSE, 0xffffffff, 0xffffffff, TRUE), /* GNU extension to record C++ vtable hierarchy. */ HOWTO (R_X86_64_GNU_VTINHERIT, 0, 4, 0, FALSE, 0, complain_overflow_dont, *************** static const struct elf_reloc_map x86_64 *** 146,151 **** --- 155,163 ---- { BFD_RELOC_X86_64_DTPOFF32, R_X86_64_DTPOFF32, }, { BFD_RELOC_X86_64_GOTTPOFF, R_X86_64_GOTTPOFF, }, { BFD_RELOC_X86_64_TPOFF32, R_X86_64_TPOFF32, }, + { BFD_RELOC_64_PCREL, R_X86_64_PC64, }, + { BFD_RELOC_X86_64_GOTOFF64, R_X86_64_GOTOFF64, }, + { BFD_RELOC_X86_64_GOTPC32, R_X86_64_GOTPC32, }, { BFD_RELOC_VTABLE_INHERIT, R_X86_64_GNU_VTINHERIT, }, { BFD_RELOC_VTABLE_ENTRY, R_X86_64_GNU_VTENTRY, }, }; *************** elf64_x86_64_check_relocs (bfd *abfd, st *** 746,752 **** } /* Fall through */ ! //case R_X86_64_GOTPCREL: create_got: if (htab->sgot == NULL) { --- 758,765 ---- } /* Fall through */ ! case R_X86_64_GOTOFF64: ! case R_X86_64_GOTPC32: create_got: if (htab->sgot == NULL) { *************** elf64_x86_64_check_relocs (bfd *abfd, st *** 799,804 **** --- 812,818 ---- case R_X86_64_PC8: case R_X86_64_PC16: case R_X86_64_PC32: + case R_X86_64_PC64: case R_X86_64_64: if (h != NULL && !info->shared) { *************** elf64_x86_64_check_relocs (bfd *abfd, st *** 842,848 **** && (sec->flags & SEC_ALLOC) != 0 && (((r_type != R_X86_64_PC8) && (r_type != R_X86_64_PC16) ! && (r_type != R_X86_64_PC32)) || (h != NULL && (! info->symbolic || h->root.type == bfd_link_hash_defweak --- 856,863 ---- && (sec->flags & SEC_ALLOC) != 0 && (((r_type != R_X86_64_PC8) && (r_type != R_X86_64_PC16) ! && (r_type != R_X86_64_PC32) ! && (r_type != R_X86_64_PC64)) || (h != NULL && (! info->symbolic || h->root.type == bfd_link_hash_defweak *************** elf64_x86_64_check_relocs (bfd *abfd, st *** 946,952 **** p->count += 1; if (r_type == R_X86_64_PC8 || r_type == R_X86_64_PC16 ! || r_type == R_X86_64_PC32) p->pc_count += 1; } break; --- 961,968 ---- p->count += 1; if (r_type == R_X86_64_PC8 || r_type == R_X86_64_PC16 ! || r_type == R_X86_64_PC32 ! || r_type == R_X86_64_PC64) p->pc_count += 1; } break; *************** elf64_x86_64_gc_sweep_hook (bfd *abfd, s *** 1088,1093 **** --- 1104,1110 ---- case R_X86_64_PC8: case R_X86_64_PC16: case R_X86_64_PC32: + case R_X86_64_PC64: if (info->shared) break; /* Fall thru */ *************** elf64_x86_64_relocate_section (bfd *outp *** 1946,1951 **** --- 1963,1969 ---- case R_X86_64_PC8: case R_X86_64_PC16: case R_X86_64_PC32: + case R_X86_64_PC64: if (info->shared && !SYMBOL_REFERENCES_LOCAL (info, h) && (input_section->flags & SEC_ALLOC) != 0 *************** elf64_x86_64_relocate_section (bfd *outp *** 1981,1987 **** || h->root.type != bfd_link_hash_undefweak) && ((r_type != R_X86_64_PC8 && r_type != R_X86_64_PC16 ! && r_type != R_X86_64_PC32) || !SYMBOL_CALLS_LOCAL (info, h))) || (ELIMINATE_COPY_RELOCS && !info->shared --- 1999,2006 ---- || h->root.type != bfd_link_hash_undefweak) && ((r_type != R_X86_64_PC8 && r_type != R_X86_64_PC16 ! && r_type != R_X86_64_PC32 ! && r_type != R_X86_64_PC64) || !SYMBOL_CALLS_LOCAL (info, h))) || (ELIMINATE_COPY_RELOCS && !info->shared *************** elf64_x86_64_relocate_section (bfd *outp *** 2027,2032 **** --- 2046,2052 ---- && (r_type == R_X86_64_PC8 || r_type == R_X86_64_PC16 || r_type == R_X86_64_PC32 + || r_type == R_X86_64_PC64 || !info->shared || !info->symbolic || (h->elf_link_hash_flags *************** elf64_x86_64_relocate_section (bfd *outp *** 2395,2400 **** --- 2415,2439 ---- relocation = tpoff (info, relocation); break; + case R_X86_64_GOTOFF64: + /* Relocation is relative to the start of the global offset + table. */ + + /* Note that sgot->output_offset is not involved in this + calculation. We always want the start of .got. If we + defined _GLOBAL_OFFSET_TABLE in a different way, as is + permitted by the ABI, we might have to change this + calculation. */ + relocation -= htab->sgot->output_section->vma; + break; + + case R_X86_64_GOTPC32: + /* Use global offset table as symbol value. + ??? This constant makes it to come out right... */ + relocation = htab->sgot->output_section->vma - 3; + unresolved_reloc = FALSE; + break; + default: break; } Index: bfd/libbfd.h =================================================================== RCS file: /cvs/src/src/bfd/libbfd.h,v retrieving revision 1.122 diff -c -3 -p -r1.122 libbfd.h *** bfd/libbfd.h 25 Aug 2004 12:54:14 -0000 1.122 --- bfd/libbfd.h 28 Aug 2004 10:25:03 -0000 *************** static const char *const bfd_reloc_code_ *** 989,994 **** --- 989,995 ---- "BFD_RELOC_X86_64_DTPOFF32", "BFD_RELOC_X86_64_GOTTPOFF", "BFD_RELOC_X86_64_TPOFF32", + "BFD_RELOC_X86_64_GOTOFF64", "BFD_RELOC_NS32K_IMM_8", "BFD_RELOC_NS32K_IMM_16", "BFD_RELOC_NS32K_IMM_32", Index: bfd/reloc.c =================================================================== RCS file: /cvs/src/src/bfd/reloc.c,v retrieving revision 1.111 diff -c -3 -p -r1.111 reloc.c *** bfd/reloc.c 25 Aug 2004 12:54:14 -0000 1.111 --- bfd/reloc.c 28 Aug 2004 10:25:03 -0000 *************** ENUMX *** 2278,2283 **** --- 2278,2287 ---- BFD_RELOC_X86_64_GOTTPOFF ENUMX BFD_RELOC_X86_64_TPOFF32 + ENUMX + BFD_RELOC_X86_64_GOTOFF64 + ENUMX + BFD_RELOC_X86_64_GOTPC32 ENUMDOC x86-64/elf relocations Index: gas/config/tc-i386.c =================================================================== RCS file: /cvs/src/src/gas/config/tc-i386.c,v retrieving revision 1.156 diff -c -3 -p -r1.156 tc-i386.c *** gas/config/tc-i386.c 21 Jul 2004 18:18:02 -0000 1.156 --- gas/config/tc-i386.c 28 Aug 2004 10:25:06 -0000 *************** reloc (size, pcrel, sign, other) *** 1194,1199 **** --- 1194,1200 ---- case 1: return BFD_RELOC_8_PCREL; case 2: return BFD_RELOC_16_PCREL; case 4: return BFD_RELOC_32_PCREL; + case 8: return BFD_RELOC_64_PCREL; } as_bad (_("can not do %d byte pc-relative relocation"), size); } *************** tc_i386_fix_adjustable (fixP) *** 1258,1263 **** --- 1259,1265 ---- || fixP->fx_r_type == BFD_RELOC_386_TLS_GOTIE || fixP->fx_r_type == BFD_RELOC_386_TLS_LE_32 || fixP->fx_r_type == BFD_RELOC_386_TLS_LE + || fixP->fx_r_type == BFD_RELOC_X86_64_GOTOFF64 || fixP->fx_r_type == BFD_RELOC_X86_64_PLT32 || fixP->fx_r_type == BFD_RELOC_X86_64_GOT32 || fixP->fx_r_type == BFD_RELOC_X86_64_GOTPCREL *************** output_disp (insn_start_frag, insn_start *** 3336,3349 **** p = frag_more (size); reloc_type = reloc (size, pcrel, sign, i.reloc[n]); ! if (reloc_type == BFD_RELOC_32 ! && GOT_symbol ! && GOT_symbol == i.op[n].disps->X_add_symbol ! && (i.op[n].disps->X_op == O_symbol ! || (i.op[n].disps->X_op == O_add ! && ((symbol_get_value_expression ! (i.op[n].disps->X_op_symbol)->X_op) ! == O_subtract)))) { offsetT add; --- 3338,3354 ---- p = frag_more (size); reloc_type = reloc (size, pcrel, sign, i.reloc[n]); ! if ((reloc_type == BFD_RELOC_32 ! && GOT_symbol ! && GOT_symbol == i.op[n].disps->X_add_symbol ! && (i.op[n].disps->X_op == O_symbol ! || (i.op[n].disps->X_op == O_add ! && ((symbol_get_value_expression ! (i.op[n].disps->X_op_symbol)->X_op) ! == O_subtract)))) ! || (reloc_type == BFD_RELOC_32_PCREL ! && GOT_symbol ! && GOT_symbol == i.op[n].disps->X_add_symbol)) { offsetT add; *************** output_disp (insn_start_frag, insn_start *** 3360,3369 **** add += p - frag_now->fr_literal; } - /* We don't support dynamic linking on x86-64 yet. */ if (flag_code == CODE_64BIT) ! abort (); ! reloc_type = BFD_RELOC_386_GOTPC; i.op[n].disps->X_add_number += add; } fix_new_exp (frag_now, p - frag_now->fr_literal, size, --- 3365,3374 ---- add += p - frag_now->fr_literal; } if (flag_code == CODE_64BIT) ! reloc_type = BFD_RELOC_X86_64_GOTPC32; ! else ! reloc_type = BFD_RELOC_386_GOTPC; i.op[n].disps->X_add_number += add; } fix_new_exp (frag_now, p - frag_now->fr_literal, size, *************** output_imm (insn_start_frag, insn_start_ *** 3471,3484 **** * since the expression is not pcrel, I felt it would be * confusing to do it this way. */ ! if (reloc_type == BFD_RELOC_32 ! && GOT_symbol ! && GOT_symbol == i.op[n].imms->X_add_symbol ! && (i.op[n].imms->X_op == O_symbol ! || (i.op[n].imms->X_op == O_add ! && ((symbol_get_value_expression ! (i.op[n].imms->X_op_symbol)->X_op) ! == O_subtract)))) { offsetT add; --- 3476,3492 ---- * since the expression is not pcrel, I felt it would be * confusing to do it this way. */ ! if ((reloc_type == BFD_RELOC_32 ! && GOT_symbol ! && GOT_symbol == i.op[n].imms->X_add_symbol ! && (i.op[n].imms->X_op == O_symbol ! || (i.op[n].imms->X_op == O_add ! && ((symbol_get_value_expression ! (i.op[n].imms->X_op_symbol)->X_op) ! == O_subtract)))) ! || (reloc_type == BFD_RELOC_32_PCREL ! && GOT_symbol ! && GOT_symbol == i.op[n].disps->X_add_symbol)) { offsetT add; *************** output_imm (insn_start_frag, insn_start_ *** 3495,3504 **** add += p - frag_now->fr_literal; } - /* We don't support dynamic linking on x86-64 yet. */ if (flag_code == CODE_64BIT) ! abort (); ! reloc_type = BFD_RELOC_386_GOTPC; i.op[n].imms->X_add_number += add; } fix_new_exp (frag_now, p - frag_now->fr_literal, size, --- 3503,3512 ---- add += p - frag_now->fr_literal; } if (flag_code == CODE_64BIT) ! reloc_type = BFD_RELOC_X86_64_GOTPC32; ! else ! reloc_type = BFD_RELOC_386_GOTPC; i.op[n].imms->X_add_number += add; } fix_new_exp (frag_now, p - frag_now->fr_literal, size, *************** lex_got (reloc, adjust) *** 3531,3537 **** const enum bfd_reloc_code_real rel[NUM_FLAG_CODE]; } gotrel[] = { { "PLT", { BFD_RELOC_386_PLT32, 0, BFD_RELOC_X86_64_PLT32 } }, ! { "GOTOFF", { BFD_RELOC_386_GOTOFF, 0, 0 } }, { "GOTPCREL", { 0, 0, BFD_RELOC_X86_64_GOTPCREL } }, { "TLSGD", { BFD_RELOC_386_TLS_GD, 0, BFD_RELOC_X86_64_TLSGD } }, { "TLSLDM", { BFD_RELOC_386_TLS_LDM, 0, 0 } }, --- 3539,3545 ---- const enum bfd_reloc_code_real rel[NUM_FLAG_CODE]; } gotrel[] = { { "PLT", { BFD_RELOC_386_PLT32, 0, BFD_RELOC_X86_64_PLT32 } }, ! { "GOTOFF", { BFD_RELOC_386_GOTOFF, 0, BFD_RELOC_X86_64_GOTOFF64} }, { "GOTPCREL", { 0, 0, BFD_RELOC_X86_64_GOTPCREL } }, { "TLSGD", { BFD_RELOC_386_TLS_GD, 0, BFD_RELOC_X86_64_TLSGD } }, { "TLSLDM", { BFD_RELOC_386_TLS_LDM, 0, 0 } }, *************** lex_got (reloc, adjust) *** 3542,3548 **** { "DTPOFF", { BFD_RELOC_386_TLS_LDO_32, 0, BFD_RELOC_X86_64_DTPOFF32 } }, { "GOTNTPOFF",{ BFD_RELOC_386_TLS_GOTIE, 0, 0 } }, { "INDNTPOFF",{ BFD_RELOC_386_TLS_IE, 0, 0 } }, ! { "GOT", { BFD_RELOC_386_GOT32, 0, BFD_RELOC_X86_64_GOT32 } } }; char *cp; unsigned int j; --- 3550,3557 ---- { "DTPOFF", { BFD_RELOC_386_TLS_LDO_32, 0, BFD_RELOC_X86_64_DTPOFF32 } }, { "GOTNTPOFF",{ BFD_RELOC_386_TLS_GOTIE, 0, 0 } }, { "INDNTPOFF",{ BFD_RELOC_386_TLS_IE, 0, 0 } }, ! { "GOT", { BFD_RELOC_386_GOT32, 0, BFD_RELOC_X86_64_GOT32 } }, ! //{ "GOTOFF64", { 0, 0, BFD_RELOC_X86_64_GOTOFF64 } } }; char *cp; unsigned int j; *************** i386_displacement (disp_start, disp_end) *** 3934,3939 **** --- 3943,3949 ---- the symbol table. We will ultimately change the relocation to be relative to the beginning of the section. */ if (i.reloc[this_operand] == BFD_RELOC_386_GOTOFF + || i.reloc[this_operand] == BFD_RELOC_X86_64_GOTOFF64 || i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL) { if (exp->X_op != O_symbol) *************** i386_displacement (disp_start, disp_end) *** 3941,3947 **** as_bad (_("bad expression used with @%s"), (i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL ? "GOTPCREL" ! : "GOTOFF")); return 0; } --- 3951,3959 ---- as_bad (_("bad expression used with @%s"), (i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL ? "GOTPCREL" ! : (i.reloc[this_operand] == BFD_RELOC_X86_64_GOTOFF64 ! ? "GOTOFF64" ! : "GOTOFF"))); return 0; } *************** md_estimate_size_before_relax (fragP, se *** 4400,4407 **** reloc_type = fragP->fr_var; else if (size == 2) reloc_type = BFD_RELOC_16_PCREL; ! else reloc_type = BFD_RELOC_32_PCREL; old_fr_fix = fragP->fr_fix; opcode = (unsigned char *) fragP->fr_opcode; --- 4412,4421 ---- reloc_type = fragP->fr_var; else if (size == 2) reloc_type = BFD_RELOC_16_PCREL; ! else if (size == 4) reloc_type = BFD_RELOC_32_PCREL; + else + reloc_type = BFD_RELOC_64_PCREL; old_fr_fix = fragP->fr_fix; opcode = (unsigned char *) fragP->fr_opcode; *************** md_apply_fix3 (fixP, valP, seg) *** 4642,4647 **** --- 4656,4664 ---- default: break; + case BFD_RELOC_64: + fixP->fx_r_type = BFD_RELOC_64_PCREL; + break; case BFD_RELOC_32: fixP->fx_r_type = BFD_RELOC_32_PCREL; break; *************** md_apply_fix3 (fixP, valP, seg) *** 4655,4661 **** } if (fixP->fx_addsy != NULL ! && (fixP->fx_r_type == BFD_RELOC_32_PCREL || fixP->fx_r_type == BFD_RELOC_16_PCREL || fixP->fx_r_type == BFD_RELOC_8_PCREL) && !use_rela_relocations) --- 4672,4679 ---- } if (fixP->fx_addsy != NULL ! && (fixP->fx_r_type == BFD_RELOC_64_PCREL ! || fixP->fx_r_type == BFD_RELOC_32_PCREL || fixP->fx_r_type == BFD_RELOC_16_PCREL || fixP->fx_r_type == BFD_RELOC_8_PCREL) && !use_rela_relocations) *************** i386_validate_fix (fixp) *** 5159,5165 **** { if (fixp->fx_subsy && fixp->fx_subsy == GOT_symbol) { - /* GOTOFF relocation are nonsense in 64bit mode. */ if (fixp->fx_r_type == BFD_RELOC_32_PCREL) { if (flag_code != CODE_64BIT) --- 5177,5182 ---- *************** i386_validate_fix (fixp) *** 5169,5176 **** else { if (flag_code == CODE_64BIT) ! abort (); ! fixp->fx_r_type = BFD_RELOC_386_GOTOFF; } fixp->fx_subsy = 0; } --- 5186,5194 ---- else { if (flag_code == CODE_64BIT) ! fixp->fx_r_type = BFD_RELOC_X86_64_GOTOFF64; ! else ! fixp->fx_r_type = BFD_RELOC_386_GOTOFF; } fixp->fx_subsy = 0; } *************** tc_gen_reloc (section, fixp) *** 5189,5194 **** --- 5207,5213 ---- case BFD_RELOC_X86_64_PLT32: case BFD_RELOC_X86_64_GOT32: case BFD_RELOC_X86_64_GOTPCREL: + case BFD_RELOC_X86_64_GOTPC32: case BFD_RELOC_386_PLT32: case BFD_RELOC_386_GOT32: case BFD_RELOC_386_GOTOFF: *************** tc_gen_reloc (section, fixp) *** 5201,5206 **** --- 5220,5226 ---- case BFD_RELOC_386_TLS_GOTIE: case BFD_RELOC_386_TLS_LE_32: case BFD_RELOC_386_TLS_LE: + case BFD_RELOC_X86_64_GOTOFF64: case BFD_RELOC_X86_64_32S: case BFD_RELOC_X86_64_TLSGD: case BFD_RELOC_X86_64_TLSLD: *************** tc_gen_reloc (section, fixp) *** 5229,5234 **** --- 5249,5255 ---- case 1: code = BFD_RELOC_8_PCREL; break; case 2: code = BFD_RELOC_16_PCREL; break; case 4: code = BFD_RELOC_32_PCREL; break; + case 8: code = BFD_RELOC_64_PCREL; break; } } else *************** tc_gen_reloc (section, fixp) *** 5252,5265 **** break; } ! if (code == BFD_RELOC_32 && GOT_symbol && fixp->fx_addsy == GOT_symbol) { - /* We don't support GOTPC on 64bit targets. */ if (flag_code == CODE_64BIT) ! abort (); ! code = BFD_RELOC_386_GOTPC; } rel = (arelent *) xmalloc (sizeof (arelent)); --- 5273,5286 ---- break; } ! if ((code == BFD_RELOC_32 || code == BFD_RELOC_32_PCREL) && GOT_symbol && fixp->fx_addsy == GOT_symbol) { if (flag_code == CODE_64BIT) ! code = BFD_RELOC_X86_64_GOTPC32; ! else ! code = BFD_RELOC_386_GOTPC; } rel = (arelent *) xmalloc (sizeof (arelent)); Index: include/elf/x86-64.h =================================================================== RCS file: /cvs/src/src/include/elf/x86-64.h,v retrieving revision 1.3 diff -c -3 -p -r1.3 x86-64.h *** include/elf/x86-64.h 27 Sep 2002 19:29:16 -0000 1.3 --- include/elf/x86-64.h 28 Aug 2004 10:25:07 -0000 *************** START_RELOC_NUMBERS (elf_x86_64_reloc_ty *** 51,56 **** --- 51,59 ---- RELOC_NUMBER (R_X86_64_TPOFF32, 23) /* Offset in initial TLS block */ RELOC_NUMBER (R_X86_64_GNU_VTINHERIT, 250) /* GNU C++ hack */ RELOC_NUMBER (R_X86_64_GNU_VTENTRY, 251) /* GNU C++ hack */ + RELOC_NUMBER (R_X86_64_PC64, 24) /* PC relative 64 bit signed */ + RELOC_NUMBER (R_X86_64_GOTOFF64, 25) /* 64bit offset to GOT */ + RELOC_NUMBER (R_X86_64_GOTPC32, 26) /* 32 bit PC relative offset to GOT */ END_RELOC_NUMBERS (R_X86_64_max) #endif Index: ld/emulparams/elf_x86_64.sh =================================================================== RCS file: /cvs/src/src/ld/emulparams/elf_x86_64.sh,v retrieving revision 1.12 diff -c -3 -p -r1.12 elf_x86_64.sh *** ld/emulparams/elf_x86_64.sh 11 May 2004 17:08:33 -0000 1.12 --- ld/emulparams/elf_x86_64.sh 28 Aug 2004 10:25:07 -0000 *************** NOP=0x90909090 *** 11,18 **** TEMPLATE_NAME=elf32 GENERATE_SHLIB_SCRIPT=yes GENERATE_PIE_SCRIPT=yes NO_SMALL_DATA=yes SEPARATE_GOTPLT=24 if [ "x${host}" = "x${target}" ]; then case " $EMULATION_LIBPATH " in --- 11,19 ---- TEMPLATE_NAME=elf32 GENERATE_SHLIB_SCRIPT=yes GENERATE_PIE_SCRIPT=yes SEPARATE_GOTPLT=24 NO_SMALL_DATA=yes + EARLY_GOT=".got ${RELOCATING-0} : { *(.got.plt) *(.got) }" if [ "x${host}" = "x${target}" ]; then case " $EMULATION_LIBPATH " in Index: ld/scripttempl/elf.sc =================================================================== RCS file: /cvs/src/src/ld/scripttempl/elf.sc,v retrieving revision 1.46 diff -c -3 -p -r1.46 elf.sc *** ld/scripttempl/elf.sc 5 Jul 2004 20:00:13 -0000 1.46 --- ld/scripttempl/elf.sc 28 Aug 2004 10:25:07 -0000 *************** if test -n "${COMMONPAGESIZE}"; then *** 97,103 **** fi INTERP=".interp ${RELOCATING-0} : { *(.interp) }" PLT=".plt ${RELOCATING-0} : { *(.plt) }" ! if test -z "$GOT"; then if test -z "$SEPARATE_GOTPLT"; then GOT=".got ${RELOCATING-0} : { *(.got.plt) *(.got) }" else --- 97,103 ---- fi INTERP=".interp ${RELOCATING-0} : { *(.interp) }" PLT=".plt ${RELOCATING-0} : { *(.plt) }" ! if test -z "$GOT" && test -z "$EARLY_GOT" ; then if test -z "$SEPARATE_GOTPLT"; then GOT=".got ${RELOCATING-0} : { *(.got.plt) *(.got) }" else *************** cat <<EOF *** 303,308 **** --- 303,309 ---- KEEP (*(.fini)) ${RELOCATING+${FINI_END}} } =${NOP-0} + ${EARLY_GOT} ${RELOCATING+PROVIDE (__etext = .);} ${RELOCATING+PROVIDE (_etext = .);} ${RELOCATING+PROVIDE (etext = .);}
- Previous message (by thread): [PATCH] Update opcodes to autoconf 2.59
- Next message (by thread): [RFC] binutils support for x86-64 medium model shared libraries
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Binutils mailing list