[lld] r174916 - [ELF] Add support for reading dynamic libraries.

Michael J. Spencer bigcheesegs at gmail.com
Mon Feb 11 15:03:36 PST 2013


Author: mspencer
Date: Mon Feb 11 17:03:35 2013
New Revision: 174916

URL: http://llvm.org/viewvc/llvm-project?rev=174916&view=rev
Log:
[ELF] Add support for reading dynamic libraries.

Added:
    lld/trunk/lib/ReaderWriter/ELF/CreateELF.h
    lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h
    lld/trunk/test/elf/Inputs/shared.c
    lld/trunk/test/elf/Inputs/shared.so-x86-64
    lld/trunk/test/elf/Inputs/use-shared.c
    lld/trunk/test/elf/Inputs/use-shared.x86-64
    lld/trunk/test/elf/dynamic-library.test
Modified:
    lld/trunk/include/lld/Core/File.h
    lld/trunk/include/lld/Core/LLVM.h
    lld/trunk/include/lld/Core/SharedLibraryFile.h
    lld/trunk/lib/ReaderWriter/ELF/Atoms.h
    lld/trunk/lib/ReaderWriter/ELF/File.h
    lld/trunk/lib/ReaderWriter/ELF/Reader.cpp
    lld/trunk/lib/ReaderWriter/ReaderArchive.cpp
    lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
    lld/trunk/test/CMakeLists.txt

Modified: lld/trunk/include/lld/Core/File.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/File.h?rev=174916&r1=174915&r2=174916&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/File.h (original)
+++ lld/trunk/include/lld/Core/File.h Mon Feb 11 17:03:35 2013
@@ -165,22 +165,26 @@ protected:
   class atom_collection_vector : public atom_collection<T> {
   public:
     virtual atom_iterator<T> begin() const {
-      return atom_iterator<T>(*this, reinterpret_cast<const void*>
-                                                              (_atoms.data()));
+      return atom_iterator<T>(*this,
+          _atoms.empty() ? 0 : reinterpret_cast<const void *>(_atoms.data()));
     }
+
     virtual atom_iterator<T> end() const{
-      return atom_iterator<T>(*this, reinterpret_cast<const void*>
-                                              (_atoms.data() + _atoms.size()));
+      return atom_iterator<T>(*this, _atoms.empty() ? 0 :
+          reinterpret_cast<const void *>(_atoms.data() + _atoms.size()));
     }
+
     virtual const T *deref(const void *it) const {
       return *reinterpret_cast<const T* const*>(it);
     }
+
     virtual void next(const void *&it) const {
       const T *const *p = reinterpret_cast<const T *const*>(it);
       ++p;
       it = reinterpret_cast<const void*>(p);
     }
-    std::vector<const T*> _atoms;
+
+    std::vector<const T *> _atoms;
   };
 
   /// \brief This is a convenience class for File subclasses which need to

Modified: lld/trunk/include/lld/Core/LLVM.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/LLVM.h?rev=174916&r1=174915&r2=174916&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/LLVM.h (original)
+++ lld/trunk/include/lld/Core/LLVM.h Mon Feb 11 17:03:35 2013
@@ -17,8 +17,11 @@
 
 // This should be the only #include, force #includes of all the others on
 // clients.
+#include "llvm/ADT/Hashing.h"
 #include "llvm/Support/Casting.h"
 
+#include <utility>
+
 namespace llvm {
   // ADT's.
   class StringRef;
@@ -77,4 +80,13 @@ namespace lld {
   using llvm::raw_ostream;
 } // end namespace clang.
 
+namespace std {
+template <> struct hash<llvm::StringRef> {
+public:
+  size_t operator()(const llvm::StringRef &s) const {
+    return llvm::hash_value(s);
+  }
+};
+}
+
 #endif

Modified: lld/trunk/include/lld/Core/SharedLibraryFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/SharedLibraryFile.h?rev=174916&r1=174915&r2=174916&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/SharedLibraryFile.h (original)
+++ lld/trunk/include/lld/Core/SharedLibraryFile.h Mon Feb 11 17:03:35 2013
@@ -41,15 +41,10 @@ public:
   /// If so, return a SharedLibraryAtom which represents that exported
   /// symbol.  Otherwise return nullptr.
   virtual const SharedLibraryAtom *exports(StringRef name,
-                                           bool dataSymbolOnly) const;
+                                           bool dataSymbolOnly) const = 0;
 protected:
   /// only subclasses of SharedLibraryFile can be instantiated 
