From c3c8bc1e5cc644c6f7bb2d4f9dc0d12b1ae082a0 Mon Sep 17 00:00:00 2001 From: "Michael J. Spencer" Date: Mon, 11 Feb 2013 23:03:35 +0000 Subject: [PATCH] [ELF] Add support for reading dynamic libraries. llvm-svn: 174916 --- lld/include/lld/Core/File.h | 14 ++- lld/include/lld/Core/LLVM.h | 12 +++ lld/include/lld/Core/SharedLibraryFile.h | 9 +- lld/lib/ReaderWriter/ELF/Atoms.h | 50 +++++++++- lld/lib/ReaderWriter/ELF/CreateELF.h | 109 ++++++++++++++++++++ lld/lib/ReaderWriter/ELF/DynamicFile.h | 132 +++++++++++++++++++++++++ lld/lib/ReaderWriter/ELF/File.h | 10 -- lld/lib/ReaderWriter/ELF/Reader.cpp | 100 ++++++++----------- lld/lib/ReaderWriter/ReaderArchive.cpp | 11 --- lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp | 14 +-- lld/test/CMakeLists.txt | 2 +- lld/test/elf/Inputs/shared.c | 5 + lld/test/elf/Inputs/shared.so-x86-64 | Bin 0 -> 8125 bytes lld/test/elf/Inputs/use-shared.c | 5 + lld/test/elf/Inputs/use-shared.x86-64 | Bin 0 -> 1264 bytes lld/test/elf/dynamic-library.test | 7 ++ 16 files changed, 377 insertions(+), 103 deletions(-) create mode 100644 lld/lib/ReaderWriter/ELF/CreateELF.h create mode 100644 lld/lib/ReaderWriter/ELF/DynamicFile.h create mode 100644 lld/test/elf/Inputs/shared.c create mode 100644 lld/test/elf/Inputs/shared.so-x86-64 create mode 100644 lld/test/elf/Inputs/use-shared.c create mode 100644 lld/test/elf/Inputs/use-shared.x86-64 create mode 100644 lld/test/elf/dynamic-library.test diff --git a/lld/include/lld/Core/File.h b/lld/include/lld/Core/File.h index 4242c20..109a824 100644 --- a/lld/include/lld/Core/File.h +++ b/lld/include/lld/Core/File.h @@ -165,22 +165,26 @@ protected: class atom_collection_vector : public atom_collection { public: virtual atom_iterator begin() const { - return atom_iterator(*this, reinterpret_cast - (_atoms.data())); + return atom_iterator(*this, + _atoms.empty() ? 0 : reinterpret_cast(_atoms.data())); } + virtual atom_iterator end() const{ - return atom_iterator(*this, reinterpret_cast - (_atoms.data() + _atoms.size())); + return atom_iterator(*this, _atoms.empty() ? 0 : + reinterpret_cast(_atoms.data() + _atoms.size())); } + virtual const T *deref(const void *it) const { return *reinterpret_cast(it); } + virtual void next(const void *&it) const { const T *const *p = reinterpret_cast(it); ++p; it = reinterpret_cast(p); } - std::vector _atoms; + + std::vector _atoms; }; /// \brief This is a convenience class for File subclasses which need to diff --git a/lld/include/lld/Core/LLVM.h b/lld/include/lld/Core/LLVM.h index eb80914..7f7a652 100644 --- a/lld/include/lld/Core/LLVM.h +++ b/lld/include/lld/Core/LLVM.h @@ -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 + namespace llvm { // ADT's. class StringRef; @@ -77,4 +80,13 @@ namespace lld { using llvm::raw_ostream; } // end namespace clang. +namespace std { +template <> struct hash { +public: + size_t operator()(const llvm::StringRef &s) const { + return llvm::hash_value(s); + } +}; +} + #endif diff --git a/lld/include/lld/Core/SharedLibraryFile.h b/lld/include/lld/Core/SharedLibraryFile.h index 0303363..730fbea 100644 --- a/lld/include/lld/Core/SharedLibraryFile.h +++ b/lld/include/lld/Core/SharedLibraryFile.h @@ -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 diff --git a/lld/lib/ReaderWriter/ELF/Atoms.h b/lld/lib/ReaderWriter/ELF/Atoms.h index fd85806..9cff16b 100644 --- a/lld/lib/ReaderWriter/ELF/Atoms.h +++ b/lld/lib/ReaderWriter/ELF/Atoms.h @@ -21,6 +21,7 @@ namespace lld { namespace elf { +template class DynamicFile; template class ELFFile; template class TargetAtomHandler; @@ -95,7 +96,7 @@ public: : _owningFile(file), _name(name), _symbol(symbol), _value(value) { } - virtual const class ELFFile &file() const { + virtual const ELFFile &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 &file() const { + virtual const ELFFile &file() const { return _owningFile; } @@ -187,7 +188,7 @@ public: _ordinal = ++orderNumber; } - virtual const class ELFFile &file() const { + virtual const ELFFile &file() const { return _owningFile; } @@ -440,6 +441,49 @@ private: std::vector*> & _referenceList; }; + +/// \brief An atom from a shared library. +template +class ELFDynamicAtom LLVM_FINAL : public SharedLibraryAtom { + typedef llvm::object::Elf_Sym_Impl Elf_Sym; + +public: + ELFDynamicAtom(const DynamicFile &file, StringRef symbolName, + StringRef loadName, const Elf_Sym *symbol) + : _owningFile(file), _symbolName(symbolName), _loadName(loadName), + _symbol(symbol) { + } + + virtual const DynamicFile &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 &_owningFile; + StringRef _symbolName; + StringRef _loadName; + const Elf_Sym *_symbol; +}; } // end namespace elf } // end namespace lld diff --git a/lld/lib/ReaderWriter/ELF/CreateELF.h b/lld/lib/ReaderWriter/ELF/CreateELF.h new file mode 100644 index 0000000..8a29976 --- /dev/null +++ b/lld/lib/ReaderWriter/ELF/CreateELF.h @@ -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::create. + +#define LLVM_CREATE_ELF_CreateELFTraits(endian, align, is64, ...) \ + Traits::template create>( \ + __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 +typename Traits::result_type createELF( + std::pair ident, std::size_t maxAlignment, + Args &&...args) { + LLVM_CREATE_ELF_IMPL(std::forward(args)...) +} +#else +template +typename Traits::result_type createELF( + std::pair ident, std::size_t maxAlignment, + T1 &&t1) { + LLVM_CREATE_ELF_IMPL(std::forward(t1)) +} + +template +typename Traits::result_type createELF( + std::pair ident, std::size_t maxAlignment, + T1 &&t1, T2 &&t2) { + LLVM_CREATE_ELF_IMPL(std::forward(t1), std::forward(t2)) +} + +template +typename Traits::result_type createELF( + std::pair ident, std::size_t maxAlignment, + T1 &&t1, T2 &&t2, T3 &&t3) { + LLVM_CREATE_ELF_IMPL(std::forward(t1), std::forward(t2), + std::forward(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 diff --git a/lld/lib/ReaderWriter/ELF/DynamicFile.h b/lld/lib/ReaderWriter/ELF/DynamicFile.h new file mode 100644 index 0000000..2e80745 --- /dev/null +++ b/lld/lib/ReaderWriter/ELF/DynamicFile.h @@ -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 + +namespace lld { +namespace elf { +template class DynamicFile LLVM_FINAL : public SharedLibraryFile { +public: + static ErrorOr > create( + const ELFTargetInfo &ti, std::unique_ptr mb) { + std::unique_ptr file( + new DynamicFile(ti, mb->getBufferIdentifier())); + + static uint32_t lastOrdinal = 0; + file->_ordinal = lastOrdinal++; + + llvm::OwningPtr 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>(binaryFile.get())); + + if (!file->_objFile) + return make_error_code(llvm::object::object_error::invalid_file_type); + + binaryFile.take(); + + llvm::object::ELFObjectFile &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 &defined() const { + return _definedAtoms; + } + + virtual const atom_collection &undefined() const { + return _undefinedAtoms; + } + + virtual const atom_collection &sharedLibrary() const { + return _sharedLibraryAtoms; + } + + virtual const atom_collection &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( + *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> _objFile; + atom_collection_vector _definedAtoms; + atom_collection_vector _undefinedAtoms; + atom_collection_vector _sharedLibraryAtoms; + atom_collection_vector _absoluteAtoms; + /// \brief DT_SONAME + StringRef _soname; + + struct SymAtomPair { + const typename llvm::object::ELFObjectFile::Elf_Sym *_symbol; + const SharedLibraryAtom *_atom; + }; + + mutable std::unordered_map _nameToSym; + mutable llvm::BumpPtrAllocator _alloc; +}; +} // end namespace elf +} // end namespace lld + +#endif diff --git a/lld/lib/ReaderWriter/ELF/File.h b/lld/lib/ReaderWriter/ELF/File.h index 91b03ec..f1123ef 100644 --- a/lld/lib/ReaderWriter/ELF/File.h +++ b/lld/lib/ReaderWriter/ELF/File.h @@ -38,16 +38,6 @@ #include #include -namespace std { -template <> struct hash { -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 diff --git a/lld/lib/ReaderWriter/ELF/Reader.cpp b/lld/lib/ReaderWriter/ELF/Reader.cpp index 8a95ced..be2fedb 100644 --- a/lld/lib/ReaderWriter/ELF/Reader.cpp +++ b/lld/lib/ReaderWriter/ELF/Reader.cpp @@ -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> result_type; + + template + static result_type create(const lld::ELFTargetInfo &ti, + std::unique_ptr mb) { + return lld::elf::DynamicFile::create(ti, std::move(mb)); + } +}; + +struct ELFFileCreateELFTraits { + typedef std::unique_ptr result_type; + + template + static result_type create(const lld::ELFTargetInfo &ti, + std::unique_ptr mb, + lld::error_code &ec) { + return std::unique_ptr( + new lld::elf::ELFFile(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 Ident = getElfArchType(&*mb); - std::unique_ptr 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 >( - _elfTargetInfo, std::move(mb), ec)); - else -#endif - if (MaxAlignment >= 2) - f.reset(new ELFFile >( - _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 >( - _elfTargetInfo, std::move(mb), ec)); - else -#endif - if (MaxAlignment >= 2) - f.reset(new ELFFile >( - _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 >( - _elfTargetInfo, std::move(mb), ec)); - else -#endif - if (MaxAlignment >= 2) - f.reset(new ELFFile >( - _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 >( - _elfTargetInfo, std::move(mb), ec)); - else -#endif - if (MaxAlignment >= 2) - f.reset(new ELFFile >( - _elfTargetInfo, std::move(mb), ec)); - else - llvm_unreachable("Invalid alignment for ELF file!"); - } - if (!ec) - result.push_back(std::move(f)); + std::unique_ptr f(createELF( + 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( + getElfArchType(&*mb), MaxAlignment, _elfTargetInfo, std::move(mb)); + if (!f) + return f; + result.push_back(std::move(*f)); break; } case llvm::sys::Archive_FileType: diff --git a/lld/lib/ReaderWriter/ReaderArchive.cpp b/lld/lib/ReaderWriter/ReaderArchive.cpp index e3736d7..ba92087 100644 --- a/lld/lib/ReaderWriter/ReaderArchive.cpp +++ b/lld/lib/ReaderWriter/ReaderArchive.cpp @@ -17,17 +17,6 @@ #include -namespace std { - template<> - struct hash { - 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 { diff --git a/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp b/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp index e351cc1..5320b6e 100644 --- a/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp +++ b/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp @@ -220,13 +220,15 @@ private: template class AtomList : public lld::File::atom_collection { public: - virtual lld::File::atom_iterator begin() const { - return lld::File::atom_iterator(*this, reinterpret_cast - (_atoms.data())); + virtual lld::File::atom_iterator begin() const { + return lld::File::atom_iterator< + T>(*this, + _atoms.empty() ? 0 : reinterpret_cast(_atoms.data())); } - virtual lld::File::atom_iterator end() const{ - return lld::File::atom_iterator(*this, reinterpret_cast - (_atoms.data() + _atoms.size())); + virtual lld::File::atom_iterator end() const{ + return lld::File::atom_iterator< + T>(*this, _atoms.empty() ? 0 : + reinterpret_cast(_atoms.data() + _atoms.size())); } virtual const T *deref(const void *it) const { return *reinterpret_cast(it); diff --git a/lld/test/CMakeLists.txt b/lld/test/CMakeLists.txt index 4bf808d..f1ae51f 100644 --- a/lld/test/CMakeLists.txt +++ b/lld/test/CMakeLists.txt @@ -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 diff --git a/lld/test/elf/Inputs/shared.c b/lld/test/elf/Inputs/shared.c new file mode 100644 index 0000000..9bf69f8 --- /dev/null +++ b/lld/test/elf/Inputs/shared.c @@ -0,0 +1,5 @@ +#include + +void foo() { + puts("Fooo!!"); +} diff --git a/lld/test/elf/Inputs/shared.so-x86-64 b/lld/test/elf/Inputs/shared.so-x86-64 new file mode 100644 index 0000000000000000000000000000000000000000..cc2fe5610ba59d5c43273c9a15206720d9647bf4 GIT binary patch literal 8125 zcmeHMU2Ggz6~60@W2a8+jq_7C3CcD~g* zc4k|nwP(*g-#zEtd(Ygzx#!!1!$UQ(m_mxHFDd30Ydxe_3PyHIhDfjKR(14y zNZqGpMRY^Jmm90|7*M5>8sIv%bFNXdM3Y`dXh)65b_<0bv#i%5dMzRkx+Glzt@q5R zZAAI`rId&1QIP{>SxzJGxf#wc>&8~oLt09aFT4c3FO#0ANXaJ?v~yJI+srQt{tznN z(S6%XRmABzeSTa${n|^f^uPVPf7HJJ^*8oBv%PELow@IF3%H!?g8wgGPsY@?-W`lJ z(6fu4Q-kl`zUW+R_}L$?Jbm+* z&~~c*uwUal)lzs+nCA41T{IonD!Hbq%zQELDszg6GS7^iGc(yzb~^94+0xj#{(@c1 zj#-n1tXCFYVy5RTHeeO*HMN1WZH0SG6$sHdqOBb6_Ez%ywcn%>Y zeYjsfwQ#$Bl-QmsF5m42HJ_fn4e91E=8TBr2D3(WI0SY0NT z?WA6;Jw{;aJ4HQPd#`ib?Lp-!kxw^YbI`x;$L@o ziXTp_-{Sg6{_~!Er%(R%JMq+|>#5iOd@>bVPF;F4_4eJe*5CJ*)_=z({Xek&g`STI zQRPpk7J7clxpAt`-I;o^=eNYI^iY#ma`ZFtX6-Tov5#&{aWX3HUFi8<9jUp8sd3XJ z!M)luPVIk|V6wHoJhA!}GO#*IKT|KWdGbMm1P)M#SKhk2zJ6)&pX7wZ#EquI7u3lECm#CTQN5h7%m6*yN4-Y$H71^~>EGoaL#)1)wmh)qfh`Yg zd0@)}|IZ%4ISl76w3QDaocK(~X{Sdj=X?H6;Dqz+eI8pm=N%NjUMO$goN(UbeUuZ* z|8{rXW`0d7##!xx9Ja8(;=Ax37N+z=kLYg~&bA0&Iitz>3};2Xx04Lc0XVbWD|)R` zG4PxmCeh9%k)y+{PNn6MQ#^>wRAQ@QP5J zzfbq~e<9gAK3Oih<@RCv$SB##F5_XNv#qnN!OuSE@k$xa{ETZ&5_L-+%^_E`-K;TP zEE|*Md?C}8&nV61EGMUo%zTkFJ?fUck|(kyCvO)6j7epsY{6m$$;}pAW#}&`!_Cf7 zUVld!C0l>o7}=aTRkCKXW-ddz;5-e}DwV8xPXqaHq)CjdTQm7IRc(_&`Z07Zo<;gv zQbyXInaLL2unYeyp63mZJ&f1Q?kQkgh7(w2Q10(EwxEys1o}mh#JIz_h5x8PHrW%RnFVpqDVV4SmdCP|Q~n(FyYde2OwWcc72?0*ZA5?S~xbIO+3T1dsU$ znv{yT{aiQNFR;o`27O};^B;7HK}x6}`sja=%KZ9RPe8H$us*M0Vf{J6xLsK9aGwI& zNM-)Sb@`J+j9-6N<}WDfhfYE=puFDu^>Ggfn&d)Xf*zpfDC5`1{s4+~6Y}BqzaaXZ zBJeA51Sr;J=%YEHS41E0e_8ZFF@B&Qu75G4zb5*i87Kl2PqGIz|3Rp17kWO3l!E7-e=nA zLI1IS@%)Uc{|EZAL#cfsN3&p9$*q?%UTw&h{;@i}Ph(^X$t-?ML zl;5tf{s-~8%K9F}>lN1PAYOg1%jI!e$+5l$<>@|I*54o=aSyER>{3|gg7S@(_(KqH zQdpOQI1Lt=_d$Gj<@_DQn`wPW`XQZj6u=8Fqpeq7Udwf}Ds&h4KK*}1LdtKVY-8I1D7X8qku@-f;`MnW6s5sg>-fvSzP zZ)o}I_jp3%)#GG92&*C z_i^)hS6d-pEYG#kcT_ulg0&ll{8yExOK#qpF literal 0 HcmV?d00001 diff --git a/lld/test/elf/Inputs/use-shared.c b/lld/test/elf/Inputs/use-shared.c new file mode 100644 index 0000000..5433235 --- /dev/null +++ b/lld/test/elf/Inputs/use-shared.c @@ -0,0 +1,5 @@ +void foo(); + +int main() { + foo(); +} diff --git a/lld/test/elf/Inputs/use-shared.x86-64 b/lld/test/elf/Inputs/use-shared.x86-64 new file mode 100644 index 0000000000000000000000000000000000000000..f7236ff697305ded47b7835c06f13865c79bbb5c GIT binary patch literal 1264 zcmbtTJxjw-6uoJyt=dW~B7zROIB9Sc2Wcy9MS>M=!9_yaMk?ACk_gqsO>pZ^@FzGr z3jPU47r{|?q280cSHdGMdLj4Rd+z6ZkKC5cN;lbDh8lbK z?~n8W<_YTb1)69+1k!GfNE_(dQZ}6#a^q#@@j>!X#aaC>v74KO4KZBj(l&f&;FHnx zJTiKH-!ZBOjSbJYTNfhkbgVPi?mA?69nW`tyUCWs>u%t;ZQl-i{zGFg+{bu7(W@XZ zID@bOdc=l_+LXe?+bqXKq6ijsDe5x%L(ZD*ZMiG#a^oXHebzM z<3ex=rNN2tw-jEUU(%~=sAod#HRk^CMzUVs-zIbF*-<})VmS<9tkwNX98q^i@`Gsl zDJrKK)BLIPx0#EbFZN#-^%B(il2;LVDf$|zJp5$ri-C{Z1bo~LgP(|N&%F9K5al>C zADJuviv{NOm@bIN@pR=mUdMKww$Y-lecq$9exIzWSt}Jyt5&HTm+Mx&STf62&=q$M T!3ppWeUCy}VH<+Ci@x6vT(n3; literal 0 HcmV?d00001 diff --git a/lld/test/elf/dynamic-library.test b/lld/test/elf/dynamic-library.test new file mode 100644 index 0000000..d559bcc --- /dev/null +++ b/lld/test/elf/dynamic-library.test @@ -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 -- 2.7.4