Skip to content

Commit ad5bcd4

Browse files
committed
Merging r361090:
------------------------------------------------------------------------ r361090 | maskray | 2019-05-17 20:16:00 -0700 (Fri, 17 May 2019) | 34 lines [ARM][AArch64] Revert Android Bionic PT_TLS overaligning hack This reverts D53906. D53906 increased p_align of PT_TLS on ARM/AArch64 to 32/64 to make the static TLS layout compatible with Android Bionic's ELF TLS. However, this may cause glibc ARM/AArch64 programs to crash (see PR41527). The faulty PT_TLS in the executable satisfies p_vaddr%p_align != 0. The remainder is normally 0 but may be non-zero with the hack in place. The problem is that we increase PT_TLS's p_align after OutputSections' addresses are fixed (assignAddress()). It is possible that p_vaddr%old_p_align = 0 while p_vaddr%new_p_align != 0. For a thread local variable defined in the executable, lld computed TLS offset (local exec) is different from glibc computed TLS offset from another module (initial exec/generic dynamic). Note: PR41527 said the bug affects initial exec but actually generic dynamic is affected as well. (glibc is correct in that it compute offsets that satisfy `offset%p_align == p_vaddr%p_align`, which is a basic ELF requirement. This hack appears to work on FreeBSD rtld, musl<=1.1.22, and Bionic, but that is just because they (and lld) incorrectly compute offsets that satisfy `offset%p_align = 0` instead.) Android developers are fine to revert this patch, carry this patch in their tree before figuring out a long-term solution (e.g. a dummy .tdata with sh_addralign=64 sh_size={0,1} in crtbegin*.o files. The overhead is now insignificant after D62059). Reviewed By: rprichard, srhines Differential Revision: https://reviews.llvm.org/D62055 ------------------------------------------------------------------------ llvm-svn: 362858
1 parent 0e657d4 commit ad5bcd4

9 files changed

+44
-59
lines changed

