X32: Add REX prefix to encode R_X86_64_GOTTPOFF
authorH.J. Lu <hjl.tools@gmail.com>
Fri, 7 Nov 2014 20:22:53 +0000 (12:22 -0800)
committerH.J. Lu <hjl.tools@gmail.com>
Fri, 7 Nov 2014 20:31:01 +0000 (12:31 -0800)
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.

bfd/ChangeLog
bfd/elf64-x86-64.c
gas/ChangeLog
gas/config/tc-i386.c
gas/testsuite/ChangeLog
gas/testsuite/gas/i386/ilp32/x32-tls.d [new file with mode: 0644]
gas/testsuite/gas/i386/ilp32/x32-tls.s [new file with mode: 0644]
ld/testsuite/ChangeLog
ld/testsuite/ld-x86-64/tlsie4.dd

index eff716ec4c046311054a5e7af92e09674026771a..91bbd61dc870374fd351e8617fa69008dde47056 100644 (file)
@@ -1,3 +1,12 @@
+2014-11-07  H.J. Lu  <hongjiu.lu@intel.com>
+
+       Apply trunk patch:
+       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-04  Tristan Gingold  <gingold@adacore.com>
 
        * development.sh: Set development to false.
index dcd4ffaef9431db7c8fe33cdb01d61d5bfe02c9f..b21040380530c636abc581c59fb0a8a519c4a9ab 100644 (file)
@@ -4281,17 +4281,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;
@@ -4311,8 +4321,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);
@@ -4326,7 +4336,7 @@ direct:
                    }
                  else
                    {
-                     /* addq -> leaq */
+                     /* addq/addl -> leaq/leal */
                      if (val == 0x4c)
                        bfd_put_8 (output_bfd, 0x4d,
                                   contents + roff - 3);
index fde4a5251e7f296864afb0c66fe93e2ceb7f0282..cb1829d45d739d3361012ef6c95d30c50024deb0 100644 (file)
@@ -1,3 +1,12 @@
+2014-11-07  H.J. Lu  <hongjiu.lu@intel.com>
+
+       Apply trunk patch:
+       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-03  Nick Clifton  <nickc@redhat.com>
 
        Apply trunk patch:
index 2e34ce3df6143247ea3e9227952582e6e6a6210d..cdd4ed49bb6a2c891a9b9c774ed1d745552ee6b4 100644 (file)
@@ -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)
index 90c9d57b911800be03d1e57a64311345a2f5eddd..e39be365f75f157c6de31641a54438f0413cd5a6 100644 (file)
@@ -1,3 +1,12 @@
+2014-11-07  H.J. Lu  <hongjiu.lu@intel.com>
+
+       Apply trunk patch:
+       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-10-28  Matthew Fortune  <matthew.fortune@imgtec.com>
 
        Apply trunk patches
diff --git a/gas/testsuite/gas/i386/ilp32/x32-tls.d b/gas/testsuite/gas/i386/ilp32/x32-tls.d
new file mode 100644 (file)
index 0000000..1255829
--- /dev/null
@@ -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 (file)
index 0000000..f9626cd
--- /dev/null
@@ -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
index 131e585e9be17a342cc7d9757f55aa441fdaf5e8..1453b048f9c1314c3bdd3961485fda8204d2ae57 100644 (file)
@@ -1,3 +1,11 @@
+2014-11-07  H.J. Lu  <hongjiu.lu@intel.com>
+
+       Apply trunk patch:
+       2014-11-07  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/17482
+       * ld-x86-64/tlsie4.dd: Updated.
+
 2014-10-24  Tejas Belagod  <tejas.belagod@arm.com>
 
        * ld-aarch64/aarch64-elf.exp (aarch64elftests): Drive erratum
index d52e337a79e7f141b25a32deb301a894d53a63a8..e40b917750017378fe2f75f24c7887c6b1206594 100644 (file)
@@ -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