[lld] r271815 - Implement gd to ie relaxation for aarch64.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Sat Jun 4 16:33:31 PDT 2016


Author: rafael
Date: Sat Jun  4 18:33:31 2016
New Revision: 271815

URL: http://llvm.org/viewvc/llvm-project?rev=271815&view=rev
Log:
Implement gd to ie relaxation for aarch64.

Added:
    lld/trunk/test/ELF/Inputs/aarch64-tls-gdie.s
    lld/trunk/test/ELF/aarch64-tls-gdie.s
Modified:
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/Relocations.cpp
    lld/trunk/ELF/Relocations.h
    lld/trunk/ELF/Target.cpp

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=271815&r1=271814&r2=271815&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Sat Jun  4 18:33:31 2016
@@ -183,8 +183,10 @@ getSymVA(uint32_t Type, typename ELFT::u
   case R_GOT_FROM_END:
     return Body.getGotOffset<ELFT>() + A -
            Out<ELFT>::Got->getNumEntries() * sizeof(uintX_t);
+  case R_RELAX_TLS_GD_TO_IE_ABS:
   case R_GOT:
     return Body.getGotVA<ELFT>() + A;
+  case R_RELAX_TLS_GD_TO_IE_PAGE_PC:
   case R_GOT_PAGE_PC:
     return getAArch64Page(Body.getGotVA<ELFT>() + A) - getAArch64Page(P);
   case R_RELAX_TLS_GD_TO_IE:
@@ -324,6 +326,8 @@ void InputSectionBase<ELFT>::relocate(ui
       Target->relaxTlsGdToLe(BufLoc, Type, SymVA);
       break;
     case R_RELAX_TLS_GD_TO_IE:
+    case R_RELAX_TLS_GD_TO_IE_ABS:
+    case R_RELAX_TLS_GD_TO_IE_PAGE_PC:
     case R_RELAX_TLS_GD_TO_IE_END:
       Target->relaxTlsGdToIe(BufLoc, Type, SymVA);
       break;

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=271815&r1=271814&r2=271815&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Sat Jun  4 18:33:31 2016
@@ -156,7 +156,7 @@ static unsigned handleTlsRelocation(uint
                                       Body.getGotOffset<ELFT>(), false, &Body,
                                       0});
       }
-      return 2;
+      return Target->TlsGdRelaxSkip;
     }
     C.Relocations.push_back(
         {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_GD_TO_LE), Type,

Modified: lld/trunk/ELF/Relocations.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.h?rev=271815&r1=271814&r2=271815&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.h (original)
+++ lld/trunk/ELF/Relocations.h Sat Jun  4 18:33:31 2016
@@ -43,6 +43,8 @@ enum RelExpr {
   R_RELAX_GOT_PC_NOPIC,
   R_RELAX_TLS_GD_TO_IE,
   R_RELAX_TLS_GD_TO_IE_END,
+  R_RELAX_TLS_GD_TO_IE_ABS,
+  R_RELAX_TLS_GD_TO_IE_PAGE_PC,
   R_RELAX_TLS_GD_TO_LE,
   R_RELAX_TLS_GD_TO_LE_NEG,
   R_RELAX_TLS_IE_TO_LE,

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=271815&r1=271814&r2=271815&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Sat Jun  4 18:33:31 2016
@@ -156,7 +156,10 @@ public:
                 int32_t Index, unsigned RelOff) const override;
   bool usesOnlyLowPageBits(uint32_t Type) const override;
   void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
+  RelExpr adjustRelaxExpr(uint32_t Type, const uint8_t *Data,
+                          RelExpr Expr) const override;
   void relaxTlsGdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
+  void relaxTlsGdToIe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
   void relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
 };
 
@@ -1141,6 +1144,16 @@ RelExpr AArch64TargetInfo::getRelExpr(ui
   }
 }
 
