[llvm-branch-commits] [lld] r351401 - Merging r351396:

Rui Ueyama via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Jan 16 15:46:28 PST 2019


Author: ruiu
Date: Wed Jan 16 15:46:28 2019
New Revision: 351401

URL: http://llvm.org/viewvc/llvm-project?rev=351401&view=rev
Log:
Merging r351396:
------------------------------------------------------------------------
r351396 | lekensteyn | 2019-01-16 15:28:51 -0800 (Wed, 16 Jan 2019) | 17 lines

[ELF][X86_64] Fix corrupted LD -> LE optimization for TLS without PLT

The LD -> LE optimization for Thread-Local Storage without PLT requires
an additional "66" prefix, otherwise the next instruction will be
corrupted, causing runtime misbehavior (crashes) of the linked object.

The other (GD -> IE/LD) optimizations are the same with or without PLT,
but add tests for completeness. The instructions are copied from
https://raw.githubusercontent.com/wiki/hjl-tools/x86-psABI/x86-64-psABI-1.0.pdf#subsection.11.1.2

This does not try to address ILP32 (x32) support.

Fixes https://bugs.llvm.org/show_bug.cgi?id=37303

Reviewed By: ruiu

Differential Revision: https://reviews.llvm.org/D56779
------------------------------------------------------------------------

Added:
    lld/branches/release_80/test/ELF/tls-opt-x86_64-noplt.s
Modified:
    lld/branches/release_80/ELF/Arch/X86_64.cpp