lld/ELF/InputSection.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -580,10 +580,6 @@ static int64_t getTlsTpOffset() {
580580
// Variant 1. The thread pointer points to a TCB with a fixed 2-word size,
581581
// followed by a variable amount of alignment padding, followed by the TLS
582582
// segment.
583-
//
584-
// NB: While the ARM/AArch64 ABI formally has a 2-word TCB size, lld
585-
// effectively increases the TCB size to 8 words for Android compatibility.
586-
// It accomplishes this by increasing the segment's alignment.
587583
return alignTo(Config->Wordsize * 2, Out::TlsPhdr->p_align);
588584
case EM_386:
589585
case EM_X86_64:

lld/ELF/Writer.cpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2197,17 +2197,6 @@ template <class ELFT> void Writer<ELFT>::setPhdrs() {
21972197
}
21982198

21992199
if (P->p_type == PT_TLS && P->p_memsz) {
2200-
if (!Config->Shared &&
2201-
(Config->EMachine == EM_ARM || Config->EMachine == EM_AARCH64)) {
2202-
// On ARM/AArch64, reserve extra space (8 words) between the thread
2203-
// pointer and an executable's TLS segment by overaligning the segment.
2204-
// This reservation is needed for backwards compatibility with Android's
2205-
// TCB, which allocates several slots after the thread pointer (e.g.
2206-
// TLS_SLOT_STACK_GUARD==5). For simplicity, this overalignment is also
2207-
// done on other operating systems.
2208-
P->p_align = std::max<uint64_t>(P->p_align, Config->Wordsize * 8);
2209-
}
2210-
22112200
// The TLS pointer goes after PT_TLS for variant 2 targets. At least glibc
22122201
// will align it, so round up the size to make sure the offsets are
22132202
// correct.

lld/test/ELF/aarch64-cortex-a53-843419-tlsrelax.s

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ _start:
2626
// CHECK: _start:
2727
// CHECK-NEXT: 210ff8: 41 d0 3b d5 mrs x1, TPIDR_EL0
2828
// CHECK-NEXT: 210ffc: 00 00 a0 d2 movz x0, #0, lsl #16
29-
// CHECK-NEXT: 211000: 01 08 80 f2 movk x1, #64
29+
// CHECK-NEXT: 211000: 01 02 80 f2 movk x1, #16
3030
// CHECK-NEXT: 211004: 00 00 a0 d2 movz x0, #0, lsl #16
31-
// CHECK-NEXT: 211008: 01 08 80 f2 movk x1, #64
31+
// CHECK-NEXT: 211008: 01 02 80 f2 movk x1, #16
3232
// CHECK-NEXT: 21100c: c0 03 5f d6 ret
3333

3434
.type v,@object

lld/test/ELF/aarch64-tls-gdle.s

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
#RELOC: Relocations [
1010
#RELOC-NEXT: ]
1111

12-
# TCB size = 64 and foo is first element from TLS register.
12+
# TCB size = 0x16 and foo is first element from TLS register.
1313
# CHECK: Disassembly of section .text:
1414
# CHECK: _start:
1515
# CHECK: 210000: 00 00 a0 d2 movz x0, #0, lsl #16
16-
# CHECK: 210004: 00 08 80 f2 movk x0, #64
16+
# CHECK: 210004: 00 02 80 f2 movk x0, #16
1717
# CHECK: 210008: 1f 20 03 d5 nop
1818
# CHECK: 21000c: 1f 20 03 d5 nop
1919

lld/test/ELF/aarch64-tls-iele.s

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@
99
# RELOC: Relocations [
1010
# RELOC-NEXT: ]
1111

12-
# TCB size = 64 and foo is first element from TLS register.
12+
# TCB size = 0x16 and foo is first element from TLS register.
1313
# CHECK: Disassembly of section .text:
1414
# CHECK: _start:
1515
# CHECK-NEXT: 210000: 00 00 a0 d2 movz x0, #0, lsl #16
16-
# CHECK-NEXT: 210004: 80 08 80 f2 movk x0, #68
16+
# CHECK-NEXT: 210004: 80 02 80 f2 movk x0, #20
1717
# CHECK-NEXT: 210008: 00 00 a0 d2 movz x0, #0, lsl #16
18-
# CHECK-NEXT: 21000c: 00 08 80 f2 movk x0, #64
18+
# CHECK-NEXT: 21000c: 00 02 80 f2 movk x0, #16
1919

2020
.section .tdata
2121
.align 2

lld/test/ELF/aarch64-tls-le.s

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ _start:
1717
add x0, x0, :tprel_hi12:v2
1818
add x0, x0, :tprel_lo12_nc:v2
1919

20-
# TCB size = 64 and foo is first element from TLS register.
20+
# TCB size = 0x16 and foo is first element from TLS register.
2121
#CHECK: Disassembly of section .text:
2222
#CHECK: _start:
2323
#CHECK: 210000: 40 d0 3b d5 mrs x0, TPIDR_EL0
2424
#CHECK: 210004: 00 00 40 91 add x0, x0, #0, lsl #12
25-
#CHECK: 210008: 00 00 01 91 add x0, x0, #64
25+
#CHECK: 210008: 00 40 00 91 add x0, x0, #16
2626
#CHECK: 21000c: 40 d0 3b d5 mrs x0, TPIDR_EL0
2727
#CHECK: 210010: 00 fc 7f 91 add x0, x0, #4095, lsl #12
2828
#CHECK: 210014: 00 e0 3f 91 add x0, x0, #4088
@@ -36,9 +36,9 @@ v1:
3636
.word 0
3737
.size v1, 4
3838

39-
# The current offset from the thread pointer is 68. Raise it to just below the
39+
# The current offset from the thread pointer is 20. Raise it to just below the
4040
# 24-bit limit.
41-
.space (0xfffff8 - 68)
41+
.space (0xfffff8 - 20)
4242

4343
.type v2,@object
4444
.globl v2

lld/test/ELF/aarch64-tlsld-ldst.s

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -26,27 +26,27 @@ _start: mrs x8, TPIDR_EL0
2626

2727
// CHECK: _start:
2828
// CHECK-NEXT: 210000: 48 d0 3b d5 mrs x8, TPIDR_EL0
29-
// 0x0 + c40 = 0xc40 = tcb (64-bytes) + var0
30-
// CHECK-NEXT: 210004: 08 01 40 91 add x8, x8, #0, lsl #12
31-
// CHECK-NEXT: 210008: 14 11 c3 3d ldr q20, [x8, #3136]
32-
// 0x1000 + 0x850 = 0x1850 = tcb + var1
33-
// CHECK-NEXT: 21000c: 08 05 40 91 add x8, x8, #1, lsl #12
34-
// CHECK-NEXT: 210010: 00 29 44 f9 ldr x0, [x8, #2128]
35-
// 0x2000 + 0x458 = 0x2458 = tcb + var2
36-
// CHECK-NEXT: 210014: 08 09 40 91 add x8, x8, #2, lsl #12
37-
// CHECK-NEXT: 210018: 00 59 44 b9 ldr w0, [x8, #1112]
38-
// 0x3000 + 0x5c = 0x305c = tcb + var3
39-
// CHECK-NEXT: 21001c: 08 0d 40 91 add x8, x8, #3, lsl #12
40-
// CHECK-NEXT: 210020: 00 b9 40 79 ldrh w0, [x8, #92]
41-
// 0x3000 + 0xc5e = 0x3c5e = tcb + var4
42-
// CHECK-NEXT: 210024: 08 0d 40 91 add x8, x8, #3, lsl #12
43-
// CHECK-NEXT: 210028: 00 79 71 39 ldrb w0, [x8, #3166]
29+
// 0x0 + c10 = 0xc10 = tcb (16-bytes) + var0
30+
// CHECK-NEXT: 210004: 08 01 40 91 add x8, x8, #0, lsl #12
31+
// CHECK-NEXT: 210008: 14 05 c3 3d ldr q20, [x8, #3088]
32+
// 0x1000 + 0x820 = 0x1820 = tcb + var1
33+
// CHECK-NEXT: 21000c: 08 05 40 91 add x8, x8, #1, lsl #12
34+
// CHECK-NEXT: 210010: 00 11 44 f9 ldr x0, [x8, #2080]
35+
// 0x2000 + 0x428 = 0x2428 = tcb + var2
36+
// CHECK-NEXT: 210014: 08 09 40 91 add x8, x8, #2, lsl #12
37+
// CHECK-NEXT: 210018: 00 29 44 b9 ldr w0, [x8, #1064]
38+
// 0x3000 + 0x2c = 0x302c = tcb + var3
39+
// CHECK-NEXT: 21001c: 08 0d 40 91 add x8, x8, #3, lsl #12
40+
// CHECK-NEXT: 210020: 00 59 40 79 ldrh w0, [x8, #44]
41+
// 0x3000 + 0xc2e = 0x32ce = tcb + var4
42+
// CHECK-NEXT: 210024: 08 0d 40 91 add x8, x8, #3, lsl #12
43+
// CHECK-NEXT: 210028: 00 b9 70 39 ldrb w0, [x8, #3118]
4444

45-
// CHECK-SYMS: 0000000000000c00 16 TLS GLOBAL DEFAULT 2 var0
46-
// CHECK-SYMS-NEXT: 0000000000001810 8 TLS GLOBAL DEFAULT 2 var1
47-
// CHECK-SYMS-NEXT: 0000000000002418 4 TLS GLOBAL DEFAULT 2 var2
48-
// CHECK-SYMS-NEXT: 000000000000301c 2 TLS GLOBAL DEFAULT 2 var3
49-
// CHECK-SYMS-NEXT: 0000000000003c1e 1 TLS GLOBAL DEFAULT 2 var4
45+
// CHECK-SYMS: 0000000000000c00 0 TLS GLOBAL DEFAULT 2 var0
46+
// CHECK-SYMS-NEXT: 0000000000001810 4 TLS GLOBAL DEFAULT 2 var1
47+
// CHECK-SYMS-NEXT: 0000000000002418 2 TLS GLOBAL DEFAULT 2 var2
48+
// CHECK-SYMS-NEXT: 000000000000301c 1 TLS GLOBAL DEFAULT 2 var3
49+
// CHECK-SYMS-NEXT: 0000000000003c1e 0 TLS GLOBAL DEFAULT 2 var4
5050

5151
.globl var0
5252
.globl var1
@@ -59,27 +59,27 @@ _start: mrs x8, TPIDR_EL0
5959
.type var3,@object
6060

6161
.section .tbss,"awT",@nobits
62-
.balign 64
62+
.balign 16
6363
.space 1024 * 3
6464
var0:
6565
.quad 0
6666
.quad 0
67-
.size var0, 16
67+
.size var1, 16
6868
.space 1024 * 3
6969
var1:
7070
.quad 0
7171
.size var1, 8
7272
.space 1024 * 3
7373
var2:
7474
.word 0
75-
.size var2, 4
75+
.size var1, 4
7676

7777
.space 1024 * 3
7878
var3:
7979
.hword 0
80-
.size var3, 2
80+
.size var2, 2
8181
.space 1024 * 3
8282
var4:
8383
.byte 0
84-
.size var4, 1
84+
.size var3, 1
8585
.space 1024 * 3

lld/test/ELF/arm-tls-le32.s

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ x:
6969

7070
// CHECK: Disassembly of section .text:
7171
// CHECK-NEXT: _start:
72-
// offset of x from Thread pointer = (TcbSize + 0x0 = 0x20)
73-
// CHECK-NEXT: 11000: 20 00 00 00
74-
// offset of z from Thread pointer = (TcbSize + 0x8 = 0x28)
75-
// CHECK-NEXT: 11004: 28 00 00 00
76-
// offset of y from Thread pointer = (TcbSize + 0x4 = 0x24)
77-
// CHECK-NEXT: 11008: 24 00 00 00
72+
// offset of x from Thread pointer = (TcbSize + 0x0 = 0x8)
73+
// CHECK-NEXT: 11000: 08 00 00 00
74+
// offset of z from Thread pointer = (TcbSize + 0x8 = 0x10)
75+
// CHECK-NEXT: 11004: 10 00 00 00
76+
// offset of y from Thread pointer = (TcbSize + 0x4 = 0xc)
77+
// CHECK-NEXT: 11008: 0c 00 00 00

lld/test/ELF/arm-tls-norelax-ie-le.s

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,5 @@ x2:
3737
.type x2, %object
3838

3939
// CHECK: Contents of section .got:
40-
// x1 at offset 0x20 from TP, x2 at offset 0x24 from TP. Offsets include TCB size of 0x20
41-
// CHECK-NEXT: 13064 20000000 24000000
40+
// x1 at offset 8 from TP, x2 at offset 0xc from TP. Offsets include TCB size of 8
41+
// CHECK-NEXT: 13064 08000000 0c000000

0 commit comments

Comments
 (0)