+RelExpr AArch64TargetInfo::adjustRelaxExpr(uint32_t Type, const uint8_t *Data,
+                                           RelExpr Expr) const {
+  if (Expr == R_RELAX_TLS_GD_TO_IE) {
+    if (Type == R_AARCH64_TLSDESC_ADR_PAGE21)
+      return R_RELAX_TLS_GD_TO_IE_PAGE_PC;
+    return R_RELAX_TLS_GD_TO_IE_ABS;
+  }
+  return Expr;
+}
+
 bool AArch64TargetInfo::usesOnlyLowPageBits(uint32_t Type) const {
   switch (Type) {
   default:
@@ -1320,6 +1333,7 @@ void AArch64TargetInfo::relaxTlsGdToLe(u
   //   ldr     x1, [x0, #:tlsdesc_lo12:v  [R_AARCH64_TLSDESC_LD64_LO12_NC]
   //   add     x0, x0, :tlsdesc_los:v     [_AARCH64_TLSDESC_ADD_LO12_NC]
   //   .tlsdesccall                       [R_AARCH64_TLSDESC_CALL]
+  //   blr     x1
   // And it can optimized to:
   //   movz    x0, #0x0, lsl #16
   //   movk    x0, #0x10
@@ -1348,6 +1362,38 @@ void AArch64TargetInfo::relaxTlsGdToLe(u
   write32le(Loc, NewInst);
 }
 
+void AArch64TargetInfo::relaxTlsGdToIe(uint8_t *Loc, uint32_t Type,
+                                       uint64_t Val) const {
+  // TLSDESC Global-Dynamic relocation are in the form:
+  //   adrp    x0, :tlsdesc:v             [R_AARCH64_TLSDESC_ADR_PAGE21]
+  //   ldr     x1, [x0, #:tlsdesc_lo12:v  [R_AARCH64_TLSDESC_LD64_LO12_NC]
+  //   add     x0, x0, :tlsdesc_los:v     [_AARCH64_TLSDESC_ADD_LO12_NC]
+  //   .tlsdesccall                       [R_AARCH64_TLSDESC_CALL]
+  //   blr     x1
+  // And it can optimized to:
+  //   adrp    x0, :gottprel:v
+  //   ldr     x0, [x0, :gottprel_lo12:v]
+  //   nop
+  //   nop
+
+  switch (Type) {
+  case R_AARCH64_TLSDESC_ADD_LO12_NC:
+  case R_AARCH64_TLSDESC_CALL:
+    write32le(Loc, 0xd503201f); // nop
+    break;
+  case R_AARCH64_TLSDESC_ADR_PAGE21:
+    write32le(Loc, 0x90000000); // adrp
+    relocateOne(Loc, R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21, Val);
+    break;
+  case R_AARCH64_TLSDESC_LD64_LO12_NC:
+    write32le(Loc, 0xf9400000); // ldr
+    relocateOne(Loc, R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC, Val);
+    break;
+  default:
+    llvm_unreachable("unsupported Relocation for TLS GD to LE relax");
+  }
+}
+
 void AArch64TargetInfo::relaxTlsIeToLe(uint8_t *Loc, uint32_t Type,
                                        uint64_t Val) const {
   checkUInt<32>(Val, Type);

Added: lld/trunk/test/ELF/Inputs/aarch64-tls-gdie.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/aarch64-tls-gdie.s?rev=271815&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/aarch64-tls-gdie.s (added)
+++ lld/trunk/test/ELF/Inputs/aarch64-tls-gdie.s Sat Jun  4 18:33:31 2016
@@ -0,0 +1,4 @@
+        .section        .tdata,"awT", at progbits
+        .globl  a
+a:
+        .word   42

Added: lld/trunk/test/ELF/aarch64-tls-gdie.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/aarch64-tls-gdie.s?rev=271815&view=auto
==============================================================================
--- lld/trunk/test/ELF/aarch64-tls-gdie.s (added)
+++ lld/trunk/test/ELF/aarch64-tls-gdie.s Sat Jun  4 18:33:31 2016
@@ -0,0 +1,34 @@
+// REQUIRES: aarch64
+// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=aarch64-pc-linux
+// RUN: llvm-mc %p/Inputs/aarch64-tls-gdie.s -o %t2.o -filetype=obj -triple=aarch64-pc-linux
+// RUN: ld.lld %t2.o -o %t2.so -shared
+// RUN: ld.lld %t.o %t2.so -o %t
+// RUN: llvm-readobj -s %t | FileCheck --check-prefix=SEC %s
+// RUN: llvm-objdump -d %t | FileCheck %s
+
+        .globl  _start
+_start:
+        nop
+        adrp    x0, :tlsdesc:a
+        ldr     x1, [x0, :tlsdesc_lo12:a]
+        add     x0, x0, :tlsdesc_lo12:a
+        .tlsdesccall a
+        blr     x1
+
+// SEC:      Name: .got
+// SEC-NEXT: Type: SHT_PROGBITS
+// SEC-NEXT: Flags [
+// SEC-NEXT:   SHF_ALLOC
+// SEC-NEXT:   SHF_WRITE
+// SEC-NEXT: ]
+// SEC-NEXT: Address: 0x120B0
+
+// page(0x120B0) - page(0x11004) = 4096
+// 0x0B0 = 176
+
+// CHECK:      _start:
+// CHECK-NEXT: 11000: {{.*}} nop
+// CHECK-NEXT: 11004: {{.*}} adrp       x0, #4096
+// CHECK-NEXT: 11008: {{.*}} ldr        x0, [x0, #176]
+// CHECK-NEXT: 1100c: {{.*}} nop
+// CHECK-NEXT: 11010: {{.*}} nop




More information about the llvm-commits mailing list