Index: lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.h =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.h +++ lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.h @@ -9,35 +9,28 @@ #ifndef AARCH64_EXECUTABLE_WRITER_H #define AARCH64_EXECUTABLE_WRITER_H -#include "AArch64LinkingContext.h" #include "ExecutableWriter.h" namespace lld { namespace elf { +class AArch64TargetLayout; +class AArch64LinkingContext; + class AArch64ExecutableWriter : public ExecutableWriter { public: AArch64ExecutableWriter(AArch64LinkingContext &ctx, - TargetLayout &layout); + AArch64TargetLayout &layout); protected: // Add any runtime files and their atoms to the output void createImplicitFiles(std::vector> &) override; -}; -AArch64ExecutableWriter::AArch64ExecutableWriter(AArch64LinkingContext &ctx, - TargetLayout &layout) - : ExecutableWriter(ctx, layout) {} - -void AArch64ExecutableWriter::createImplicitFiles( - std::vector> &result) { - ExecutableWriter::createImplicitFiles(result); - auto gotFile = llvm::make_unique("GOTFile"); - gotFile->addAtom(*new (gotFile->allocator()) GlobalOffsetTableAtom(*gotFile)); - if (this->_ctx.isDynamic()) - gotFile->addAtom(*new (gotFile->allocator()) DynamicAtom(*gotFile)); - result.push_back(std::move(gotFile)); -} + void buildDynamicSymbolTable(const File &file) override; + +private: + AArch64TargetLayout &_targetLayout; +}; } // namespace elf } // namespace lld Index: lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.cpp =================================================================== --- /dev/null +++ lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.cpp @@ -0,0 +1,51 @@ +//===- lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.cpp -------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "AArch64LinkingContext.h" +#include "AArch64ExecutableWriter.h" +#include "AArch64TargetHandler.h" +#include "AArch64SectionChunks.h" + +namespace lld { +namespace elf { + +AArch64ExecutableWriter::AArch64ExecutableWriter(AArch64LinkingContext &ctx, + AArch64TargetLayout &layout) + : ExecutableWriter(ctx, layout), _targetLayout(layout) +{ +} + +void AArch64ExecutableWriter::createImplicitFiles( + std::vector> &result) { + ExecutableWriter::createImplicitFiles(result); + auto gotFile = llvm::make_unique("GOTFile"); + gotFile->addAtom(*new (gotFile->allocator()) GlobalOffsetTableAtom(*gotFile)); + if (this->_ctx.isDynamic()) + gotFile->addAtom(*new (gotFile->allocator()) DynamicAtom(*gotFile)); + result.push_back(std::move(gotFile)); +} + +void AArch64ExecutableWriter::buildDynamicSymbolTable(const File &file) +{ + for (auto sec : this->_layout.sections()) + if (auto section = dyn_cast>(sec)) + for (const auto &atom : section->atoms()) { + if (_targetLayout.getGOTSection().hasGlobalGOTEntry(atom->_atom)) { + this->_dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(), + atom->_virtualAddr, atom); + continue; + } + } + + ExecutableWriter::buildDynamicSymbolTable(file); +} + +} // namespace elf +} // namespace lld + Index: lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp +++ lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp @@ -433,6 +433,7 @@ case R_AARCH64_IRELATIVE: case R_AARCH64_JUMP_SLOT: case R_AARCH64_GLOB_DAT: + case R_AARCH64_TLS_TPREL64: break; case R_AARCH64_ADR_PREL_PG_HI21: return relocR_AARCH64_ADR_PREL_PG_HI21(loc, reloc, target, addend); Index: lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp +++ lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp @@ -56,11 +56,20 @@ /// \brief Atoms that are used by AArch64 dynamic linking class AArch64GOTAtom : public GOTAtom { public: - AArch64GOTAtom(const File &f, StringRef secName) : GOTAtom(f, secName) {} + AArch64GOTAtom(const File &f) : GOTAtom(f, ".got") {} ArrayRef rawContent() const override { return ArrayRef(AArch64GotAtomContent, 8); } + +protected: + // Constructor for AArch64GOTAtom + AArch64GOTAtom(const File &f, StringRef secName) : GOTAtom(f, secName) {} +}; + +class AArch64GOTPLTAtom : public AArch64GOTAtom { +public: + AArch64GOTPLTAtom(const File &f) : AArch64GOTAtom(f, ".got.plt") {} }; class AArch64PLT0Atom : public PLT0Atom { @@ -73,7 +82,7 @@ class AArch64PLTAtom : public PLTAtom { public: - AArch64PLTAtom(const File &f, StringRef secName) : PLTAtom(f, secName) {} + AArch64PLTAtom(const File &f) : PLTAtom(f, ".plt") {} ArrayRef rawContent() const override { return ArrayRef(AArch64PltAtomContent, 16); @@ -138,9 +147,11 @@ break; case R_AARCH64_ADR_GOT_PAGE: case R_AARCH64_LD64_GOT_LO12_NC: + static_cast(this)->handleGOT(ref); + break; case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: - static_cast(this)->handleGOT(ref); + static_cast(this)->handleGOTTPREL(ref); break; } } @@ -153,9 +164,9 @@ auto plt = _pltMap.find(da); if (plt != _pltMap.end()) return plt->second; - auto ga = new (_file._alloc) AArch64GOTAtom(_file, ".got.plt"); + auto ga = new (_file._alloc) AArch64GOTPLTAtom(_file); ga->addReferenceELF_AArch64(R_AARCH64_IRELATIVE, 0, da, 0); - auto pa = new (_file._alloc) AArch64PLTAtom(_file, ".plt"); + auto pa = new (_file._alloc) AArch64PLTAtom(_file); pa->addReferenceELF_AArch64(R_AARCH64_PREL32, 2, ga, -4); #ifndef NDEBUG ga->_name = "__got_ifunc_"; @@ -182,11 +193,11 @@ } /// \brief Create a GOT entry for the TP offset of a TLS atom. - const GOTAtom *getGOTTPOFF(const Atom *atom) { + const GOTAtom *getGOTTPREL(const Atom *atom) { auto got = _gotMap.find(atom); if (got == _gotMap.end()) { - auto g = new (_file._alloc) AArch64GOTAtom(_file, ".got"); - g->addReferenceELF_AArch64(R_AARCH64_GOTREL64, 0, atom, 0); + auto g = new (_file._alloc) AArch64GOTAtom(_file); + g->addReferenceELF_AArch64(R_AARCH64_TLS_TPREL64, 0, atom, 0); #ifndef NDEBUG g->_name = "__got_tls_"; g->_name += atom->name(); @@ -198,17 +209,19 @@ return got->second; } - /// \brief Create a TPOFF64 GOT entry and change the relocation to a PC32 to + /// \brief Create a GOT TPREL entry and change the relocation to a PC32 to /// the GOT. - void handleGOTTPOFF(const Reference &ref) { - const_cast(ref).setTarget(getGOTTPOFF(ref.target())); - const_cast(ref).setKindValue(R_AARCH64_PREL32); + std::error_code handleGOTTPREL(const Reference &ref) { + if (const auto *target = dyn_cast(ref.target())) { + const_cast(ref).setTarget(getGOTTPREL(ref.target())); + } + return std::error_code(); } /// \brief Create a GOT entry containing 0. const GOTAtom *getNullGOT() { if (!_null) { - _null = new (_file._alloc) AArch64GOTAtom(_file, ".got.plt"); + _null = new (_file._alloc) AArch64GOTPLTAtom(_file); #ifndef NDEBUG _null->_name = "__got_null"; #endif @@ -219,7 +232,7 @@ const GOTAtom *getGOT(const DefinedAtom *da) { auto got = _gotMap.find(da); if (got == _gotMap.end()) { - auto g = new (_file._alloc) AArch64GOTAtom(_file, ".got"); + auto g = new (_file._alloc) AArch64GOTAtom(_file); g->addReferenceELF_AArch64(R_AARCH64_ABS64, 0, da, 0); #ifndef NDEBUG g->_name = "__got_"; @@ -386,8 +399,8 @@ // Fill in the null entry. getNullGOT(); _plt0 = new (_file._alloc) AArch64PLT0Atom(_file); - _got0 = new (_file._alloc) AArch64GOTAtom(_file, ".got.plt"); - _got1 = new (_file._alloc) AArch64GOTAtom(_file, ".got.plt"); + _got0 = new (_file._alloc) AArch64GOTPLTAtom(_file); + _got1 = new (_file._alloc) AArch64GOTPLTAtom(_file); _plt0->addReferenceELF_AArch64(R_AARCH64_ADR_GOT_PAGE, 4, _got0, 0); _plt0->addReferenceELF_AArch64(R_AARCH64_LD64_GOT_LO12_NC, 8, _got1, 0); _plt0->addReferenceELF_AArch64(ADD_AARCH64_GOTRELINDEX, 12, _got1, 0); @@ -403,9 +416,9 @@ auto plt = _pltMap.find(a); if (plt != _pltMap.end()) return plt->second; - auto ga = new (_file._alloc) AArch64GOTAtom(_file, ".got.plt"); + auto ga = new (_file._alloc) AArch64GOTPLTAtom(_file); ga->addReferenceELF_AArch64(R_AARCH64_JUMP_SLOT, 0, a, 0); - auto pa = new (_file._alloc) AArch64PLTAtom(_file, ".plt"); + auto pa = new (_file._alloc) AArch64PLTAtom(_file); pa->addReferenceELF_AArch64(R_AARCH64_ADR_GOT_PAGE, 0, ga, 0); pa->addReferenceELF_AArch64(R_AARCH64_LD64_GOT_LO12_NC, 4, ga, 0); pa->addReferenceELF_AArch64(ADD_AARCH64_GOTRELINDEX, 8, ga, 0); @@ -472,7 +485,7 @@ const GOTAtom *getSharedGOT(const SharedLibraryAtom *sla) { auto got = _gotMap.find(sla); if (got == _gotMap.end()) { - auto g = new (_file._alloc) AArch64GOTAtom(_file, ".got"); + auto g = new (_file._alloc) AArch64GOTAtom(_file); g->addReferenceELF_AArch64(R_AARCH64_GLOB_DAT, 0, sla, 0); #ifndef NDEBUG g->_name = "__got_"; Index: lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.h =================================================================== --- /dev/null +++ lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.h @@ -0,0 +1,35 @@ +//===- lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.h ----------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef LLD_READER_WRITER_ELF_AARCH64_AARCH64_SECTION_CHUNKS_H +#define LLD_READER_WRITER_ELF_AARCH64_AARCH64_SECTION_CHUNKS_H + +#include "TargetLayout.h" + +namespace lld { +namespace elf { + +class AArch64GOTSection : public AtomSection { +public: + AArch64GOTSection(const ELFLinkingContext &ctx); + + bool hasGlobalGOTEntry(const Atom *a) const { + return _tlsMap.count(a); + } + + const AtomLayout *appendAtom(const Atom *atom) override; + +private: + /// \brief Map TLS Atoms to their GOT entry index. + llvm::DenseMap _tlsMap; +}; + +} // elf +} // lld + +#endif Index: lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.cpp =================================================================== --- /dev/null +++ lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.cpp @@ -0,0 +1,41 @@ +//===- lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.cpp --------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "AArch64SectionChunks.h" +#include "TargetLayout.h" + +namespace lld { +namespace elf { + +AArch64GOTSection::AArch64GOTSection(const ELFLinkingContext &ctx) + : AtomSection(ctx, ".got", DefinedAtom::typeGOT, DefinedAtom::permRW_, + TargetLayout::ORDER_GOT) +{ + this->_alignment = 8; +} + +const AtomLayout *AArch64GOTSection::appendAtom(const Atom *atom) { + const DefinedAtom *da = dyn_cast(atom); + + for (const auto &r : *da) { + if (r->kindNamespace() != Reference::KindNamespace::ELF) + continue; + assert(r->kindArch() == Reference::KindArch::AArch64); + switch (r->kindValue()) { + case R_AARCH64_TLS_TPREL64: + _tlsMap[r->target()] = _tlsMap.size(); + break; + } + } + + return AtomSection::appendAtom(atom); +} + +} // elf +} // lld Index: lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.h =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.h +++ lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.h @@ -17,13 +17,22 @@ namespace lld { namespace elf { + class AArch64LinkingContext; +class AArch64GOTSection; class AArch64TargetLayout final : public TargetLayout { typedef llvm::object::Elf_Shdr_Impl Elf_Shdr; public: - AArch64TargetLayout(ELFLinkingContext &ctx) : TargetLayout(ctx) {} + AArch64TargetLayout(ELFLinkingContext &ctx); // : TargetLayout(ctx) {} + + AtomSection * + createSection(StringRef name, int32_t type, + DefinedAtom::ContentPermissions permissions, + typename TargetLayout::SectionOrder order) override; + + const AArch64GOTSection &getGOTSection() const { return *_gotSection; } uint64_t getTPOffset() { std::call_once(_tpOffOnce, [this]() { @@ -44,6 +53,7 @@ }; private: + AArch64GOTSection *_gotSection; uint64_t _tpOff = 0; std::once_flag _tpOffOnce; }; Index: lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp +++ lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp @@ -12,10 +12,26 @@ #include "AArch64ExecutableWriter.h" #include "AArch64LinkingContext.h" #include "AArch64TargetHandler.h" +#include "AArch64SectionChunks.h" using namespace lld; using namespace elf; +AArch64TargetLayout::AArch64TargetLayout(ELFLinkingContext &ctx) : + TargetLayout(ctx), + _gotSection(new (this->_allocator) AArch64GOTSection(ctx)) +{ +} + +AtomSection *AArch64TargetLayout::createSection( + StringRef name, int32_t type, DefinedAtom::ContentPermissions permissions, + typename TargetLayout::SectionOrder order) { + if (type == DefinedAtom::typeGOT && name == ".got") + return _gotSection; + return TargetLayout::createSection(name, type, permissions, order); +} + + AArch64TargetHandler::AArch64TargetHandler(AArch64LinkingContext &ctx) : _ctx(ctx), _targetLayout(new AArch64TargetLayout(ctx)), _relocationHandler(new AArch64TargetRelocationHandler(*_targetLayout)) {} Index: lib/ReaderWriter/ELF/AArch64/CMakeLists.txt =================================================================== --- lib/ReaderWriter/ELF/AArch64/CMakeLists.txt +++ lib/ReaderWriter/ELF/AArch64/CMakeLists.txt @@ -3,6 +3,8 @@ AArch64TargetHandler.cpp AArch64RelocationHandler.cpp AArch64RelocationPass.cpp + AArch64ExecutableWriter.cpp + AArch64SectionChunks.cpp LINK_LIBS lldELF lldReaderWriter Index: test/elf/AArch64/Inputs/initial-exec-tls-1.yaml =================================================================== --- /dev/null +++ test/elf/AArch64/Inputs/initial-exec-tls-1.yaml @@ -0,0 +1,78 @@ +--- +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + OSABI: ELFOSABI_GNU + Type: ET_REL + Machine: EM_AARCH64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x0000000000000004 + Content: '' + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + AddressAlign: 0x0000000000000004 + Content: '' + - Name: .bss + Type: SHT_NOBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + AddressAlign: 0x0000000000000004 + Content: '' + - Name: .tbss + Type: SHT_NOBITS + Flags: [ SHF_WRITE, SHF_ALLOC, SHF_TLS ] + AddressAlign: 0x0000000000000004 + Content: 00636C616E672076657273696F6E2033 + - Name: .comment + Type: SHT_PROGBITS + Flags: [ SHF_MERGE, SHF_STRINGS ] + AddressAlign: 0x0000000000000001 + Content: 00636C616E672076657273696F6E20332E372E302028687474703A2F2F6C6C766D2E6F72672F6769742F636C616E672E6769742065653461393664373236383264353237636635353336313135366235656531383662303964363138292028687474703A2F2F6C6C766D2E6F72672F6769742F6C6C766D2E67697420623065376165623639343236646331346637376466626535343533333536366664363866396466632900 + - Name: .note.GNU-stack + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: '' +Symbols: + Local: + - Name: '$d.0' + Type: STT_TLS + Section: .tbss + - Name: '$d.1' + Section: .comment + - Name: .tbss + Type: STT_TLS + Section: .tbss + - Type: STT_SECTION + Section: .text + - Type: STT_SECTION + Section: .data + - Type: STT_SECTION + Section: .bss + - Type: STT_SECTION + Section: .comment + - Type: STT_SECTION + Section: .note.GNU-stack + Global: + - Name: e0 + Type: STT_TLS + Section: .tbss + Size: 0x0000000000000004 + - Name: e1 + Type: STT_TLS + Section: .tbss + Value: 0x0000000000000004 + Size: 0x0000000000000004 + - Name: e2 + Type: STT_TLS + Section: .tbss + Value: 0x0000000000000008 + Size: 0x0000000000000004 + - Name: e3 + Type: STT_TLS + Section: .tbss + Value: 0x000000000000000C + Size: 0x0000000000000004 +... Index: test/elf/AArch64/initial-exec-tls-0.test =================================================================== --- /dev/null +++ test/elf/AArch64/initial-exec-tls-0.test @@ -0,0 +1,148 @@ +# Check for initial executable TLS access across different modules. For +# this case compiler will emit R_AARCH64_TLSLD_ADR_PAGE21 and +# R_AARCH64_TLSLD_ADD_LO12_NC static relocations and linker should create +# a R_AARCH64_TLS_TPREL64 dynamic relocation for variable access. + +# The test case was generated from following code snippet: +# +# t1.c (initial-exec-tls-1.yaml) +# +# __thread int e0; +# __thread int e1; +# __thread int e2; +# __thread int e3; +# +# t0.c +# include +# +# extern __thread int e0; +# extern __thread int e1; +# extern __thread int e2; +# extern __thread int e3; +# +# int main () +# { +# e0 = 1; +# e1 = 2; +# e1 = 3; +# e1 = 4; +# } + +#RUN: yaml2obj -format=elf %p/Inputs/initial-exec-tls-1.yaml -o=%t-t1.o +#RUN: yaml2obj -format=elf %s -o %t-t0.o +#RUN: lld -flavor gnu -target arm64 --noinhibit-exec -o %t.exe %t-t0.o %t-t1.o +#RUN: llvm-readobj -relocations %t.exe | FileCheck %s -check-prefix=CHECKRELOCATION +#RUN: llvm-objdump -s -t %t.exe | FileCheck %s + +#CHECKRELOCATION: R_AARCH64_TLS_TPREL64 e0 0x0 +#CHECKRELOCATION: R_AARCH64_TLS_TPREL64 e1 0x0 +#CHECKRELOCATION: R_AARCH64_TLS_TPREL64 e2 0x0 +#CHECKRELOCATION: R_AARCH64_TLS_TPREL64 e3 0x0 + +#CHECK: Contents of section .text: +#CHECK-NEXT: 4002c0 ff4300d1 e8031f2a e9031e32 0a0000b0 .C.....*...2.... +# \_ adrp x10, 401000 (R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21) +#CHECK-NEXT: 4002d0 4a4940f9 4bd03bd5 ec030032 6c692ab8 JI@.K.;....2li*. +# \_ ldr x10, [x10,#144] (R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC) +#CHECK-NEXT: 4002e0 0a0000b0 4a4d40f9 ec031f32 6c692ab8 ....JM@....2li*. +# \_ | adrp x10, 401000 (R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21) +# \_ ldr x10, [x10,#152] (R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC) +#CHECK-NEXT: 4002f0 0a0000b0 4a5140f9 ec070032 6c692ab8 ....JQ@....2li*. +# \_ | adrp x10, 401000 (R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21) +# \_ ldr x10, [x10,#160] (R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC) +#CHECK-NEXT: 400300 0a0000b0 4a5540f9 ec031e32 6c692ab8 ....JU@....2li*. +# \_ | adrp x10, 401000 (R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21) +# \_ ldr x10, [x10,#168] (R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC) + +--- +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + OSABI: ELFOSABI_GNU + Type: ET_REL + Machine: EM_AARCH64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x0000000000000004 + Content: FF4300D1E8031F2AE9031E320A0000904A0140F94BD03BD5EC0300326C692AB80A0000904A0140F9EC031F326C692AB80A0000904A0140F9EC0700326C692AB80A0000904A0140F9EC031E326C692AB8E003082AE90F00B9FF430091C0035FD6 + - Name: .rela.text + Type: SHT_RELA + Link: .symtab + AddressAlign: 0x0000000000000008 + Info: .text + Relocations: + - Offset: 0x000000000000000C + Symbol: e0 + Type: R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 + - Offset: 0x0000000000000010 + Symbol: e0 + Type: R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC + - Offset: 0x0000000000000020 + Symbol: e1 + Type: R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 + - Offset: 0x0000000000000024 + Symbol: e1 + Type: R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC + - Offset: 0x0000000000000030 + Symbol: e2 + Type: R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 + - Offset: 0x0000000000000034 + Symbol: e2 + Type: R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC + - Offset: 0x0000000000000040 + Symbol: e3 + Type: R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 + - Offset: 0x0000000000000044 + Symbol: e3 + Type: R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + AddressAlign: 0x0000000000000004 + Content: '' + - Name: .bss + Type: SHT_NOBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + AddressAlign: 0x0000000000000004 + Content: '' + - Name: .comment + Type: SHT_PROGBITS + Flags: [ SHF_MERGE, SHF_STRINGS ] + AddressAlign: 0x0000000000000001 + Content: 00636C616E672076657273696F6E20332E372E302028687474703A2F2F6C6C766D2E6F72672F6769742F636C616E672E6769742065653461393664373236383264353237636635353336313135366235656531383662303964363138292028687474703A2F2F6C6C766D2E6F72672F6769742F6C6C766D2E67697420623065376165623639343236646331346637376466626535343533333536366664363866396466632900 + - Name: .note.GNU-stack + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: '' +Symbols: + Local: + - Name: '$d.1' + Section: .comment + - Name: '$x.0' + Section: .text + - Type: STT_SECTION + Section: .text + - Type: STT_SECTION + Section: .data + - Type: STT_SECTION + Section: .bss + - Type: STT_SECTION + Section: .comment + - Type: STT_SECTION + Section: .note.GNU-stack + Global: + - Name: e0 + Type: STT_TLS + - Name: e1 + Type: STT_TLS + - Name: e2 + Type: STT_TLS + - Name: e3 + Type: STT_TLS + - Name: main + Type: STT_FUNC + Section: .text + Size: 0x0000000000000060 +...