[lld] r238981 - [ELF/AArch64] Fix TLS initial executable relocation

Adhemerval Zanella azanella at linux.vnet.ibm.com
Wed Jun 3 14:44:04 PDT 2015


Author: azanella
Date: Wed Jun  3 16:44:03 2015
New Revision: 238981

URL: http://llvm.org/viewvc/llvm-project?rev=238981&view=rev
Log:
[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.

Added:
    lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.cpp
    lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.cpp
    lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.h
    lld/trunk/test/elf/AArch64/Inputs/initial-exec-tls-1.yaml
    lld/trunk/test/elf/AArch64/initial-exec-tls-0.test
Modified:
    lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.h
    lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp
    lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.h
    lld/trunk/lib/ReaderWriter/ELF/AArch64/CMakeLists.txt

Added: lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.cpp?rev=238981&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.cpp (added)
+++ lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.cpp Wed Jun  3 16:44:03 2015
@@ -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
+

Modified: lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.h?rev=238981&r1=238980&r2=238981&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.h Wed Jun  3 16:44:03 2015
@@ -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

Modified: lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp?rev=238981&r1=238980&r2=238981&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp Wed Jun  3 16:44:03 2015
@@ -433,6 +433,7 @@ std::error_code AArch64TargetRelocationH
   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);

Modified: lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp?rev=238981&r1=238980&r2=238981&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp Wed Jun  3 16:44:03 2015
@@ -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 AArch64Re
       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_";

Added: lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.cpp?rev=238981&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.cpp (added)
+++ lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.cpp Wed Jun  3 16:44:03 2015
@@ -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

Added: lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.h?rev=238981&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.h Wed Jun  3 16:44:03 2015
@@ -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

Modified: lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp?rev=238981&r1=238980&r2=238981&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp Wed Jun  3 16:44:03 2015
@@ -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)) {}

Modified: lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.h?rev=238981&r1=238980&r2=238981&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.h Wed Jun  3 16:44:03 2015
@@ -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;
 };

Modified: lld/trunk/lib/ReaderWriter/ELF/AArch64/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/AArch64/CMakeLists.txt?rev=238981&r1=238980&r2=238981&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/AArch64/CMakeLists.txt (original)
+++ lld/trunk/lib/ReaderWriter/ELF/AArch64/CMakeLists.txt Wed Jun  3 16:44:03 2015
@@ -3,6 +3,8 @@ add_llvm_library(lldAArch64ELFTarget
   AArch64TargetHandler.cpp
   AArch64RelocationHandler.cpp
   AArch64RelocationPass.cpp
+  AArch64ExecutableWriter.cpp
+  AArch64SectionChunks.cpp
   LINK_LIBS
     lldELF
     lldReaderWriter

Added: lld/trunk/test/elf/AArch64/Inputs/initial-exec-tls-1.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/AArch64/Inputs/initial-exec-tls-1.yaml?rev=238981&view=auto
==============================================================================
--- lld/trunk/test/elf/AArch64/Inputs/initial-exec-tls-1.yaml (added)
+++ lld/trunk/test/elf/AArch64/Inputs/initial-exec-tls-1.yaml Wed Jun  3 16:44:03 2015
@@ -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
+...

Added: lld/trunk/test/elf/AArch64/initial-exec-tls-0.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/AArch64/initial-exec-tls-0.test?rev=238981&view=auto
==============================================================================
--- lld/trunk/test/elf/AArch64/initial-exec-tls-0.test (added)
+++ lld/trunk/test/elf/AArch64/initial-exec-tls-0.test Wed Jun  3 16:44:03 2015
@@ -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 at .K.;....2li*.
+#                   \_                                   ldr     x10, [x10,#144]  (R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC)
+#CHECK-NEXT: 4002e0 0a0000b0 4a4d40f9 ec031f32 6c692ab8  ....JM at ....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 at ....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 at ....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
+...





More information about the llvm-commits mailing list