Skip to content

Commit

Permalink
[LLD][ELF] - Set DF_STATIC_TLS flag for i386 target.
Browse files Browse the repository at this point in the history
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

llvm-svn: 353293
  • Loading branch information
George Rimar committed Feb 6, 2019
1 parent 5a6712b commit da60ad2
Show file tree
Hide file tree
Showing 11 changed files with 140 additions and 71 deletions.
9 changes: 9 additions & 0 deletions lld/ELF/Arch/X86.cpp
Expand Up @@ -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:
Expand Down
2 changes: 2 additions & 0 deletions lld/ELF/Config.h
Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions lld/ELF/SyntheticSections.cpp
Expand Up @@ -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);
Expand Down
9 changes: 9 additions & 0 deletions lld/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
9 changes: 9 additions & 0 deletions lld/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
9 changes: 9 additions & 0 deletions lld/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
9 changes: 9 additions & 0 deletions lld/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
20 changes: 20 additions & 0 deletions lld/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
52 changes: 26 additions & 26 deletions lld/test/ELF/i386-tls-ie-shared.s
Expand Up @@ -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
Expand All @@ -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
Expand Down
46 changes: 23 additions & 23 deletions lld/test/ELF/tls-dynamic-i686.s
Expand Up @@ -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
Expand All @@ -66,34 +66,34 @@ 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:
// DIS-NEXT: _start:
// 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
44 changes: 22 additions & 22 deletions lld/test/ELF/tls-opt-iele-i686-nopic.s
Expand Up @@ -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
Expand All @@ -24,33 +24,33 @@
// 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: ]

// DISASM: Disassembly of section .text:
// 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
Expand Down

0 comments on commit da60ad2

Please sign in to comment.