[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