diff options
author | George Rimar <grimar@accesssoftek.com> | 2019-02-06 13:38:10 +0000 |
---|---|---|
committer | George Rimar <grimar@accesssoftek.com> | 2019-02-06 13:38:10 +0000 |
commit | bdddf3e48de1d498081954f9ebf2c9692cc2aec3 (patch) | |
tree | 96aca404fbf0a444afe7da389cdcfcb381f2033e | |
parent | 5865fb2366bfe26c8f46cb109f06490191d6f502 (diff) | |
download | lld-bdddf3e48de1d498081954f9ebf2c9692cc2aec3.tar.gz |
[LLD][ELF] - Set DF_STATIC_TLS flag for i386 target.
DF_STATIC_TLS flag indicates that the shared object or executable
contains code using a static thread-local storage scheme.
Patch checks if IE/LE relocations were used to check if the code uses
a static model. If so it sets the DF_STATIC_TLS flag.
Differential revision: https://reviews.llvm.org/D57749
git-svn-id: https://llvm.org/svn/llvm-project/lld/trunk@353293 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | ELF/Arch/X86.cpp | 9 | ||||
-rw-r--r-- | ELF/Config.h | 2 | ||||
-rw-r--r-- | ELF/SyntheticSections.cpp | 2 | ||||
-rw-r--r-- | test/ELF/Inputs/i386-static-tls-model1.s | 9 | ||||
-rw-r--r-- | test/ELF/Inputs/i386-static-tls-model2.s | 9 | ||||
-rw-r--r-- | test/ELF/Inputs/i386-static-tls-model3.s | 9 | ||||
-rw-r--r-- | test/ELF/Inputs/i386-static-tls-model4.s | 9 | ||||
-rw-r--r-- | test/ELF/i386-static-tls-model.s | 20 | ||||
-rw-r--r-- | test/ELF/i386-tls-ie-shared.s | 52 | ||||
-rw-r--r-- | test/ELF/tls-dynamic-i686.s | 46 | ||||
-rw-r--r-- | test/ELF/tls-opt-iele-i686-nopic.s | 44 |
11 files changed, 140 insertions, 71 deletions
diff --git a/ELF/Arch/X86.cpp b/ELF/Arch/X86.cpp index 061538d22..0827dd36a 100644 --- a/ELF/Arch/X86.cpp +++ b/ELF/Arch/X86.cpp @@ -72,6 +72,15 @@ int X86::getTlsGdRelaxSkip(RelType Type) const { RelExpr X86::getRelExpr(RelType Type, const Symbol &S, const uint8_t *Loc) const { + // There are 4 different TLS variable models with varying degrees of + // flexibility and performance. LocalExec and InitialExec models are fast but + // less-flexible models. They cannot be used for dlopen(). If they are in use, + // we set DF_STATIC_TLS in the ELF header so that the runtime can reject such + // DSOs. + if (Type == R_386_TLS_LE || Type == R_386_TLS_LE_32 || Type == R_386_TLS_IE || + Type == R_386_TLS_GOTIE) + Config->HasStaticTlsModel = true; + switch (Type) { case R_386_8: case R_386_16: diff --git a/ELF/Config.h b/ELF/Config.h index 8943ced3c..a12f8c96b 100644 --- a/ELF/Config.h +++ b/ELF/Config.h @@ -17,6 +17,7 @@ #include "llvm/Support/CachePruning.h" #include "llvm/Support/CodeGen.h" #include "llvm/Support/Endian.h" +#include <atomic> #include <vector> namespace lld { @@ -80,6 +81,7 @@ struct VersionDefinition { // and such fields have the same name as the corresponding options. // Most fields are initialized by the driver. struct Configuration { + std::atomic<bool> HasStaticTlsModel = false; uint8_t OSABI = 0; llvm::CachePruningPolicy ThinLTOCachePolicy; llvm::StringMap<uint64_t> SectionStartMap; diff --git a/ELF/SyntheticSections.cpp b/ELF/SyntheticSections.cpp index 507359847..f1b5c77dd 100644 --- a/ELF/SyntheticSections.cpp +++ b/ELF/SyntheticSections.cpp @@ -1295,6 +1295,8 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() { } if (!Config->ZText) DtFlags |= DF_TEXTREL; + if (Config->HasStaticTlsModel) + DtFlags |= DF_STATIC_TLS; if (DtFlags) addInt(DT_FLAGS, DtFlags); diff --git a/test/ELF/Inputs/i386-static-tls-model1.s b/test/ELF/Inputs/i386-static-tls-model1.s new file mode 100644 index 000000000..d287fb64e --- /dev/null +++ b/test/ELF/Inputs/i386-static-tls-model1.s @@ -0,0 +1,9 @@ +.section ".tdata", "awT", @progbits +.globl var +var: + +.section .foo, "aw" +.global _start +_start: + movl $var@tpoff, %edx # R_386_TLS_LE_32 + movl %gs:0, %ecx diff --git a/test/ELF/Inputs/i386-static-tls-model2.s b/test/ELF/Inputs/i386-static-tls-model2.s new file mode 100644 index 000000000..2c01cee42 --- /dev/null +++ b/test/ELF/Inputs/i386-static-tls-model2.s @@ -0,0 +1,9 @@ +.section ".tdata", "awT", @progbits +.globl var +var: + +.section .foo, "aw" +.global _start +_start: + movl %gs:0, %eax + addl var@gotntpoff(%ebx), %eax # R_386_TLS_GOTIE diff --git a/test/ELF/Inputs/i386-static-tls-model3.s b/test/ELF/Inputs/i386-static-tls-model3.s new file mode 100644 index 000000000..fd18fceb7 --- /dev/null +++ b/test/ELF/Inputs/i386-static-tls-model3.s @@ -0,0 +1,9 @@ +.section ".tdata", "awT", @progbits +.globl var +var: + +.section .foo, "aw" +.global _start +_start: + movl %gs:0, %eax + addl var@indntpoff, %eax # R_386_TLS_IE diff --git a/test/ELF/Inputs/i386-static-tls-model4.s b/test/ELF/Inputs/i386-static-tls-model4.s new file mode 100644 index 000000000..6006518bf --- /dev/null +++ b/test/ELF/Inputs/i386-static-tls-model4.s @@ -0,0 +1,9 @@ +.section ".tdata", "awT", @progbits +.globl var +var: + +.section .foo, "aw" +.global _start +_start: + movl %gs:0, %eax + leal var@ntpoff(%eax), %eax # R_386_TLS_LE diff --git a/test/ELF/i386-static-tls-model.s b/test/ELF/i386-static-tls-model.s new file mode 100644 index 000000000..a6dbc6db9 --- /dev/null +++ b/test/ELF/i386-static-tls-model.s @@ -0,0 +1,20 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %S/Inputs/i386-static-tls-model1.s -o %t.o +# RUN: ld.lld %t.o -o %t1 -shared +# RUN: llvm-readobj -dynamic-table %t1 | FileCheck %s + +# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %S/Inputs/i386-static-tls-model2.s -o %t.o +# RUN: ld.lld %t.o -o %t2 -shared +# RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s + +# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %S/Inputs/i386-static-tls-model3.s -o %t.o +# RUN: ld.lld %t.o -o %t3 -shared +# RUN: llvm-readobj -dynamic-table %t3 | FileCheck %s + +# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %S/Inputs/i386-static-tls-model4.s -o %t.o +# RUN: ld.lld %t.o -o %t4 -shared +# RUN: llvm-readobj -dynamic-table %t4 | FileCheck %s + +# CHECK: DynamicSection [ +# CHECK: FLAGS STATIC_TLS diff --git a/test/ELF/i386-tls-ie-shared.s b/test/ELF/i386-tls-ie-shared.s index 9e5ed1bcc..0e9694fd5 100644 --- a/test/ELF/i386-tls-ie-shared.s +++ b/test/ELF/i386-tls-ie-shared.s @@ -14,8 +14,8 @@ // GOTRELSHARED-NEXT: SHF_ALLOC // GOTRELSHARED-NEXT: SHF_WRITE // GOTRELSHARED-NEXT: ] -// GOTRELSHARED-NEXT: Address: 0x2058 -// GOTRELSHARED-NEXT: Offset: 0x2058 +// GOTRELSHARED-NEXT: Address: 0x2060 +// GOTRELSHARED-NEXT: Offset: 0x2060 // GOTRELSHARED-NEXT: Size: 16 // GOTRELSHARED-NEXT: Link: 0 // GOTRELSHARED-NEXT: Info: 0 @@ -32,36 +32,36 @@ // GOTRELSHARED-NEXT: 0x102D R_386_RELATIVE - 0x0 // GOTRELSHARED-NEXT: 0x1036 R_386_RELATIVE - 0x0 // GOTRELSHARED-NEXT: 0x103F R_386_RELATIVE - 0x0 -// GOTRELSHARED-NEXT: 0x2058 R_386_TLS_TPOFF tlslocal0 0x0 -// GOTRELSHARED-NEXT: 0x205C R_386_TLS_TPOFF tlslocal1 0x0 -// GOTRELSHARED-NEXT: 0x2060 R_386_TLS_TPOFF tlsshared0 0x0 -// GOTRELSHARED-NEXT: 0x2064 R_386_TLS_TPOFF tlsshared1 0x0 +// GOTRELSHARED-NEXT: 0x2060 R_386_TLS_TPOFF tlslocal0 0x0 +// GOTRELSHARED-NEXT: 0x2064 R_386_TLS_TPOFF tlslocal1 0x0 +// GOTRELSHARED-NEXT: 0x2068 R_386_TLS_TPOFF tlsshared0 0x0 +// GOTRELSHARED-NEXT: 0x206C R_386_TLS_TPOFF tlsshared1 0x0 // GOTRELSHARED-NEXT: } // GOTRELSHARED-NEXT: ] // GOTRELSHARED: 0x6FFFFFFA RELCOUNT 8 // DISASMSHARED: Disassembly of section test: // DISASMSHARED-NEXT: _start: -// (.got)[0] = 0x2058 = 8280 -// (.got)[1] = 0x205C = 8284 -// (.got)[2] = 0x2060 = 8288 -// (.got)[3] = 0x2064 = 8292 -// DISASMSHARED-NEXT: 1000: 8b 0d 58 20 00 00 movl 8280, %ecx -// DISASMSHARED-NEXT: 1006: 65 8b 01 movl %gs:(%ecx), %eax -// DISASMSHARED-NEXT: 1009: a1 58 20 00 00 movl 8280, %eax -// DISASMSHARED-NEXT: 100e: 65 8b 00 movl %gs:(%eax), %eax -// DISASMSHARED-NEXT: 1011: 03 0d 58 20 00 00 addl 8280, %ecx -// DISASMSHARED-NEXT: 1017: 65 8b 01 movl %gs:(%ecx), %eax -// DISASMSHARED-NEXT: 101a: 8b 0d 5c 20 00 00 movl 8284, %ecx -// DISASMSHARED-NEXT: 1020: 65 8b 01 movl %gs:(%ecx), %eax -// DISASMSHARED-NEXT: 1023: a1 5c 20 00 00 movl 8284, %eax -// DISASMSHARED-NEXT: 1028: 65 8b 00 movl %gs:(%eax), %eax -// DISASMSHARED-NEXT: 102b: 03 0d 5c 20 00 00 addl 8284, %ecx -// DISASMSHARED-NEXT: 1031: 65 8b 01 movl %gs:(%ecx), %eax -// DISASMSHARED-NEXT: 1034: 8b 0d 60 20 00 00 movl 8288, %ecx -// DISASMSHARED-NEXT: 103a: 65 8b 01 movl %gs:(%ecx), %eax -// DISASMSHARED-NEXT: 103d: 03 0d 64 20 00 00 addl 8292, %ecx -// DISASMSHARED-NEXT: 1043: 65 8b 01 movl %gs:(%ecx), %eax +// (.got)[0] = 0x2060 = 8288 +// (.got)[1] = 0x2064 = 8292 +// (.got)[2] = 0x2068 = 8296 +// (.got)[3] = 0x206C = 8300 +// DISASMSHARED-NEXT: 1000: {{.*}} movl 8288, %ecx +// DISASMSHARED-NEXT: 1006: {{.*}} movl %gs:(%ecx), %eax +// DISASMSHARED-NEXT: 1009: {{.*}} movl 8288, %eax +// DISASMSHARED-NEXT: 100e: {{.*}} movl %gs:(%eax), %eax +// DISASMSHARED-NEXT: 1011: {{.*}} addl 8288, %ecx +// DISASMSHARED-NEXT: 1017: {{.*}} movl %gs:(%ecx), %eax +// DISASMSHARED-NEXT: 101a: {{.*}} movl 8292, %ecx +// DISASMSHARED-NEXT: 1020: {{.*}} movl %gs:(%ecx), %eax +// DISASMSHARED-NEXT: 1023: {{.*}} movl 8292, %eax +// DISASMSHARED-NEXT: 1028: {{.*}} movl %gs:(%eax), %eax +// DISASMSHARED-NEXT: 102b: {{.*}} addl 8292, %ecx +// DISASMSHARED-NEXT: 1031: {{.*}} movl %gs:(%ecx), %eax +// DISASMSHARED-NEXT: 1034: {{.*}} movl 8296, %ecx +// DISASMSHARED-NEXT: 103a: {{.*}} movl %gs:(%ecx), %eax +// DISASMSHARED-NEXT: 103d: {{.*}} addl 8300, %ecx +// DISASMSHARED-NEXT: 1043: {{.*}} movl %gs:(%ecx), %eax .type tlslocal0,@object .section .tbss,"awT",@nobits diff --git a/test/ELF/tls-dynamic-i686.s b/test/ELF/tls-dynamic-i686.s index 1b13f26cc..dc651d09b 100644 --- a/test/ELF/tls-dynamic-i686.s +++ b/test/ELF/tls-dynamic-i686.s @@ -56,8 +56,8 @@ addl tls1@gotntpoff(%ebx),%eax // CHECK-NEXT: SHF_ALLOC // CHECK-NEXT: SHF_WRITE // CHECK-NEXT: ] -// CHECK-NEXT: Address: 0x3068 -// CHECK-NEXT: Offset: 0x3068 +// CHECK-NEXT: Address: 0x3070 +// CHECK-NEXT: Offset: 0x3070 // CHECK-NEXT: Size: 32 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 @@ -66,13 +66,13 @@ addl tls1@gotntpoff(%ebx),%eax // CHECK: Relocations [ // CHECK: Section ({{.+}}) .rel.dyn { -// CHECK-NEXT: 0x3078 R_386_TLS_DTPMOD32 - 0x0 -// CHECK-NEXT: 0x3068 R_386_TLS_DTPMOD32 tls0 0x0 -// CHECK-NEXT: 0x306C R_386_TLS_DTPOFF32 tls0 0x0 -// CHECK-NEXT: 0x3080 R_386_TLS_TPOFF tls0 0x0 -// CHECK-NEXT: 0x3070 R_386_TLS_DTPMOD32 tls1 0x0 -// CHECK-NEXT: 0x3074 R_386_TLS_DTPOFF32 tls1 0x0 -// CHECK-NEXT: 0x3084 R_386_TLS_TPOFF tls1 0x0 +// CHECK-NEXT: 0x3080 R_386_TLS_DTPMOD32 - 0x0 +// CHECK-NEXT: 0x3070 R_386_TLS_DTPMOD32 tls0 0x0 +// CHECK-NEXT: 0x3074 R_386_TLS_DTPOFF32 tls0 0x0 +// CHECK-NEXT: 0x3088 R_386_TLS_TPOFF tls0 0x0 +// CHECK-NEXT: 0x3078 R_386_TLS_DTPMOD32 tls1 0x0 +// CHECK-NEXT: 0x307C R_386_TLS_DTPOFF32 tls1 0x0 +// CHECK-NEXT: 0x308C R_386_TLS_TPOFF tls1 0x0 // CHECK-NEXT: } // DIS: Disassembly of section .text: @@ -80,20 +80,20 @@ addl tls1@gotntpoff(%ebx),%eax // General dynamic model: // -32 and -24 are first and second GOT entries offsets. // Each one is a pair of records. -// DIS-NEXT: 1000: 8d 04 1d e0 ff ff ff leal -32(,%ebx), %eax -// DIS-NEXT: 1007: e8 64 00 00 00 calll 100 -// DIS-NEXT: 100c: 8d 04 1d e8 ff ff ff leal -24(,%ebx), %eax -// DIS-NEXT: 1013: e8 58 00 00 00 calll 88 +// DIS-NEXT: 1000: {{.*}} leal -32(,%ebx), %eax +// DIS-NEXT: 1007: {{.*}} calll 100 +// DIS-NEXT: 100c: {{.*}} leal -24(,%ebx), %eax +// DIS-NEXT: 1013: {{.*}} calll 88 // Local dynamic model: // -16 is a local module tls index offset. -// DIS-NEXT: 1018: 8d 83 f0 ff ff ff leal -16(%ebx), %eax -// DIS-NEXT: 101e: e8 4d 00 00 00 calll 77 -// DIS-NEXT: 1023: 8d 90 08 00 00 00 leal 8(%eax), %edx -// DIS-NEXT: 1029: 8d 83 f0 ff ff ff leal -16(%ebx), %eax -// DIS-NEXT: 102f: e8 3c 00 00 00 calll 60 -// DIS-NEXT: 1034: 8d 90 0c 00 00 00 leal 12(%eax), %edx +// DIS-NEXT: 1018: {{.*}} leal -16(%ebx), %eax +// DIS-NEXT: 101e: {{.*}} calll 77 +// DIS-NEXT: 1023: {{.*}} leal 8(%eax), %edx +// DIS-NEXT: 1029: {{.*}} leal -16(%ebx), %eax +// DIS-NEXT: 102f: {{.*}} calll 60 +// DIS-NEXT: 1034: {{.*}} leal 12(%eax), %edx // Initial exec model: -// DIS-NEXT: 103a: 65 a1 00 00 00 00 movl %gs:0, %eax -// DIS-NEXT: 1040: 03 83 f8 ff ff ff addl -8(%ebx), %eax -// DIS-NEXT: 1046: 65 a1 00 00 00 00 movl %gs:0, %eax -// DIS-NEXT: 104c: 03 83 fc ff ff ff addl -4(%ebx), %eax +// DIS-NEXT: 103a: {{.*}} movl %gs:0, %eax +// DIS-NEXT: 1040: {{.*}} addl -8(%ebx), %eax +// DIS-NEXT: 1046: {{.*}} movl %gs:0, %eax +// DIS-NEXT: 104c: {{.*}} addl -4(%ebx), %eax diff --git a/test/ELF/tls-opt-iele-i686-nopic.s b/test/ELF/tls-opt-iele-i686-nopic.s index 704928b2b..9b97264a0 100644 --- a/test/ELF/tls-opt-iele-i686-nopic.s +++ b/test/ELF/tls-opt-iele-i686-nopic.s @@ -14,8 +14,8 @@ // GOTREL-NEXT: SHF_ALLOC // GOTREL-NEXT: SHF_WRITE // GOTREL-NEXT: ] -// GOTREL-NEXT: Address: 0x402058 -// GOTREL-NEXT: Offset: 0x2058 +// GOTREL-NEXT: Address: 0x402060 +// GOTREL-NEXT: Offset: 0x2060 // GOTREL-NEXT: Size: 8 // GOTREL-NEXT: Link: 0 // GOTREL-NEXT: Info: 0 @@ -24,8 +24,8 @@ // GOTREL-NEXT: } // GOTREL: Relocations [ // GOTREL-NEXT: Section ({{.*}}) .rel.dyn { -// GOTREL-NEXT: 0x402058 R_386_TLS_TPOFF tlsshared0 0x0 -// GOTREL-NEXT: 0x40205C R_386_TLS_TPOFF tlsshared1 0x0 +// GOTREL-NEXT: 0x402060 R_386_TLS_TPOFF tlsshared0 0x0 +// GOTREL-NEXT: 0x402064 R_386_TLS_TPOFF tlsshared1 0x0 // GOTREL-NEXT: } // GOTREL-NEXT: ] @@ -33,24 +33,24 @@ // DISASM-NEXT: _start: // 4294967288 = 0xFFFFFFF8 // 4294967292 = 0xFFFFFFFC -// 4202584 = (.got)[0] = 0x402058 -// 4202588 = (.got)[1] = 0x40205C -// DISASM-NEXT: 401000: c7 c1 f8 ff ff ff movl $4294967288, %ecx -// DISASM-NEXT: 401006: 65 8b 01 movl %gs:(%ecx), %eax -// DISASM-NEXT: 401009: b8 f8 ff ff ff movl $4294967288, %eax -// DISASM-NEXT: 40100e: 65 8b 00 movl %gs:(%eax), %eax -// DISASM-NEXT: 401011: 81 c1 f8 ff ff ff addl $4294967288, %ecx -// DISASM-NEXT: 401017: 65 8b 01 movl %gs:(%ecx), %eax -// DISASM-NEXT: 40101a: c7 c1 fc ff ff ff movl $4294967292, %ecx -// DISASM-NEXT: 401020: 65 8b 01 movl %gs:(%ecx), %eax -// DISASM-NEXT: 401023: b8 fc ff ff ff movl $4294967292, %eax -// DISASM-NEXT: 401028: 65 8b 00 movl %gs:(%eax), %eax -// DISASM-NEXT: 40102b: 81 c1 fc ff ff ff addl $4294967292, %ecx -// DISASM-NEXT: 401031: 65 8b 01 movl %gs:(%ecx), %eax -// DISASM-NEXT: 401034: 8b 0d 58 20 40 00 movl 4202584, %ecx -// DISASM-NEXT: 40103a: 65 8b 01 movl %gs:(%ecx), %eax -// DISASM-NEXT: 40103d: 03 0d 5c 20 40 00 addl 4202588, %ecx -// DISASM-NEXT: 401043: 65 8b 01 movl %gs:(%ecx), %eax +// 4202592 = (.got)[0] = 0x402060 +// 4202596 = (.got)[1] = 0x402064 +// DISASM-NEXT: 401000: {{.*}} movl $4294967288, %ecx +// DISASM-NEXT: 401006: {{.*}} movl %gs:(%ecx), %eax +// DISASM-NEXT: 401009: {{.*}} movl $4294967288, %eax +// DISASM-NEXT: 40100e: {{.*}} movl %gs:(%eax), %eax +// DISASM-NEXT: 401011: {{.*}} addl $4294967288, %ecx +// DISASM-NEXT: 401017: {{.*}} movl %gs:(%ecx), %eax +// DISASM-NEXT: 40101a: {{.*}} movl $4294967292, %ecx +// DISASM-NEXT: 401020: {{.*}} movl %gs:(%ecx), %eax +// DISASM-NEXT: 401023: {{.*}} movl $4294967292, %eax +// DISASM-NEXT: 401028: {{.*}} movl %gs:(%eax), %eax +// DISASM-NEXT: 40102b: {{.*}} addl $4294967292, %ecx +// DISASM-NEXT: 401031: {{.*}} movl %gs:(%ecx), %eax +// DISASM-NEXT: 401034: {{.*}} movl 4202592, %ecx +// DISASM-NEXT: 40103a: {{.*}} movl %gs:(%ecx), %eax +// DISASM-NEXT: 40103d: {{.*}} addl 4202596, %ecx +// DISASM-NEXT: 401043: {{.*}} movl %gs:(%ecx), %eax .type tlslocal0,@object .section .tbss,"awT",@nobits |