This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: PR ld/17482: -melf32_x86_64 IE->LE transition error


Hi,

I checked this patch into trunk as well as 2.25 branch.

Thanks.


H.J.
---
    X32: Add REX prefix to encode R_X86_64_GOTTPOFF
    
    Structions with R_X86_64_GOTTPOFF relocation must be encoded with REX
    prefix even if it isn't required by destination register.  Otherwise
    linker can't safely perform IE -> LE optimization.
    
    bfd/
    
    	PR ld/17482
    	* elf64-x86-64.c (elf_x86_64_relocate_section): Update comments
    	for IE->LE transition.
    
    gas/
    
    	PR ld/17482
    	* config/tc-i386.c (output_insn): Add a dummy REX_OPCODE prefix
    	for structions with R_X86_64_GOTTPOFF relocation for x32 if needed.
    
    gas/testsuite/
    
    	PR ld/17482
    	* gas/i386/ilp32/x32-tls.d: New file.
    	* gas/i386/ilp32/x32-tls.s: Likewise.
    
    ld/testsuite/
    
    	PR ld/17482
    	* ld-x86-64/tlsie4.dd: Updated.

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 9d0f0f1..8fb37c6 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,9 @@
+2014-11-07  H.J. Lu  <hongjiu.lu@intel.com>
+
+	PR ld/17482
+	* elf64-x86-64.c (elf_x86_64_relocate_section): Update comments
+	for IE->LE transition.
+
 2014-11-07  Alan Modra  <amodra@gmail.com>
 
 	* tekhex.c (tekhex_set_arch_mach): Ignore unknown arch errors.
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 6c3a65a..d0ed8a7 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -4283,17 +4283,27 @@ direct:
 	      else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_GOTTPOFF)
 		{
 		  /* IE->LE transition:
-		     Originally it can be one of:
+		     For 64bit, originally it can be one of:
 		     movq foo@gottpoff(%rip), %reg
 		     addq foo@gottpoff(%rip), %reg
 		     We change it into:
 		     movq $foo, %reg
 		     leaq foo(%reg), %reg
-		     addq $foo, %reg.  */
+		     addq $foo, %reg.
+		     For 32bit, originally it can be one of:
+		     movq foo@gottpoff(%rip), %reg
+		     addl foo@gottpoff(%rip), %reg
+		     We change it into:
+		     movq $foo, %reg
+		     leal foo(%reg), %reg
+		     addl $foo, %reg. */
 
 		  unsigned int val, type, reg;
 
-		  val = bfd_get_8 (input_bfd, contents + roff - 3);
+		  if (roff >= 3)
+		    val = bfd_get_8 (input_bfd, contents + roff - 3);
+		  else
+		    val = 0;
 		  type = bfd_get_8 (input_bfd, contents + roff - 2);
 		  reg = bfd_get_8 (input_bfd, contents + roff - 1);
 		  reg >>= 3;
@@ -4313,8 +4323,8 @@ direct:
 		    }
 		  else if (reg == 4)
 		    {
-		      /* addq -> addq - addressing with %rsp/%r12 is
-			 special  */
+		      /* addq/addl -> addq/addl - addressing with %rsp/%r12
+			 is special  */
 		      if (val == 0x4c)
 			bfd_put_8 (output_bfd, 0x49,
 				   contents + roff - 3);
@@ -4328,7 +4338,7 @@ direct:
 		    }
 		  else
 		    {
-		      /* addq -> leaq */
+		      /* addq/addl -> leaq/leal */
 		      if (val == 0x4c)
 			bfd_put_8 (output_bfd, 0x4d,
 				   contents + roff - 3);
diff --git a/gas/ChangeLog b/gas/ChangeLog
index dc11a68..524cecd 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,9 @@
+2014-11-07  H.J. Lu  <hongjiu.lu@intel.com>
+
+	PR ld/17482
+	* config/tc-i386.c (output_insn): Add a dummy REX_OPCODE prefix
+	for structions with R_X86_64_GOTTPOFF relocation for x32 if needed.
+
 2014-11-06  Sandra Loosemore  <sandra@codesourcery.com>
 
 	* config/tc-nios2.c (nios2_diagnose_overflow): Adjust call to
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 2e34ce3..cdd4ed4 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -6997,6 +6997,15 @@ check_prefix:
 	      abort ();
 	    }
 