-  SharedLibraryFile(const TargetInfo &ti, StringRef path)
-      : File(path), _targetInfo(ti) {
-  }
-
-private:
-  const TargetInfo &_targetInfo;
+  SharedLibraryFile(StringRef path) : File(path) {}
 };
 
 } // namespace lld

Modified: lld/trunk/lib/ReaderWriter/ELF/Atoms.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Atoms.h?rev=174916&r1=174915&r2=174916&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Atoms.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Atoms.h Mon Feb 11 17:03:35 2013
@@ -21,6 +21,7 @@
 
 namespace lld {
 namespace elf {
+template <class ELFT> class DynamicFile;
 template <typename ELFT> class ELFFile;
 template <typename ELFT> class TargetAtomHandler;
 
@@ -95,7 +96,7 @@ public:
       : _owningFile(file), _name(name), _symbol(symbol), _value(value) {
   }
 
-  virtual const class ELFFile<ELFT> &file() const {
+  virtual const ELFFile<ELFT> &file() const {
     return _owningFile;
   } virtual Scope scope() const {
     if (_symbol->st_other == llvm::ELF::STV_HIDDEN)
@@ -132,7 +133,7 @@ public:
                    const Elf_Sym *symbol)
       : _owningFile(file), _name(name), _symbol(symbol) {}
 
-  virtual const class ELFFile<ELFT> &file() const {
+  virtual const ELFFile<ELFT> &file() const {
     return _owningFile;
   }
 
@@ -187,7 +188,7 @@ public:
     _ordinal = ++orderNumber;
   }
 
-  virtual const class ELFFile<ELFT> &file() const {
+  virtual const ELFFile<ELFT> &file() const {
     return _owningFile;
   }
 
@@ -440,6 +441,49 @@ private:
   std::vector<ELFReference<ELFT>*> &
     _referenceList;
 };
+
+/// \brief An atom from a shared library.
+template <class ELFT>
+class ELFDynamicAtom LLVM_FINAL : public SharedLibraryAtom {
+  typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
+
+public:
+  ELFDynamicAtom(const DynamicFile<ELFT> &file, StringRef symbolName,
+                 StringRef loadName, const Elf_Sym *symbol)
+      : _owningFile(file), _symbolName(symbolName), _loadName(loadName),
+        _symbol(symbol) {
+  }
+
+  virtual const DynamicFile<ELFT> &file() const {
+    return _owningFile;
+  }
+
+  virtual StringRef name() const {
+    return _symbolName;
+  }
+
+  virtual Scope scope() const {
+    if (_symbol->st_other == llvm::ELF::STV_HIDDEN)
+      return scopeLinkageUnit;
+    else if (_symbol->getBinding() != llvm::ELF::STB_LOCAL)
+      return scopeGlobal;
+    else
+      return scopeTranslationUnit;
+  }
+
+  virtual StringRef loadName() const { return _loadName; }
+
+  virtual bool canBeNullAtRuntime() const {
+    return _symbol->getBinding() == llvm::ELF::STB_WEAK;
+  }
+
+private:
+
+  const DynamicFile<ELFT> &_owningFile;
+  StringRef _symbolName;
+  StringRef _loadName;
+  const Elf_Sym *_symbol;
+};
 } // end namespace elf
 } // end namespace lld
 

Added: lld/trunk/lib/ReaderWriter/ELF/CreateELF.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/CreateELF.h?rev=174916&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/CreateELF.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/CreateELF.h Mon Feb 11 17:03:35 2013
@@ -0,0 +1,109 @@
+//===- lib/ReaderWriter/ELF/CreateELF.h -----------------------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file provides a simple way to create an object templated on
+/// ELFType depending on the runtime type needed.
+///
+//===----------------------------------------------------------------------===//
+#ifndef LLD_READER_WRITER_ELF_CREATE_ELF_H
+#define LLD_READER_WRITER_ELF_CREATE_ELF_H
+
+#include "llvm/Object/ELF.h"
+#include "llvm/Support/Compiler.h"
+
+namespace {
+using llvm::object::ELFType;
+
+/// \func createELF
+/// \brief Create an object depending on the runtime attributes and alignment
+/// of an ELF file.
+///
+/// \param Traits
+/// Traits::result_type must be a type convertable from what create returns.
+/// Traits::create must be a template function which takes an ELFType and
+/// returns something convertable to Traits::result_type.
+///
+/// \param ident pair of EI_CLASS and EI_DATA.
+/// \param maxAlignment the maximum alignment of the file.
+/// \param args arguments forwarded to CreateELFTraits<T>::create.
+
+#define LLVM_CREATE_ELF_CreateELFTraits(endian, align, is64, ...) \
+  Traits::template create<ELFType<llvm::support::endian, align, is64>>( \
+      __VA_ARGS__);
+
+#if !LLVM_IS_UNALIGNED_ACCESS_FAST
+# define LLVM_CREATE_ELF_MaxAlignCheck(normal, low, endian, is64, ...) \
+  if (maxAlignment >= normal) \
+    return LLVM_CREATE_ELF_CreateELFTraits(endian, normal, is64, __VA_ARGS__) \
+  else if (maxAlignment >= low) \
+    return LLVM_CREATE_ELF_CreateELFTraits(endian, low, is64, __VA_ARGS__) \
+  else \
+    llvm_unreachable("Invalid alignment for ELF file!");
+#else
+# define LLVM_CREATE_ELF_MaxAlignCheck(normal, low, endian, is64, ...) \
+  if (maxAlignment >= low) \
+    return LLVM_CREATE_ELF_CreateELFTraits(endian, low, is64, __VA_ARGS__) \
+  else \
+    llvm_unreachable("Invalid alignment for ELF file!");
+#endif
+
+#define LLVM_CREATE_ELF_IMPL(...) \
+    if (ident.first == llvm::ELF::ELFCLASS32 && \
+        ident.second == llvm::ELF::ELFDATA2LSB) { \
+      LLVM_CREATE_ELF_MaxAlignCheck(4, 2, little, false, __VA_ARGS__) \
+    } else if (ident.first == llvm::ELF::ELFCLASS32 && \
+               ident.second == llvm::ELF::ELFDATA2MSB) { \
+      LLVM_CREATE_ELF_MaxAlignCheck(4, 2, big, false, __VA_ARGS__) \
+    } else if (ident.first == llvm::ELF::ELFCLASS64 && \
+               ident.second == llvm::ELF::ELFDATA2MSB) { \
+      LLVM_CREATE_ELF_MaxAlignCheck(8, 2, big, true, __VA_ARGS__) \
+    } else if (ident.first == llvm::ELF::ELFCLASS64 && \
+               ident.second == llvm::ELF::ELFDATA2LSB) { \
+      LLVM_CREATE_ELF_MaxAlignCheck(8, 2, little, true, __VA_ARGS__) \
+    } \
+    llvm_unreachable("Invalid ELF type!");
+
+#if LLVM_HAS_VARIADIC_TEMPLATES
+template <class Traits, class ...Args>
+typename Traits::result_type createELF(
+    std::pair<unsigned char, unsigned char> ident, std::size_t maxAlignment,
+    Args &&...args) {
+  LLVM_CREATE_ELF_IMPL(std::forward<Args>(args)...)
+}
+#else
+template <class Traits, class T1>
+typename Traits::result_type createELF(
+    std::pair<unsigned char, unsigned char> ident, std::size_t maxAlignment,
+    T1 &&t1) {
+  LLVM_CREATE_ELF_IMPL(std::forward<T1>(t1))
+}
+
+template <class Traits, class T1, class T2>
+typename Traits::result_type createELF(
+    std::pair<unsigned char, unsigned char> ident, std::size_t maxAlignment,
+    T1 &&t1, T2 &&t2) {
+  LLVM_CREATE_ELF_IMPL(std::forward<T1>(t1), std::forward<T2>(t2))
+}
+
+template <class Traits, class T1, class T2, class T3>
+typename Traits::result_type createELF(
+    std::pair<unsigned char, unsigned char> ident, std::size_t maxAlignment,
+    T1 &&t1, T2 &&t2, T3 &&t3) {
+  LLVM_CREATE_ELF_IMPL(std::forward<T1>(t1), std::forward<T2>(t2),
+                       std::forward<T3>(t3))
+}
+#endif // LLVM_HAS_VARIADIC_TEMPLATES
+} // end anon namespace
+
+#undef LLVM_CREATE_ELF_CreateELFTraits
+#undef LLVM_CREATE_ELF_MaxAlignCheck
+#undef LLVM_CREATE_ELF_IMPL
+
+#endif

Added: lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h?rev=174916&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h Mon Feb 11 17:03:35 2013
@@ -0,0 +1,132 @@
+//===- lib/ReaderWriter/ELF/DynamicFile.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_DYNAMIC_FILE_H
+#define LLD_READER_WRITER_ELF_DYNAMIC_FILE_H
+
+#include "lld/Core/SharedLibraryFile.h"
+#include "lld/ReaderWriter/ELFTargetInfo.h"
+
+#include "llvm/Object/ELF.h"
+#include "llvm/Support/Path.h"
+
+#include <unordered_map>
+
+namespace lld {
+namespace elf {
+template <class ELFT> class DynamicFile LLVM_FINAL : public SharedLibraryFile {
+public:
+  static ErrorOr<std::unique_ptr<DynamicFile> > create(
+      const ELFTargetInfo &ti, std::unique_ptr<llvm::MemoryBuffer> mb) {
+    std::unique_ptr<DynamicFile> file(
+        new DynamicFile(ti, mb->getBufferIdentifier()));
+
+    static uint32_t lastOrdinal = 0;
+    file->_ordinal = lastOrdinal++;
+
+    llvm::OwningPtr<llvm::object::Binary> binaryFile;
+    if (error_code ec = createBinary(mb.release(), binaryFile))
+      return ec;
+
+    // Point Obj to correct class and bitwidth ELF object
+    file->_objFile.reset(
+        dyn_cast<llvm::object::ELFObjectFile<ELFT>>(binaryFile.get()));
+
+    if (!file->_objFile)
+      return make_error_code(llvm::object::object_error::invalid_file_type);
+
+    binaryFile.take();
+
+    llvm::object::ELFObjectFile<ELFT> &obj = *file->_objFile;
+
+    file->_soname = obj.getLoadName();
+    if (file->_soname.empty())
+      file->_soname = llvm::sys::path::filename(file->path());
+
+    // Create a map from names to dynamic symbol table entries.
+    // TODO: This should use the object file's build in hash table instead if
+    // it exists.
+    for (auto i = obj.begin_elf_dynamic_symbols(),
+              e = obj.end_elf_dynamic_symbols();
+         i != e; ++i) {
+      // Don't expose undefined or absolute symbols to export.
+      if (i->st_shndx == llvm::ELF::SHN_ABS ||
+          i->st_shndx == llvm::ELF::SHN_UNDEF)
+        continue;
+      StringRef name;
+      if (error_code ec =
+              obj.getSymbolName(obj.getDynamicSymbolTableSectionHeader(), &*i,
+                                name))
+        return ec;
+      file->_nameToSym[name]._symbol = &*i;
+
+      // TODO: Read undefined dynamic symbols into _undefinedAtoms.
+    }
+
+    return std::move(file);
+  }
+
+  virtual const atom_collection<DefinedAtom> &defined() const {
+    return _definedAtoms;
+  }
+
+  virtual const atom_collection<UndefinedAtom> &undefined() const {
+    return _undefinedAtoms;
+  }
+
+  virtual const atom_collection<SharedLibraryAtom> &sharedLibrary() const {
+    return _sharedLibraryAtoms;
+  }
+
+  virtual const atom_collection<AbsoluteAtom> &absolute() const {
+    return _absoluteAtoms;
+  }
+
+  virtual const SharedLibraryAtom *exports(StringRef name,
+                                           bool dataSymbolOnly) const {
+    assert(!dataSymbolOnly && "Invalid option for ELF exports!");
+    // See if we have the symbol.
+    auto sym = _nameToSym.find(name);
+    if (sym == _nameToSym.end())
+      return nullptr;
+    // Have we already created a SharedLibraryAtom for it?
+    if (sym->second._atom)
+      return sym->second._atom;
+    // Create a SharedLibraryAtom for this symbol.
+    return sym->second._atom = new (_alloc) ELFDynamicAtom<ELFT>(
+        *this, name, _soname, sym->second._symbol);
+  }
+
+  virtual const ELFTargetInfo &getTargetInfo() const { return _targetInfo; }
+
+private:
+  DynamicFile(const ELFTargetInfo &ti, StringRef name)
+      : SharedLibraryFile(name), _targetInfo(ti) {}
+
+  const ELFTargetInfo &_targetInfo;
+  std::unique_ptr<llvm::object::ELFObjectFile<ELFT>> _objFile;
+  atom_collection_vector<DefinedAtom> _definedAtoms;
+  atom_collection_vector<UndefinedAtom> _undefinedAtoms;
+  atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
+  atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
+  /// \brief DT_SONAME
+  StringRef _soname;
+
+  struct SymAtomPair {
+    const typename llvm::object::ELFObjectFile<ELFT>::Elf_Sym *_symbol;
+    const SharedLibraryAtom *_atom;
+  };
+
+  mutable std::unordered_map<StringRef, SymAtomPair> _nameToSym;
+  mutable llvm::BumpPtrAllocator _alloc;
+};
+} // end namespace elf
+} // end namespace lld
+
+#endif

Modified: lld/trunk/lib/ReaderWriter/ELF/File.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/File.h?rev=174916&r1=174915&r2=174916&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/File.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/File.h Mon Feb 11 17:03:35 2013
@@ -38,16 +38,6 @@
 #include <map>
 #include <unordered_map>
 
-namespace std {
-template <> struct hash<llvm::StringRef> {
-public:
-  size_t operator()(const llvm::StringRef &s) const {
-    using llvm::hash_value;
-    return hash_value(s);
-  }
-};
-}
-
 namespace lld {
 namespace elf {
 /// \brief Read a binary, find out based on the symbol table contents what kind

Modified: lld/trunk/lib/ReaderWriter/ELF/Reader.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Reader.cpp?rev=174916&r1=174915&r2=174916&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Reader.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Reader.cpp Mon Feb 11 17:03:35 2013
@@ -16,6 +16,8 @@
 #include "lld/ReaderWriter/Reader.h"
 
 #include "Atoms.h"
+#include "CreateELF.h"
+#include "DynamicFile.h"
 #include "File.h"
 
 #include "lld/Core/Reference.h"
@@ -46,6 +48,30 @@
 using llvm::support::endianness;
 using namespace llvm::object;
 
+namespace {
+struct DynamicFileCreateELFTraits {
+  typedef llvm::ErrorOr<std::unique_ptr<lld::SharedLibraryFile>> result_type;
+
+  template <class ELFT>
+  static result_type create(const lld::ELFTargetInfo &ti,
+                            std::unique_ptr<llvm::MemoryBuffer> mb) {
+    return lld::elf::DynamicFile<ELFT>::create(ti, std::move(mb));
+  }
+};
+
+struct ELFFileCreateELFTraits {
+  typedef std::unique_ptr<lld::File> result_type;
+
+  template <class ELFT>
+  static result_type create(const lld::ELFTargetInfo &ti,
+                            std::unique_ptr<llvm::MemoryBuffer> mb,
+                            lld::error_code &ec) {
+    return std::unique_ptr<lld::File>(
+        new lld::elf::ELFFile<ELFT>(ti, std::move(mb), ec));
+  }
+};
+}
+
 namespace lld {
 namespace elf {
 /// \brief A reader object that will instantiate correct File by examining the
@@ -69,66 +95,20 @@ public:
     llvm::error_code ec;
     switch (fileType) {
     case llvm::sys::ELF_Relocatable_FileType: {
-      std::pair<unsigned char, unsigned char> Ident = getElfArchType(&*mb);
-      std::unique_ptr<File> f;
-      // Instantiate the correct File template instance based on the Ident
-      // pair. Once the File is created we push the file to the vector of files
-      // already created during parser's life.
-      if (Ident.first == llvm::ELF::ELFCLASS32 &&
-          Ident.second == llvm::ELF::ELFDATA2LSB) {
-#if !LLVM_IS_UNALIGNED_ACCESS_FAST
-        if (MaxAlignment >= 4)
-          f.reset(new ELFFile<ELFType<llvm::support::little, 4, false> >(
-                          _elfTargetInfo, std::move(mb), ec));
-        else
-#endif
-        if (MaxAlignment >= 2)
-          f.reset(new ELFFile<ELFType<llvm::support::little, 2, false> >(
-                          _elfTargetInfo, std::move(mb), ec));
-        else
-          llvm_unreachable("Invalid alignment for ELF file!");
-      } else if (Ident.first == llvm::ELF::ELFCLASS32 &&
-                 Ident.second == llvm::ELF::ELFDATA2MSB) {
-#if !LLVM_IS_UNALIGNED_ACCESS_FAST
-        if (MaxAlignment >= 4)
-          f.reset(new ELFFile<ELFType<llvm::support::big, 4, false> >(
-                          _elfTargetInfo, std::move(mb), ec));
-        else
-#endif
-        if (MaxAlignment >= 2)
-          f.reset(new ELFFile<ELFType<llvm::support::big, 2, false> >(
-                          _elfTargetInfo, std::move(mb), ec));
-        else
-          llvm_unreachable("Invalid alignment for ELF file!");
-      } else if (Ident.first == llvm::ELF::ELFCLASS64 &&
-                 Ident.second == llvm::ELF::ELFDATA2MSB) {
-#if !LLVM_IS_UNALIGNED_ACCESS_FAST
-        if (MaxAlignment >= 8)
-          f.reset(new ELFFile<ELFType<llvm::support::big, 8, true> >(
-                          _elfTargetInfo, std::move(mb), ec));
-        else
-#endif
-        if (MaxAlignment >= 2)
-          f.reset(new ELFFile<ELFType<llvm::support::big, 2, true> >(
-                          _elfTargetInfo, std::move(mb), ec));
-        else
-          llvm_unreachable("Invalid alignment for ELF file!");
-      } else if (Ident.first == llvm::ELF::ELFCLASS64 &&
-                 Ident.second == llvm::ELF::ELFDATA2LSB) {
-#if !LLVM_IS_UNALIGNED_ACCESS_FAST
-        if (MaxAlignment >= 8)
-          f.reset(new ELFFile<ELFType<llvm::support::little, 8, true> >(
-                          _elfTargetInfo, std::move(mb), ec));
-        else
-#endif
-        if (MaxAlignment >= 2)
-          f.reset(new ELFFile<ELFType<llvm::support::little, 2, true> >(
-                          _elfTargetInfo, std::move(mb), ec));
-        else
-          llvm_unreachable("Invalid alignment for ELF file!");
-      }
-      if (!ec)
-        result.push_back(std::move(f));
+      std::unique_ptr<File> f(createELF<ELFFileCreateELFTraits>(
+          getElfArchType(&*mb), MaxAlignment, _elfTargetInfo, std::move(mb),
+          ec));
+      if (ec)
+        return ec;
+      result.push_back(std::move(f));
+      break;
+    }
+    case llvm::sys::ELF_SharedObject_FileType: {
+      auto f = createELF<DynamicFileCreateELFTraits>(
+          getElfArchType(&*mb), MaxAlignment, _elfTargetInfo, std::move(mb));
+      if (!f)
+        return f;
+      result.push_back(std::move(*f));
       break;
     }
     case llvm::sys::Archive_FileType:

Modified: lld/trunk/lib/ReaderWriter/ReaderArchive.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ReaderArchive.cpp?rev=174916&r1=174915&r2=174916&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ReaderArchive.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ReaderArchive.cpp Mon Feb 11 17:03:35 2013
@@ -17,17 +17,6 @@
 
 #include <unordered_map>
 
-namespace std {
-  template<>
-  struct hash<llvm::StringRef> {
-  public:
-    size_t operator()(const llvm::StringRef &s) const {
-      using llvm::hash_value;
-      return hash_value(s);
-    }
-  };
-}
-
 namespace lld {
 /// \brief The FileArchive class represents an Archive Library file
 class FileArchive : public ArchiveLibraryFile {

Modified: lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp?rev=174916&r1=174915&r2=174916&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp (original)
+++ lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp Mon Feb 11 17:03:35 2013
@@ -220,13 +220,15 @@ private:
 template <typename T>
 class AtomList : public lld::File::atom_collection<T> {
 public:
-  virtual lld::File::atom_iterator<T> begin() const { 
-    return lld::File::atom_iterator<T>(*this, reinterpret_cast<const void*>
-                                                            (_atoms.data()));
+  virtual lld::File::atom_iterator<T> begin() const {
+    return lld::File::atom_iterator<
+        T>(*this,
+           _atoms.empty() ? 0 : reinterpret_cast<const void *>(_atoms.data()));
   }
-  virtual lld::File::atom_iterator<T> end() const{ 
-    return lld::File::atom_iterator<T>(*this, reinterpret_cast<const void*>
-                                            (_atoms.data() + _atoms.size()));
+  virtual lld::File::atom_iterator<T> end() const{
+    return lld::File::atom_iterator<
+        T>(*this, _atoms.empty() ? 0 :
+               reinterpret_cast<const void *>(_atoms.data() + _atoms.size()));
   }
   virtual const T *deref(const void *it) const {
     return *reinterpret_cast<const T *const*>(it);

Modified: lld/trunk/test/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/CMakeLists.txt?rev=174916&r1=174915&r2=174916&view=diff
==============================================================================
--- lld/trunk/test/CMakeLists.txt (original)
+++ lld/trunk/test/CMakeLists.txt Mon Feb 11 17:03:35 2013
@@ -20,7 +20,7 @@ if ( NOT LLD_BUILT_STANDALONE )
   set(LLD_TEST_DEPS
     lld-core lld-test.deps
     FileCheck not llvm-nm
-    lld llvm-objdump
+    lld llvm-objdump llvm-readobj
     )
   set(LLD_TEST_PARAMS
     lld_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg

Added: lld/trunk/test/elf/Inputs/shared.c
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Inputs/shared.c?rev=174916&view=auto
==============================================================================
--- lld/trunk/test/elf/Inputs/shared.c (added)
+++ lld/trunk/test/elf/Inputs/shared.c Mon Feb 11 17:03:35 2013
@@ -0,0 +1,5 @@
+#include <stdio.h>
+
+void foo() {
+  puts("Fooo!!");
+}

Added: lld/trunk/test/elf/Inputs/shared.so-x86-64
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Inputs/shared.so-x86-64?rev=174916&view=auto
==============================================================================
Binary files lld/trunk/test/elf/Inputs/shared.so-x86-64 (added) and lld/trunk/test/elf/Inputs/shared.so-x86-64 Mon Feb 11 17:03:35 2013 differ

Added: lld/trunk/test/elf/Inputs/use-shared.c
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Inputs/use-shared.c?rev=174916&view=auto
==============================================================================
--- lld/trunk/test/elf/Inputs/use-shared.c (added)
+++ lld/trunk/test/elf/Inputs/use-shared.c Mon Feb 11 17:03:35 2013
@@ -0,0 +1,5 @@
+void foo();
+
+int main() {
+  foo();
+}

Added: lld/trunk/test/elf/Inputs/use-shared.x86-64
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Inputs/use-shared.x86-64?rev=174916&view=auto
==============================================================================
Binary files lld/trunk/test/elf/Inputs/use-shared.x86-64 (added) and lld/trunk/test/elf/Inputs/use-shared.x86-64 Mon Feb 11 17:03:35 2013 differ

Added: lld/trunk/test/elf/dynamic-library.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/dynamic-library.test?rev=174916&view=auto
==============================================================================
--- lld/trunk/test/elf/dynamic-library.test (added)
+++ lld/trunk/test/elf/dynamic-library.test Mon Feb 11 17:03:35 2013
@@ -0,0 +1,7 @@
+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: | FileCheck %s
+
+CHECK: shared-library-atoms:
+CHECK: name: foo
+CHECK: load-name: shared.so-x86-64





More information about the llvm-commits mailing list