PATCH: PR ld/13048: Invalid address for x32

H.J. Lu hongjiu.lu@intel.com
Mon Aug 1 23:10:00 GMT 2011


Hi,

X32 instruction set really has 64bit address space.   We just limit
it to 32bit.  I checked in this patch to enable 64bit address for x32
so that I can properly check R_X86_64_32S overflow.  It also alows
R_X86_64_64 for x32.  I also simplified bfd_mach_XXX checking.


H.J.
----
bfd/

2011-08-01  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/13048
	* archures.c (bfd_mach_i386_intel_syntax): New.
	(bfd_mach_i386_i8086): Updated.
	(bfd_mach_i386_i386): Likewise.
	(bfd_mach_x86_64): Likewise.
	(bfd_mach_x64_32): Likewise.
	(bfd_mach_i386_i386_intel_syntax): Likewise.
	(bfd_mach_x86_64_intel_syntax): Likewise.
	(bfd_mach_x64_32_intel_syntax): Likewise.
	(bfd_mach_l1om): Likewise.
	(bfd_mach_l1om_intel_syntax): Likewise.
	(bfd_mach_k1om): Likewise.
	(bfd_mach_k1om_intel_syntax): Likewise.

	* bfd-in2.h: Regenerated.

	* cpu-i386.c (bfd_i386_compatible): Check mach instead of
	bits_per_address.
	(bfd_x64_32_arch_intel_syntax): Set bits_per_address to 64.
	(bfd_x64_32_arch): Likewise.

	* elf64-x86-64.c: Include "libiberty.h".
	(x86_64_elf_howto_table): Append x32 R_X86_64_32.
	(elf_x86_64_rtype_to_howto): Support x32 R_X86_64_32.
	(elf_x86_64_reloc_type_lookup): Likewise.
	(elf_x86_64_reloc_name_lookup): Likewise.
	(elf_x86_64_relocate_section): Likewise.
	(elf_x86_64_check_relocs): Allow R_X86_64_64 relocations for x32.

gas/

2011-08-01  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/13048
	* config/tc-i386.c (handle_quad): Removed.
	(md_pseudo_table): Remove "quad".
	(tc_gen_reloc): Don't check BFD_RELOC_64 for disallow_64bit_reloc.
	(x86_dwarf2_addr_size): New.

	* config/tc-i386.h (x86_dwarf2_addr_size): New.
	(DWARF2_ADDR_SIZE): Likewise.

gas/testsuite/

2011-08-01  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/13048
	* gas/i386/ilp32/ilp32.exp: Don't run inval.

	* gas/i386/ilp32/inval.l: Removed.
	* gas/i386/ilp32/inval.s: Likewise.

	* gas/i386/ilp32/quad.d: Expect R_X86_64_64 instead of
	R_X86_64_32.

	* gas/i386/ilp32/x86-64-pcrel.s: Add tests for movabs.
	* gas/i386/ilp32/x86-64-pcrel.d: Updated.

ld/testsuite/

2011-08-01  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/13048
	* ld-x86-64/ilp32-6.d: New.
	* ld-x86-64/ilp32-6.s: Likewise.
	* ld-x86-64/ilp32-7.d: Likewise.
	* ld-x86-64/ilp32-7.s: Likewise.
	* ld-x86-64/ilp32-8.d: Likewise.
	* ld-x86-64/ilp32-8.s: Likewise.
	* ld-x86-64/ilp32-9.d: Likewise.
	* ld-x86-64/ilp32-9.s: Likewise.

	* ld-x86-64/x86-64.exp: Run ilp32-6, ilp32-7, ilp32-8 and ilp32-9.

opcodes/

2011-08-01  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/13048
	* i386-dis.c (print_insn): Optimize info->mach check.

diff --git a/bfd/archures.c b/bfd/archures.c
index 65682f2..44850e7 100644
--- a/bfd/archures.c
+++ b/bfd/archures.c
@@ -183,19 +183,20 @@ DESCRIPTION
 .#define bfd_mach_mipsisa64r2           65
 .#define bfd_mach_mips_micromips        96
 .  bfd_arch_i386,      {* Intel 386 *}
