gas/
authorJan Beulich <jbeulich@novell.com>
Mon, 18 Jul 2005 06:27:24 +0000 (06:27 +0000)
committerJan Beulich <jbeulich@novell.com>
Mon, 18 Jul 2005 06:27:24 +0000 (06:27 +0000)
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.

gas/ChangeLog
gas/config/tc-i386.c
gas/testsuite/ChangeLog
gas/testsuite/gas/i386/i386.exp
gas/testsuite/gas/i386/reloc32.d [new file with mode: 0644]
gas/testsuite/gas/i386/reloc32.l [new file with mode: 0644]
gas/testsuite/gas/i386/reloc32.s [new file with mode: 0644]
gas/testsuite/gas/i386/reloc64.d [new file with mode: 0644]
gas/testsuite/gas/i386/reloc64.l [new file with mode: 0644]
gas/testsuite/gas/i386/reloc64.s [new file with mode: 0644]

index fb902be..5218925 100644 (file)
@@ -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.
 
index 3917b84..cdc915b 100644 (file)
@@ -1204,23 +1204,51 @@ pt (t)
 
 #endif /* DEBUG386 */
 \f
-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)
 }
 \f
 #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;
 }
 
index 5af722a..da74841 100644 (file)
@@ -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.
index 851f698..8cafb0a 100644 (file)
@@ -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 (file)
index 0000000..b2cd29c
--- /dev/null
@@ -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 (file)
index 0000000..74e80df
--- /dev/null
@@ -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 (file)
index 0000000..1a893ff
--- /dev/null
@@ -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 (file)
index 0000000..ae08796
--- /dev/null
@@ -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 (file)
index 0000000..a72a452
--- /dev/null
@@ -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 (file)
index 0000000..9b93eb2
--- /dev/null
@@ -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