Modified: lld/branches/release_80/ELF/Arch/X86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/branches/release_80/ELF/Arch/X86_64.cpp?rev=351401&r1=351400&r2=351401&view=diff
==============================================================================
--- lld/branches/release_80/ELF/Arch/X86_64.cpp (original)
+++ lld/branches/release_80/ELF/Arch/X86_64.cpp Wed Jan 16 15:46:28 2019
@@ -264,15 +264,6 @@ void X86_64<ELFT>::relaxTlsIeToLe(uint8_
 template <class ELFT>
 void X86_64<ELFT>::relaxTlsLdToLe(uint8_t *Loc, RelType Type,
                                   uint64_t Val) const {
-  // Convert
-  //   leaq bar at tlsld(%rip), %rdi
-  //   callq __tls_get_addr at PLT
-  //   leaq bar at dtpoff(%rax), %rcx
-  // to
-  //   .word 0x6666
-  //   .byte 0x66
-  //   mov %fs:0,%rax
-  //   leaq bar at tpoff(%rax), %rcx
   if (Type == R_X86_64_DTPOFF64) {
     write64le(Loc, Val);
     return;
@@ -287,7 +278,37 @@ void X86_64<ELFT>::relaxTlsLdToLe(uint8_
       0x66,                                                 // .byte 0x66
       0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, // mov %fs:0,%rax
   };
-  memcpy(Loc - 3, Inst, sizeof(Inst));
+
+  if (Loc[4] == 0xe8) {
+    // Convert
+    //   leaq bar at tlsld(%rip), %rdi           # 48 8d 3d <Loc>
+    //   callq __tls_get_addr at PLT             # e8 <disp32>
+    //   leaq bar at dtpoff(%rax), %rcx
+    // to
+    //   .word 0x6666
+    //   .byte 0x66
+    //   mov %fs:0,%rax
+    //   leaq bar at tpoff(%rax), %rcx
+    memcpy(Loc - 3, Inst, sizeof(Inst));
+    return;
+  }
+
+  if (Loc[4] == 0xff && Loc[5] == 0x15) {
+    // Convert
+    //   leaq  x at tlsld(%rip),%rdi               # 48 8d 3d <Loc>
+    //   call *__tls_get_addr at GOTPCREL(%rip)    # ff 15 <disp32>
+    // to
+    //   .long  0x66666666
+    //   movq   %fs:0,%rax
+    // See "Table 11.9: LD -> LE Code Transition (LP64)" in
+    // https://raw.githubusercontent.com/wiki/hjl-tools/x86-psABI/x86-64-psABI-1.0.pdf
+    Loc[-3] = 0x66;
+    memcpy(Loc - 2, Inst, sizeof(Inst));
+    return;
+  }
+
+  error(getErrorLocation(Loc - 3) +
+        "expected R_X86_64_PLT32 or R_X86_64_GOTPCRELX after R_X86_64_TLSLD");
 }
 
 template <class ELFT>

Added: lld/branches/release_80/test/ELF/tls-opt-x86_64-noplt.s
URL: http://llvm.org/viewvc/llvm-project/lld/branches/release_80/test/ELF/tls-opt-x86_64-noplt.s?rev=351401&view=auto
==============================================================================
--- lld/branches/release_80/test/ELF/tls-opt-x86_64-noplt.s (added)
+++ lld/branches/release_80/test/ELF/tls-opt-x86_64-noplt.s Wed Jan 16 15:46:28 2019
@@ -0,0 +1,88 @@
+// REQUIRES: x86
+
+// Checks whether the TLS optimizations match the cases in Chapter 11 of
+// https://raw.githubusercontent.com/wiki/hjl-tools/x86-psABI/x86-64-psABI-1.0.pdf
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/tls-opt-gdie.s -o %tso.o
+// RUN: ld.lld -shared %tso.o -o %t.so
+// RUN: ld.lld %t.o %t.so -o %t1
+// RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=RELOC %s
+// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s
+
+// RELOC:      Relocations [
+// RELOC-NEXT:  Section {{.*}} .rela.dyn {
+// RELOC-NEXT:    0x2020C0 R_X86_64_TPOFF64 tlsshared0 0x0
+// RELOC-NEXT:    0x2020C8 R_X86_64_TPOFF64 tlsshared1 0x0
+// RELOC-NEXT:  }
+// RELOC-NEXT: ]
+
+// DISASM:      _start:
+
+// Table 11.5: GD -> IE Code Transition (LP64)
+// DISASM-NEXT: 201000: 64 48 8b 04 25 00 00 00 00      movq %fs:0, %rax
+// DISASM-NEXT: 201009: 48 03 05 b0 10 00 00            addq 4272(%rip), %rax
+// DISASM-NEXT: 201010: 64 48 8b 04 25 00 00 00 00      movq %fs:0, %rax
+// DISASM-NEXT: 201019: 48 03 05 a8 10 00 00            addq 4264(%rip), %rax
+
+// Table 11.7: GD -> LE Code Transition (LP64)
+// DISASM-NEXT: 201020: 64 48 8b 04 25 00 00 00 00      movq %fs:0, %rax
+// DISASM-NEXT: 201029: 48 8d 80 f8 ff ff ff            leaq -8(%rax), %rax
+// DISASM-NEXT: 201030: 64 48 8b 04 25 00 00 00 00      movq %fs:0, %rax
+// DISASM-NEXT: 201039: 48 8d 80 fc ff ff ff            leaq -4(%rax), %rax
+
+
+// Table 11.9: LD -> LE Code Transition (LP64)
+// DISASM-NEXT: 201040: 66 66 66 66 64 48 8b 04 25 00 00 00 00  movq %fs:0, %rax
+// DISASM-NEXT: 20104d: 66 66 66 66 64 48 8b 04 25 00 00 00 00  movq %fs:0, %rax
+
+.type tls0, at object
+.section .tbss,"awT", at nobits
+.globl tls0
+.align 4
+tls0:
+ .long 0
+ .size tls0, 4
+
+.type  tls1, at object
+.globl tls1
+.align 4
+tls1:
+ .long 0
+ .size tls1, 4
+
+.section .text
+.globl _start
+_start:
+ // Table 11.5: GD -> IE Code Transition (LP64)
+ .byte  0x66
+ leaq   tlsshared0 at tlsgd(%rip),%rdi
+ .byte  0x66
+ rex64
+ call   *__tls_get_addr at GOTPCREL(%rip)
+
+ .byte  0x66
+ leaq   tlsshared1 at tlsgd(%rip),%rdi
+ .byte  0x66
+ rex64
+ call   *__tls_get_addr at GOTPCREL(%rip)
+
+ // Table 11.7: GD -> LE Code Transition (LP64)
+ .byte  0x66
+ leaq   tls0 at tlsgd(%rip),%rdi
+ .byte  0x66
+ rex64
+ call   *__tls_get_addr at GOTPCREL(%rip)
+
+ .byte  0x66
+ leaq   tls1 at tlsgd(%rip),%rdi
+ .byte  0x66
+ rex64
+ call   *__tls_get_addr at GOTPCREL(%rip)
+
+ // Table 11.9: LD -> LE Code Transition (LP64)
+ leaq   tls0 at tlsld(%rip),%rdi
+ call   *__tls_get_addr at GOTPCREL(%rip)
+
+ leaq   tls1 at tlsld(%rip),%rdi
+ call   *__tls_get_addr at GOTPCREL(%rip)




More information about the llvm-branch-commits mailing list