-.#define bfd_mach_i386_i386 1
-.#define bfd_mach_i386_i8086 2
-.#define bfd_mach_i386_i386_intel_syntax 3
-.#define bfd_mach_x64_32 32
-.#define bfd_mach_x64_32_intel_syntax 33
-.#define bfd_mach_x86_64 64
-.#define bfd_mach_x86_64_intel_syntax 65
+.#define bfd_mach_i386_intel_syntax	(1 << 0)
+.#define bfd_mach_i386_i8086		(1 << 1)
+.#define bfd_mach_i386_i386		(1 << 2)
+.#define bfd_mach_x86_64		(1 << 3)
+.#define bfd_mach_x64_32		(1 << 4)
+.#define bfd_mach_i386_i386_intel_syntax (bfd_mach_i386_i386 | bfd_mach_i386_intel_syntax)
+.#define bfd_mach_x86_64_intel_syntax	(bfd_mach_x86_64 | bfd_mach_i386_intel_syntax)
+.#define bfd_mach_x64_32_intel_syntax	(bfd_mach_x64_32 | bfd_mach_i386_intel_syntax)
 .  bfd_arch_l1om,   {* Intel L1OM *}
-.#define bfd_mach_l1om 66
-.#define bfd_mach_l1om_intel_syntax 67
+.#define bfd_mach_l1om			(1 << 5)
+.#define bfd_mach_l1om_intel_syntax	(bfd_mach_l1om | bfd_mach_i386_intel_syntax)
 .  bfd_arch_k1om,   {* Intel K1OM *}
-.#define bfd_mach_k1om 68
-.#define bfd_mach_k1om_intel_syntax 69
+.#define bfd_mach_k1om			(1 << 6)
+.#define bfd_mach_k1om_intel_syntax	(bfd_mach_k1om | bfd_mach_i386_intel_syntax)
 .  bfd_arch_we32k,     {* AT&T WE32xxx *}
 .  bfd_arch_tahoe,     {* CCI/Harris Tahoe *}
 .  bfd_arch_i860,      {* Intel 860 *}
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 6b7be67..ac8145d 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -1886,19 +1886,20 @@ enum bfd_architecture
 #define bfd_mach_mipsisa64r2           65
 #define bfd_mach_mips_micromips        96
   bfd_arch_i386,      /* Intel 386 */
-#define bfd_mach_i386_i386 1
-#define bfd_mach_i386_i8086 2
-#define bfd_mach_i386_i386_intel_syntax 3
-#define bfd_mach_x64_32 32
-#define bfd_mach_x64_32_intel_syntax 33
-#define bfd_mach_x86_64 64
-#define bfd_mach_x86_64_intel_syntax 65
+#define bfd_mach_i386_intel_syntax     (1 << 0)
+#define bfd_mach_i386_i8086            (1 << 1)
+#define bfd_mach_i386_i386             (1 << 2)
+#define bfd_mach_x86_64                (1 << 3)
+#define bfd_mach_x64_32                (1 << 4)
+#define bfd_mach_i386_i386_intel_syntax (bfd_mach_i386_i386 | bfd_mach_i386_intel_syntax)
+#define bfd_mach_x86_64_intel_syntax   (bfd_mach_x86_64 | bfd_mach_i386_intel_syntax)
+#define bfd_mach_x64_32_intel_syntax   (bfd_mach_x64_32 | bfd_mach_i386_intel_syntax)
   bfd_arch_l1om,   /* Intel L1OM */
-#define bfd_mach_l1om 66
-#define bfd_mach_l1om_intel_syntax 67
+#define bfd_mach_l1om                  (1 << 5)
+#define bfd_mach_l1om_intel_syntax     (bfd_mach_l1om | bfd_mach_i386_intel_syntax)
   bfd_arch_k1om,   /* Intel K1OM */
-#define bfd_mach_k1om 68
-#define bfd_mach_k1om_intel_syntax 69
+#define bfd_mach_k1om                  (1 << 6)
+#define bfd_mach_k1om_intel_syntax     (bfd_mach_k1om | bfd_mach_i386_intel_syntax)
   bfd_arch_we32k,     /* AT&T WE32xxx */
   bfd_arch_tahoe,     /* CCI/Harris Tahoe */
   bfd_arch_i860,      /* Intel 860 */
