aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@novell.com>2005-07-18 06:27:24 +0000
committerJan Beulich <jbeulich@novell.com>2005-07-18 06:27:24 +0000
commit3956db082e7861afb30f45276fe709beb98b5b03 (patch)
tree73da0547f1990a481cb8c0e6473f91f3b46bb33a
parentac2aa337d30099606f140bdf01abaf7e22d68327 (diff)
downloadgdb-3956db082e7861afb30f45276fe709beb98b5b03.zip
gdb-3956db082e7861afb30f45276fe709beb98b5b03.tar.gz
gdb-3956db082e7861afb30f45276fe709beb98b5b03.tar.bz2
gas/
2005-07-18 Jan Beulich <jbeulich@novell.com> * config/tc-i386.c (reloc): Convert to ISO C90. Change first parameter to unsigned. Parameter sign now is tristate - zero/ positive mean unsigned/signed, negative means signedness doesn't matter. Check field size, signedness, and pcrel-ness are in agreement between relocated field and relocation type. Adjust diagnostics. (optimize_imm): And type mask of operand instead of overwriting it. (lex_got): Convert to ISO C90. Add third parameter. Add new field to local structure and initialize gotrel accordingly. Pass caller as mask of types that the operator can match. (x86_cons_fix_new): Let reloc know that signedness of relocation doesn't matter. (x86_pe_cons_fix_new): Likewise. (x86_cons): Pass additional argument to lex_got. (i386_immediate): New local variable 'types'. Pass its address as additional argument to lex_got. Mask out operand types not supported befoe returning. (i386_displacement): Likewise. Set bigdisp to all types supported in 64-bit mode, combining the previously split initialization. gas/testsuite/ 2005-07-18 Jan Beulich <jbeulich@novell.com> * gas/i386/reloc32.[sdl]: New. * gas/i386/reloc64.[sdl]: New. * gas/i386/i386.exp: Run new tests.
-rw-r--r--gas/ChangeLog22
-rw-r--r--gas/config/tc-i386.c128
-rw-r--r--gas/testsuite/ChangeLog6
-rw-r--r--gas/testsuite/gas/i386/i386.exp8
-rw-r--r--gas/testsuite/gas/i386/reloc32.d67
-rw-r--r--gas/testsuite/gas/i386/reloc32.l67
-rw-r--r--gas/testsuite/gas/i386/reloc32.s161
-rw-r--r--gas/testsuite/gas/i386/reloc64.d71
-rw-r--r--gas/testsuite/gas/i386/reloc64.l77
-rw-r--r--gas/testsuite/gas/i386/reloc64.s183
10 files changed, 746 insertions, 44 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index fb902be..5218925 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,27 @@
2005-07-18 Jan Beulich <jbeulich@novell.com>
+ * config/tc-i386.c (reloc): Convert to ISO C90. Change first
+ parameter to unsigned. Parameter sign now is tristate - zero/
+ positive mean unsigned/signed, negative means signedness doesn't
+ matter. Check field size,
+ signedness, and pcrel-ness are in agreement between relocated field
+ and relocation type. Adjust diagnostics.
+ (optimize_imm): And type mask of operand instead of overwriting it.
+ (lex_got): Convert to ISO C90. Add third parameter. Add new field to
+ local structure and initialize gotrel accordingly. Pass caller as
+ mask of types that the operator can match.
+ (x86_cons_fix_new): Let reloc know that signedness of relocation
+ doesn't matter.
+ (x86_pe_cons_fix_new): Likewise.
+ (x86_cons): Pass additional argument to lex_got.
+ (i386_immediate): New local variable 'types'. Pass its address as
+ additional argument to lex_got. Mask out operand types not supported
+ befoe returning.
+ (i386_displacement): Likewise. Set bigdisp to all types supported in
+ 64-bit mode, combining the previously split initialization.
+
+2005-07-18 Jan Beulich <jbeulich@novell.com>
+
* config/tc-i386.c (parse_insn): Reject prefix if unavailable in
current mode.
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 3917b84..cdc915b 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -1204,23 +1204,51 @@ pt (t)
#endif /* DEBUG386 */
-static bfd_reloc_code_real_type reloc
- PARAMS ((int, int, int, bfd_reloc_code_real_type));
-
static bfd_reloc_code_real_type
-reloc (size, pcrel, sign, other)
- int size;
- int pcrel;
- int sign;
- bfd_reloc_code_real_type other;
+reloc (unsigned int size,
+ int pcrel,
+ int sign,
+ bfd_reloc_code_real_type other)
{
if (other != NO_RELOC)
- return other;
+ {
+ reloc_howto_type *reloc;
+
+ if (size == 8)
+ switch (other)
+ {
+ case BFD_RELOC_X86_64_TPOFF32:
+ other = BFD_RELOC_X86_64_TPOFF64;
+ break;
+ case BFD_RELOC_X86_64_DTPOFF32:
+ other = BFD_RELOC_X86_64_DTPOFF64;
+ break;
+ default:
+ break;
+ }
+ reloc = bfd_reloc_type_lookup (stdoutput, other);
+ if (!reloc)
+ as_bad (_("unknown relocation (%u)"), other);
+ else if (size != bfd_get_reloc_size (reloc))
+ as_bad (_("%u-byte relocation cannot be applied to %u-byte field"),
+ bfd_get_reloc_size (reloc),
+ size);
+ else if (pcrel && !reloc->pc_relative)
+ as_bad (_("non-pc-relative relocation for pc-relative field"));
+ else if ((reloc->complain_on_overflow == complain_overflow_signed
+ && !sign)
+ || (reloc->complain_on_overflow == complain_overflow_unsigned
+ && sign > 0))
+ as_bad (_("relocated field and relocation type differ in signedness"));
+ else
+ return other;
+ return NO_RELOC;
+ }
if (pcrel)
{
if (!sign)
- as_bad (_("There are no unsigned pc-relative relocations"));
+ as_bad (_("there are no unsigned pc-relative relocations"));
switch (size)
{
case 1: return BFD_RELOC_8_PCREL;
@@ -1228,11 +1256,11 @@ reloc (size, pcrel, sign, other)
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);
+ as_bad (_("cannot do %u byte pc-relative relocation"), size);
}
else
{
- if (sign)
+ if (sign > 0)
switch (size)
{
case 4: return BFD_RELOC_X86_64_32S;
@@ -1245,8 +1273,8 @@ reloc (size, pcrel, sign, other)
case 4: return BFD_RELOC_32;
case 8: return BFD_RELOC_64;
}
- as_bad (_("can not do %s %d byte relocation"),
- sign ? "signed" : "unsigned", size);
+ as_bad (_("cannot do %s %u byte relocation"),
+ sign > 0 ? "signed" : "unsigned", size);
}
abort ();
@@ -2059,16 +2087,16 @@ optimize_imm ()
switch (guess_suffix)
{
case QWORD_MNEM_SUFFIX:
- i.types[op] = Imm64 | Imm32S;
+ i.types[op] &= Imm64 | Imm32S;
break;
case LONG_MNEM_SUFFIX:
- i.types[op] = Imm32;
+ i.types[op] &= Imm32;
break;
case WORD_MNEM_SUFFIX:
- i.types[op] = Imm16;
+ i.types[op] &= Imm16;
break;
case BYTE_MNEM_SUFFIX:
- i.types[op] = Imm8 | Imm8S;
+ i.types[op] &= Imm8 | Imm8S;
break;
}
break;
@@ -3714,8 +3742,6 @@ output_imm (insn_start_frag, insn_start_off)
}
#ifndef LEX_AT
-static char *lex_got PARAMS ((enum bfd_reloc_code_real *, int *));
-
/* Parse operands of the form
<symbol>@GOTOFF+<nnn>
and similar .plt or .got references.
@@ -3726,28 +3752,29 @@ static char *lex_got PARAMS ((enum bfd_reloc_code_real *, int *));
is non-null set it to the length of the string we removed from the
input line. Otherwise return NULL. */
static char *
-lex_got (reloc, adjust)
- enum bfd_reloc_code_real *reloc;
- int *adjust;
+lex_got (enum bfd_reloc_code_real *reloc,
+ int *adjust,
+ unsigned int *types)
{
static const char * const mode_name[NUM_FLAG_CODE] = { "32", "16", "64" };
static const struct {
const char *str;
const enum bfd_reloc_code_real rel[NUM_FLAG_CODE];
+ const unsigned int types64;
} 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 } },
- { "TLSLD", { 0, 0, BFD_RELOC_X86_64_TLSLD } },
- { "GOTTPOFF", { BFD_RELOC_386_TLS_IE_32, 0, BFD_RELOC_X86_64_GOTTPOFF } },
- { "TPOFF", { BFD_RELOC_386_TLS_LE_32, 0, BFD_RELOC_X86_64_TPOFF32 } },
- { "NTPOFF", { BFD_RELOC_386_TLS_LE, 0, 0 } },
- { "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 } }
+ { "PLT", { BFD_RELOC_386_PLT32, 0, BFD_RELOC_X86_64_PLT32 }, Imm32|Imm32S|Disp32 },
+ { "GOTOFF", { BFD_RELOC_386_GOTOFF, 0, BFD_RELOC_X86_64_GOTOFF64 }, Imm64|Disp64 },
+ { "GOTPCREL", { 0, 0, BFD_RELOC_X86_64_GOTPCREL }, Imm32|Imm32S|Disp32 },
+ { "TLSGD", { BFD_RELOC_386_TLS_GD, 0, BFD_RELOC_X86_64_TLSGD }, Imm32|Imm32S|Disp32 },
+ { "TLSLDM", { BFD_RELOC_386_TLS_LDM, 0, 0 }, 0 },
+ { "TLSLD", { 0, 0, BFD_RELOC_X86_64_TLSLD }, Imm32|Imm32S|Disp32 },
+ { "GOTTPOFF", { BFD_RELOC_386_TLS_IE_32, 0, BFD_RELOC_X86_64_GOTTPOFF }, Imm32|Imm32S|Disp32 },
+ { "TPOFF", { BFD_RELOC_386_TLS_LE_32, 0, BFD_RELOC_X86_64_TPOFF32 }, Imm32|Imm32S|Imm64|Disp32|Disp64 },
+ { "NTPOFF", { BFD_RELOC_386_TLS_LE, 0, 0 }, 0 },
+ { "DTPOFF", { BFD_RELOC_386_TLS_LDO_32, 0, BFD_RELOC_X86_64_DTPOFF32 }, Imm32|Imm32S|Imm64|Disp32|Disp64 },
+ { "GOTNTPOFF",{ BFD_RELOC_386_TLS_GOTIE, 0, 0 }, 0 },
+ { "INDNTPOFF",{ BFD_RELOC_386_TLS_IE, 0, 0 }, 0 },
+ { "GOT", { BFD_RELOC_386_GOT32, 0, BFD_RELOC_X86_64_GOT32 }, Imm32|Imm32S|Disp32 }
};
char *cp;
unsigned int j;
@@ -3772,6 +3799,14 @@ lex_got (reloc, adjust)
if (adjust)
*adjust = len;
+ if (types)
+ {
+ if (flag_code != CODE_64BIT)
+ *types = Imm32|Disp32;
+ else
+ *types = gotrel[j].types64;
+ }
+
if (GOT_symbol == NULL)
GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
@@ -3820,7 +3855,7 @@ x86_cons_fix_new (frag, off, len, exp)
unsigned int len;
expressionS *exp;
{
- enum bfd_reloc_code_real r = reloc (len, 0, 0, got_reloc);
+ enum bfd_reloc_code_real r = reloc (len, 0, -1, got_reloc);
got_reloc = NO_RELOC;
fix_new_exp (frag, off, len, exp, 0, r);
}
@@ -3838,7 +3873,7 @@ x86_cons (exp, size)
int adjust;
save = input_line_pointer;
- gotfree_input_line = lex_got (&got_reloc, &adjust);
+ gotfree_input_line = lex_got (&got_reloc, &adjust, NULL);
if (gotfree_input_line)
input_line_pointer = gotfree_input_line;
@@ -3869,7 +3904,7 @@ x86_pe_cons_fix_new (frag, off, len, exp)
unsigned int len;
expressionS *exp;
{
- enum bfd_reloc_code_real r = reloc (len, 0, 0, NO_RELOC);
+ enum bfd_reloc_code_real r = reloc (len, 0, -1, NO_RELOC);
if (exp->X_op == O_secrel)
{
@@ -3914,6 +3949,7 @@ i386_immediate (imm_start)
#endif
segT exp_seg = 0;
expressionS *exp;
+ unsigned int types = ~0U;
if (i.imm_operands == MAX_IMMEDIATE_OPERANDS)
{
@@ -3931,7 +3967,7 @@ i386_immediate (imm_start)
input_line_pointer = imm_start;
#ifndef LEX_AT
- gotfree_input_line = lex_got (&i.reloc[this_operand], NULL);
+ gotfree_input_line = lex_got (&i.reloc[this_operand], NULL, &types);
if (gotfree_input_line)
input_line_pointer = gotfree_input_line;
#endif
@@ -3986,6 +4022,7 @@ i386_immediate (imm_start)
determined later, depending on destination register,
suffix, or the default for the section. */
i.types[this_operand] |= Imm8 | Imm16 | Imm32 | Imm32S | Imm64;
+ i.types[this_operand] &= types;
}
return 1;
@@ -4056,11 +4093,12 @@ i386_displacement (disp_start, disp_end)
char *gotfree_input_line;
#endif
int bigdisp = Disp32;
+ unsigned int types = Disp;
if (flag_code == CODE_64BIT)
{
if (i.prefix[ADDR_PREFIX] == 0)
- bigdisp = Disp64;
+ bigdisp = Disp64 | Disp32S | Disp32;
}
else if ((flag_code == CODE_16BIT) ^ (i.prefix[ADDR_PREFIX] != 0))
bigdisp = Disp16;
@@ -4118,7 +4156,7 @@ i386_displacement (disp_start, disp_end)
}
#endif
#ifndef LEX_AT
- gotfree_input_line = lex_got (&i.reloc[this_operand], NULL);
+ gotfree_input_line = lex_got (&i.reloc[this_operand], NULL, &types);
if (gotfree_input_line)
input_line_pointer = gotfree_input_line;
#endif
@@ -4192,8 +4230,10 @@ i386_displacement (disp_start, disp_end)
return 0;
}
#endif
- else if (flag_code == CODE_64BIT)
- i.types[this_operand] |= Disp32S | Disp32;
+
+ if (!(i.types[this_operand] & ~Disp))
+ i.types[this_operand] &= types;
+
return 1;
}
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 5af722a..da74841 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2005-07-18 Jan Beulich <jbeulich@novell.com>
+
+ * gas/i386/reloc32.[sdl]: New.
+ * gas/i386/reloc64.[sdl]: New.
+ * gas/i386/i386.exp: Run new tests.
+
2007-07-15 H.J. Lu <hongjiu.lu@intel.com>
* gas/i386/i386.exp: Add vmx and x86-64-vmx.
diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp
index 851f698..8cafb0a 100644
--- a/gas/testsuite/gas/i386/i386.exp
+++ b/gas/testsuite/gas/i386/i386.exp
@@ -103,6 +103,8 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_32_check]]
run_dump_test "tlspic"
run_dump_test "tlsnopic"
run_dump_test "bss"
+ run_dump_test "reloc32"
+ run_list_test "reloc32" "--defsym _bad_=1"
}
# This is a PE specific test.
@@ -141,5 +143,11 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t
run_dump_test "x86-64-unwind"
}
+ # ELF specific tests
+ if [is_elf_format] then {
+ run_dump_test "reloc64"
+ run_list_test "reloc64" "--defsym _bad_=1"
+ }
+
set ASFLAGS "$old_ASFLAGS"
}
diff --git a/gas/testsuite/gas/i386/reloc32.d b/gas/testsuite/gas/i386/reloc32.d
new file mode 100644
index 0000000..b2cd29c
--- /dev/null
+++ b/gas/testsuite/gas/i386/reloc32.d
@@ -0,0 +1,67 @@
+#objdump: -Drw
+#name: i386 relocs
+
+.*: +file format .*i386.*
+
+Disassembly of section \.text:
+#...
+.*[ ]+R_386_32[ ]+xtrn
+.*[ ]+R_386_16[ ]+xtrn
+.*[ ]+R_386_8[ ]+xtrn
+.*[ ]+R_386_32[ ]+xtrn
+.*[ ]+R_386_16[ ]+xtrn
+.*[ ]+R_386_PC32[ ]+xtrn
+.*[ ]+R_386_PC16[ ]+xtrn
+.*[ ]+R_386_PC8[ ]+xtrn
+.*[ ]+R_386_PC32[ ]+xtrn
+.*[ ]+R_386_PC16[ ]+xtrn
+.*[ ]+R_386_PC32[ ]+xtrn
+.*[ ]+R_386_PC8[ ]+xtrn
+.*[ ]+R_386_GOT32[ ]+xtrn
+.*[ ]+R_386_GOT32[ ]+xtrn
+.*[ ]+R_386_GOTOFF[ ]+xtrn
+.*[ ]+R_386_GOTOFF[ ]+xtrn
+.*[ ]+R_386_GOTPC[ ]+_GLOBAL_OFFSET_TABLE_
+.*[ ]+R_386_GOTPC[ ]+_GLOBAL_OFFSET_TABLE_
+.*[ ]+R_386_PLT32[ ]+xtrn
+.*[ ]+R_386_PLT32[ ]+xtrn
+.*[ ]+R_386_PLT32[ ]+xtrn
+.*[ ]+R_386_TLS_GD[ ]+xtrn
+.*[ ]+R_386_TLS_GD[ ]+xtrn
+.*[ ]+R_386_TLS_GOTIE[ ]+xtrn
+.*[ ]+R_386_TLS_GOTIE[ ]+xtrn
+.*[ ]+R_386_TLS_IE[ ]+xtrn
+.*[ ]+R_386_TLS_IE[ ]+xtrn
+.*[ ]+R_386_TLS_IE_32[ ]+xtrn
+.*[ ]+R_386_TLS_IE_32[ ]+xtrn
+.*[ ]+R_386_TLS_LDM[ ]+xtrn
+.*[ ]+R_386_TLS_LDM[ ]+xtrn
+.*[ ]+R_386_TLS_LDO_32[ ]+xtrn
+.*[ ]+R_386_TLS_LDO_32[ ]+xtrn
+.*[ ]+R_386_TLS_LE[ ]+xtrn
+.*[ ]+R_386_TLS_LE[ ]+xtrn
+.*[ ]+R_386_TLS_LE_32[ ]+xtrn
+.*[ ]+R_386_TLS_LE_32[ ]+xtrn
+Disassembly of section \.data:
+#...
+.*[ ]+R_386_32[ ]+xtrn
+.*[ ]+R_386_PC32[ ]+xtrn
+.*[ ]+R_386_GOT32[ ]+xtrn
+.*[ ]+R_386_GOTOFF[ ]+xtrn
+.*[ ]+R_386_GOTPC[ ]+_GLOBAL_OFFSET_TABLE_
+.*[ ]+R_386_GOTPC[ ]+_GLOBAL_OFFSET_TABLE_
+.*[ ]+R_386_PLT32[ ]+xtrn
+#...
+.*[ ]+R_386_TLS_GD[ ]+xtrn
+#...
+.*[ ]+R_386_TLS_GOTIE[ ]+xtrn
+.*[ ]+R_386_TLS_IE[ ]+xtrn
+.*[ ]+R_386_TLS_IE_32[ ]+xtrn
+.*[ ]+R_386_TLS_LDM[ ]+xtrn
+.*[ ]+R_386_TLS_LDO_32[ ]+xtrn
+.*[ ]+R_386_TLS_LE[ ]+xtrn
+.*[ ]+R_386_TLS_LE_32[ ]+xtrn
+.*[ ]+R_386_16[ ]+xtrn
+.*[ ]+R_386_PC16[ ]+xtrn
+.*[ ]+R_386_8[ ]+xtrn
+.*[ ]+R_386_PC8[ ]+xtrn
diff --git a/gas/testsuite/gas/i386/reloc32.l b/gas/testsuite/gas/i386/reloc32.l
new file mode 100644
index 0000000..74e80df
--- /dev/null
+++ b/gas/testsuite/gas/i386/reloc32.l
@@ -0,0 +1,67 @@
+.*: Assembler messages:
+.*:30: Error: .*
+.*:31: Error: .*
+.*:33: Error: .*
+.*:34: Error: .*
+.*:37: Error: .*
+.*:38: Error: .*
+.*:40: Error: .*
+.*:41: Error: .*
+.*:51: Error: .*
+.*:52: Error: .*
+.*:54: Error: .*
+.*:56: Error: .*
+.*:59: Error: .*
+.*:60: Error: .*
+.*:62: Error: .*
+.*:63: Error: .*
+.*:66: Error: .*
+.*:67: Error: .*
+.*:69: Error: .*
+.*:70: Error: .*
+.*:73: Error: .*
+.*:74: Error: .*
+.*:76: Error: .*
+.*:77: Error: .*
+.*:80: Error: .*
+.*:81: Error: .*
+.*:83: Error: .*
+.*:84: Error: .*
+.*:87: Error: .*
+.*:88: Error: .*
+.*:90: Error: .*
+.*:91: Error: .*
+.*:94: Error: .*
+.*:95: Error: .*
+.*:97: Error: .*
+.*:98: Error: .*
+.*:101: Error: .*
+.*:102: Error: .*
+.*:104: Error: .*
+.*:105: Error: .*
+.*:108: Error: .*
+.*:109: Error: .*
+.*:111: Error: .*
+.*:112: Error: .*
+.*:133: Error: .*
+.*:134: Error: .*
+.*:137: Error: .*
+.*:138: Error: .*
+.*:139: Error: .*
+.*:140: Error: .*
+.*:141: Error: .*
+.*:142: Error: .*
+.*:143: Error: .*
+.*:144: Error: .*
+.*:145: Error: .*
+.*:149: Error: .*
+.*:150: Error: .*
+.*:153: Error: .*
+.*:154: Error: .*
+.*:155: Error: .*
+.*:156: Error: .*
+.*:157: Error: .*
+.*:158: Error: .*
+.*:159: Error: .*
+.*:160: Error: .*
+.*:161: Error: .*
diff --git a/gas/testsuite/gas/i386/reloc32.s b/gas/testsuite/gas/i386/reloc32.s
new file mode 100644
index 0000000..1a893ff
--- /dev/null
+++ b/gas/testsuite/gas/i386/reloc32.s
@@ -0,0 +1,161 @@
+ .macro bad args:vararg
+ .ifdef _bad_
+ \args
+ .endif
+ .endm
+
+ .macro ill args:vararg
+ # This is used to mark entries that aren't handled consistently,
+ # and thus shouldn't currently be checked for.
+ # \args
+ .endm
+
+ .text
+_start:
+ mov $xtrn, %eax
+ mov $xtrn, %ax
+ mov $xtrn, %al
+ mov xtrn(%ebx), %eax
+ mov xtrn(%bx), %eax
+
+ mov $(xtrn - .), %eax
+ mov $(xtrn - .), %ax
+ mov $(xtrn - .), %al
+ mov xtrn - .(%ebx), %eax
+ mov xtrn - .(%bx), %eax
+ call xtrn
+ jecxz xtrn
+
+ mov $xtrn@got, %eax
+bad mov $xtrn@got, %ax
+bad mov $xtrn@got, %al
+ mov xtrn@got(%ebx), %eax
+bad mov xtrn@got(%bx), %eax
+bad call xtrn@got
+
+ mov $xtrn@gotoff, %eax
+bad mov $xtrn@gotoff, %ax
+bad mov $xtrn@gotoff, %al
+ mov xtrn@gotoff(%ebx), %eax
+bad mov xtrn@gotoff(%bx), %eax
+bad call xtrn@gotoff
+
+ add $_GLOBAL_OFFSET_TABLE_, %eax
+ill add $_GLOBAL_OFFSET_TABLE_, %ax
+ill add $_GLOBAL_OFFSET_TABLE_, %al
+ add $(_GLOBAL_OFFSET_TABLE_ - .), %eax
+ill add $(_GLOBAL_OFFSET_TABLE_ - .), %ax
+ill add $(_GLOBAL_OFFSET_TABLE_ - .), %al
+
+ mov $xtrn@plt, %eax
+bad mov $xtrn@plt, %ax
+bad mov $xtrn@plt, %al
+ mov xtrn@plt(%ebx), %eax
+bad mov xtrn@plt(%bx), %eax
+ call xtrn@plt
+bad jecxz xtrn@plt
+
+ mov $xtrn@tlsgd, %eax
+bad mov $xtrn@tlsgd, %ax
+bad mov $xtrn@tlsgd, %al
+ mov xtrn@tlsgd(%ebx), %eax
+bad mov xtrn@tlsgd(%bx), %eax
+bad call xtrn@tlsgd
+
+ mov $xtrn@gotntpoff, %eax
+bad mov $xtrn@gotntpoff, %ax
+bad mov $xtrn@gotntpoff, %al
+ mov xtrn@gotntpoff(%ebx), %eax
+bad mov xtrn@gotntpoff(%bx), %eax
+bad call xtrn@gotntpoff
+
+ mov $xtrn@indntpoff, %eax
+bad mov $xtrn@indntpoff, %ax
+bad mov $xtrn@indntpoff, %al
+ mov xtrn@indntpoff(%ebx), %eax
+bad mov xtrn@indntpoff(%bx), %eax
+bad call xtrn@indntpoff
+
+ mov $xtrn@gottpoff, %eax
+bad mov $xtrn@gottpoff, %ax
+bad mov $xtrn@gottpoff, %al
+ mov xtrn@gottpoff(%ebx), %eax
+bad mov xtrn@gottpoff(%bx), %eax
+bad call xtrn@gottpoff
+
+ mov $xtrn@tlsldm, %eax
+bad mov $xtrn@tlsldm, %ax
+bad mov $xtrn@tlsldm, %al
+ mov xtrn@tlsldm(%ebx), %eax
+bad mov xtrn@tlsldm(%bx), %eax
+bad call xtrn@tlsldm
+
+ mov $xtrn@dtpoff, %eax
+bad mov $xtrn@dtpoff, %ax
+bad mov $xtrn@dtpoff, %al
+ mov xtrn@dtpoff(%ebx), %eax
+bad mov xtrn@dtpoff(%bx), %eax
+bad call xtrn@dtpoff
+
+ mov $xtrn@ntpoff, %eax
+bad mov $xtrn@ntpoff, %ax
+bad mov $xtrn@ntpoff, %al
+ mov xtrn@ntpoff(%ebx), %eax
+bad mov xtrn@ntpoff(%bx), %eax
+bad call xtrn@ntpoff
+
+ mov $xtrn@tpoff, %eax
+bad mov $xtrn@tpoff, %ax
+bad mov $xtrn@tpoff, %al
+ mov xtrn@tpoff(%ebx), %eax
+bad mov xtrn@tpoff(%bx), %eax
+bad call xtrn@tpoff
+
+ .data
+ .long xtrn
+ .long xtrn - .
+ .long xtrn@got
+ .long xtrn@gotoff
+ .long _GLOBAL_OFFSET_TABLE_
+ .long _GLOBAL_OFFSET_TABLE_ - .
+ .long xtrn@plt
+ .long xtrn@tlsgd
+ .long xtrn@gotntpoff
+ .long xtrn@indntpoff
+ .long xtrn@gottpoff
+ .long xtrn@tlsldm
+ .long xtrn@dtpoff
+ .long xtrn@ntpoff
+ .long xtrn@tpoff
+
+ .word xtrn
+ .word xtrn - .
+bad .word xtrn@got
+bad .word xtrn@gotoff
+ill .word _GLOBAL_OFFSET_TABLE_
+ill .word _GLOBAL_OFFSET_TABLE_ - .
+bad .word xtrn@plt
+bad .word xtrn@tlsgd
+bad .word xtrn@gotntpoff
+bad .word xtrn@indntpoff
+bad .word xtrn@gottpoff
+bad .word xtrn@tlsldm
+bad .word xtrn@dtpoff
+bad .word xtrn@ntpoff
+bad .word xtrn@tpoff
+
+ .byte xtrn
+ .byte xtrn - .
+bad .byte xtrn@got
+bad .byte xtrn@gotoff
+ill .byte _GLOBAL_OFFSET_TABLE_
+ill .byte _GLOBAL_OFFSET_TABLE_ - .
+bad .byte xtrn@plt
+bad .byte xtrn@tlsgd
+bad .byte xtrn@gotntpoff
+bad .byte xtrn@indntpoff
+bad .byte xtrn@gottpoff
+bad .byte xtrn@tlsldm
+bad .byte xtrn@dtpoff
+bad .byte xtrn@ntpoff
+bad .byte xtrn@tpoff
diff --git a/gas/testsuite/gas/i386/reloc64.d b/gas/testsuite/gas/i386/reloc64.d
new file mode 100644
index 0000000..ae08796
--- /dev/null
+++ b/gas/testsuite/gas/i386/reloc64.d
@@ -0,0 +1,71 @@
+#objdump: -Drw
+#name: x86-64 relocs
+
+.*: +file format .*x86-64.*
+
+Disassembly of section \.text:
+#...
+.*[ ]+R_X86_64_64[ ]+xtrn
+.*[ ]+R_X86_64_32S[ ]+xtrn
+.*[ ]+R_X86_64_32[ ]+xtrn
+.*[ ]+R_X86_64_16[ ]+xtrn
+.*[ ]+R_X86_64_8[ ]+xtrn
+.*[ ]+R_X86_64_32S[ ]+xtrn
+.*[ ]+R_X86_64_32[ ]+xtrn
+.*[ ]+R_X86_64_PC64[ ]+xtrn\+0x0*2
+.*[ ]+R_X86_64_PC32[ ]+xtrn\+0x0*2
+.*[ ]+R_X86_64_PC16[ ]+xtrn\+0x0*2
+.*[ ]+R_X86_64_PC8[ ]+xtrn\+0x0*1
+.*[ ]+R_X86_64_PC32[ ]+xtrn\+0xf+c
+.*[ ]+R_X86_64_PC32[ ]+xtrn\+0xf+c
+.*[ ]+R_X86_64_PC8[ ]+xtrn\+0xf+f
+.*[ ]+R_X86_64_GOT32[ ]+xtrn
+.*[ ]+R_X86_64_GOT32[ ]+xtrn
+.*[ ]+R_X86_64_GOTOFF64[ ]+xtrn
+.*[ ]+R_X86_64_GOTPCREL[ ]+xtrn
+.*[ ]+R_X86_64_GOTPCREL[ ]+xtrn
+.*[ ]+R_X86_64_GOTPCREL[ ]+xtrn\+0xf+c
+.*[ ]+R_X86_64_GOTPC32[ ]+_GLOBAL_OFFSET_TABLE_\+0x0*2
+.*[ ]+R_X86_64_GOTPC32[ ]+_GLOBAL_OFFSET_TABLE_\+0xf+f
+.*[ ]+R_X86_64_GOTPC32[ ]+_GLOBAL_OFFSET_TABLE_\+0x0*2
+.*[ ]+R_X86_64_PLT32[ ]+xtrn
+.*[ ]+R_X86_64_PLT32[ ]+xtrn
+.*[ ]+R_X86_64_PLT32[ ]+xtrn\+0xf+c
+.*[ ]+R_X86_64_TLSGD[ ]+xtrn
+.*[ ]+R_X86_64_TLSGD[ ]+xtrn
+.*[ ]+R_X86_64_TLSGD[ ]+xtrn\+0xf+c
+.*[ ]+R_X86_64_GOTTPOFF[ ]+xtrn
+.*[ ]+R_X86_64_GOTTPOFF[ ]+xtrn
+.*[ ]+R_X86_64_GOTTPOFF[ ]+xtrn\+0xf+c
+.*[ ]+R_X86_64_TLSLD[ ]+xtrn
+.*[ ]+R_X86_64_TLSLD[ ]+xtrn
+.*[ ]+R_X86_64_TLSLD[ ]+xtrn\+0xf+c
+.*[ ]+R_X86_64_DTPOFF64[ ]+xtrn
+.*[ ]+R_X86_64_DTPOFF32[ ]+xtrn
+.*[ ]+R_X86_64_DTPOFF32[ ]+xtrn
+.*[ ]+R_X86_64_TPOFF64[ ]+xtrn
+.*[ ]+R_X86_64_TPOFF32[ ]+xtrn
+.*[ ]+R_X86_64_TPOFF32[ ]+xtrn
+Disassembly of section \.data:
+#...
+.*[ ]+R_X86_64_64[ ]+xtrn
+.*[ ]+R_X86_64_PC64[ ]+xtrn
+.*[ ]+R_X86_64_GOTOFF64[ ]+xtrn
+.*[ ]+R_X86_64_DTPOFF64[ ]+xtrn
+.*[ ]+R_X86_64_TPOFF64[ ]+xtrn
+.*[ ]+R_X86_64_32[ ]+xtrn
+.*[ ]+R_X86_64_PC32[ ]+xtrn
+.*[ ]+R_X86_64_GOT32[ ]+xtrn
+.*[ ]+R_X86_64_GOTPCREL[ ]+xtrn
+.*[ ]+R_X86_64_GOTPC32[ ]+_GLOBAL_OFFSET_TABLE_
+.*[ ]+R_X86_64_GOTPC32[ ]+_GLOBAL_OFFSET_TABLE_
+.*[ ]+R_X86_64_PLT32[ ]+xtrn
+.*[ ]+R_X86_64_TLSGD[ ]+xtrn
+.*[ ]+R_X86_64_GOTTPOFF[ ]+xtrn
+.*[ ]+R_X86_64_TLSLD[ ]+xtrn
+.*[ ]+R_X86_64_DTPOFF32[ ]+xtrn
+.*[ ]+R_X86_64_TPOFF32[ ]+xtrn
+.*[ ]+R_X86_64_16[ ]+xtrn
+.*[ ]+R_X86_64_PC16[ ]+xtrn
+.*[ ]+R_X86_64_8[ ]+xtrn
+.*[ ]+R_X86_64_PC8[ ]+xtrn
diff --git a/gas/testsuite/gas/i386/reloc64.l b/gas/testsuite/gas/i386/reloc64.l
new file mode 100644
index 0000000..a72a452
--- /dev/null
+++ b/gas/testsuite/gas/i386/reloc64.l
@@ -0,0 +1,77 @@
+.*: Assembler messages:
+.*:29: Error: .*
+.*:33: Error: .*
+.*:35: Error: .*
+.*:36: Error: .*
+.*:37: Error: .*
+.*:39: Error: .*
+.*:40: Error: .*
+.*:43: Error: .*
+.*:44: Error: .*
+.*:45: Error: .*
+.*:46: Error: .*
+.*:47: Error: .*
+.*:48: Error: .*
+.*:49: Error: .*
+.*:51: Error: .*
+.*:53: Error: .*
+.*:54: Error: .*
+.*:55: Error: .*
+.*:57: Error: .*
+.*:66: Error: .*
+.*:73: Error: .*
+.*:75: Error: .*
+.*:76: Error: .*
+.*:77: Error: .*
+.*:79: Error: .*
+.*:81: Error: .*
+.*:83: Error: .*
+.*:85: Error: .*
+.*:86: Error: .*
+.*:87: Error: .*
+.*:89: Error: .*
+.*:92: Error: .*
+.*:94: Error: .*
+.*:95: Error: .*
+.*:96: Error: .*
+.*:98: Error: .*
+.*:101: Error: .*
+.*:103: Error: .*
+.*:104: Error: .*
+.*:105: Error: .*
+.*:107: Error: .*
+.*:112: Error: .*
+.*:113: Error: .*
+.*:114: Error: .*
+.*:116: Error: .*
+.*:117: Error: .*
+.*:121: Error: .*
+.*:122: Error: .*
+.*:123: Error: .*
+.*:125: Error: .*
+.*:126: Error: .*
+.*:131: Error: .*
+.*:133: Error: .*
+.*:136: Error: .*
+.*:137: Error: .*
+.*:138: Error: .*
+.*:139: Error: .*
+.*:146: Error: .*
+.*:159: Error: .*
+.*:160: Error: .*
+.*:161: Error: .*
+.*:164: Error: .*
+.*:165: Error: .*
+.*:166: Error: .*
+.*:167: Error: .*
+.*:168: Error: .*
+.*:169: Error: .*
+.*:173: Error: .*
+.*:174: Error: .*
+.*:175: Error: .*
+.*:178: Error: .*
+.*:179: Error: .*
+.*:180: Error: .*
+.*:181: Error: .*
+.*:182: Error: .*
+.*:183: Error: .*
diff --git a/gas/testsuite/gas/i386/reloc64.s b/gas/testsuite/gas/i386/reloc64.s
new file mode 100644
index 0000000..9b93eb2
--- /dev/null
+++ b/gas/testsuite/gas/i386/reloc64.s
@@ -0,0 +1,183 @@
+ .macro bad args:vararg
+ .ifdef _bad_
+ \args
+ .endif
+ .endm
+
+ .macro ill args:vararg
+ # This is used to mark entries that aren't handled consistently,
+ # and thus shouldn't currently be checked for.
+ # \args
+ .endm
+
+ .text
+_start:
+ movabs $xtrn, %rax
+ add $xtrn, %rax
+ mov $xtrn, %eax
+ mov $xtrn, %ax
+ mov $xtrn, %al
+ mov xtrn(%rbx), %eax
+ mov xtrn(%ebx), %eax
+
+ movabs $(xtrn - .), %rax
+ add $(xtrn - .), %rax
+ill mov $(xtrn - .), %eax
+ mov $(xtrn - .), %ax
+ mov $(xtrn - .), %al
+ mov xtrn(%rip), %eax
+bad mov xtrn(%eip), %eax
+ call xtrn
+ jrcxz xtrn
+
+bad movabs $xtrn@got, %rax
+ add $xtrn@got, %rax
+bad mov $xtrn@got, %eax
+bad mov $xtrn@got, %ax
+bad mov $xtrn@got, %al
+ mov xtrn@got(%rbx), %eax
+bad mov xtrn@got(%ebx), %eax
+bad call xtrn@got
+
+ movabs $xtrn@gotoff, %rax
+bad add $xtrn@gotoff, %rax
+bad mov $xtrn@gotoff, %eax
+bad mov $xtrn@gotoff, %ax
+bad mov $xtrn@gotoff, %al
+bad mov xtrn@gotoff(%rbx), %eax
+bad mov xtrn@gotoff(%ebx), %eax
+bad call xtrn@gotoff
+
+bad movabs $xtrn@gotpcrel, %rax
+ add $xtrn@gotpcrel, %rax
+bad mov $xtrn@gotpcrel, %eax
+bad mov $xtrn@gotpcrel, %ax
+bad mov $xtrn@gotpcrel, %al
+ mov xtrn@gotpcrel(%rbx), %eax
+bad mov xtrn@gotpcrel(%ebx), %eax
+ call xtrn@gotpcrel
+
+ill movabs $_GLOBAL_OFFSET_TABLE_, %rax
+ add $_GLOBAL_OFFSET_TABLE_, %rax
+ill add $_GLOBAL_OFFSET_TABLE_, %eax
+ill add $_GLOBAL_OFFSET_TABLE_, %ax
+ill add $_GLOBAL_OFFSET_TABLE_, %al
+ lea _GLOBAL_OFFSET_TABLE_(%rip), %rax #???
+bad lea _GLOBAL_OFFSET_TABLE_(%eip), %rax
+ill movabs $(_GLOBAL_OFFSET_TABLE_ - .), %rax
+ add $(_GLOBAL_OFFSET_TABLE_ - .), %rax
+ill add $(_GLOBAL_OFFSET_TABLE_ - .), %eax
+ill add $(_GLOBAL_OFFSET_TABLE_ - .), %ax
+ill add $(_GLOBAL_OFFSET_TABLE_ - .), %al
+
+bad movabs $xtrn@plt, %rax
+ add $xtrn@plt, %rax
+bad mov $xtrn@plt, %eax
+bad mov $xtrn@plt, %ax
+bad mov $xtrn@plt, %al
+ mov xtrn@plt(%rbx), %eax
+bad mov xtrn@plt(%ebx), %eax
+ call xtrn@plt
+bad jrcxz xtrn@plt
+
+bad movabs $xtrn@tlsgd, %rax
+ add $xtrn@tlsgd, %rax
+bad mov $xtrn@tlsgd, %eax
+bad mov $xtrn@tlsgd, %ax
+bad mov $xtrn@tlsgd, %al
+ mov xtrn@tlsgd(%rbx), %eax
+bad mov xtrn@tlsgd(%ebx), %eax
+ call xtrn@tlsgd
+
+bad movabs $xtrn@gottpoff, %rax
+ add $xtrn@gottpoff, %rax
+bad mov $xtrn@gottpoff, %eax
+bad mov $xtrn@gottpoff, %ax
+bad mov $xtrn@gottpoff, %al
+ mov xtrn@gottpoff(%rbx), %eax
+bad mov xtrn@gottpoff(%ebx), %eax
+ call xtrn@gottpoff
+
+bad movabs $xtrn@tlsld, %rax
+ add $xtrn@tlsld, %rax
+bad mov $xtrn@tlsld, %eax
+bad mov $xtrn@tlsld, %ax
+bad mov $xtrn@tlsld, %al
+ mov xtrn@tlsld(%rbx), %eax
+bad mov xtrn@tlsld(%ebx), %eax
+ call xtrn@tlsld
+
+ movabs $xtrn@dtpoff, %rax
+ add $xtrn@dtpoff, %rax
+bad mov $xtrn@dtpoff, %eax
+bad mov $xtrn@dtpoff, %ax
+bad mov $xtrn@dtpoff, %al
+ mov xtrn@dtpoff(%rbx), %eax
+bad mov xtrn@dtpoff(%ebx), %eax
+bad call xtrn@dtpoff
+
+ movabs $xtrn@tpoff, %rax
+ add $xtrn@tpoff, %rax
+bad mov $xtrn@tpoff, %eax
+bad mov $xtrn@tpoff, %ax
+bad mov $xtrn@tpoff, %al
+ mov xtrn@tpoff(%rbx), %eax
+bad mov xtrn@tpoff(%ebx), %eax
+bad call xtrn@tpoff
+
+ .data
+ .quad xtrn
+ .quad xtrn - .
+bad .quad xtrn@got
+ .quad xtrn@gotoff
+bad .quad xtrn@gotpcrel
+ill .quad _GLOBAL_OFFSET_TABLE_
+ill .quad _GLOBAL_OFFSET_TABLE_ - .
+bad .quad xtrn@plt
+bad .quad xtrn@tlsgd
+bad .quad xtrn@gottpoff
+bad .quad xtrn@tlsld
+ .quad xtrn@dtpoff
+ .quad xtrn@tpoff
+
+ .long xtrn
+ .long xtrn - .
+ .long xtrn@got
+bad .long xtrn@gotoff
+ .long xtrn@gotpcrel
+ .long _GLOBAL_OFFSET_TABLE_
+ .long _GLOBAL_OFFSET_TABLE_ - .
+ .long xtrn@plt
+ .long xtrn@tlsgd
+ .long xtrn@gottpoff
+ .long xtrn@tlsld
+ .long xtrn@dtpoff
+ .long xtrn@tpoff
+
+ .word xtrn
+ .word xtrn - .
+bad .word xtrn@got
+bad .word xtrn@gotoff
+bad .word xtrn@gotpcrel
+ill .word _GLOBAL_OFFSET_TABLE_
+ill .word _GLOBAL_OFFSET_TABLE_ - .
+bad .word xtrn@plt
+bad .word xtrn@tlsgd
+bad .word xtrn@gottpoff
+bad .word xtrn@tlsld
+bad .word xtrn@dtpoff
+bad .word xtrn@tpoff
+
+ .byte xtrn
+ .byte xtrn - .
+bad .byte xtrn@got
+bad .byte xtrn@gotoff
+bad .byte xtrn@gotpcrel
+ill .byte _GLOBAL_OFFSET_TABLE_
+ill .byte _GLOBAL_OFFSET_TABLE_ - .
+bad .byte xtrn@plt
+bad .byte xtrn@tlsgd
+bad .byte xtrn@gottpoff
+bad .byte xtrn@tlsld
+bad .byte xtrn@dtpoff
+bad .byte xtrn@tpoff