From 5bd6b9bea9a2d51a6dce5e63ceedfcc2740b7b44 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 17 Jun 2005 08:03:59 +0000 Subject: [PATCH] bfd/ 2005-06-17 Jan Beulich * bfd-in2.h (elf_x86_64_reloc_type): Add BFD_RELOC_X86_64_GOTOFF64 and BFD_RELOC_X86_64_GOTPC32. * libbfd.h (bfd_reloc_code_real_names): Likewise. * elf64-x86-64.c (x86_64_elf_howto_table): Add entries for R_X86_64_PC64, R_X86_64_GOTOFF64, and R_X86_64_GOTPC32. (x86_64_reloc_map): Add entries for R_X86_64_PC64, R_X86_64_GOTOFF64, and R_X86_64_GOTPC32. (elf64_x86_64_info_to_howto): Adjust bounding relocation type. (elf64_x86_64_check_relocs): Also handle R_X86_64_PC64, R_X86_64_GOTOFF64, and R_X86_64_GOTPC32. (elf64_x86_64_relocate_section): Likewise. (elf64_x86_64_gc_sweep_hook): Also handle R_X86_64_PC64. gas/ 2005-06-17 Jan Beulich * config/tc-i386.c (reloc): Also handle BFD_RELOC_64_PCREL. (tc_i386_fix_adjustable): Include BFD_RELOC_X86_64_GOTOFF64, BFD_RELOC_X86_64_DTPOFF64, and BFD_RELOC_X86_64_TPOFF64. (output_disp): Do GOTPC conversion also for BFD_RELOC_X86_64_32S and BFD_RELOC_32_PCREL. Use BFD_RELOC_X86_64_GOTPC32 instead of aborting. (output_imm): Do GOTPC conversion also for BFD_RELOC_X86_64_32S. Use BFD_RELOC_X86_64_GOTPC32 instead of aborting. (tc_gen_reloc): Do GOTPC conversion also for BFD_RELOC_32_PCREL. Use BFD_RELOC_X86_64_GOTPC32 instead of aborting. Also handle BFD_RELOC_X86_64_GOTOFF64, BFD_RELOC_X86_64_GOTPC32, BFD_RELOC_X86_64_DTPOFF64, and BFD_RELOC_X86_64_TPOFF64. Also convert 8-byte pc-relative relocations. (lex_got): Use BFD_RELOC_X86_64_GOTOFF64 for 64-bit @gotoff. (i386_validate_fix): Likewise. (x86_cons): Also handle quad values in 64-bit mode. (i386_displacement): Also handle BFD_RELOC_X86_64_GOTOFF64. (md_apply_fix): Include BFD_RELOC_X86_64_DTPOFF64 and BFD_RELOC_X86_64_TPOFF64 in the TLS check. Also convert BFD_RELOC_64 to pc-relative variant. Also check for BFD_RELOC_64_PCREL. gas/testsuite/ 2005-06-17 Jan Beulich * gas/i386/x86-64-pcrel.s: Add insn requiring 64-bit pc-relative relocation. Add insns for all widths of non-pc-relative relocations. * gas/i386/x86-64-pcrel.d: Adjust. include/elf/ 2005-06-17 Jan Beulich * x86-64.h (elf_x86_64_reloc_type): Adjust comment for R_X86_64_GOTPCREL. Add R_X86_64_PC64, R_X86_64_GOTOFF64, and R_X86_64_GOTPC32. --- bfd/ChangeLog | 15 +++++++ bfd/bfd-in2.h | 2 + bfd/elf64-x86-64.c | 70 +++++++++++++++++++++++++++---- bfd/libbfd.h | 2 + gas/ChangeLog | 23 ++++++++++ gas/config/tc-i386.c | 79 ++++++++++++++++++++++------------- gas/testsuite/ChangeLog | 6 +++ gas/testsuite/gas/i386/x86-64-pcrel.d | 11 +++-- gas/testsuite/gas/i386/x86-64-pcrel.s | 6 +++ include/elf/ChangeLog | 6 +++ include/elf/x86-64.h | 6 ++- 11 files changed, 187 insertions(+), 39 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 12e06b69e..f374000ac 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,18 @@ +2005-06-17 Jan Beulich + + * bfd-in2.h (elf_x86_64_reloc_type): Add BFD_RELOC_X86_64_GOTOFF64 + and BFD_RELOC_X86_64_GOTPC32. + * libbfd.h (bfd_reloc_code_real_names): Likewise. + * elf64-x86-64.c (x86_64_elf_howto_table): Add entries for + R_X86_64_PC64, R_X86_64_GOTOFF64, and R_X86_64_GOTPC32. + (x86_64_reloc_map): Add entries for R_X86_64_PC64, R_X86_64_GOTOFF64, + and R_X86_64_GOTPC32. + (elf64_x86_64_info_to_howto): Adjust bounding relocation type. + (elf64_x86_64_check_relocs): Also handle R_X86_64_PC64, + R_X86_64_GOTOFF64, and R_X86_64_GOTPC32. + (elf64_x86_64_relocate_section): Likewise. + (elf64_x86_64_gc_sweep_hook): Also handle R_X86_64_PC64. + 2005-06-15 Mark Kettenis * archive.c: Include "libiberty.h". diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 739277c8f..1107dc48d 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -2617,6 +2617,8 @@ in the instruction. */ 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, diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 179530b38..f63fd03ea 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -103,6 +103,15 @@ static reloc_howto_type x86_64_elf_howto_table[] = 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_bitfield, + 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_bitfield, + 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, @@ -147,6 +156,9 @@ static const struct elf_reloc_map x86_64_reloc_map[] = { 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, }, }; @@ -179,13 +191,13 @@ elf64_x86_64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr, r_type = ELF64_R_TYPE (dst->r_info); if (r_type < (unsigned int) R_X86_64_GNU_VTINHERIT) { - BFD_ASSERT (r_type <= (unsigned int) R_X86_64_TPOFF32); + BFD_ASSERT (r_type <= (unsigned int) R_X86_64_GOTPC32); i = r_type; } else { BFD_ASSERT (r_type < (unsigned int) R_X86_64_max); - i = r_type - ((unsigned int) R_X86_64_GNU_VTINHERIT - R_X86_64_TPOFF32 - 1); + i = r_type - ((unsigned int) R_X86_64_GNU_VTINHERIT - R_X86_64_GOTPC32 - 1); } cache_ptr->howto = &x86_64_elf_howto_table[i]; BFD_ASSERT (r_type == cache_ptr->howto->type); @@ -749,7 +761,8 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, } /* Fall through */ - //case R_X86_64_GOTPCREL: + case R_X86_64_GOTOFF64: + case R_X86_64_GOTPC32: create_got: if (htab->sgot == NULL) { @@ -802,6 +815,7 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, 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) { @@ -816,7 +830,7 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, /* We may need a .plt entry if the function this reloc refers to is in a shared lib. */ h->plt.refcount += 1; - if (r_type != R_X86_64_PC32) + if (r_type != R_X86_64_PC32 && r_type != R_X86_64_PC64) h->pointer_equality_needed = 1; } @@ -845,7 +859,8 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, && (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_PC32) + && (r_type != R_X86_64_PC64)) || (h != NULL && (! info->symbolic || h->root.type == bfd_link_hash_defweak @@ -948,7 +963,8 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, 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_PC32 + || r_type == R_X86_64_PC64) p->pc_count += 1; } break; @@ -1093,6 +1109,7 @@ elf64_x86_64_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info, 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 */ @@ -1941,6 +1958,42 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info, break; + case R_X86_64_GOTOFF64: + /* Relocation is relative to the start of the global offset + table. */ + + /* Check to make sure it isn't a protected function symbol + for shared library since it may not be local when used + as function address. */ + if (info->shared + && h + && h->def_regular + && h->type == STT_FUNC + && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED) + { + (*_bfd_error_handler) + (_("%B: relocation R_X86_64_GOTOFF64 against protected function `%s' can not be used when making a shared object"), + input_bfd, h->root.root.string); + bfd_set_error (bfd_error_bad_value); + return FALSE; + } + + /* Note that sgot is not involved in this + calculation. We always want the start of .got.plt. 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->sgotplt->output_section->vma + + htab->sgotplt->output_offset; + break; + + case R_X86_64_GOTPC32: + /* Use global offset table as symbol value. */ + relocation = htab->sgotplt->output_section->vma + + htab->sgotplt->output_offset; + unresolved_reloc = FALSE; + break; + case R_X86_64_PLT32: /* Relocation is to the entry for this symbol in the procedure linkage table. */ @@ -1999,6 +2052,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info, case R_X86_64_8: case R_X86_64_16: case R_X86_64_32: + case R_X86_64_PC64: case R_X86_64_64: /* FIXME: The ABI says the linker should make sure the value is the same when it's zeroextended to 64 bit. */ @@ -2016,7 +2070,8 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info, || 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_PC32 + && r_type != R_X86_64_PC64) || !SYMBOL_CALLS_LOCAL (info, h))) || (ELIMINATE_COPY_RELOCS && !info->shared @@ -2060,6 +2115,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info, && (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->def_regular)) diff --git a/bfd/libbfd.h b/bfd/libbfd.h index a318744fc..df2fbcab9 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -1049,6 +1049,8 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "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", "BFD_RELOC_NS32K_IMM_8", "BFD_RELOC_NS32K_IMM_16", "BFD_RELOC_NS32K_IMM_32", diff --git a/gas/ChangeLog b/gas/ChangeLog index 6ca97910d..fc33e1bcd 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,26 @@ +2005-06-17 Jan Beulich + + * config/tc-i386.c (reloc): Also handle BFD_RELOC_64_PCREL. + (tc_i386_fix_adjustable): Include BFD_RELOC_X86_64_GOTOFF64, + BFD_RELOC_X86_64_DTPOFF64, and BFD_RELOC_X86_64_TPOFF64. + (output_disp): Do GOTPC conversion also for BFD_RELOC_X86_64_32S + and BFD_RELOC_32_PCREL. Use BFD_RELOC_X86_64_GOTPC32 instead of + aborting. + (output_imm): Do GOTPC conversion also for BFD_RELOC_X86_64_32S. + Use BFD_RELOC_X86_64_GOTPC32 instead of aborting. + (tc_gen_reloc): Do GOTPC conversion also for BFD_RELOC_32_PCREL. + Use BFD_RELOC_X86_64_GOTPC32 instead of aborting. Also handle + BFD_RELOC_X86_64_GOTOFF64, BFD_RELOC_X86_64_GOTPC32, + BFD_RELOC_X86_64_DTPOFF64, and BFD_RELOC_X86_64_TPOFF64. Also + convert 8-byte pc-relative relocations. + (lex_got): Use BFD_RELOC_X86_64_GOTOFF64 for 64-bit @gotoff. + (i386_validate_fix): Likewise. + (x86_cons): Also handle quad values in 64-bit mode. + (i386_displacement): Also handle BFD_RELOC_X86_64_GOTOFF64. + (md_apply_fix): Include BFD_RELOC_X86_64_DTPOFF64 and + BFD_RELOC_X86_64_TPOFF64 in the TLS check. Also convert BFD_RELOC_64 + to pc-relative variant. Also check for BFD_RELOC_64_PCREL. + 2005-06-13 Zack Weinberg * config/tc-arm.c (find_real_start): Check S_IS_LOCAL on diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 00957974b..18df9cfe3 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -1222,6 +1222,7 @@ reloc (size, pcrel, sign, other) 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); } @@ -1292,8 +1293,11 @@ tc_i386_fix_adjustable (fixP) || fixP->fx_r_type == BFD_RELOC_X86_64_TLSGD || fixP->fx_r_type == BFD_RELOC_X86_64_TLSLD || fixP->fx_r_type == BFD_RELOC_X86_64_DTPOFF32 + || fixP->fx_r_type == BFD_RELOC_X86_64_DTPOFF64 || fixP->fx_r_type == BFD_RELOC_X86_64_GOTTPOFF || fixP->fx_r_type == BFD_RELOC_X86_64_TPOFF32 + || fixP->fx_r_type == BFD_RELOC_X86_64_TPOFF64 + || fixP->fx_r_type == BFD_RELOC_X86_64_GOTOFF64 || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY) return 0; @@ -3502,14 +3506,16 @@ output_disp (insn_start_frag, insn_start_off) p = frag_more (size); reloc_type = reloc (size, pcrel, sign, i.reloc[n]); - if (reloc_type == BFD_RELOC_32 - && GOT_symbol + if (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 + || reloc_type == BFD_RELOC_X86_64_32S) + && (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)) { offsetT add; @@ -3526,10 +3532,10 @@ output_disp (insn_start_frag, insn_start_off) 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; + if (flag_code != CODE_64BIT) + reloc_type = BFD_RELOC_386_GOTPC; + else + reloc_type = BFD_RELOC_X86_64_GOTPC32; i.op[n].disps->X_add_number += add; } fix_new_exp (frag_now, p - frag_now->fr_literal, size, @@ -3638,7 +3644,8 @@ output_imm (insn_start_frag, insn_start_off) * since the expression is not pcrel, I felt it would be * confusing to do it this way. */ - if (reloc_type == BFD_RELOC_32 + if ((reloc_type == BFD_RELOC_32 + || reloc_type == BFD_RELOC_X86_64_32S) && GOT_symbol && GOT_symbol == i.op[n].imms->X_add_symbol && (i.op[n].imms->X_op == O_symbol @@ -3662,10 +3669,10 @@ output_imm (insn_start_frag, insn_start_off) 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; + if (flag_code != CODE_64BIT) + reloc_type = BFD_RELOC_386_GOTPC; + else + reloc_type = BFD_RELOC_X86_64_GOTPC32; i.op[n].imms->X_add_number += add; } fix_new_exp (frag_now, p - frag_now->fr_literal, size, @@ -3698,7 +3705,7 @@ lex_got (reloc, adjust) 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 } }, + { "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 } }, @@ -3792,7 +3799,7 @@ x86_cons (exp, size) expressionS *exp; int size; { - if (size == 4) + if (size == 4 || (flag_code == CODE_64BIT && size == 8)) { /* Handle @GOTOFF and the like in an expression. */ char *save; @@ -4104,7 +4111,8 @@ i386_displacement (disp_start, disp_end) 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_GOTPCREL) + || i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL + || i.reloc[this_operand] == BFD_RELOC_X86_64_GOTOFF64) { if (exp->X_op != O_symbol) { @@ -4122,6 +4130,8 @@ i386_displacement (disp_start, disp_end) exp->X_op_symbol = GOT_symbol; if (i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL) i.reloc[this_operand] = BFD_RELOC_32_PCREL; + else if (i.reloc[this_operand] == BFD_RELOC_X86_64_GOTOFF64) + i.reloc[this_operand] = BFD_RELOC_64; else i.reloc[this_operand] = BFD_RELOC_32; } @@ -4812,6 +4822,9 @@ md_apply_fix (fixP, valP, seg) default: break; + case BFD_RELOC_64: + fixP->fx_r_type = BFD_RELOC_64_PCREL; + break; case BFD_RELOC_32: case BFD_RELOC_X86_64_32S: fixP->fx_r_type = BFD_RELOC_32_PCREL; @@ -4827,6 +4840,7 @@ md_apply_fix (fixP, valP, seg) if (fixP->fx_addsy != NULL && (fixP->fx_r_type == BFD_RELOC_32_PCREL + || fixP->fx_r_type == BFD_RELOC_64_PCREL || fixP->fx_r_type == BFD_RELOC_16_PCREL || fixP->fx_r_type == BFD_RELOC_8_PCREL) && !use_rela_relocations) @@ -4901,7 +4915,9 @@ md_apply_fix (fixP, valP, seg) case BFD_RELOC_386_TLS_LDO_32: case BFD_RELOC_386_TLS_LE_32: case BFD_RELOC_X86_64_DTPOFF32: + case BFD_RELOC_X86_64_DTPOFF64: case BFD_RELOC_X86_64_TPOFF32: + case BFD_RELOC_X86_64_TPOFF64: S_SET_THREAD_LOCAL (fixP->fx_addsy); break; @@ -5339,7 +5355,6 @@ i386_validate_fix (fixp) { 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) @@ -5348,9 +5363,10 @@ i386_validate_fix (fixp) } else { - if (flag_code == CODE_64BIT) - abort (); - fixp->fx_r_type = BFD_RELOC_386_GOTOFF; + if (flag_code != CODE_64BIT) + fixp->fx_r_type = BFD_RELOC_386_GOTOFF; + else + fixp->fx_r_type = BFD_RELOC_X86_64_GOTOFF64; } fixp->fx_subsy = 0; } @@ -5384,8 +5400,12 @@ tc_gen_reloc (section, fixp) case BFD_RELOC_X86_64_TLSGD: case BFD_RELOC_X86_64_TLSLD: case BFD_RELOC_X86_64_DTPOFF32: + case BFD_RELOC_X86_64_DTPOFF64: case BFD_RELOC_X86_64_GOTTPOFF: case BFD_RELOC_X86_64_TPOFF32: + case BFD_RELOC_X86_64_TPOFF64: + case BFD_RELOC_X86_64_GOTOFF64: + case BFD_RELOC_X86_64_GOTPC32: case BFD_RELOC_RVA: case BFD_RELOC_VTABLE_ENTRY: case BFD_RELOC_VTABLE_INHERIT: @@ -5415,6 +5435,9 @@ tc_gen_reloc (section, fixp) case 1: code = BFD_RELOC_8_PCREL; break; case 2: code = BFD_RELOC_16_PCREL; break; case 4: code = BFD_RELOC_32_PCREL; break; +#ifdef BFD64 + case 8: code = BFD_RELOC_64_PCREL; break; +#endif } } else @@ -5438,14 +5461,14 @@ tc_gen_reloc (section, fixp) break; } - if (code == BFD_RELOC_32 + if ((code == BFD_RELOC_32 || code == BFD_RELOC_32_PCREL) && 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; + if (flag_code != CODE_64BIT) + code = BFD_RELOC_386_GOTPC; + else + code = BFD_RELOC_X86_64_GOTPC32; } rel = (arelent *) xmalloc (sizeof (arelent)); diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 35f59b9f8..1dd1ccf4c 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2005-06-17 Jan Beulich + + * gas/i386/x86-64-pcrel.s: Add insn requiring 64-bit pc-relative + relocation. Add insns for all widths of non-pc-relative relocations. + * gas/i386/x86-64-pcrel.d: Adjust. + 2005-06-13 Zack Weinberg * gas/arm/thumb.s: Only branch to labels defined in this file. diff --git a/gas/testsuite/gas/i386/x86-64-pcrel.d b/gas/testsuite/gas/i386/x86-64-pcrel.d index 3d647bfba..3be86c7c3 100644 --- a/gas/testsuite/gas/i386/x86-64-pcrel.d +++ b/gas/testsuite/gas/i386/x86-64-pcrel.d @@ -8,7 +8,12 @@ Disassembly of section .text: 0+000 <_start>: [ ]*[0-9a-f]+:[ ]+b0 00[ ]+movb?[ ]+\$(0x)?0,%al[ ]*[0-9a-f]+:[ ]+R_X86_64_PC8[ ]+xtrn\+(0x)?1 [ ]*[0-9a-f]+:[ ]+66 b8 00 00[ ]+movw?[ ]+\$(0x)?0,%ax[ ]*[0-9a-f]+:[ ]+R_X86_64_PC16[ ]+xtrn\+(0x)?2 -[ ]*[0-9a-f]+:[ ]+b8 00 00 00 00[ ]+movl?[ ]+\$(0x)?0,%eax[ ]*[0-9a-f]+:[ ]+R_X86_64_PC32[ ]+xtrn\+(0x)?1 -[ ]*[0-9a-f]+:[ ]+48 c7 c0 00 00 00 00[ ]+movq?[ ]+\$(0x)?0,%rax[ ]*[0-9a-f]+:[ ]+R_X86_64_PC32[ ]+xtrn\+(0x)?3 -[ ]*[0-9a-f]+:[ ]+48 c7 c0 00 00 00 00[ ]+movq?[ ]+\$(0x)?0,%rax[ ]*[0-9a-f]+:[ ]+R_X86_64_32S[ ]+xtrn +[ ]*[0-9a-f]+:[ ]+b8( 00){4}[ ]+movl?[ ]+\$(0x)?0,%eax[ ]*[0-9a-f]+:[ ]+R_X86_64_PC32[ ]+xtrn\+(0x)?1 +[ ]*[0-9a-f]+:[ ]+48 c7 c0( 00){4}[ ]+movq?[ ]+\$(0x)?0,%rax[ ]*[0-9a-f]+:[ ]+R_X86_64_PC32[ ]+xtrn\+(0x)?3 +[ ]*[0-9a-f]+:[ ]+48 b8( 00){8}[ ]+mov(abs)?q?[ ]+\$(0x)?0,%rax[ ]*[0-9a-f]+:[ ]+R_X86_64_PC64[ ]+xtrn\+(0x)?2 +[ ]*[0-9a-f]+:[ ]+b0 00[ ]+movb?[ ]+\$(0x)?0,%al[ ]*[0-9a-f]+:[ ]+R_X86_64_8[ ]+xtrn +[ ]*[0-9a-f]+:[ ]+66 b8 00 00[ ]+movw?[ ]+\$(0x)?0,%ax[ ]*[0-9a-f]+:[ ]+R_X86_64_16[ ]+xtrn +[ ]*[0-9a-f]+:[ ]+b8( 00){4}[ ]+movl?[ ]+\$(0x)?0,%eax[ ]*[0-9a-f]+:[ ]+R_X86_64_32[ ]+xtrn +[ ]*[0-9a-f]+:[ ]+48 c7 c0( 00){4}[ ]+movq?[ ]+\$(0x)?0,%rax[ ]*[0-9a-f]+:[ ]+R_X86_64_32S[ ]+xtrn +[ ]*[0-9a-f]+:[ ]+48 b8( 00){8}[ ]+mov(abs)?q?[ ]+\$(0x)?0,%rax[ ]*[0-9a-f]+:[ ]+R_X86_64_64[ ]+xtrn #pass diff --git a/gas/testsuite/gas/i386/x86-64-pcrel.s b/gas/testsuite/gas/i386/x86-64-pcrel.s index c58e0935b..d4dcd9e1b 100644 --- a/gas/testsuite/gas/i386/x86-64-pcrel.s +++ b/gas/testsuite/gas/i386/x86-64-pcrel.s @@ -4,6 +4,12 @@ _start: movw $(xtrn - .), %ax movl $(xtrn - .), %eax movq $(xtrn - .), %rax + movabsq $(xtrn - .), %rax + + movb $xtrn, %al + movw $xtrn, %ax + movl $xtrn, %eax movq $xtrn, %rax + movabsq $xtrn, %rax .p2align 4,0 diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog index 8aa8fe78c..40d7853e3 100644 --- a/include/elf/ChangeLog +++ b/include/elf/ChangeLog @@ -1,3 +1,9 @@ +2005-06-17 Jan Beulich + + * x86-64.h (elf_x86_64_reloc_type): Adjust comment for + R_X86_64_GOTPCREL. Add R_X86_64_PC64, R_X86_64_GOTOFF64, and + R_X86_64_GOTPC32. + 2005-06-07 Aldy Hernandez Michael Snyder Stan Cox diff --git a/include/elf/x86-64.h b/include/elf/x86-64.h index ed6f0d93a..d83fc20fa 100644 --- a/include/elf/x86-64.h +++ b/include/elf/x86-64.h @@ -34,7 +34,7 @@ START_RELOC_NUMBERS (elf_x86_64_reloc_type) RELOC_NUMBER (R_X86_64_JUMP_SLOT,7) /* Create PLT entry */ RELOC_NUMBER (R_X86_64_RELATIVE, 8) /* Adjust by program base */ RELOC_NUMBER (R_X86_64_GOTPCREL, 9) /* 32 bit signed pc relative - offset to GOT */ + offset to GOT entry */ RELOC_NUMBER (R_X86_64_32, 10) /* Direct 32 bit zero extended */ RELOC_NUMBER (R_X86_64_32S, 11) /* Direct 32 bit sign extended */ RELOC_NUMBER (R_X86_64_16, 12) /* Direct 16 bit zero extended */ @@ -49,6 +49,10 @@ START_RELOC_NUMBERS (elf_x86_64_reloc_type) RELOC_NUMBER (R_X86_64_DTPOFF32, 21) /* Offset in TLS block */ RELOC_NUMBER (R_X86_64_GOTTPOFF, 22) /* PC relative offset to IE GOT entry */ RELOC_NUMBER (R_X86_64_TPOFF32, 23) /* Offset in initial TLS block */ + RELOC_NUMBER (R_X86_64_PC64, 24) /* PC relative 64 bit */ + RELOC_NUMBER (R_X86_64_GOTOFF64, 25) /* 64 bit offset to GOT */ + RELOC_NUMBER (R_X86_64_GOTPC32, 26) /* 32 bit signed pc relative + offset to GOT */ RELOC_NUMBER (R_X86_64_GNU_VTINHERIT, 250) /* GNU C++ hack */ RELOC_NUMBER (R_X86_64_GNU_VTENTRY, 251) /* GNU C++ hack */ END_RELOC_NUMBERS (R_X86_64_max) -- 2.11.4.GIT