Skip to content

Commit 0079273

Browse files
committed
ELF,SystemZ: Don't sort relocations for TLS GD/LD optimization; support CREL
The General dynamic and Local Dynamic TLS models call `__tls_get_offset`, which is eliminated after optimization. To avoid an unneeded PLT entry and its .dynsym entry, llvm#75643 sorted the relocations. However, sorting relocations does not play well with CREL. Since GNU ld has a false dependency on `__tls_get_offset` as well, let's remove the relocation sorting. Fix llvm#149511 Pull Request: llvm#149640
1 parent 597f3c1 commit 0079273

File tree

5 files changed

+33
-49
lines changed

5 files changed

+33
-49
lines changed

lld/ELF/Arch/SystemZ.cpp

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ namespace {
2323
class SystemZ : public TargetInfo {
2424
public:
2525
SystemZ(Ctx &);
26-
int getTlsGdRelaxSkip(RelType type) const override;
2726
RelExpr getRelExpr(RelType type, const Symbol &s,
2827
const uint8_t *loc) const override;
2928
RelType getDynRel(RelType type) const override;
@@ -277,29 +276,6 @@ RelExpr SystemZ::adjustTlsExpr(RelType type, RelExpr expr) const {
277276
return expr;
278277
}
279278

280-
int SystemZ::getTlsGdRelaxSkip(RelType type) const {
281-
// A __tls_get_offset call instruction is marked with 2 relocations:
282-
//
283-
// R_390_TLS_GDCALL / R_390_TLS_LDCALL: marker relocation
284-
// R_390_PLT32DBL: __tls_get_offset
285-
//
286-
// After the relaxation we no longer call __tls_get_offset and should skip
287-
// both relocations to not create a false dependence on __tls_get_offset
288-
// being defined.
289-
//
290-
// Note that this mechanism only works correctly if the R_390_TLS_[GL]DCALL
291-
// is seen immediately *before* the R_390_PLT32DBL. Unfortunately, current
292-
// compilers on the platform will typically generate the inverse sequence.
293-
// To fix this, we sort relocations by offset in RelocationScanner::scan;
294-
// this ensures the correct sequence as the R_390_TLS_[GL]DCALL applies to
295-
// the first byte of the brasl instruction, while the R_390_PLT32DBL applies
296-
// to its third byte (the relative displacement).
297-
298-
if (type == R_390_TLS_GDCALL || type == R_390_TLS_LDCALL)
299-
return 2;
300-
return 1;
301-
}
302-
303279
void SystemZ::relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
304280
uint64_t val) const {
305281
// The general-dynamic code sequence for a global `x`:
@@ -320,6 +296,9 @@ void SystemZ::relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
320296
// Relaxing to initial-exec entails:
321297
// 1) Replacing the call by a load from the GOT.
322298
// 2) Replacing the relocation on the constant LC0 by R_390_TLS_GOTIE64.
299+
//
300+
// While we no longer call __tls_get_offset after optimization, we still
301+
// generate an unused PLT entry. This simple behavior matches GNU ld.
323302

324303
switch (rel.type) {
325304
case R_390_TLS_GDCALL:

lld/ELF/Relocations.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1654,10 +1654,8 @@ void RelocationScanner::scan(Relocs<RelTy> rels) {
16541654
// For EhInputSection, OffsetGetter expects the relocations to be sorted by
16551655
// r_offset. In rare cases (.eh_frame pieces are reordered by a linker
16561656
// script), the relocations may be unordered.
1657-
// On SystemZ, all sections need to be sorted by r_offset, to allow TLS
1658-
// relaxation to be handled correctly - see SystemZ::getTlsGdRelaxSkip.
16591657
SmallVector<RelTy, 0> storage;
1660-
if (isa<EhInputSection>(sec) || ctx.arg.emachine == EM_S390)
1658+
if (isa<EhInputSection>(sec))
16611659
rels = sortRels(rels, storage);
16621660

16631661
if constexpr (RelTy::IsCrel) {

lld/test/ELF/systemz-plt.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
# RUN: llvm-mc -filetype=obj -triple=s390x-unknown-linux %t1.s -o %t1.o
55
# RUN: ld.lld -shared %t1.o -soname=t1.so -o %t1.so
6-
# RUN: llvm-mc -filetype=obj -triple=s390x-unknown-linux %s -o %t.o
6+
# RUN: llvm-mc -filetype=obj -triple=s390x-unknown-linux --crel %s -o %t.o
77
# RUN: ld.lld %t.o %t1.so -z separate-code -o %t
88
# RUN: llvm-readelf -S -s -r -x .got.plt %t | FileCheck %s
99
# RUN: llvm-objdump -d %t | FileCheck --check-prefixes=DIS %s

lld/test/ELF/systemz-tls-gd.s

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# REQUIRES: systemz
22
# RUN: llvm-mc -filetype=obj -triple=s390x-unknown-linux %s -o %t.o
3-
# RUN: echo '.tbss; .globl b, c; b: .zero 4; c:' | llvm-mc -filetype=obj -triple=s390x-unknown-linux - -o %t1.o
3+
# RUN: echo '.globl __tls_get_offset; __tls_get_offset:; .tbss; .globl b, c; b: .zero 4; c:' | \
4+
# RUN: llvm-mc -filetype=obj -triple=s390x-unknown-linux - -o %t1.o
45
# RUN: ld.lld -shared -soname=t1.so %t1.o -o %t1.so
56

67
# RUN: ld.lld -shared %t.o %t1.o -o %t.so
@@ -19,12 +20,12 @@
1920
# RUN: llvm-objdump --section .data.rel.ro --full-contents %t.ie | FileCheck --check-prefix=IE-DATA %s
2021

2122
# GD-REL: Relocation section '.rela.dyn' at offset {{.*}} contains 6 entries:
22-
# GD-REL: 0000000000002570 0000000200000036 R_390_TLS_DTPMOD 0000000000000008 a + 0
23-
# GD-REL-NEXT: 0000000000002578 0000000200000037 R_390_TLS_DTPOFF 0000000000000008 a + 0
24-
# GD-REL-NEXT: 0000000000002580 0000000300000036 R_390_TLS_DTPMOD 000000000000000c b + 0
25-
# GD-REL-NEXT: 0000000000002588 0000000300000037 R_390_TLS_DTPOFF 000000000000000c b + 0
26-
# GD-REL-NEXT: 0000000000002590 0000000400000036 R_390_TLS_DTPMOD 0000000000000010 c + 0
27-
# GD-REL-NEXT: 0000000000002598 0000000400000037 R_390_TLS_DTPOFF 0000000000000010 c + 0
23+
# GD-REL: 0000000000002570 {{.*}} R_390_TLS_DTPMOD 0000000000000008 a + 0
24+
# GD-REL-NEXT: 0000000000002578 {{.*}} R_390_TLS_DTPOFF 0000000000000008 a + 0
25+
# GD-REL-NEXT: 0000000000002580 {{.*}} R_390_TLS_DTPMOD 000000000000000c b + 0
26+
# GD-REL-NEXT: 0000000000002588 {{.*}} R_390_TLS_DTPOFF 000000000000000c b + 0
27+
# GD-REL-NEXT: 0000000000002590 {{.*}} R_390_TLS_DTPMOD 0000000000000010 c + 0
28+
# GD-REL-NEXT: 0000000000002598 {{.*}} R_390_TLS_DTPOFF 0000000000000010 c + 0
2829

2930
## _GLOBAL_OFFSET_TABLE is at 0x2558
3031
# GD: larl %r12, 0x2558
@@ -80,33 +81,36 @@
8081

8182

8283
# IE-REL: Relocation section '.rela.dyn' at offset {{.*}} contains 2 entries:
83-
# IE-REL: 0000000001002430 0000000200000038 R_390_TLS_TPOFF 0000000000000000 b + 0
84-
# IE-REL-NEXT: 0000000001002438 0000000300000038 R_390_TLS_TPOFF 0000000000000000 c + 0
84+
# IE-REL: 0000000001002500 {{.*}} R_390_TLS_TPOFF 0000000000000000 b + 0
85+
# IE-REL-NEXT: 0000000001002508 {{.*}} R_390_TLS_TPOFF 0000000000000000 c + 0
86+
## Benign false dependency on __tls_get_offset
87+
# IE-REL: Relocation section '.rela.plt' at offset {{.*}} contains 1
88+
# IE-REL: R_390_JMP_SLOT 0000000000000000 __tls_get_offset
8589

86-
## _GLOBAL_OFFSET_TABLE is at 0x1002418
87-
# IE: larl %r12, 0x1002418
90+
## _GLOBAL_OFFSET_TABLE
91+
# IE: larl %r12, 0x10024e8
8892

89-
## TP offset of a is at 0x1002340
90-
# IE-NEXT: lgrl %r2, 0x1002340
93+
## TP offset of a
94+
# IE-NEXT: lgrl %r2, 0x10023d0
9195
# IE-NEXT: jgnop
9296
# IE-NEXT: lgf %r2, 0(%r2,%r7)
9397

94-
## GOT offset of the TP offset for b is at 0x1002348
95-
# IE-NEXT: lgrl %r2, 0x1002348
98+
## GOT offset of the TP offset for b
99+
# IE-NEXT: lgrl %r2, 0x10023d8
96100
# IE-NEXT: lg %r2, 0(%r2,%r12)
97101
# IE-NEXT: lgf %r2, 0(%r2,%r7)
98102

99-
## GOT offset of the TP offset for c is at 0x1002350
100-
# IE-NEXT: lgrl %r2, 0x1002350
103+
## GOT offset of the TP offset for c
104+
# IE-NEXT: lgrl %r2, 0x10023e0
101105
# IE-NEXT: lg %r2, 0(%r2,%r12)
102106
# IE-NEXT: lgf %r2, 0(%r2,%r7)
103107

104108
## TP offsets (a) / GOT offset of TP offsets (b, c)
105109
# a: -4
106-
# b: 0x1002430 / 0x18
107-
# c: 0x1002438 / 0x20
108-
# IE-DATA: 1002340 ffffffff fffffffc 00000000 00000018
109-
# IE-DATA-NEXT: 1002350 00000000 00000020
110+
# b: 0x10023d0 / 0x18
111+
# c: 0x10023e0 / 0x20
112+
# IE-DATA: 10023d0 ffffffff fffffffc 00000000 00000018
113+
# IE-DATA-NEXT: 10023e0 00000000 00000020
110114

111115

112116
ear %r7,%a0

lld/test/ELF/systemz-tls-ld.s

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ lgf %r1,0(%r1,%r2)
9191
lgrl %r1, .LC3
9292
lgf %r1,0(%r1,%r2)
9393

94+
.globl __tls_get_offset
95+
__tls_get_offset:
96+
9497
.section .data.rel.ro,"aw"
9598
.align 8
9699
.LC0:

0 commit comments

Comments
 (0)