+	  /* For x32, add a dummy REX_OPCODE prefix for mov/add with
+	     R_X86_64_GOTTPOFF relocation so that linker can safely
+	     perform IE->LE optimization.  */
+	  if (x86_elf_abi == X86_64_X32_ABI
+	      && i.operands == 2
+	      && i.reloc[0] == BFD_RELOC_X86_64_GOTTPOFF
+	      && i.prefix[REX_PREFIX] == 0)
+	    add_prefix (REX_OPCODE);
+
 	  /* The prefix bytes.  */
 	  for (j = ARRAY_SIZE (i.prefix), q = i.prefix; j > 0; j--, q++)
 	    if (*q)
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 4c69862..972b2e6 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2014-11-07  H.J. Lu  <hongjiu.lu@intel.com>
+
+	PR ld/17482
+	* gas/i386/ilp32/x32-tls.d: New file.
+	* gas/i386/ilp32/x32-tls.s: Likewise.
+
 2014-05-11  Matthew Fortune  <matthew.fortune@imgtec.com>
 
 	* gas/mips/elf_arch_mips32r6.d: New file.
diff --git a/gas/testsuite/gas/i386/ilp32/x32-tls.d b/gas/testsuite/gas/i386/ilp32/x32-tls.d
new file mode 100644
index 0000000..1255829
--- /dev/null
+++ b/gas/testsuite/gas/i386/ilp32/x32-tls.d
@@ -0,0 +1,13 @@
+#objdump: -dw
+#name: x86-64 (ILP32) TLS
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+ <_start>:
+[ 	]*[a-f0-9]+:	48 8b 05 00 00 00 00 	mov    0x0\(%rip\),%rax        # 7 <_start\+0x7>
+[ 	]*[a-f0-9]+:	4c 8b 25 00 00 00 00 	mov    0x0\(%rip\),%r12        # e <_start\+0xe>
+[ 	]*[a-f0-9]+:	40 03 05 00 00 00 00 	rex add 0x0\(%rip\),%eax        # 15 <_start\+0x15>
+[ 	]*[a-f0-9]+:	44 03 25 00 00 00 00 	add    0x0\(%rip\),%r12d        # 1c <_start\+0x1c>
+#pass
diff --git a/gas/testsuite/gas/i386/ilp32/x32-tls.s b/gas/testsuite/gas/i386/ilp32/x32-tls.s
new file mode 100644
index 0000000..f9626cd
--- /dev/null
+++ b/gas/testsuite/gas/i386/ilp32/x32-tls.s
@@ -0,0 +1,13 @@
+	.text
+_start:
+	mov	foo@gottpoff(%rip), %rax
+	mov	foo@gottpoff(%rip), %r12
+	add	foo@gottpoff(%rip), %eax
+	add	foo@gottpoff(%rip), %r12d
+	.globl	foo
+	.section	.tdata,"awT",@progbits
+	.align 4
+	.type	foo, @object
+	.size	foo, 4
+foo:
+	.long	100
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index ce0bc74..4a03660 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2014-11-07  H.J. Lu  <hongjiu.lu@intel.com>
+
+	PR ld/17482
+	* ld-x86-64/tlsie4.dd: Updated.
+
 2014-11-05  Matthew Fortune  <matthew.fortune@imgtec.com>
 
 	* ld-mips-elf/abiflags-strip10-ph.d: New file.
diff --git a/ld/testsuite/ld-x86-64/tlsie4.dd b/ld/testsuite/ld-x86-64/tlsie4.dd
index d52e337..e40b917 100644
--- a/ld/testsuite/ld-x86-64/tlsie4.dd
+++ b/ld/testsuite/ld-x86-64/tlsie4.dd
@@ -9,8 +9,8 @@
 Disassembly of section .text:
 
 [a-f0-9]+ <_start>:
-[ 	]*[a-f0-9]+:	c7 c0 fc ff ff ff    	mov    \$0xfffffffc,%eax
-[ 	]*[a-f0-9]+:	8d 80 fc ff ff ff    	lea    -0x4\(%rax\),%eax
+[ 	]*[a-f0-9]+:	40 c7 c0 fc ff ff ff 	rex mov \$0xfffffffc,%eax
+[ 	]*[a-f0-9]+:	40 8d 80 fc ff ff ff 	rex lea -0x4\(%rax\),%eax
 [ 	]*[a-f0-9]+:	41 c7 c0 fc ff ff ff 	mov    \$0xfffffffc,%r8d
 [ 	]*[a-f0-9]+:	45 8d 80 fc ff ff ff 	lea    -0x4\(%r8\),%r8d
 [ 	]*[a-f0-9]+:	41 c7 c4 fc ff ff ff 	mov    \$0xfffffffc,%r12d


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]