diff --git a/bfd/cpu-i386.c b/bfd/cpu-i386.c
index c4f41c5..f98c0e5 100644
--- a/bfd/cpu-i386.c
+++ b/bfd/cpu-i386.c
@@ -31,7 +31,8 @@ bfd_i386_compatible (const bfd_arch_info_type *a,
   const bfd_arch_info_type *compat = bfd_default_compatible (a, b);
 
   /* Don't allow mixing x64_32 with x86_64.  */
-  if (compat && a->bits_per_address != b->bits_per_address)
+  if (compat
+      && (a->mach & bfd_mach_x64_32) != (b->mach & bfd_mach_x64_32))
     compat = NULL;
 
   return compat;
@@ -40,7 +41,7 @@ bfd_i386_compatible (const bfd_arch_info_type *a,
 static const bfd_arch_info_type bfd_x64_32_arch_intel_syntax =
 {
   64, /* 64 bits in a word */
-  32, /* 32 bits in an address */
+  64, /* 64 bits in an address */
   8,  /* 8 bits in a byte */
   bfd_arch_i386,
   bfd_mach_x64_32_intel_syntax,
@@ -104,7 +105,7 @@ static const bfd_arch_info_type i8086_arch =
 static const bfd_arch_info_type bfd_x64_32_arch =
 {
   64, /* 64 bits in a word */
-  32, /* 32 bits in an address */
+  64, /* 64 bits in an address */
   8,  /* 8 bits in a byte */
   bfd_arch_i386,
   bfd_mach_x64_32,
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 975b558..7b92097 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -30,6 +30,7 @@
 #include "objalloc.h"
 #include "hashtab.h"
 #include "dwarf2.h"
+#include "libiberty.h"
 
 #include "elf/x86-64.h"
 
@@ -178,7 +179,12 @@ static reloc_howto_type x86_64_elf_howto_table[] =
 /* GNU extension to record C++ vtable member usage.  */
   HOWTO (R_X86_64_GNU_VTENTRY, 0, 4, 0, FALSE, 0, complain_overflow_dont,
 	 _bfd_elf_rel_vtable_reloc_fn, "R_X86_64_GNU_VTENTRY", FALSE, 0, 0,
-	 FALSE)
+	 FALSE),
+
+/* Use complain_overflow_bitfield on R_X86_64_32 for x32.  */
+  HOWTO(R_X86_64_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+	bfd_elf_generic_reloc, "R_X86_64_32", FALSE, 0xffffffff, 0xffffffff,
+	FALSE)
 };
 
 #define IS_X86_64_PCREL_TYPE(TYPE)	\
@@ -241,8 +247,15 @@ elf_x86_64_rtype_to_howto (bfd *abfd, unsigned r_type)
 {
   unsigned i;
 
-  if (r_type < (unsigned int) R_X86_64_GNU_VTINHERIT
-      || r_type >= (unsigned int) R_X86_64_max)
+  if (r_type == (unsigned int) R_X86_64_32)
+    {
+      if (ABI_64_P (abfd))
+	i = r_type;
+      else
+	i = ARRAY_SIZE (x86_64_elf_howto_table) - 1;
+    }
+  else if (r_type < (unsigned int) R_X86_64_GNU_VTINHERIT
+	   || r_type >= (unsigned int) R_X86_64_max)
     {
       if (r_type >= (unsigned int) R_X86_64_standard)
 	{
@@ -276,15 +289,21 @@ elf_x86_64_reloc_type_lookup (bfd *abfd,
 }
 
 static reloc_howto_type *
-elf_x86_64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+elf_x86_64_reloc_name_lookup (bfd *abfd,
 			      const char *r_name)
 {
   unsigned int i;
 
-  for (i = 0;
-       i < (sizeof (x86_64_elf_howto_table)
-	    / sizeof (x86_64_elf_howto_table[0]));
-       i++)
+  if (!ABI_64_P (abfd) && strcasecmp (r_name, "R_X86_64_32") == 0)
+    {
+      /* Get x32 R_X86_64_32.  */
+      reloc_howto_type *reloc
+	= &x86_64_elf_howto_table[ARRAY_SIZE (x86_64_elf_howto_table) - 1];
+      BFD_ASSERT (reloc->type == (unsigned int) R_X86_64_32);
+      return reloc;
+    }
+
+  for (i = 0; i < ARRAY_SIZE (x86_64_elf_howto_table); i++)
     if (x86_64_elf_howto_table[i].name != NULL
 	&& strcasecmp (x86_64_elf_howto_table[i].name, r_name) == 0)
       return &x86_64_elf_howto_table[i];
@@ -1396,14 +1415,6 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	  default:
 	    break;
 
-	  case R_X86_64_64:
-	    /* Allow R_X86_64_64 relocations in SEC_DEBUGGING sections
-	       when building shared libraries.  */
-	    if (info->shared
-		&& !info->executable
-		&& (sec->flags & SEC_DEBUGGING) != 0)
-	      break;
-
 	  case R_X86_64_DTPOFF64:
 	  case R_X86_64_TPOFF64:
 	  case R_X86_64_PC64:
@@ -3022,7 +3033,12 @@ elf_x86_64_relocate_section (bfd *output_bfd,
 	  return FALSE;
 	}
 
-      howto = x86_64_elf_howto_table + r_type;
+      if (r_type != (int) R_X86_64_32
+	  || ABI_64_P (output_bfd)) 
+	howto = x86_64_elf_howto_table + r_type;
+      else
+	howto = (x86_64_elf_howto_table
+		 + ARRAY_SIZE (x86_64_elf_howto_table) - 1);
       r_symndx = htab->r_sym (rel->r_info);
       h = NULL;
       sym = NULL;
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 1159572..59182bb 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -182,7 +182,6 @@ static void s_bss (int);
 #endif
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
 static void handle_large_common (int small ATTRIBUTE_UNUSED);
-static void handle_quad (int);
 #endif
 
 static const char *default_arch = DEFAULT_ARCH;
@@ -828,7 +827,6 @@ const pseudo_typeS md_pseudo_table[] =
   {"sse_check", set_sse_check, 0},
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
   {"largecomm", handle_large_common, 0},
-  {"quad", handle_quad, 8},
 #else
   {"file", (void (*) (int)) dwarf2_directive_file, 0},
   {"loc", dwarf2_directive_loc, 0},
@@ -9059,7 +9057,6 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
       if (disallow_64bit_reloc)
 	switch (code)
 	  {
-	  case BFD_RELOC_64:
 	  case BFD_RELOC_X86_64_DTPOFF64:
 	  case BFD_RELOC_X86_64_TPOFF64:
 	  case BFD_RELOC_64_PCREL:
@@ -9169,6 +9166,16 @@ tc_x86_frame_initial_instructions (void)
 }
 
 int
+x86_dwarf2_addr_size (void)
+{
+#if defined (OBJ_MAYBE_ELF) || defined (OBJ_ELF)
+  if (x86_elf_abi == X86_64_X32_ABI)
+    return 4;
+#endif
+  return bfd_arch_bits_per_address (stdoutput) / 8;
+}
+
+int
 i386_elf_section_type (const char *str, size_t len)
 {
   if (flag_code == CODE_64BIT
@@ -9267,50 +9274,4 @@ handle_large_common (int small ATTRIBUTE_UNUSED)
       bss_section = saved_bss_section;
     }
 }
-
-static void
-handle_quad (int nbytes)
-{
-  expressionS exp;
-
-  if (x86_elf_abi != X86_64_X32_ABI)
-    {
-      cons (nbytes);
-      return;
-    }
-
-  if (is_it_end_of_statement ())
-    {
-      demand_empty_rest_of_line ();
-      return;
-    }
-
-  do
-    {
-      if (*input_line_pointer == '"')
-	{
-	  as_bad (_("unexpected `\"' in expression"));
-	  ignore_rest_of_line ();
-	  return;
-	}
-      x86_cons (&exp, nbytes);
-      /* Output 4 bytes if not constant.  */
-      if (exp.X_op != O_constant)
-	nbytes = 4;
-      emit_expr (&exp, (unsigned int) nbytes);
-      /* Zero-extends to 8 bytes if not constant.  */
-      if (nbytes == 4)
-	{
-	  memset (&exp, '\0', sizeof (exp));
-	  exp.X_op = O_constant;
-	  emit_expr (&exp, nbytes);
-	}
-      nbytes = 8;
-    }
-  while (*input_line_pointer++ == ',');
-
-  input_line_pointer--;		/* Put terminator back into stream.  */
-
-  demand_empty_rest_of_line ();
-}
 #endif /* OBJ_ELF || OBJ_MAYBE_ELF */
diff --git a/gas/config/tc-i386.h b/gas/config/tc-i386.h
index deb2e9f..6a6b31d 100644
--- a/gas/config/tc-i386.h
+++ b/gas/config/tc-i386.h
@@ -279,6 +279,9 @@ extern unsigned int x86_dwarf2_return_column;
 extern int x86_cie_data_alignment;
 #define DWARF2_CIE_DATA_ALIGNMENT x86_cie_data_alignment
 
+extern int x86_dwarf2_addr_size (void);
+#define DWARF2_ADDR_SIZE(bfd) x86_dwarf2_addr_size ()
+
 #define tc_parse_to_dw2regnum tc_x86_parse_to_dw2regnum
 extern void tc_x86_parse_to_dw2regnum (expressionS *);
 
diff --git a/gas/testsuite/gas/i386/ilp32/ilp32.exp b/gas/testsuite/gas/i386/ilp32/ilp32.exp
index 7145fad..de43bf2 100644
--- a/gas/testsuite/gas/i386/ilp32/ilp32.exp
+++ b/gas/testsuite/gas/i386/ilp32/ilp32.exp
@@ -25,7 +25,6 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check] &&
 	}
     }
 
-    run_list_test "inval" "-al"
     run_list_test "reloc64" "--defsym _bad_=1"
 
     set ASFLAGS "$old_ASFLAGS"
diff --git a/gas/testsuite/gas/i386/ilp32/quad.d b/gas/testsuite/gas/i386/ilp32/quad.d
index 6f8a6c6..f337bae 100644
--- a/gas/testsuite/gas/i386/ilp32/quad.d
+++ b/gas/testsuite/gas/i386/ilp32/quad.d
@@ -1,14 +1,14 @@
 #objdump: -sr
-#name: xquad
+#name: x86-64 (ILP32) quad
 
 .*: +file format .*
 
 RELOCATION RECORDS FOR \[.data\]:
 OFFSET +TYPE +VALUE 
-0+ R_X86_64_32 +foo
-0+10 R_X86_64_32 +bar
-0+20 R_X86_64_32 +foo
-0+30 R_X86_64_32 +bar
+0+ R_X86_64_64 +foo
+0+10 R_X86_64_64 +bar
+0+20 R_X86_64_64 +foo
+0+30 R_X86_64_64 +bar
 
 
 Contents of section .data:
diff --git a/gas/testsuite/gas/i386/ilp32/x86-64-pcrel.d b/gas/testsuite/gas/i386/ilp32/x86-64-pcrel.d
index decbf58..6d11381 100644
--- a/gas/testsuite/gas/i386/ilp32/x86-64-pcrel.d
+++ b/gas/testsuite/gas/i386/ilp32/x86-64-pcrel.d
@@ -5,13 +5,15 @@
 
 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){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]+:[	 ]+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+ <_start>:
+[ 	]*[a-f0-9]+:	b0 00                	mov    \$0x0,%al	1: R_X86_64_PC8	xtrn\+0x1
+[ 	]*[a-f0-9]+:	66 b8 00 00          	mov    \$0x0,%ax	4: R_X86_64_PC16	xtrn\+0x2
+[ 	]*[a-f0-9]+:	b8 00 00 00 00       	mov    \$0x0,%eax	7: R_X86_64_PC32	xtrn\+0x1
+[ 	]*[a-f0-9]+:	48 c7 c0 00 00 00 00 	mov    \$0x0,%rax	e: R_X86_64_PC32	xtrn\+0x3
+[ 	]*[a-f0-9]+:	b0 00                	mov    \$0x0,%al	13: R_X86_64_8	xtrn
+[ 	]*[a-f0-9]+:	66 b8 00 00          	mov    \$0x0,%ax	16: R_X86_64_16	xtrn
+[ 	]*[a-f0-9]+:	b8 00 00 00 00       	mov    \$0x0,%eax	19: R_X86_64_32	xtrn
+[ 	]*[a-f0-9]+:	48 c7 c0 00 00 00 00 	mov    \$0x0,%rax	20: R_X86_64_32S	xtrn
+[ 	]*[a-f0-9]+:	48 b8 00 00 00 00 00 00 00 00 	movabs \$0x0,%rax	26: R_X86_64_64	xtrn
+[ 	]*[a-f0-9]+:	48 a1 00 00 00 00 00 00 00 00 	movabs 0x0,%rax	30: R_X86_64_64	xtrn
 #pass
diff --git a/gas/testsuite/gas/i386/ilp32/x86-64-pcrel.s b/gas/testsuite/gas/i386/ilp32/x86-64-pcrel.s
index 0fbee46..f8392ee 100644
--- a/gas/testsuite/gas/i386/ilp32/x86-64-pcrel.s
+++ b/gas/testsuite/gas/i386/ilp32/x86-64-pcrel.s
@@ -9,3 +9,5 @@ _start:
 	movw	$xtrn, %ax
 	movl	$xtrn, %eax
 	movq	$xtrn, %rax
+	movabs	$xtrn, %rax
+	movabsq	xtrn, %rax
diff --git a/ld/testsuite/ld-x86-64/ilp32-6.d b/ld/testsuite/ld-x86-64/ilp32-6.d
new file mode 100644
index 0000000..dbd808e
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ilp32-6.d
@@ -0,0 +1,3 @@
+#as: --x32
+#ld: -m elf32_x86_64 -Ttext-segment 0xe0000000
+#error: .*relocation truncated to fit: R_X86_64_32S.*
diff --git a/ld/testsuite/ld-x86-64/ilp32-6.s b/ld/testsuite/ld-x86-64/ilp32-6.s
new file mode 100644
index 0000000..f49edf7
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ilp32-6.s
@@ -0,0 +1,3 @@
+	.globl _start
+_start:
+	mov $_start,%rax
diff --git a/ld/testsuite/ld-x86-64/ilp32-7.d b/ld/testsuite/ld-x86-64/ilp32-7.d
new file mode 100644
index 0000000..dbd808e
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ilp32-7.d
@@ -0,0 +1,3 @@
+#as: --x32
+#ld: -m elf32_x86_64 -Ttext-segment 0xe0000000
+#error: .*relocation truncated to fit: R_X86_64_32S.*
diff --git a/ld/testsuite/ld-x86-64/ilp32-7.s b/ld/testsuite/ld-x86-64/ilp32-7.s
new file mode 100644
index 0000000..397aba3
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ilp32-7.s
@@ -0,0 +1,3 @@
+	.globl _start
+_start:
+	mov _start,%rax
diff --git a/ld/testsuite/ld-x86-64/ilp32-8.d b/ld/testsuite/ld-x86-64/ilp32-8.d
new file mode 100644
index 0000000..2fe2c60
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ilp32-8.d
@@ -0,0 +1,13 @@
+#as: --x32
+#ld: -m elf32_x86_64 -Ttext-segment 0xe0000000
+#objdump: -dw
+
+.*: +file format elf32-x86-64
+
+
+Disassembly of section .text:
+
+e0000054 <_start>:
+[ 	]*[a-f0-9]+:	48 b8 54 00 00 e0 00 00 00 00 	movabs \$0xe0000054,%rax
+[ 	]*[a-f0-9]+:	48 a1 54 00 00 e0 00 00 00 00 	movabs 0xe0000054,%rax
+#pass
diff --git a/ld/testsuite/ld-x86-64/ilp32-8.s b/ld/testsuite/ld-x86-64/ilp32-8.s
new file mode 100644
index 0000000..c466a6c
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ilp32-8.s
@@ -0,0 +1,5 @@
+	.text
+	.globl _start
+_start:
+	movabs $_start,%rax
+	movabs _start,%rax
diff --git a/ld/testsuite/ld-x86-64/ilp32-9.d b/ld/testsuite/ld-x86-64/ilp32-9.d
new file mode 100644
index 0000000..8fced17
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ilp32-9.d
@@ -0,0 +1,9 @@
+#as: --x32
+#ld: -m elf32_x86_64 -Ttext-segment 0xe0000000
+#objdump: -s -j .text
+
+.*: +file format .*
+
+Contents of section .text:
+ e0000054 540000e0 00000000                    T.......        
+#pass
diff --git a/ld/testsuite/ld-x86-64/ilp32-9.s b/ld/testsuite/ld-x86-64/ilp32-9.s
new file mode 100644
index 0000000..432a458
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/ilp32-9.s
@@ -0,0 +1,4 @@
+	.text
+	.globl _start
+_start:
+	.quad	_start
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index bf75d00..2b8721c 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -203,6 +203,10 @@ run_dump_test "ilp32-2"
 run_dump_test "ilp32-3"
 run_dump_test "ilp32-4"
 run_dump_test "ilp32-5"
+run_dump_test "ilp32-6"
+run_dump_test "ilp32-7"
+run_dump_test "ilp32-8"
+run_dump_test "ilp32-9"
 run_dump_test "ia32-1"
 run_dump_test "ia32-2"
 run_dump_test "ia32-3"
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index 8420f55..6b5ccf2 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -11161,40 +11161,19 @@ print_insn (bfd_vma pc, disassemble_info *info)
   int prefix_length;
   int default_prefixes;
 
-  if (info->mach == bfd_mach_x86_64_intel_syntax
-      || info->mach == bfd_mach_x86_64
-      || info->mach == bfd_mach_x64_32_intel_syntax
-      || info->mach == bfd_mach_x64_32
-      || info->mach == bfd_mach_l1om
-      || info->mach == bfd_mach_l1om_intel_syntax
-      || info->mach == bfd_mach_k1om
-      || info->mach == bfd_mach_k1om_intel_syntax)
-    address_mode = mode_64bit;
-  else
+  priv.orig_sizeflag = AFLAG | DFLAG;
+  if ((info->mach & bfd_mach_i386_i386) != 0)
     address_mode = mode_32bit;
-
-  if (intel_syntax == (char) -1)
-    intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
-		    || info->mach == bfd_mach_x86_64_intel_syntax
-		    || info->mach == bfd_mach_x64_32_intel_syntax
-		    || info->mach == bfd_mach_l1om_intel_syntax
-		    || info->mach == bfd_mach_k1om_intel_syntax);
-
-  if (info->mach == bfd_mach_i386_i386
-      || info->mach == bfd_mach_x86_64
-      || info->mach == bfd_mach_x64_32
-      || info->mach == bfd_mach_l1om
-      || info->mach == bfd_mach_k1om
-      || info->mach == bfd_mach_i386_i386_intel_syntax
-      || info->mach == bfd_mach_x86_64_intel_syntax
-      || info->mach == bfd_mach_x64_32_intel_syntax
-      || info->mach == bfd_mach_l1om_intel_syntax
-      || info->mach == bfd_mach_k1om_intel_syntax)
-    priv.orig_sizeflag = AFLAG | DFLAG;
   else if (info->mach == bfd_mach_i386_i8086)
-    priv.orig_sizeflag = 0;
+    {
+      address_mode = mode_16bit;
+      priv.orig_sizeflag = 0;
+    }
   else
-    abort ();
+    address_mode = mode_64bit;
+
+  if (intel_syntax == (char) -1)
+    intel_syntax = (info->mach & bfd_mach_i386_intel_syntax) != 0;
 
   for (p = info->disassembler_options; p != NULL; )
     {
@@ -11299,8 +11278,7 @@ print_insn (bfd_vma pc, disassemble_info *info)
   /* The output looks better if we put 7 bytes on a line, since that
      puts most long word instructions on a single line.  Use 8 bytes
      for Intel L1OM.  */
-  if (info->mach == bfd_mach_l1om
-      || info->mach == bfd_mach_l1om_intel_syntax)
+  if ((info->mach & bfd_mach_l1om) != 0)
     info->bytes_per_line = 8;
   else
     info->bytes_per_line = 7;



More information about the Binutils mailing list