--- /dev/null
+//===- 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
+
#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
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);
/// \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 {
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);
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;
}
}
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_";
}
/// \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();
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
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_";
// 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);
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);
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_";
--- /dev/null
+//===- 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
--- /dev/null
+//===- 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
#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)) {}
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]() {
};
private:
+ AArch64GOTSection *_gotSection;
uint64_t _tpOff = 0;
std::once_flag _tpOffOnce;
};
AArch64TargetHandler.cpp
AArch64RelocationHandler.cpp
AArch64RelocationPass.cpp
+ AArch64ExecutableWriter.cpp
+ AArch64SectionChunks.cpp
LINK_LIBS
lldELF
lldReaderWriter
--- /dev/null
+---
+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
+...
--- /dev/null
+# 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
+...