diff options
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 23 | ||||
-rw-r--r-- | gas/config/tc-i386.c | 79 | ||||
-rw-r--r-- | gas/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/x86-64-pcrel.d | 11 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/x86-64-pcrel.s | 6 |
5 files changed, 94 insertions, 31 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 6ca9791..fc33e1b 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,26 @@ +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. + 2005-06-13 Zack Weinberg <zack@codesourcery.com> * 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 0095797..18df9cf 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 35f59b9..1dd1ccf 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,9 @@ +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. + 2005-06-13 Zack Weinberg <zack@codesourcery.com> * 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 3d647bf..3be86c7 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 c58e093..d4dcd9e 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 |