[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