[lld] r176294 - [ELF][x86-64] Separate static and dynamic GOT/PLT generation.

Michael J. Spencer bigcheesegs at gmail.com
Thu Feb 28 12:04:33 PST 2013


Author: mspencer
Date: Thu Feb 28 14:04:32 2013
New Revision: 176294

URL: http://llvm.org/viewvc/llvm-project?rev=176294&view=rev
Log:
[ELF][x86-64] Separate static and dynamic GOT/PLT generation.

Added:
    lld/trunk/test/elf/dynamic.test
    lld/trunk/test/elf/x86-64-dynamic.test
Removed:
    lld/trunk/test/elf/dynamic-hash.test
    lld/trunk/test/elf/dynamic-interp.test
    lld/trunk/test/elf/dynamic-library.test
    lld/trunk/test/elf/dynamic-phdr.test
    lld/trunk/test/elf/dynamic-symbols.test
    lld/trunk/test/elf/dynamic-table.test
Modified:
    lld/trunk/include/lld/ReaderWriter/Simple.h
    lld/trunk/lib/ReaderWriter/ELF/Atoms.h
    lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp
    lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h
    lld/trunk/test/elf/gotpcrel.test
    lld/trunk/test/elf/ifunc.test
    lld/trunk/test/elf/tls.test

Modified: lld/trunk/include/lld/ReaderWriter/Simple.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/Simple.h?rev=176294&r1=176293&r2=176294&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/Simple.h (original)
+++ lld/trunk/include/lld/ReaderWriter/Simple.h Thu Feb 28 14:04:32 2013
@@ -164,9 +164,11 @@ public:
     _references.push_back(SimpleReference(kind, offset, target, addend));
   }
 
+  void setOrdinal(uint64_t ord) { _ordinal = ord; }
+
 private:
   const File &_file;
-  uint32_t _ordinal;
+  uint64_t _ordinal;
   std::vector<SimpleReference> _references;
 };
 

Modified: lld/trunk/lib/ReaderWriter/ELF/Atoms.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Atoms.h?rev=176294&r1=176293&r2=176294&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Atoms.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Atoms.h Thu Feb 28 14:04:32 2013
@@ -184,10 +184,7 @@ public:
     , _referenceStartIndex(referenceStart)
     , _referenceEndIndex(referenceEnd)
     , _referenceList(referenceList)
-    , _targetAtomHandler(nullptr) {
-    static uint64_t orderNumber = 0;
-    _ordinal = ++orderNumber;
-  }
+    , _targetAtomHandler(nullptr) {}
 
   virtual const ELFFile<ELFT> &file() const {
     return _owningFile;
@@ -480,8 +477,9 @@ public:
     _referenceEndIndex = _referenceList.size();
   }
 
-private:
+  void setOrdinal(uint64_t ord) { _ordinal = ord; }
 
+private:
   const ELFFile<ELFT> &_owningFile;
   StringRef _symbolName;
   StringRef _sectionName;

Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp?rev=176294&r1=176293&r2=176294&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp Thu Feb 28 14:04:32 2013
@@ -98,7 +98,8 @@ ErrorOr<void> X86_64TargetRelocationHand
       *reinterpret_cast<llvm::support::little64_t *>(location) = result;
     }
     break;
