summaryrefslogtreecommitdiffstats
path: root/gas/config/tc-i386.c
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@novell.com>2005-06-17 08:03:59 +0000
committerJan Beulich <jbeulich@novell.com>2005-06-17 08:03:59 +0000
commitd6ab8113e32876e3d8ca06ad090d3160d51c8e16 (patch)
treeb33aaa00d229952fbbe27876a714ca5337933031 /gas/config/tc-i386.c
parent7a55f27940166650342bc8e7dfcfe97d43a7e7ce (diff)
downloadppe42-binutils-d6ab8113e32876e3d8ca06ad090d3160d51c8e16.tar.gz
ppe42-binutils-d6ab8113e32876e3d8ca06ad090d3160d51c8e16.zip
bfd/
2005-06-17 Jan Beulich <jbeulich@novell.com> * 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 <jbeulich@novell.com> * 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 <jbeulich@novell.com> * 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 <jbeulich@novell.com> * 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.
Diffstat (limited to 'gas/config/tc-i386.c')
-rw-r--r--gas/config/tc-i386.c79
1 files changed, 51 insertions, 28 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 00957974bc..18df9cfe36 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));
OpenPOWER on IntegriCloud