diff options
author | Adhemerval Zanella <azanella@linux.vnet.ibm.com> | 2015-06-03 21:44:03 +0000 |
---|---|---|
committer | Adhemerval Zanella <azanella@linux.vnet.ibm.com> | 2015-06-03 21:44:03 +0000 |
commit | 9f0c63bfdfe849095ff8c673f7b6bdb993144fa5 (patch) | |
tree | 9706f86935509d2c500fb227bf62e4fcf8d6195e | |
parent | 8c52a9b0f611e4daa09c00e0da15b44b9528dbe5 (diff) | |
download | bcm5719-llvm-9f0c63bfdfe849095ff8c673f7b6bdb993144fa5.tar.gz bcm5719-llvm-9f0c63bfdfe849095ff8c673f7b6bdb993144fa5.zip |
[ELF/AArch64] Fix TLS initial executable relocation
This patch fixes the TLS initial executable for AArch64. Current
implementation have two issues: 1. does not generate dynamic
R_AARCH64_TLS_TPREL64 relocation for the external module symbols,
and 2. does not export the TLS initial executable symbol in dynamic
symbol table.
The fix follows the MIPS strategy to add a arch-specific GOTSection
class to keep track of TLS symbols required to be place in dynamic
symbol table. It also overrides the buildDynamicSymbolTable for
ExecutableWrite class to add the symbols.
It also adds some refactoring on AArch64RelocationPass.cpp based on ARM
backend.
llvm-svn: 238981
11 files changed, 418 insertions, 36 deletions
diff --git a/lld/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.cpp b/lld/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.cpp new file mode 100644 index 00000000000..ba4259479a8 --- /dev/null +++ b/lld/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.cpp @@ -0,0 +1,50 @@ +//===- 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<std::unique_ptr<File>> &result) { + ExecutableWriter::createImplicitFiles(result); + auto gotFile = llvm::make_unique<SimpleFile>("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<AtomSection<ELF64LE>>(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<ELF64LE>::buildDynamicSymbolTable(file); +} + +} // namespace elf +} // namespace lld + diff --git a/lld/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.h b/lld/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.h index c3d9ed24e25..eef825040ff 100644 --- a/lld/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.h +++ b/lld/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<ELF64LE> { public: AArch64ExecutableWriter(AArch64LinkingContext &ctx, - TargetLayout<ELF64LE> &layout); + AArch64TargetLayout &layout); protected: // Add any runtime files and their atoms to the output void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override; -}; -AArch64ExecutableWriter::AArch64ExecutableWriter(AArch64LinkingContext &ctx, - TargetLayout<ELF64LE> &layout) - : ExecutableWriter(ctx, layout) {} - -void AArch64ExecutableWriter::createImplicitFiles( - std::vector<std::unique_ptr<File>> &result) { - ExecutableWriter::createImplicitFiles(result); - auto gotFile = llvm::make_unique<SimpleFile>("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 diff --git a/lld/lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp b/lld/lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp index b80bc21976a..5c425d0dc65 100644 --- a/lld/lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp +++ b/lld/lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp @@ -433,6 +433,7 @@ std::error_code AArch64TargetRelocationHandler::applyRelocation( 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); diff --git a/lld/lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp b/lld/lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp index 03a3ce1fc05..2614a03dfbf 100644 --- a/lld/lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp +++ b/lld/lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp @@ -56,11 +56,20 @@ namespace { /// \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<uint8_t> rawContent() const override { return ArrayRef<uint8_t>(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 @@ public: class AArch64PLTAtom : public PLTAtom { public: - AArch64PLTAtom(const File &f, StringRef secName) : PLTAtom(f, secName) {} + AArch64PLTAtom(const File &f) : PLTAtom(f, ".plt") {} ArrayRef<uint8_t> rawContent() const override { return ArrayRef<uint8_t>(AArch64PltAtomContent, 16); @@ -138,9 +147,11 @@ template <class Derived> class AArch64RelocationPass : public Pass { break; case R_AARCH64_ADR_GOT_PAGE: case R_AARCH64_LD64_GOT_LO12_NC: + static_cast<Derived *>(this)->handleGOT(ref); + break; case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: - static_cast<Derived *>(this)->handleGOT(ref); + static_cast<Derived *>(this)->handleGOTTPREL(ref); break; } } @@ -153,9 +164,9 @@ protected: 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 @@ protected: } /// \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 @@ protected: 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<Reference &>(ref).setTarget(getGOTTPOFF(ref.target())); - const_cast<Reference &>(ref).setKindValue(R_AARCH64_PREL32); + std::error_code handleGOTTPREL(const Reference &ref) { + if (isa<DefinedAtom>(ref.target())) { + const_cast<Reference &>(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 @@ protected: 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 @@ public: // 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 @@ public: 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 @@ public: 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_"; diff --git a/lld/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.cpp b/lld/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.cpp new file mode 100644 index 00000000000..ee8a8110d6f --- /dev/null +++ b/lld/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.cpp @@ -0,0 +1,38 @@ +//===- 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<ELF64LE>(ctx, ".got", DefinedAtom::typeGOT, DefinedAtom::permRW_, + TargetLayout<ELF64LE>::ORDER_GOT) +{ + this->_alignment = 8; +} + +const AtomLayout *AArch64GOTSection::appendAtom(const Atom *atom) { + const DefinedAtom *da = dyn_cast<DefinedAtom>(atom); + + for (const auto &r : *da) { + if (r->kindNamespace() != Reference::KindNamespace::ELF) + continue; + assert(r->kindArch() == Reference::KindArch::AArch64); + if (r->kindValue() == R_AARCH64_TLS_TPREL64) + _tlsMap[r->target()] = _tlsMap.size(); + } + + return AtomSection<ELF64LE>::appendAtom(atom); +} + +} // elf +} // lld diff --git a/lld/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.h b/lld/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.h new file mode 100644 index 00000000000..84533dd7c93 --- /dev/null +++ b/lld/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.h @@ -0,0 +1,36 @@ +//===- 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<ELF64LE> { +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<const Atom *, std::size_t> _tlsMap; +}; + +} // elf +} // lld + +#endif diff --git a/lld/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp b/lld/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp index 1d8b7add115..fa83cf9ecc4 100644 --- a/lld/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp +++ b/lld/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp @@ -12,10 +12,24 @@ #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<ELF64LE> *AArch64TargetLayout::createSection( + StringRef name, int32_t type, DefinedAtom::ContentPermissions permissions, + typename TargetLayout<ELF64LE>::SectionOrder order) { + if (type == DefinedAtom::typeGOT && name == ".got") + return _gotSection; + return TargetLayout<ELF64LE>::createSection(name, type, permissions, order); +} + + AArch64TargetHandler::AArch64TargetHandler(AArch64LinkingContext &ctx) : _ctx(ctx), _targetLayout(new AArch64TargetLayout(ctx)), _relocationHandler(new AArch64TargetRelocationHandler(*_targetLayout)) {} diff --git a/lld/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.h b/lld/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.h index aac46171660..6f077e6a5ee 100644 --- a/lld/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.h +++ b/lld/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.h @@ -17,13 +17,22 @@ namespace lld { namespace elf { + class AArch64LinkingContext; +class AArch64GOTSection; class AArch64TargetLayout final : public TargetLayout<ELF64LE> { typedef llvm::object::Elf_Shdr_Impl<ELF64LE> Elf_Shdr; public: - AArch64TargetLayout(ELFLinkingContext &ctx) : TargetLayout(ctx) {} + AArch64TargetLayout(ELFLinkingContext &ctx); + + AtomSection<ELF64LE> * + createSection(StringRef name, int32_t type, + DefinedAtom::ContentPermissions permissions, + typename TargetLayout<ELF64LE>::SectionOrder order) override; + + const AArch64GOTSection &getGOTSection() const { return *_gotSection; } uint64_t getTPOffset() { std::call_once(_tpOffOnce, [this]() { @@ -44,6 +53,7 @@ private: }; private: + AArch64GOTSection *_gotSection; uint64_t _tpOff = 0; std::once_flag _tpOffOnce; }; diff --git a/lld/lib/ReaderWriter/ELF/AArch64/CMakeLists.txt b/lld/lib/ReaderWriter/ELF/AArch64/CMakeLists.txt index de94a4df507..2347dda9adb 100644 --- a/lld/lib/ReaderWriter/ELF/AArch64/CMakeLists.txt +++ b/lld/lib/ReaderWriter/ELF/AArch64/CMakeLists.txt @@ -3,6 +3,8 @@ add_llvm_library(lldAArch64ELFTarget AArch64TargetHandler.cpp AArch64RelocationHandler.cpp AArch64RelocationPass.cpp + AArch64ExecutableWriter.cpp + AArch64SectionChunks.cpp LINK_LIBS lldELF lldReaderWriter diff --git a/lld/test/elf/AArch64/Inputs/initial-exec-tls-1.yaml b/lld/test/elf/AArch64/Inputs/initial-exec-tls-1.yaml new file mode 100644 index 00000000000..564292bedad --- /dev/null +++ b/lld/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 +... diff --git a/lld/test/elf/AArch64/initial-exec-tls-0.test b/lld/test/elf/AArch64/initial-exec-tls-0.test new file mode 100644 index 00000000000..d4da2f9b112 --- /dev/null +++ b/lld/test/elf/AArch64/initial-exec-tls-0.test @@ -0,0 +1,147 @@ +# 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 (initial-exec-tls-0.test) +# +# 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 +... |