-  case R_X86_64_TLSLD:
+  }
+  case R_X86_64_TLSLD: {
     // Rewrite to move %fs:0 into %rax. Technically we should verify that the
     // next relocation is a PC32 to __tls_get_addr...
     static uint8_t instr[] = { 0x66, 0x66, 0x66, 0x64, 0x48, 0x8b, 0x04, 0x25,
@@ -106,9 +107,25 @@ ErrorOr<void> X86_64TargetRelocationHand
     std::memcpy(location - 3, instr, sizeof(instr));
     break;
   }
+  case LLD_R_X86_64_GOTRELINDEX: {
+    const DefinedAtom *target = cast<const DefinedAtom>(ref.target());
+    for (const Reference *r : *target) {
+      if (r->kind() == R_X86_64_JUMP_SLOT) {
+        uint32_t index;
+        if (!_targetInfo.getTargetHandler<X86_64ELFType>().targetLayout()
+                .getPLTRelocationTable()->getRelocationIndex(*r, index))
+          llvm_unreachable("Relocation doesn't exist");
+        reloc32(location, 0, index, 0);
+        break;
+      }
+    }
+    break;
+  }
   // Runtime only relocations. Ignore here.
   case R_X86_64_RELATIVE:
   case R_X86_64_IRELATIVE:
+  case R_X86_64_JUMP_SLOT:
+  case R_X86_64_GLOB_DAT:
     break;
 
   case lld::Reference::kindLayoutAfter:
@@ -142,7 +159,7 @@ public:
 
   virtual SectionChoice sectionChoice() const { return sectionCustomRequired; }
 
-  virtual StringRef customSectionName() const { return ".got"; }
+  virtual StringRef customSectionName() const { return ".got.plt"; }
 
   virtual ContentType contentType() const { return typeGOT; }
 

Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp?rev=176294&r1=176293&r2=176294&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp Thu Feb 28 14:04:32 2013
@@ -19,6 +19,7 @@
 #include "llvm/ADT/StringSwitch.h"
 
 using namespace lld;
+using namespace lld::elf;
 
 namespace {
 using namespace llvm::ELF;
@@ -90,8 +91,7 @@ public:
   }
 
   virtual Alignment alignment() const {
-    // The alignment should be 4 byte aligned
-    return Alignment(2);
+    return Alignment(4); // 16
   }
 
 #ifndef NDEBUG
@@ -105,10 +105,31 @@ public:
 
 const uint8_t PLTAtom::_defaultContent[16] = {
   0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmpq *gotatom(%rip)
-  0x68, 0x00, 0x00, 0x00, 0x00,       // pushq pltentry
+  0x68, 0x00, 0x00, 0x00, 0x00,       // pushq reloc-index
   0xe9, 0x00, 0x00, 0x00, 0x00        // jmpq plt[-1]
 };
 
+class PLT0Atom : public PLTAtom {
+  static const uint8_t _plt0Content[16];
+
+public:
+  PLT0Atom(const File &f) : PLTAtom(f, ".plt") {
+#ifndef NDEBUG
+    _name = ".PLT0";
+#endif
+  }
+
+  virtual ArrayRef<uint8_t> rawContent() const {
+    return ArrayRef<uint8_t>(_plt0Content, 16);
+  }
+};
+
+const uint8_t PLT0Atom::_plt0Content[16] = {
+  0xff, 0x35, 0x00, 0x00, 0x00, 0x00, // pushq GOT+8(%rip)
+  0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp *GOT+16(%rip)
+  0x90, 0x90, 0x90, 0x90        // nopnopnop
+};
+
 class ELFPassFile : public SimpleFile {
 public:
   ELFPassFile(const ELFTargetInfo &eti) : SimpleFile(eti, "ELFPassFile") {}
@@ -121,16 +142,15 @@ public:
 template <class Derived> class GOTPLTPass : public Pass {
   /// \brief Handle a specific reference.
   void handleReference(const DefinedAtom &atom, const Reference &ref) {
-    const DefinedAtom *da = dyn_cast_or_null<const DefinedAtom>(ref.target());
     switch (ref.kind()) {
     case R_X86_64_PLT32:
       static_cast<Derived *>(this)->handlePLT32(ref);
       break;
     case R_X86_64_PC32:
-      static_cast<Derived *>(this)->handleIFUNC(ref, da);
+      static_cast<Derived *>(this)->handlePC32(ref);
       break;
     case R_X86_64_GOTTPOFF: // GOT Thread Pointer Offset
-      static_cast<Derived *>(this)->handleGOTTPOFF(ref, da);
+      static_cast<Derived *>(this)->handleGOTTPOFF(ref);
       break;
     case R_X86_64_GOTPCREL:
       static_cast<Derived *>(this)->handleGOTPCREL(ref);
@@ -165,7 +185,8 @@ protected:
   ///
   /// This create a PLT and GOT entry for the IFUNC if one does not exist. The
   /// GOT entry and a IRELATIVE relocation to the original target resolver.
-  ErrorOr<void> handleIFUNC(const Reference &ref, const DefinedAtom *target) {
+  ErrorOr<void> handleIFUNC(const Reference &ref) {
+    auto target = dyn_cast_or_null<const DefinedAtom>(ref.target());
     if (target && target->contentType() == DefinedAtom::typeResolver)
       const_cast<Reference &>(ref).setTarget(getIFUNCPLTEntry(target));
     return error_code::success();
@@ -189,7 +210,8 @@ protected:
 
   /// \brief Create a TPOFF64 GOT entry and change the relocation to a PC32 to
   /// the GOT.
-  void handleGOTTPOFF(const Reference &ref, const DefinedAtom *target) {
+  void handleGOTTPOFF(const Reference &ref) {
+    auto target = dyn_cast_or_null<const DefinedAtom>(ref.target());
     const_cast<Reference &>(ref).setTarget(getGOTTPOFF(target));
     const_cast<Reference &>(ref).setKind(R_X86_64_PC32);
   }
@@ -197,7 +219,7 @@ protected:
   /// \brief Create a GOT entry containing 0.
   const GOTAtom *getNullGOT() {
     if (!_null) {
-      _null = new (_file._alloc) GOTAtom(_file, ".got");
+      _null = new (_file._alloc) GOTAtom(_file, ".got.plt");
 #ifndef NDEBUG
       _null->_name = "__got_null";
 #endif
@@ -231,7 +253,9 @@ protected:
   }
 
 public:
-  GOTPLTPass(const ELFTargetInfo &ti) : _file(ti), _null(nullptr) {}
+  GOTPLTPass(const ELFTargetInfo &ti)
+      : _file(ti), _null(nullptr), _PLT0(nullptr), _got0(nullptr),
+        _got1(nullptr) {}
 
   /// \brief Do the pass.
   ///
@@ -248,23 +272,51 @@ public:
         handleReference(*atom, *ref);
 
     // Add all created atoms to the link.
-    if (_null)
+    uint64_t ordinal = 0;
+    if (_PLT0) {
+      _PLT0->setOrdinal(ordinal++);
+      mf.addAtom(*_PLT0);
+    }
+    for (const auto &plt : _pltMap) {
+      plt.second->setOrdinal(ordinal++);
+      mf.addAtom(*plt.second);
+    }
+    if (_null) {
+      _null->setOrdinal(ordinal++);
       mf.addAtom(*_null);
-    for (const auto &got : _gotMap)
+    }
+    if (_PLT0) {
+      _got0->setOrdinal(ordinal++);
+      _got1->setOrdinal(ordinal++);
+      mf.addAtom(*_got0);
+      mf.addAtom(*_got1);
+    }
+    for (const auto &got : _gotMap) {
+      got.second->setOrdinal(ordinal++);
       mf.addAtom(*got.second);
-    for (const auto &plt : _pltMap)
-      mf.addAtom(*plt.second);
+    }
   }
 
 protected:
   /// \brief Owner of all the Atoms created by this pass.
   ELFPassFile _file;
+  
   /// \brief Map Atoms to their GOT entries.
-  llvm::DenseMap<const Atom *, const GOTAtom *> _gotMap;
+  llvm::DenseMap<const Atom *, GOTAtom *> _gotMap;
+
   /// \brief Map Atoms to their PLT entries.
-  llvm::DenseMap<const Atom *, const PLTAtom *> _pltMap;
+  llvm::DenseMap<const Atom *, PLTAtom *> _pltMap;
+
   /// \brief GOT entry that is always 0. Used for undefined weaks.
   GOTAtom *_null;
+
+  /// \brief The got and plt entries for .PLT0. This is used to call into the
+  /// dynamic linker for symbol resolution.
+  /// @{
+  PLT0Atom *_PLT0;
+  GOTAtom *_got0;
+  GOTAtom *_got1;
+  /// @}
 };
 
 /// This implements the static relocation model. Meaning GOT and PLT entries are
@@ -288,23 +340,47 @@ public:
     // Handle IFUNC.
     if (const DefinedAtom *da = dyn_cast_or_null<const DefinedAtom>(ref.target()))
       if (da->contentType() == DefinedAtom::typeResolver)
-        return handleIFUNC(ref, da);
+        return handleIFUNC(ref);
     return error_code::success();
   }
+
+  ErrorOr<void> handlePC32(const Reference &ref) { return handleIFUNC(ref); }
 };
 
 class DynamicGOTPLTPass LLVM_FINAL : public GOTPLTPass<DynamicGOTPLTPass> {
 public:
   DynamicGOTPLTPass(const elf::X86_64TargetInfo &ti) : GOTPLTPass(ti) {}
 
+  const PLT0Atom *getPLT0() {
+    if (_PLT0)
+      return _PLT0;
+    // Fill in the null entry.
+    getNullGOT();
+    _PLT0 = new (_file._alloc) PLT0Atom(_file);
+    _got0 = new (_file._alloc) GOTAtom(_file, ".got.plt");
+    _got1 = new (_file._alloc) GOTAtom(_file, ".got.plt");
+    _PLT0->addReference(R_X86_64_PC32, 2, _got0, -4);
+    _PLT0->addReference(R_X86_64_PC32, 8, _got1, -4);
+#ifndef NDEBUG
+    _got0->_name = "__got0";
+    _got1->_name = "__got1";
+#endif
+    return _PLT0;
+  }
+
   const PLTAtom *getPLTEntry(const Atom *a) {
     auto plt = _pltMap.find(a);
     if (plt != _pltMap.end())
       return plt->second;
     auto ga = new (_file._alloc) GOTAtom(_file, ".got.plt");
-    ga->addReference(R_X86_64_RELATIVE, 0, a, 0);
+    ga->addReference(R_X86_64_JUMP_SLOT, 0, a, 0);
     auto pa = new (_file._alloc) PLTAtom(_file, ".plt");
     pa->addReference(R_X86_64_PC32, 2, ga, -4);
+    pa->addReference(LLD_R_X86_64_GOTRELINDEX, 7, ga, 0);
+    pa->addReference(R_X86_64_PC32, 12, getPLT0(), -4);
+    // Set the starting address of the got entry to the second instruction in
+    // the plt entry.
+    ga->addReference(R_X86_64_64, 0, pa, 6);
 #ifndef NDEBUG
     ga->_name = "__got_";
     ga->_name += a->name();
@@ -322,10 +398,16 @@ public:
     // Handle IFUNC.
     if (const DefinedAtom *da = dyn_cast_or_null<const DefinedAtom>(ref.target()))
       if (da->contentType() == DefinedAtom::typeResolver)
-        return handleIFUNC(ref, da);
+        return handleIFUNC(ref);
     const_cast<Reference &>(ref).setTarget(getPLTEntry(ref.target()));
     return error_code::success();
   }
+
+  ErrorOr<void> handlePC32(const Reference &ref) {
+    if (ref.target() && isa<SharedLibraryAtom>(ref.target()))
+      return handlePLT32(ref);
+    return handleIFUNC(ref);
+  }
 };
 } // end anon namespace
 
@@ -335,6 +417,7 @@ void elf::X86_64TargetInfo::addPasses(Pa
   else if (_options._outputKind == OutputKind::DynamicExecutable ||
            _options._outputKind == OutputKind::Shared)
     pm.add(std::unique_ptr<Pass>(new DynamicGOTPLTPass(*this)));
+  ELFTargetInfo::addPasses(pm);
 }
 
 #define LLD_CASE(name) .Case(#name, llvm::ELF::name)
@@ -380,6 +463,7 @@ ErrorOr<int32_t> elf::X86_64TargetInfo::
     LLD_CASE(R_X86_64_TLSDESC_CALL)
     LLD_CASE(R_X86_64_TLSDESC)
     LLD_CASE(R_X86_64_IRELATIVE)
+    .Case("LLD_R_X86_64_GOTRELINDEX", LLD_R_X86_64_GOTRELINDEX)
     .Default(-1);
 
   if (ret == -1)
@@ -432,6 +516,8 @@ ErrorOr<std::string> elf::X86_64TargetIn
   LLD_CASE(R_X86_64_TLSDESC_CALL)
   LLD_CASE(R_X86_64_TLSDESC)
   LLD_CASE(R_X86_64_IRELATIVE)
+  case LLD_R_X86_64_GOTRELINDEX:
+    return std::string("LLD_R_X86_64_GOTRELINDEX");
   }
 
   return make_error_code(yaml_reader_error::illegal_value);

Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h?rev=176294&r1=176293&r2=176294&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h Thu Feb 28 14:04:32 2013
@@ -20,6 +20,12 @@
 
 namespace lld {
 namespace elf {
+/// \brief x86-64 internal references.
+enum {
+  /// \brief The 32 bit index of the relocation in the got this reference refers
+  /// to.
+  LLD_R_X86_64_GOTRELINDEX = 1024,
+};
 
 class X86_64TargetInfo LLVM_FINAL : public ELFTargetInfo {
 public:
@@ -38,9 +44,26 @@ public:
     return _options._baseAddress;
   }
 
-  virtual bool isRuntimeRelocation(const DefinedAtom &,
+  virtual bool isDynamicRelocation(const DefinedAtom &,
                                    const Reference &r) const {
-    return r.kind() == llvm::ELF::R_X86_64_IRELATIVE;
+    switch (r.kind()){
+    case llvm::ELF::R_X86_64_RELATIVE:
+    case llvm::ELF::R_X86_64_GLOB_DAT:
+      return true;
+    default:
+      return false;
+    }
+  }
+
+  virtual bool isPLTRelocation(const DefinedAtom &,
+                               const Reference &r) const {
+    switch (r.kind()){
+    case llvm::ELF::R_X86_64_JUMP_SLOT:
+    case llvm::ELF::R_X86_64_IRELATIVE:
+      return true;
+    default:
+      return false;
+    }
   }
 
   virtual ErrorOr<int32_t> relocKindFromString(StringRef str) const;

Removed: lld/trunk/test/elf/dynamic-hash.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/dynamic-hash.test?rev=176293&view=auto
==============================================================================
--- lld/trunk/test/elf/dynamic-hash.test (original)
+++ lld/trunk/test/elf/dynamic-hash.test (removed)
@@ -1,7 +0,0 @@
-RUN: lld -core -target x86_64-linux %p/Inputs/use-shared.x86-64 \
-RUN:   %p/Inputs/shared.so-x86-64 -output=%t -entry=main \
-RUN:   -output-type=dynamic
-RUN: llvm-readobj %t | FileCheck %s
-
-CHECK: Sections:
-CHECK:   .hash {{[0-9a-f]+}} 8 4 required,rodata

Removed: lld/trunk/test/elf/dynamic-interp.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/dynamic-interp.test?rev=176293&view=auto
==============================================================================
--- lld/trunk/test/elf/dynamic-interp.test (original)
+++ lld/trunk/test/elf/dynamic-interp.test (removed)
@@ -1,8 +0,0 @@
-RUN: lld -core -target x86_64-linux %p/Inputs/use-shared.x86-64 \
-RUN:   %p/Inputs/shared.so-x86-64 -output=%t -entry=main \
-RUN:   -output-type=dynamic
-RUN: llvm-objdump -p %t | FileCheck %s
-
-CHECK: INTERP
-CHECK: flags r--
-CHECK: off

Removed: lld/trunk/test/elf/dynamic-library.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/dynamic-library.test?rev=176293&view=auto
==============================================================================
--- lld/trunk/test/elf/dynamic-library.test (original)
+++ lld/trunk/test/elf/dynamic-library.test (removed)
@@ -1,18 +0,0 @@
-RUN: lld -core -target x86_64-linux %p/Inputs/use-shared.x86-64 \
-RUN:   %p/Inputs/shared.so-x86-64 -emit-yaml -output=- -noinhibit-exec \
-RUN:   -output-type=dynamic \
-RUN: | FileCheck %s
-
-CHECK: name: main
-CHECK: kind: R_X86_64_PC32
-CHECK: target: [[PLTNAME:[-a-zA-Z0-9_]+]]
-
-CHECK: type: got
-CHECK: R_X86_64_RELATIVE
-
-CHECK: name: [[PLTNAME]]
-CHECK: type: stub
-
-CHECK: shared-library-atoms:
-CHECK: name: foo
-CHECK: load-name: shared.so-x86-64

Removed: lld/trunk/test/elf/dynamic-phdr.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/dynamic-phdr.test?rev=176293&view=auto
==============================================================================
--- lld/trunk/test/elf/dynamic-phdr.test (original)
+++ lld/trunk/test/elf/dynamic-phdr.test (removed)
@@ -1,7 +0,0 @@
-RUN: lld -core -target x86_64-linux %p/Inputs/use-shared.x86-64 \
-RUN:   %p/Inputs/shared.so-x86-64 -output=%t -entry=main \
-RUN:   -output-type=dynamic
-RUN: llvm-objdump -p %t | FileCheck %s
-
-CHECK: PHDR off 0x{{0+}}40
-CHECK: flags r--

Removed: lld/trunk/test/elf/dynamic-symbols.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/dynamic-symbols.test?rev=176293&view=auto
==============================================================================
--- lld/trunk/test/elf/dynamic-symbols.test (original)
+++ lld/trunk/test/elf/dynamic-symbols.test (removed)
@@ -1,8 +0,0 @@
-RUN: lld -core -target x86_64-linux %p/Inputs/use-shared.x86-64 \
-RUN:   %p/Inputs/shared.so-x86-64 -output=%t -entry=main \
-RUN:   -output-type=dynamic
-RUN: llvm-readobj %t | FileCheck %s
-
-CHECK: Dynamic Symbols:
-CHECK:   foo FUNC {{[0-9a-f]+}} 0 {{[0-9a-f]+}} undef,global
-CHECK:   Total: 1

Removed: lld/trunk/test/elf/dynamic-table.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/dynamic-table.test?rev=176293&view=auto
==============================================================================
--- lld/trunk/test/elf/dynamic-table.test (original)
+++ lld/trunk/test/elf/dynamic-table.test (removed)
@@ -1,15 +0,0 @@
-RUN: lld -core -target x86_64-linux %p/Inputs/use-shared.x86-64 \
-RUN:   %p/Inputs/shared.so-x86-64 -output=%t -entry=main \
-RUN:   -output-type=dynamic
-RUN: llvm-readobj %t | FileCheck %s
-
-CHECK: Dynamic section contains 7 entries
-CHECK:   Tag                Type                 Name/Value
-CHECK:  0x0000000000000004 (HASH)
-CHECK:  0x0000000000000005 (STRTAB)
-CHECK:  0x0000000000000006 (SYMTAB)
-CHECK:  0x000000000000000a (STRSZ)
-CHECK:  0x000000000000000b (SYMENT) 24
-CHECK:  0x0000000000000001 (NEEDED) Shared library: [shared.so-x86-64]
-CHECK:  0x0000000000000000 (NULL)               0x0
-CHECK:   Total: 7

Added: lld/trunk/test/elf/dynamic.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/dynamic.test?rev=176294&view=auto
==============================================================================
--- lld/trunk/test/elf/dynamic.test (added)
+++ lld/trunk/test/elf/dynamic.test Thu Feb 28 14:04:32 2013
@@ -0,0 +1,49 @@
+RUN: lld -core -target x86_64-linux %p/Inputs/use-shared.x86-64 \
+RUN:   %p/Inputs/shared.so-x86-64 -output=%t -entry=main \
+RUN:   -output-type=dynamic
+RUN: lld -core -target x86_64-linux %p/Inputs/use-shared.x86-64 \
+RUN:   %p/Inputs/shared.so-x86-64 -emit-yaml -output=%t2 -noinhibit-exec \
+RUN:   -output-type=dynamic
+RUN: llvm-objdump -p %t >> %t2
+RUN: llvm-readobj %t >> %t2
+RUN: FileCheck %s < %t2
+
+CHECK: type: got
+CHECK: R_X86_64_JUMP_SLOT
+
+CHECK: name: main
+CHECK: kind: R_X86_64_PC32
+CHECK: target: [[PLTNAME:[-a-zA-Z0-9_]+]]
+
+CHECK: name: [[PLTNAME]]
+CHECK: type: stub
+
+CHECK: shared-library-atoms:
+CHECK: name: foo
+CHECK: load-name: shared.so-x86-64
+
+CHECK: PHDR off 0x{{0+}}40
+CHECK: INTERP
+CHECK: flags r--
+
+CHECK: Dynamic Symbols:
+CHECK:   foo FUNC {{[0-9a-f]+}} 0 {{[0-9a-f]+}} undef,global
+CHECK:   Total: 1
+
+CHECK: Sections:
+CHECK:   .hash {{[0-9a-f]+}} 8 4 required,rodata
+
+CHECK: Dynamic section contains 11 entries
+CHECK:   Tag                Type                 Name/Value
+CHECK:  0x0000000000000004 (HASH)
+CHECK:  0x0000000000000005 (STRTAB)
+CHECK:  0x0000000000000006 (SYMTAB)
+CHECK:  0x000000000000000a (STRSZ)
+CHECK:  0x000000000000000b (SYMENT) 24
+CHECK:  0x0000000000000002 (PLTRELSZ) 24
+CHECK:  0x0000000000000003 (PLTGOT)
+CHECK:  0x0000000000000014 (PLTREL) RELA
+CHECK:  0x0000000000000017 (JMPREL)
+CHECK:  0x0000000000000001 (NEEDED) Shared library: [shared.so-x86-64]
+CHECK:  0x0000000000000000 (NULL)               0x0
+CHECK:   Total: 11

Modified: lld/trunk/test/elf/gotpcrel.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/gotpcrel.test?rev=176294&r1=176293&r2=176294&view=diff
==============================================================================
--- lld/trunk/test/elf/gotpcrel.test (original)
+++ lld/trunk/test/elf/gotpcrel.test Thu Feb 28 14:04:32 2013
@@ -2,16 +2,16 @@ RUN: lld -core -target x86_64-linux -out
 RUN:   %p/Inputs/gotpcrel.x86-64 -emit-yaml -noinhibit-exec \
 RUN: | FileCheck %s -check-prefix=YAML
 
-YAML: name: main
-YAML: kind: R_X86_64_PC32
-YAML: target: [[NULLGOT:[a-zA-Z0-9_]+]]
-YAML: kind: R_X86_64_PC32
-YAML: target: [[MAINGOT:[a-zA-Z0-9_]+]]
-
-YAML: name: [[NULLGOT]]
+YAML: name: [[NULLGOT:[a-zA-Z0-9_]+]]
 YAML: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ]
 YAML-NOT: references:
 
-YAML: name: [[MAINGOT]]
+YAML: name: [[MAINGOT:[a-zA-Z0-9_]+]]
 YAML: kind: R_X86_64_64
 YAML: target: main
+
+YAML: name: main
+YAML: kind: R_X86_64_PC32
+YAML: target: [[NULLGOT]]
+YAML: kind: R_X86_64_PC32
+YAML: target: [[MAINGOT]]

Modified: lld/trunk/test/elf/ifunc.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/ifunc.test?rev=176294&r1=176293&r2=176294&view=diff
==============================================================================
--- lld/trunk/test/elf/ifunc.test (original)
+++ lld/trunk/test/elf/ifunc.test Thu Feb 28 14:04:32 2013
@@ -9,9 +9,10 @@ RUN: lld -core -target x86_64-linux -out
 RUN:   -entry=main -output-type=static %p/Inputs/ifunc.cpp.x86-64 \
 RUN: && llvm-objdump -d -s %t| FileCheck %s --check-prefix=BIN
 
-CHECK: name: hey
-CHECK: scope: global
-CHECK: type: resolver
+// Make sure there's a got entry with a IRELATIVE relocation.
+PLT: type: got
+PLT: kind: R_X86_64_IRELATIVE
+PLT: target: hey
 
 PLT: name: plt
 PLT: scope: global
@@ -24,9 +25,9 @@ PLT: references
 PLT: kind: R_X86_64_PC32
 PLT: target: [[PLTNAME]]
 
-// Make sure there's a got entry with a IRELATIVE relocation.
-PLT: type: got
-PLT: kind: R_X86_64_IRELATIVE
+CHECK: name: hey
+CHECK: scope: global
+CHECK: type: resolver
 
 // Make sure the target of main's relocation is a stub with a PC32 relocation.
 // This relocation is to the got atom, but you can't really write that check in
@@ -36,8 +37,6 @@ PLT: type: stub
 PLT: references
 PLT: kind: R_X86_64_PC32
 
-// This is a horribly brittle test. We need a way to do arithmetic on captured
-// variables.
-BIN: 4000ec: ff 25 0e 0f 00 00 jmpq *3854(%rip)
+BIN: {{[0-9a-f]+}}: ff 25 {{[0-9a-f]+}} {{[0-9a-f]+}} 00 00 jmpq *{{[0-9]+}}(%rip)
 BIN: .got.plt:
-BIN-NEXT: 401000 00000000 00000000
+BIN-NEXT: {{[0-9a-f]+}} 00000000 00000000

Modified: lld/trunk/test/elf/tls.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/tls.test?rev=176294&r1=176293&r2=176294&view=diff
==============================================================================
--- lld/trunk/test/elf/tls.test (original)
+++ lld/trunk/test/elf/tls.test Thu Feb 28 14:04:32 2013
@@ -8,6 +8,10 @@ RUN: | FileCheck %s
 
 // Verify that the TLS accesses have the correct offsets.
 
+YAML: type: got
+YAML: kind: R_X86_64_TPOFF64
+YAML: target: tls2
+
 YAML: name: main
 YAML: kind: R_X86_64_TPOFF32
 YAML: offset: 9
@@ -23,11 +27,6 @@ YAML: name: GOTTPOFF
 YAML: kind: R_X86_64_PC32
 YAML: target: [[GOTNAME:[a-zA-Z0-9_]+]]
 
-YAML: name: [[GOTNAME]]
-YAML: type: got
-YAML: kind: R_X86_64_TPOFF64
-YAML: target: tls2
-
 // main
 CHECK: addl %fs:-4
 CHECK: addl %fs:-8

Added: lld/trunk/test/elf/x86-64-dynamic.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/x86-64-dynamic.test?rev=176294&view=auto
==============================================================================
--- lld/trunk/test/elf/x86-64-dynamic.test (added)
+++ lld/trunk/test/elf/x86-64-dynamic.test Thu Feb 28 14:04:32 2013
@@ -0,0 +1,90 @@
+RUN: lld -core -target x86_64-linux %p/Inputs/use-shared.x86-64 \
+RUN:   %p/Inputs/shared.so-x86-64 -emit-yaml -output=- -noinhibit-exec \
+RUN:   -output-type=dynamic | FileCheck %s
+
+// Don't check the GOT and PLT names as they are only present in assert builds.
+
+        - name:            __got_null
+CHECK:    type:            got
+CHECK:    content:         [ 00, 00, 00, 00, 00, 00, 00, 00 ]
+CHECK:    alignment:       2^3
+CHECK:    section-choice:  custom-required
+CHECK:    section-name:    .got.plt
+CHECK:    permissions:     rw-
+        - name:            __got0
+CHECK:    type:            got
+CHECK:    content:         [ 00, 00, 00, 00, 00, 00, 00, 00 ]
+CHECK:    alignment:       2^3
+CHECK:    section-choice:  custom-required
+CHECK:    section-name:    .got.plt
+CHECK:    permissions:     rw-
+        - name:            __got1
+CHECK:    type:            got
+CHECK:    content:         [ 00, 00, 00, 00, 00, 00, 00, 00 ]
+CHECK:    alignment:       2^3
+CHECK:    section-choice:  custom-required
+CHECK:    section-name:    .got.plt
+CHECK:    permissions:     rw-
+        - name:            __got_foo
+CHECK:    type:            got
+CHECK:    content:         [ 00, 00, 00, 00, 00, 00, 00, 00 ]
+CHECK:    alignment:       2^3
+CHECK:    section-choice:  custom-required
+CHECK:    section-name:    .got.plt
+CHECK:    permissions:     rw-
+CHECK:    references:
+CHECK:      - kind:            R_X86_64_JUMP_SLOT
+CHECK:        offset:          0
+CHECK:        target:          foo
+CHECK:      - kind:            R_X86_64_64
+CHECK:        offset:          0
+              target:          __plt_foo
+CHECK:        addend:          6
+
+CHECK:  - name:            main
+CHECK:    scope:           global
+CHECK:    references:
+CHECK:      - kind:            R_X86_64_PC32
+CHECK:        offset:          7
+              target:          __plt_foo
+CHECK:        addend:          -4
+
+        - name:            .PLT0
+CHECK:    type:            stub
+CHECK:    content:         [ FF, 35, 00, 00, 00, 00, FF, 25, 00, 00, 00, 00,
+CHECK:                       90, 90, 90, 90 ]
+CHECK:    alignment:       2^4
+CHECK:    section-choice:  custom-required
+CHECK:    section-name:    .plt
+CHECK:    references:
+CHECK:      - kind:            R_X86_64_PC32
+CHECK:        offset:          2
+              target:          __got0
+CHECK:        addend:          -4
+CHECK:      - kind:            R_X86_64_PC32
+CHECK:        offset:          8
+              target:          __got1
+CHECK:        addend:          -4
+        - name:            __plt_foo
+CHECK:    type:            stub
+CHECK:    content:         [ FF, 25, 00, 00, 00, 00, 68, 00, 00, 00, 00, E9,
+CHECK:                       00, 00, 00, 00 ]
+CHECK:    alignment:       2^4
+CHECK:    section-choice:  custom-required
+CHECK:    section-name:    .plt
+CHECK:    references:
+CHECK:      - kind:            R_X86_64_PC32
+CHECK:        offset:          2
+              target:          __got_foo
+CHECK:        addend:          -4
+CHECK:      - kind:            LLD_R_X86_64_GOTRELINDEX
+CHECK:        offset:          7
+              target:          __got_foo
+CHECK:      - kind:            R_X86_64_PC32
+CHECK:        offset:          12
+              target:          .PLT0
+CHECK:        addend:          -4
+
+CHECK:shared-library-atoms:
+CHECK:  - name:            foo
+CHECK:    load-name:       shared.so-x86-64





More information about the llvm-commits mailing list