[lld] r255884 - [ELF] - implemented @indntpoff (x86) relocation and its optimization.
George Rimar via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 17 01:32:21 PST 2015
Author: grimar
Date: Thu Dec 17 03:32:21 2015
New Revision: 255884
URL: http://llvm.org/viewvc/llvm-project?rev=255884&view=rev
Log:
[ELF] - implemented @indntpoff (x86) relocation and its optimization.
@indntpoff is similar to @gotntpoff, but for use in position dependent code. While @gotntpoff resolves to GOT slot address relative to the
start of the GOT in the movl or addl instructions, @indntpoff resolves to the
absolute GOT slot address. ("ELF Handling For Thread-Local Storage", Ulrich Drepper).
Differential revision: http://reviews.llvm.org/D15494
Added:
lld/trunk/test/ELF/Inputs/tls-opt-iele-i686-nopic.s
lld/trunk/test/ELF/tls-opt-iele-i686-nopic.s
Modified:
lld/trunk/ELF/InputSection.cpp
lld/trunk/ELF/OutputSections.cpp
lld/trunk/ELF/Target.cpp
lld/trunk/ELF/Target.h
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=255884&r1=255883&r2=255884&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Thu Dec 17 03:32:21 2015
@@ -198,11 +198,11 @@ void InputSectionBase<ELFT>::relocate(ui
} else if (Target->relocNeedsGot(Type, Body)) {
SymVA = Out<ELFT>::Got->getEntryAddr(Body);
if (Body.isTls())
- Type = Target->getTlsGotReloc();
+ Type = Target->getTlsGotReloc(Type);
} else if (!Target->needsCopyRel(Type, Body) &&
isa<SharedSymbol<ELFT>>(Body)) {
continue;
- } else if (Target->isTlsDynReloc(Type) ||
+ } else if (Target->isTlsDynReloc(Type, Body) ||
Target->isSizeDynReloc(Type, Body)) {
continue;
} else if (Config->EMachine == EM_MIPS) {
Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=255884&r1=255883&r2=255884&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Thu Dec 17 03:32:21 2015
@@ -263,10 +263,11 @@ template <class ELFT> void RelocationSec
bool CanBePreempted = canBePreempted(Body, NeedsGot);
bool LazyReloc = Body && Target->supportsLazyRelocations() &&
Target->relocNeedsPlt(Type, *Body);
+ bool IsDynRelative = Type == Target->getRelativeReloc();
unsigned Sym = CanBePreempted ? Body->DynamicSymbolTableIndex : 0;
unsigned Reloc;
- if (!CanBePreempted)
+ if (!CanBePreempted || IsDynRelative)
Reloc = Target->getRelativeReloc();
else if (LazyReloc)
Reloc = Target->getPltReloc();
@@ -297,7 +298,7 @@ template <class ELFT> void RelocationSec
uintX_t Addend;
if (NeedsCopy)
Addend = 0;
- else if (CanBePreempted)
+ else if (CanBePreempted || IsDynRelative)
Addend = OrigAddend;
else if (Body)
Addend = getSymVA<ELFT>(cast<ELFSymbolBody<ELFT>>(*Body)) + OrigAddend;
Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=255884&r1=255883&r2=255884&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Thu Dec 17 03:32:21 2015
@@ -76,7 +76,8 @@ public:
X86TargetInfo();
void writeGotPltHeaderEntries(uint8_t *Buf) const override;
unsigned getDynReloc(unsigned Type) const override;
- bool isTlsDynReloc(unsigned Type) const override;
+ unsigned getTlsGotReloc(unsigned Type) const override;
+ bool isTlsDynReloc(unsigned Type, const SymbolBody &S) const override;
void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override;
void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
uint64_t PltEntryAddr) const override;
@@ -84,6 +85,7 @@ public:
uint64_t PltEntryAddr, int32_t Index,
unsigned RelOff) const override;
bool needsCopyRel(uint32_t Type, const SymbolBody &S) const override;
+ bool relocNeedsDynRelative(unsigned Type) const override;
bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override;
bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override;
void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
@@ -101,15 +103,15 @@ private:
uint64_t SA) const;
void relocateTlsGdToLe(uint8_t *Loc, uint8_t *BufEnd, uint64_t P,
uint64_t SA) const;
- void relocateTlsIeToLe(uint8_t *Loc, uint8_t *BufEnd, uint64_t P,
- uint64_t SA) const;
+ void relocateTlsIeToLe(unsigned Type, uint8_t *Loc, uint8_t *BufEnd,
+ uint64_t P, uint64_t SA) const;
};
class X86_64TargetInfo final : public TargetInfo {
public:
X86_64TargetInfo();
unsigned getPltRefReloc(unsigned Type) const override;
- bool isTlsDynReloc(unsigned Type) const override;
+ bool isTlsDynReloc(unsigned Type, const SymbolBody &S) const override;
void writeGotPltHeaderEntries(uint8_t *Buf) const override;
void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override;
void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
@@ -253,6 +255,7 @@ X86TargetInfo::X86TargetInfo() {
PCRelReloc = R_386_PC32;
GotReloc = R_386_GLOB_DAT;
PltReloc = R_386_JUMP_SLOT;
+ RelativeReloc = R_386_RELATIVE;
TlsGotReloc = R_386_TLS_TPOFF;
TlsGlobalDynamicReloc = R_386_TLS_GD;
TlsLocalDynamicReloc = R_386_TLS_LDM;
@@ -280,10 +283,18 @@ unsigned X86TargetInfo::getDynReloc(unsi
return Type;
}
-bool X86TargetInfo::isTlsDynReloc(unsigned Type) const {
+unsigned X86TargetInfo::getTlsGotReloc(unsigned Type) const {
+ if (Type == R_386_TLS_IE)
+ return Type;
+ return TlsGotReloc;
+}
+
+bool X86TargetInfo::isTlsDynReloc(unsigned Type, const SymbolBody &S) const {
if (Type == R_386_TLS_LE || Type == R_386_TLS_LE_32 ||
Type == R_386_TLS_GOTIE)
return Config->Shared;
+ if (Type == R_386_TLS_IE)
+ return canBePreempted(&S, true);
return Type == R_386_TLS_GD;
}
@@ -337,7 +348,7 @@ bool X86TargetInfo::needsCopyRel(uint32_
bool X86TargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const {
if (S.isTls() && Type == R_386_TLS_GD)
return Target->isTlsOptimized(Type, &S) && canBePreempted(&S, true);
- if (Type == R_386_TLS_GOTIE)
+ if (Type == R_386_TLS_GOTIE || Type == R_386_TLS_IE)
return !isTlsOptimized(Type, &S);
return Type == R_386_GOT32 || relocNeedsPlt(Type, S);
}
@@ -373,6 +384,7 @@ void X86TargetInfo::relocateOne(uint8_t
write32le(Loc, V);
break;
}
+ case R_386_TLS_IE:
case R_386_TLS_LDO_32:
write32le(Loc, SA);
break;
@@ -392,9 +404,14 @@ bool X86TargetInfo::isTlsOptimized(unsig
return false;
return Type == R_386_TLS_LDO_32 || Type == R_386_TLS_LDM ||
Type == R_386_TLS_GD ||
+ (Type == R_386_TLS_IE && !canBePreempted(S, true)) ||
(Type == R_386_TLS_GOTIE && !canBePreempted(S, true));
}
+bool X86TargetInfo::relocNeedsDynRelative(unsigned Type) const {
+ return Config->Shared && Type == R_386_TLS_IE;
+}
+
unsigned X86TargetInfo::relocateTlsOptimize(uint8_t *Loc, uint8_t *BufEnd,
uint32_t Type, uint64_t P,
uint64_t SA,
@@ -408,7 +425,8 @@ unsigned X86TargetInfo::relocateTlsOptim
// The next relocation should be against __tls_get_addr, so skip it
return 1;
case R_386_TLS_GOTIE:
- relocateTlsIeToLe(Loc, BufEnd, P, SA);
+ case R_386_TLS_IE:
+ relocateTlsIeToLe(Type, Loc, BufEnd, P, SA);
return 0;
case R_386_TLS_LDM:
relocateTlsLdToLe(Loc, BufEnd, P, SA);
@@ -478,27 +496,47 @@ void X86TargetInfo::relocateTlsLdToLe(ui
memcpy(Loc - 2, Inst, sizeof(Inst));
}
-// In some conditions, R_386_TLS_GOTIE relocation can be optimized to
-// R_386_TLS_LE so that it does not use GOT.
-// This function does that. Read "ELF Handling For Thread-Local Storage,
-// 5.1 IA-32 Linker Optimizations" (http://www.akkadia.org/drepper/tls.pdf)
+// In some conditions, relocations can be optimized to avoid using GOT.
+// This function does that for Initial Exec to Local Exec case.
+// Read "ELF Handling For Thread-Local Storage, 5.1
+// IA-32 Linker Optimizations" (http://www.akkadia.org/drepper/tls.pdf)
// by Ulrich Drepper for details.
-void X86TargetInfo::relocateTlsIeToLe(uint8_t *Loc, uint8_t *BufEnd, uint64_t P,
+void X86TargetInfo::relocateTlsIeToLe(unsigned Type, uint8_t *Loc,
+ uint8_t *BufEnd, uint64_t P,
uint64_t SA) const {
- // Ulrich's document section 6.2 says that @gotntpoff can be
- // used with MOVL or ADDL instructions.
- // "MOVL foo at GOTTPOFF(%RIP), %REG" is transformed to "MOVL $foo, %REG".
- // "ADDL foo at GOTNTPOFF(%RIP), %REG" is transformed to "LEAL foo(%REG), %REG"
- // Note: gold converts to ADDL instead of LEAL.
+ // Ulrich's document section 6.2 says that @gotntpoff can
+ // be used with MOVL or ADDL instructions.
+ // @indntpoff is similar to @gotntpoff, but for use in
+ // position dependent code.
uint8_t *Inst = Loc - 2;
- uint8_t *RegSlot = Loc - 1;
+ uint8_t *Op = Loc - 1;
uint8_t Reg = (Loc[-1] >> 3) & 7;
bool IsMov = *Inst == 0x8b;
- *Inst = IsMov ? 0xc7 : 0x8d;
- if (IsMov)
- *RegSlot = 0xc0 | ((*RegSlot >> 3) & 7);
- else
- *RegSlot = 0x80 | Reg | (Reg << 3);
+ if (Type == R_386_TLS_IE) {
+ // For R_386_TLS_IE relocation we perform the next transformations:
+ // MOVL foo at INDNTPOFF,%EAX is transformed to MOVL $foo,%EAX
+ // MOVL foo at INDNTPOFF,%REG is transformed to MOVL $foo,%REG
+ // ADDL foo at INDNTPOFF,%REG is transformed to ADDL $foo,%REG
+ // First one is special because when EAX is used the sequence is 5 bytes
+ // long, otherwise it is 6 bytes.
+ if (*Op == 0xa1) {
+ *Op = 0xb8;
+ } else {
+ *Inst = IsMov ? 0xc7 : 0x81;
+ *Op = 0xc0 | ((*Op >> 3) & 7);
+ }
+ } else {
+ // R_386_TLS_GOTIE relocation can be optimized to
+ // R_386_TLS_LE so that it does not use GOT.
+ // "MOVL foo at GOTTPOFF(%RIP), %REG" is transformed to "MOVL $foo, %REG".
+ // "ADDL foo at GOTNTPOFF(%RIP), %REG" is transformed to "LEAL foo(%REG), %REG"
+ // Note: gold converts to ADDL instead of LEAL.
+ *Inst = IsMov ? 0xc7 : 0x8d;
+ if (IsMov)
+ *Op = 0xc0 | ((*Op >> 3) & 7);
+ else
+ *Op = 0x80 | Reg | (Reg << 3);
+ }
relocateOne(Loc, BufEnd, R_386_TLS_LE, P, SA);
}
@@ -571,7 +609,7 @@ bool X86_64TargetInfo::relocNeedsGot(uin
return Type == R_X86_64_GOTPCREL || relocNeedsPlt(Type, S);
}
-bool X86_64TargetInfo::isTlsDynReloc(unsigned Type) const {
+bool X86_64TargetInfo::isTlsDynReloc(unsigned Type, const SymbolBody &S) const {
return Type == R_X86_64_GOTTPOFF || Type == R_X86_64_TLSGD;
}
Modified: lld/trunk/ELF/Target.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=255884&r1=255883&r2=255884&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Thu Dec 17 03:32:21 2015
@@ -27,7 +27,6 @@ public:
unsigned getGotReloc() const { return GotReloc; }
unsigned getPltReloc() const { return PltReloc; }
unsigned getRelativeReloc() const { return RelativeReloc; }
- unsigned getTlsGotReloc() const { return TlsGotReloc; }
bool isTlsLocalDynamicReloc(unsigned Type) const {
return Type == TlsLocalDynamicReloc;
}
@@ -42,8 +41,13 @@ public:
unsigned getGotHeaderEntriesNum() const { return GotHeaderEntriesNum; }
unsigned getGotPltHeaderEntriesNum() const { return GotPltHeaderEntriesNum; }
virtual unsigned getDynReloc(unsigned Type) const { return Type; }
- virtual bool isTlsDynReloc(unsigned Type) const { return false; }
+ virtual bool isTlsDynReloc(unsigned Type, const SymbolBody &S) const {
+ return false;
+ }
virtual unsigned getPltRefReloc(unsigned Type) const;
+ virtual unsigned getTlsGotReloc(unsigned Type = -1) const {
+ return TlsGotReloc;
+ }
virtual void writeGotHeaderEntries(uint8_t *Buf) const;
virtual void writeGotPltHeaderEntries(uint8_t *Buf) const;
virtual void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const = 0;
@@ -54,6 +58,7 @@ public:
int32_t Index, unsigned RelOff) const = 0;
virtual bool isRelRelative(uint32_t Type) const;
virtual bool isSizeDynReloc(uint32_t Type, const SymbolBody &S) const;
+ virtual bool relocNeedsDynRelative(unsigned Type) const { return false; }
virtual bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const = 0;
virtual bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const = 0;
virtual void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=255884&r1=255883&r2=255884&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Thu Dec 17 03:32:21 2015
@@ -236,9 +236,16 @@ void Writer<ELFT>::scanRelocs(
continue;
}
- if (Body && Body->isTls() && !Target->isTlsDynReloc(Type))
+ if (Body && Body->isTls() && !Target->isTlsDynReloc(Type, *Body))
continue;
+ if (Target->relocNeedsDynRelative(Type)) {
+ RelType *Rel = new (Alloc) RelType;
+ Rel->setSymbolAndType(0, Target->getRelativeReloc(), Config->Mips64EL);
+ Rel->r_offset = RI.r_offset;
+ Out<ELFT>::RelaDyn->addReloc({&C, Rel});
+ }
+
bool NeedsGot = false;
bool NeedsPlt = false;
if (Body) {
Added: lld/trunk/test/ELF/Inputs/tls-opt-iele-i686-nopic.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/tls-opt-iele-i686-nopic.s?rev=255884&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/tls-opt-iele-i686-nopic.s (added)
+++ lld/trunk/test/ELF/Inputs/tls-opt-iele-i686-nopic.s Thu Dec 17 03:32:21 2015
@@ -0,0 +1,15 @@
+.type tlsshared0, at object
+.section .tbss,"awT", at nobits
+.globl tlsshared0
+.align 4
+tlsshared0:
+ .long 0
+ .size tlsshared0, 4
+
+.type tlsshared1, at object
+.section .tbss,"awT", at nobits
+.globl tlsshared1
+.align 4
+tlsshared1:
+ .long 0
+ .size tlsshared1, 4
Added: lld/trunk/test/ELF/tls-opt-iele-i686-nopic.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/tls-opt-iele-i686-nopic.s?rev=255884&view=auto
==============================================================================
--- lld/trunk/test/ELF/tls-opt-iele-i686-nopic.s (added)
+++ lld/trunk/test/ELF/tls-opt-iele-i686-nopic.s Thu Dec 17 03:32:21 2015
@@ -0,0 +1,159 @@
+// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %p/Inputs/tls-opt-iele-i686-nopic.s -o %tso.o
+// RUN: ld.lld -shared %tso.o -o %tso
+// RUN: ld.lld %t.o %tso -o %t1
+// RUN: llvm-readobj -s -r %t1 | FileCheck --check-prefix=GOTREL %s
+// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s
+// RUN: ld.lld -shared %t.o %tso -o %t1
+// RUN: llvm-readobj -s -r %t1 | FileCheck --check-prefix=GOTRELSHARED %s
+// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASMSHARED %s
+
+// GOTREL: Section {
+// GOTREL: Index:
+// GOTREL: Name: .got
+// GOTREL-NEXT: Type: SHT_PROGBITS
+// GOTREL-NEXT: Flags [
+// GOTREL-NEXT: SHF_ALLOC
+// GOTREL-NEXT: SHF_WRITE
+// GOTREL-NEXT: ]
+// GOTREL-NEXT: Address: 0x12050
+// GOTREL-NEXT: Offset: 0x2050
+// GOTREL-NEXT: Size: 8
+// GOTREL-NEXT: Link: 0
+// GOTREL-NEXT: Info: 0
+// GOTREL-NEXT: AddressAlignment: 4
+// GOTREL-NEXT: EntrySize: 0
+// GOTREL-NEXT: }
+// GOTREL: Relocations [
+// GOTREL-NEXT: Section ({{.*}}) .rel.dyn {
+// GOTREL-NEXT: 0x12050 R_386_TLS_TPOFF tlsshared0 0x0
+// GOTREL-NEXT: 0x12054 R_386_TLS_TPOFF tlsshared1 0x0
+// GOTREL-NEXT: }
+// GOTREL-NEXT: ]
+
+// DISASM: Disassembly of section .text:
+// DISASM-NEXT: _start:
+// 4294967288 = 0xFFFFFFF8
+// 4294967292 = 0xFFFFFFFC
+// 73808 = (.got)[0] = 0x12050
+// 73812 = (.got)[1] = 0x12054
+// DISASM-NEXT: 11000: c7 c1 f8 ff ff ff movl $4294967288, %ecx
+// DISASM-NEXT: 11006: 65 8b 01 movl %gs:(%ecx), %eax
+// DISASM-NEXT: 11009: b8 f8 ff ff ff movl $4294967288, %eax
+// DISASM-NEXT: 1100e: 65 8b 00 movl %gs:(%eax), %eax
+// DISASM-NEXT: 11011: 81 c1 f8 ff ff ff addl $4294967288, %ecx
+// DISASM-NEXT: 11017: 65 8b 01 movl %gs:(%ecx), %eax
+// DISASM-NEXT: 1101a: c7 c1 fc ff ff ff movl $4294967292, %ecx
+// DISASM-NEXT: 11020: 65 8b 01 movl %gs:(%ecx), %eax
+// DISASM-NEXT: 11023: b8 fc ff ff ff movl $4294967292, %eax
+// DISASM-NEXT: 11028: 65 8b 00 movl %gs:(%eax), %eax
+// DISASM-NEXT: 1102b: 81 c1 fc ff ff ff addl $4294967292, %ecx
+// DISASM-NEXT: 11031: 65 8b 01 movl %gs:(%ecx), %eax
+// DISASM-NEXT: 11034: 8b 0d 50 20 01 00 movl 73808, %ecx
+// DISASM-NEXT: 1103a: 65 8b 01 movl %gs:(%ecx), %eax
+// DISASM-NEXT: 1103d: 03 0d 54 20 01 00 addl 73812, %ecx
+// DISASM-NEXT: 11043: 65 8b 01 movl %gs:(%ecx), %eax
+
+// GOTRELSHARED: Section {
+// GOTRELSHARED: Index: 8
+// GOTRELSHARED: Name: .got
+// GOTRELSHARED-NEXT: Type: SHT_PROGBITS
+// GOTRELSHARED-NEXT: Flags [
+// GOTRELSHARED-NEXT: SHF_ALLOC
+// GOTRELSHARED-NEXT: SHF_WRITE
+// GOTRELSHARED-NEXT: ]
+// GOTRELSHARED-NEXT: Address: 0x2050
+// GOTRELSHARED-NEXT: Offset: 0x2050
+// GOTRELSHARED-NEXT: Size: 16
+// GOTRELSHARED-NEXT: Link: 0
+// GOTRELSHARED-NEXT: Info: 0
+// GOTRELSHARED-NEXT: AddressAlignment: 4
+// GOTRELSHARED-NEXT: EntrySize: 0
+// GOTRELSHARED-NEXT: }
+// GOTRELSHARED: Relocations [
+// GOTRELSHARED-NEXT: Section ({{.*}}) .rel.dyn {
+// GOTRELSHARED-NEXT: 0x1002 R_386_RELATIVE - 0x0
+// GOTRELSHARED-NEXT: 0x2050 R_386_TLS_TPOFF tlslocal0 0x0
+// GOTRELSHARED-NEXT: 0x100A R_386_RELATIVE - 0x0
+// GOTRELSHARED-NEXT: 0x1013 R_386_RELATIVE - 0x0
+// GOTRELSHARED-NEXT: 0x101C R_386_RELATIVE - 0x0
+// GOTRELSHARED-NEXT: 0x2054 R_386_TLS_TPOFF tlslocal1 0x0
+// GOTRELSHARED-NEXT: 0x1024 R_386_RELATIVE - 0x0
+// GOTRELSHARED-NEXT: 0x102D R_386_RELATIVE - 0x0
+// GOTRELSHARED-NEXT: 0x1036 R_386_RELATIVE - 0x0
+// GOTRELSHARED-NEXT: 0x2058 R_386_TLS_TPOFF tlsshared0 0x0
+// GOTRELSHARED-NEXT: 0x103F R_386_RELATIVE - 0x0
+// GOTRELSHARED-NEXT: 0x205C R_386_TLS_TPOFF tlsshared1 0x0
+// GOTRELSHARED-NEXT: }
+// GOTRELSHARED-NEXT: ]
+
+// DISASMSHARED: Disassembly of section .text:
+// DISASMSHARED-NEXT: _start:
+// (.got)[0] = 0x2050 = 8272
+// (.got)[1] = 0x2054 = 8276
+// (.got)[2] = 0x2058 = 8280
+// (.got)[3] = 0x205C = 8284
+// DISASMSHARED-NEXT: 1000: 8b 0d 50 20 00 00 movl 8272, %ecx
+// DISASMSHARED-NEXT: 1006: 65 8b 01 movl %gs:(%ecx), %eax
+// DISASMSHARED-NEXT: 1009: a1 50 20 00 00 movl 8272, %eax
+// DISASMSHARED-NEXT: 100e: 65 8b 00 movl %gs:(%eax), %eax
+// DISASMSHARED-NEXT: 1011: 03 0d 50 20 00 00 addl 8272, %ecx
+// DISASMSHARED-NEXT: 1017: 65 8b 01 movl %gs:(%ecx), %eax
+// DISASMSHARED-NEXT: 101a: 8b 0d 54 20 00 00 movl 8276, %ecx
+// DISASMSHARED-NEXT: 1020: 65 8b 01 movl %gs:(%ecx), %eax
+// DISASMSHARED-NEXT: 1023: a1 54 20 00 00 movl 8276, %eax
+// DISASMSHARED-NEXT: 1028: 65 8b 00 movl %gs:(%eax), %eax
+// DISASMSHARED-NEXT: 102b: 03 0d 54 20 00 00 addl 8276, %ecx
+// DISASMSHARED-NEXT: 1031: 65 8b 01 movl %gs:(%ecx), %eax
+// DISASMSHARED-NEXT: 1034: 8b 0d 58 20 00 00 movl 8280, %ecx
+// DISASMSHARED-NEXT: 103a: 65 8b 01 movl %gs:(%ecx), %eax
+// DISASMSHARED-NEXT: 103d: 03 0d 5c 20 00 00 addl 8284, %ecx
+// DISASMSHARED-NEXT: 1043: 65 8b 01 movl %gs:(%ecx), %eax
+
+.type tlslocal0, at object
+.section .tbss,"awT", at nobits
+.globl tlslocal0
+.align 4
+tlslocal0:
+ .long 0
+ .size tlslocal0, 4
+
+.type tlslocal1, at object
+.section .tbss,"awT", at nobits
+.globl tlslocal1
+.align 4
+tlslocal1:
+ .long 0
+ .size tlslocal1, 4
+
+.section .text
+.globl ___tls_get_addr
+.type ___tls_get_addr, at function
+___tls_get_addr:
+
+.section .text
+.globl _start
+_start:
+movl tlslocal0 at indntpoff,%ecx
+movl %gs:(%ecx),%eax
+
+movl tlslocal0 at indntpoff,%eax
+movl %gs:(%eax),%eax
+
+addl tlslocal0 at indntpoff,%ecx
+movl %gs:(%ecx),%eax
+
+movl tlslocal1 at indntpoff,%ecx
+movl %gs:(%ecx),%eax
+
+movl tlslocal1 at indntpoff,%eax
+movl %gs:(%eax),%eax
+
+addl tlslocal1 at indntpoff,%ecx
+movl %gs:(%ecx),%eax
+
+movl tlsshared0 at indntpoff,%ecx
+movl %gs:(%ecx),%eax
+
+addl tlsshared1 at indntpoff,%ecx
+movl %gs:(%ecx),%eax
More information about the llvm-commits
mailing list