Index: docs/Readers.rst =================================================================== --- docs/Readers.rst +++ docs/Readers.rst @@ -10,8 +10,8 @@ and create an `lld::File`:cpp:class: (which is a graph of Atoms) representing the object file. A Reader inherits from `lld::Reader`:cpp:class: which lives in -:file:`include/lld/ReaderWriter/Reader.h` and -:file:`lib/ReaderWriter/Reader.cpp`. +:file:`include/lld/Core/Reader.h` and +:file:`lib/Core/Reader.cpp`. The Reader infrastructure for an object format ``Foo`` requires the following pieces in order to fit into lld: Index: include/lld/Core/LinkingContext.h =================================================================== --- include/lld/Core/LinkingContext.h +++ include/lld/Core/LinkingContext.h @@ -16,7 +16,7 @@ #include "lld/Core/Parallel.h" #include "lld/Core/Reference.h" #include "lld/Core/range.h" -#include "lld/ReaderWriter/Reader.h" +#include "lld/Core/Reader.h" #include "llvm/Support/ErrorOr.h" #include "llvm/Support/raw_ostream.h" #include Index: include/lld/Core/Reader.h =================================================================== --- /dev/null +++ include/lld/Core/Reader.h @@ -0,0 +1,170 @@ +//===- lld/Core/Reader.h - Abstract File Format Reading Interface ---------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_CORE_READER_H +#define LLD_CORE_READER_H + +#include "lld/Core/LLVM.h" +#include "lld/Core/Reference.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/YAMLTraits.h" +#include +#include +#include + +using llvm::sys::fs::file_magic; + +namespace llvm { +namespace yaml { +class IO; +} +} + +namespace lld { +class ELFLinkingContext; +class File; +class LinkingContext; +class PECOFFLinkingContext; +class TargetHandlerBase; +class MachOLinkingContext; + +/// \brief An abstract class for reading object files, library files, and +/// executable files. +/// +/// Each file format (e.g. ELF, mach-o, PECOFF, native, etc) have a concrete +/// subclass of Reader. +class Reader { +public: + virtual ~Reader() {} + + /// Sniffs the file to determine if this Reader can parse it. + /// The method is called with: + /// 1) the file_magic enumeration returned by identify_magic() + /// 2) the file extension (e.g. ".obj") + /// 3) the whole file content buffer if the above is not enough. + virtual bool canParse(file_magic magic, StringRef fileExtension, + const MemoryBuffer &mb) const = 0; + + /// \brief Parse a supplied buffer (already filled with the contents of a + /// file) and create a File object. + /// The resulting File object takes ownership of the MemoryBuffer. + virtual std::error_code + loadFile(std::unique_ptr mb, const class Registry &, + std::vector> &result) const = 0; +}; + + +/// \brief An abstract class for handling alternate yaml representations +/// of object files. +/// +/// The YAML syntax allows "tags" which are used to specify the type of +/// the YAML node. In lld, top level YAML documents can be in many YAML +/// representations (e.g mach-o encoded as yaml, etc). A tag is used to +/// specify which representation is used in the following YAML document. +/// To work, there must be a YamlIOTaggedDocumentHandler registered that +/// handles each tag type. +class YamlIOTaggedDocumentHandler { +public: + virtual ~YamlIOTaggedDocumentHandler(); + + /// This method is called on each registered YamlIOTaggedDocumentHandler + /// until one returns true. If the subclass handles tag type !xyz, then + /// this method should call io.mapTag("!xzy") to see if that is the current + /// document type, and if so, process the rest of the document using + /// YAML I/O, then convert the result into an lld::File* and return it. + virtual bool handledDocTag(llvm::yaml::IO &io, const lld::File *&f) const = 0; +}; + + +/// A registry to hold the list of currently registered Readers and +/// tables which map Reference kind values to strings. +/// The linker does not directly invoke Readers. Instead, it registers +/// Readers based on it configuration and command line options, then calls +/// the Registry object to parse files. +class Registry { +public: + Registry(); + + /// Walk the list of registered Readers and find one that can parse the + /// supplied file and parse it. + std::error_code loadFile(std::unique_ptr mb, + std::vector> &result) const; + + /// Walk the list of registered kind tables to convert a Reference Kind + /// name to a value. + bool referenceKindFromString(StringRef inputStr, Reference::KindNamespace &ns, + Reference::KindArch &a, + Reference::KindValue &value) const; + + /// Walk the list of registered kind tables to convert a Reference Kind + /// value to a string. + bool referenceKindToString(Reference::KindNamespace ns, Reference::KindArch a, + Reference::KindValue value, StringRef &) const; + + /// Walk the list of registered tag handlers and have the one that handles + /// the current document type process the yaml into an lld::File*. + bool handleTaggedDoc(llvm::yaml::IO &io, const lld::File *&file) const; + + // These methods are called to dynamically add support for various file + // formats. The methods are also implemented in the appropriate lib*.a + // library, so that the code for handling a format is only linked in, if this + // method is used. Any options that a Reader might need must be passed + // as parameters to the addSupport*() method. + void addSupportArchives(bool logLoading); + void addSupportYamlFiles(); + void addSupportNativeObjects(); + void addSupportCOFFObjects(PECOFFLinkingContext &); + void addSupportCOFFImportLibraries(PECOFFLinkingContext &); + void addSupportMachOObjects(MachOLinkingContext &); + void addSupportELFObjects(bool atomizeStrings, TargetHandlerBase *handler); + void addSupportELFDynamicSharedObjects(bool useShlibUndefines, + TargetHandlerBase *handler); + + /// To convert between kind values and names, the registry walks the list + /// of registered kind tables. Each table is a zero terminated array of + /// KindStrings elements. + struct KindStrings { + Reference::KindValue value; + StringRef name; + }; + + /// A Reference Kind value is a tuple of . All + /// entries in a conversion table have the same . The + /// array then contains the value/name pairs. + void addKindTable(Reference::KindNamespace ns, Reference::KindArch arch, + const KindStrings array[]); + + +private: + struct KindEntry { + Reference::KindNamespace ns; + Reference::KindArch arch; + const KindStrings *array; + }; + + void add(std::unique_ptr); + void add(std::unique_ptr); + + std::vector> _readers; + std::vector> _yamlHandlers; + std::vector _kindEntries; +}; + +// Utilities for building a KindString table. For instance: +// static const Registry::KindStrings table[] = { +// LLD_KIND_STRING_ENTRY(R_VAX_ADDR16), +// LLD_KIND_STRING_ENTRY(R_VAX_DATA16), +// LLD_KIND_STRING_END +// }; +#define LLD_KIND_STRING_ENTRY(name) { name, #name } +#define LLD_KIND_STRING_END { 0, "" } + +} // end namespace lld + +#endif Index: include/lld/Core/Writer.h =================================================================== --- /dev/null +++ include/lld/Core/Writer.h @@ -0,0 +1,52 @@ +//===- lld/Core/Writer.h - Abstract File Format Interface -----------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_CORE_WRITER_H +#define LLD_CORE_WRITER_H + +#include "lld/Core/LLVM.h" +#include +#include + +namespace lld { +class File; +class ELFLinkingContext; +class MachOLinkingContext; +class PECOFFLinkingContext; +class LinkingContext; +class TargetHandlerBase; + +/// \brief The Writer is an abstract class for writing object files, shared +/// library files, and executable files. Each file format (e.g. ELF, mach-o, +/// PECOFF, native, etc) have a concrete subclass of Writer. +class Writer { +public: + virtual ~Writer(); + + /// \brief Write a file from the supplied File object + virtual std::error_code writeFile(const File &linkedFile, StringRef path) = 0; + + /// \brief This method is called by Core Linking to give the Writer a chance + /// to add file format specific "files" to set of files to be linked. This is + /// how file format specific atoms can be added to the link. + virtual bool createImplicitFiles(std::vector > &); + +protected: + // only concrete subclasses can be instantiated + Writer(); +}; + +std::unique_ptr createWriterELF(TargetHandlerBase *handler); +std::unique_ptr createWriterMachO(const MachOLinkingContext &); +std::unique_ptr createWriterPECOFF(const PECOFFLinkingContext &); +std::unique_ptr createWriterNative(const LinkingContext &); +std::unique_ptr createWriterYAML(const LinkingContext &); +} // end namespace lld + +#endif Index: include/lld/Passes/LayoutPass.h =================================================================== --- include/lld/Passes/LayoutPass.h +++ include/lld/Passes/LayoutPass.h @@ -12,7 +12,7 @@ #include "lld/Core/File.h" #include "lld/Core/Pass.h" -#include "lld/ReaderWriter/Reader.h" +#include "lld/Core/Reader.h" #include "llvm/ADT/DenseMap.h" #include #include Index: include/lld/ReaderWriter/CoreLinkingContext.h =================================================================== --- include/lld/ReaderWriter/CoreLinkingContext.h +++ include/lld/ReaderWriter/CoreLinkingContext.h @@ -11,8 +11,8 @@ #define LLD_READER_WRITER_CORE_LINKER_CONTEXT_H #include "lld/Core/LinkingContext.h" -#include "lld/ReaderWriter/Reader.h" -#include "lld/ReaderWriter/Writer.h" +#include "lld/Core/Reader.h" +#include "lld/Core/Writer.h" #include "llvm/Support/ErrorHandling.h" namespace lld { Index: include/lld/ReaderWriter/ELFLinkingContext.h =================================================================== --- include/lld/ReaderWriter/ELFLinkingContext.h +++ include/lld/ReaderWriter/ELFLinkingContext.h @@ -15,8 +15,8 @@ #include "lld/Core/PassManager.h" #include "lld/Core/STDExtras.h" #include "lld/Core/range.h" -#include "lld/ReaderWriter/Reader.h" -#include "lld/ReaderWriter/Writer.h" +#include "lld/Core/Reader.h" +#include "lld/Core/Writer.h" #include "llvm/ADT/StringSet.h" #include "llvm/ADT/Triple.h" #include "llvm/Object/ELF.h" Index: include/lld/ReaderWriter/MachOLinkingContext.h =================================================================== --- include/lld/ReaderWriter/MachOLinkingContext.h +++ include/lld/ReaderWriter/MachOLinkingContext.h @@ -11,8 +11,8 @@ #define LLD_READER_WRITER_MACHO_LINKING_CONTEXT_H #include "lld/Core/LinkingContext.h" -#include "lld/ReaderWriter/Reader.h" -#include "lld/ReaderWriter/Writer.h" +#include "lld/Core/Reader.h" +#include "lld/Core/Writer.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringSet.h" #include "llvm/Support/ErrorHandling.h" Index: include/lld/ReaderWriter/PECOFFLinkingContext.h =================================================================== --- include/lld/ReaderWriter/PECOFFLinkingContext.h +++ include/lld/ReaderWriter/PECOFFLinkingContext.h @@ -11,8 +11,8 @@ #define LLD_READER_WRITER_PECOFF_LINKING_CONTEXT_H #include "lld/Core/LinkingContext.h" -#include "lld/ReaderWriter/Reader.h" -#include "lld/ReaderWriter/Writer.h" +#include "lld/Core/Reader.h" +#include "lld/Core/Writer.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/COFF.h" Index: include/lld/ReaderWriter/Reader.h =================================================================== --- include/lld/ReaderWriter/Reader.h +++ /dev/null @@ -1,170 +0,0 @@ -//===- lld/ReaderWriter/Reader.h - Abstract File Format Reading Interface -===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLD_READER_WRITER_READER_H -#define LLD_READER_WRITER_READER_H - -#include "lld/Core/LLVM.h" -#include "lld/Core/Reference.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/YAMLTraits.h" -#include -#include -#include - -using llvm::sys::fs::file_magic; - -namespace llvm { -namespace yaml { -class IO; -} -} - -namespace lld { -class ELFLinkingContext; -class File; -class LinkingContext; -class PECOFFLinkingContext; -class TargetHandlerBase; -class MachOLinkingContext; - -/// \brief An abstract class for reading object files, library files, and -/// executable files. -/// -/// Each file format (e.g. ELF, mach-o, PECOFF, native, etc) have a concrete -/// subclass of Reader. -class Reader { -public: - virtual ~Reader() {} - - /// Sniffs the file to determine if this Reader can parse it. - /// The method is called with: - /// 1) the file_magic enumeration returned by identify_magic() - /// 2) the file extension (e.g. ".obj") - /// 3) the whole file content buffer if the above is not enough. - virtual bool canParse(file_magic magic, StringRef fileExtension, - const MemoryBuffer &mb) const = 0; - - /// \brief Parse a supplied buffer (already filled with the contents of a - /// file) and create a File object. - /// The resulting File object takes ownership of the MemoryBuffer. - virtual std::error_code - loadFile(std::unique_ptr mb, const class Registry &, - std::vector> &result) const = 0; -}; - - -/// \brief An abstract class for handling alternate yaml representations -/// of object files. -/// -/// The YAML syntax allows "tags" which are used to specify the type of -/// the YAML node. In lld, top level YAML documents can be in many YAML -/// representations (e.g mach-o encoded as yaml, etc). A tag is used to -/// specify which representation is used in the following YAML document. -/// To work, there must be a YamlIOTaggedDocumentHandler registered that -/// handles each tag type. -class YamlIOTaggedDocumentHandler { -public: - virtual ~YamlIOTaggedDocumentHandler(); - - /// This method is called on each registered YamlIOTaggedDocumentHandler - /// until one returns true. If the subclass handles tag type !xyz, then - /// this method should call io.mapTag("!xzy") to see if that is the current - /// document type, and if so, process the rest of the document using - /// YAML I/O, then convert the result into an lld::File* and return it. - virtual bool handledDocTag(llvm::yaml::IO &io, const lld::File *&f) const = 0; -}; - - -/// A registry to hold the list of currently registered Readers and -/// tables which map Reference kind values to strings. -/// The linker does not directly invoke Readers. Instead, it registers -/// Readers based on it configuration and command line options, then calls -/// the Registry object to parse files. -class Registry { -public: - Registry(); - - /// Walk the list of registered Readers and find one that can parse the - /// supplied file and parse it. - std::error_code loadFile(std::unique_ptr mb, - std::vector> &result) const; - - /// Walk the list of registered kind tables to convert a Reference Kind - /// name to a value. - bool referenceKindFromString(StringRef inputStr, Reference::KindNamespace &ns, - Reference::KindArch &a, - Reference::KindValue &value) const; - - /// Walk the list of registered kind tables to convert a Reference Kind - /// value to a string. - bool referenceKindToString(Reference::KindNamespace ns, Reference::KindArch a, - Reference::KindValue value, StringRef &) const; - - /// Walk the list of registered tag handlers and have the one that handles - /// the current document type process the yaml into an lld::File*. - bool handleTaggedDoc(llvm::yaml::IO &io, const lld::File *&file) const; - - // These methods are called to dynamically add support for various file - // formats. The methods are also implemented in the appropriate lib*.a - // library, so that the code for handling a format is only linked in, if this - // method is used. Any options that a Reader might need must be passed - // as parameters to the addSupport*() method. - void addSupportArchives(bool logLoading); - void addSupportYamlFiles(); - void addSupportNativeObjects(); - void addSupportCOFFObjects(PECOFFLinkingContext &); - void addSupportCOFFImportLibraries(PECOFFLinkingContext &); - void addSupportMachOObjects(MachOLinkingContext &); - void addSupportELFObjects(bool atomizeStrings, TargetHandlerBase *handler); - void addSupportELFDynamicSharedObjects(bool useShlibUndefines, - TargetHandlerBase *handler); - - /// To convert between kind values and names, the registry walks the list - /// of registered kind tables. Each table is a zero terminated array of - /// KindStrings elements. - struct KindStrings { - Reference::KindValue value; - StringRef name; - }; - - /// A Reference Kind value is a tuple of . All - /// entries in a conversion table have the same . The - /// array then contains the value/name pairs. - void addKindTable(Reference::KindNamespace ns, Reference::KindArch arch, - const KindStrings array[]); - - -private: - struct KindEntry { - Reference::KindNamespace ns; - Reference::KindArch arch; - const KindStrings *array; - }; - - void add(std::unique_ptr); - void add(std::unique_ptr); - - std::vector> _readers; - std::vector> _yamlHandlers; - std::vector _kindEntries; -}; - -// Utilities for building a KindString table. For instance: -// static const Registry::KindStrings table[] = { -// LLD_KIND_STRING_ENTRY(R_VAX_ADDR16), -// LLD_KIND_STRING_ENTRY(R_VAX_DATA16), -// LLD_KIND_STRING_END -// }; -#define LLD_KIND_STRING_ENTRY(name) { name, #name } -#define LLD_KIND_STRING_END { 0, "" } - -} // end namespace lld - -#endif Index: include/lld/ReaderWriter/Writer.h =================================================================== --- include/lld/ReaderWriter/Writer.h +++ /dev/null @@ -1,52 +0,0 @@ -//===- lld/ReaderWriter/Writer.h - Abstract File Format Interface ---------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLD_READER_WRITER_WRITER_H -#define LLD_READER_WRITER_WRITER_H - -#include "lld/Core/LLVM.h" -#include -#include - -namespace lld { -class File; -class ELFLinkingContext; -class MachOLinkingContext; -class PECOFFLinkingContext; -class LinkingContext; -class TargetHandlerBase; - -/// \brief The Writer is an abstract class for writing object files, shared -/// library files, and executable files. Each file format (e.g. ELF, mach-o, -/// PECOFF, native, etc) have a concrete subclass of Writer. -class Writer { -public: - virtual ~Writer(); - - /// \brief Write a file from the supplied File object - virtual std::error_code writeFile(const File &linkedFile, StringRef path) = 0; - - /// \brief This method is called by Core Linking to give the Writer a chance - /// to add file format specific "files" to set of files to be linked. This is - /// how file format specific atoms can be added to the link. - virtual bool createImplicitFiles(std::vector > &); - -protected: - // only concrete subclasses can be instantiated - Writer(); -}; - -std::unique_ptr createWriterELF(TargetHandlerBase *handler); -std::unique_ptr createWriterMachO(const MachOLinkingContext &); -std::unique_ptr createWriterPECOFF(const PECOFFLinkingContext &); -std::unique_ptr createWriterNative(const LinkingContext &); -std::unique_ptr createWriterYAML(const LinkingContext &); -} // end namespace lld - -#endif Index: lib/Core/CMakeLists.txt =================================================================== --- lib/Core/CMakeLists.txt +++ lib/Core/CMakeLists.txt @@ -3,8 +3,10 @@ Error.cpp File.cpp LinkingContext.cpp + Reader.cpp Resolver.cpp SymbolTable.cpp + Writer.cpp LINK_LIBS LLVMSupport ) Index: lib/Core/LinkingContext.cpp =================================================================== --- lib/Core/LinkingContext.cpp +++ lib/Core/LinkingContext.cpp @@ -11,7 +11,7 @@ #include "lld/Core/LinkingContext.h" #include "lld/Core/Resolver.h" #include "lld/Core/Simple.h" -#include "lld/ReaderWriter/Writer.h" +#include "lld/Core/Writer.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/Process.h" Index: lib/Core/Reader.cpp =================================================================== --- /dev/null +++ lib/Core/Reader.cpp @@ -0,0 +1,119 @@ +//===- lib/Core/Reader.cpp ------------------------------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lld/Core/File.h" +#include "lld/Core/Reader.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Errc.h" +#include "llvm/Support/FileUtilities.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Path.h" +#include +#include + +namespace lld { + +YamlIOTaggedDocumentHandler::~YamlIOTaggedDocumentHandler() {} + +void Registry::add(std::unique_ptr reader) { + _readers.push_back(std::move(reader)); +} + +void Registry::add(std::unique_ptr handler) { + _yamlHandlers.push_back(std::move(handler)); +} + +std::error_code +Registry::loadFile(std::unique_ptr mb, + std::vector> &result) const { + // Get file type. + StringRef content(mb->getBufferStart(), mb->getBufferSize()); + llvm::sys::fs::file_magic fileType = llvm::sys::fs::identify_magic(content); + // Get file extension. + StringRef extension = llvm::sys::path::extension(mb->getBufferIdentifier()); + + // Ask each registered reader if it can handle this file type or extension. + for (const std::unique_ptr &reader : _readers) { + if (!reader->canParse(fileType, extension, *mb)) + continue; + if (std::error_code ec = reader->loadFile(std::move(mb), *this, result)) + return ec; + return std::error_code(); + } + + // No Reader could parse this file. + return make_error_code(llvm::errc::executable_format_error); +} + +static const Registry::KindStrings kindStrings[] = { + {Reference::kindInGroup, "in-group"}, + {Reference::kindLayoutAfter, "layout-after"}, + {Reference::kindLayoutBefore, "layout-before"}, + {Reference::kindGroupChild, "group-child"}, + {Reference::kindAssociate, "associate"}, + LLD_KIND_STRING_END}; + +Registry::Registry() { + addKindTable(Reference::KindNamespace::all, Reference::KindArch::all, + kindStrings); +} + +bool Registry::handleTaggedDoc(llvm::yaml::IO &io, + const lld::File *&file) const { + for (const std::unique_ptr &h : _yamlHandlers) + if (h->handledDocTag(io, file)) + return true; + return false; +} + + +void Registry::addKindTable(Reference::KindNamespace ns, + Reference::KindArch arch, + const KindStrings array[]) { + KindEntry entry = { ns, arch, array }; + _kindEntries.push_back(entry); +} + +bool Registry::referenceKindFromString(StringRef inputStr, + Reference::KindNamespace &ns, + Reference::KindArch &arch, + Reference::KindValue &value) const { + for (const KindEntry &entry : _kindEntries) { + for (const KindStrings *pair = entry.array; !pair->name.empty(); ++pair) { + if (!inputStr.equals(pair->name)) + continue; + ns = entry.ns; + arch = entry.arch; + value = pair->value; + return true; + } + } + return false; +} + +bool Registry::referenceKindToString(Reference::KindNamespace ns, + Reference::KindArch arch, + Reference::KindValue value, + StringRef &str) const { + for (const KindEntry &entry : _kindEntries) { + if (entry.ns != ns) + continue; + if (entry.arch != arch) + continue; + for (const KindStrings *pair = entry.array; !pair->name.empty(); ++pair) { + if (pair->value != value) + continue; + str = pair->name; + return true; + } + } + return false; +} + +} // end namespace lld Index: lib/Core/Writer.cpp =================================================================== --- /dev/null +++ lib/Core/Writer.cpp @@ -0,0 +1,23 @@ +//===- lib/Core/Writer.cpp ------------------------------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lld/Core/File.h" +#include "lld/Core/Writer.h" + +namespace lld { +Writer::Writer() { +} + +Writer::~Writer() { +} + +bool Writer::createImplicitFiles(std::vector > &) { + return true; +} +} // end namespace lld Index: lib/Driver/CoreDriver.cpp =================================================================== --- lib/Driver/CoreDriver.cpp +++ lib/Driver/CoreDriver.cpp @@ -7,9 +7,9 @@ // //===----------------------------------------------------------------------===// +#include "lld/Core/Reader.h" #include "lld/Driver/Driver.h" #include "lld/ReaderWriter/CoreLinkingContext.h" -#include "lld/ReaderWriter/Reader.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Triple.h" Index: lib/Driver/Driver.cpp =================================================================== --- lib/Driver/Driver.cpp +++ lib/Driver/Driver.cpp @@ -13,12 +13,12 @@ #include "lld/Core/LLVM.h" #include "lld/Core/Parallel.h" #include "lld/Core/PassManager.h" +#include "lld/Core/Reader.h" #include "lld/Core/Resolver.h" +#include "lld/Core/Writer.h" #include "lld/Driver/Driver.h" #include "lld/Passes/RoundTripNativePass.h" #include "lld/Passes/RoundTripYAMLPass.h" -#include "lld/ReaderWriter/Reader.h" -#include "lld/ReaderWriter/Writer.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Option/Arg.h" Index: lib/Passes/CMakeLists.txt =================================================================== --- lib/Passes/CMakeLists.txt +++ lib/Passes/CMakeLists.txt @@ -3,6 +3,8 @@ RoundTripNativePass.cpp RoundTripYAMLPass.cpp LINK_LIBS - lldReaderWriter + lldCore + lldNative + lldYAML LLVMSupport ) Index: lib/Passes/RoundTripNativePass.cpp =================================================================== --- lib/Passes/RoundTripNativePass.cpp +++ lib/Passes/RoundTripNativePass.cpp @@ -9,8 +9,8 @@ #include "lld/Core/Instrumentation.h" #include "lld/Core/Simple.h" +#include "lld/Core/Writer.h" #include "lld/Passes/RoundTripNativePass.h" -#include "lld/ReaderWriter/Writer.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Path.h" #include Index: lib/Passes/RoundTripYAMLPass.cpp =================================================================== --- lib/Passes/RoundTripYAMLPass.cpp +++ lib/Passes/RoundTripYAMLPass.cpp @@ -9,8 +9,8 @@ #include "lld/Core/Instrumentation.h" #include "lld/Core/Simple.h" +#include "lld/Core/Writer.h" #include "lld/Passes/RoundTripYAMLPass.h" -#include "lld/ReaderWriter/Writer.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Path.h" #include Index: lib/ReaderWriter/CMakeLists.txt =================================================================== --- lib/ReaderWriter/CMakeLists.txt +++ lib/ReaderWriter/CMakeLists.txt @@ -12,11 +12,10 @@ CoreLinkingContext.cpp FileArchive.cpp LinkerScript.cpp - Reader.cpp - Writer.cpp - FileArchive.cpp LINK_LIBS lldCore + lldPasses + lldYAML LLVMObject LLVMSupport ) Index: lib/ReaderWriter/ELF/ELFReader.h =================================================================== --- lib/ReaderWriter/ELF/ELFReader.h +++ lib/ReaderWriter/ELF/ELFReader.h @@ -13,7 +13,7 @@ #include "CreateELF.h" #include "DynamicFile.h" #include "ELFFile.h" -#include "lld/ReaderWriter/Reader.h" +#include "lld/Core/Reader.h" namespace lld { namespace elf { Index: lib/ReaderWriter/ELF/OutputELFWriter.h =================================================================== --- lib/ReaderWriter/ELF/OutputELFWriter.h +++ lib/ReaderWriter/ELF/OutputELFWriter.h @@ -16,7 +16,7 @@ #include "lld/Core/Parallel.h" #include "lld/Core/SharedLibraryFile.h" #include "lld/ReaderWriter/ELFLinkingContext.h" -#include "lld/ReaderWriter/Writer.h" +#include "lld/Core/Writer.h" #include "llvm/ADT/StringSet.h" #include "llvm/Support/Path.h" Index: lib/ReaderWriter/ELF/SegmentChunks.h =================================================================== --- lib/ReaderWriter/ELF/SegmentChunks.h +++ lib/ReaderWriter/ELF/SegmentChunks.h @@ -15,7 +15,7 @@ #include "SectionChunks.h" #include "Writer.h" #include "lld/Core/range.h" -#include "lld/ReaderWriter/Writer.h" +#include "lld/Core/Writer.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" #include "llvm/Object/ELF.h" Index: lib/ReaderWriter/ELF/Writer.h =================================================================== --- lib/ReaderWriter/ELF/Writer.h +++ lib/ReaderWriter/ELF/Writer.h @@ -11,7 +11,7 @@ #define LLD_READER_WRITER_ELF_WRITER_H #include "lld/Core/File.h" -#include "lld/ReaderWriter/Writer.h" +#include "lld/Core/Writer.h" namespace lld { namespace elf { Index: lib/ReaderWriter/ELF/Writer.cpp =================================================================== --- lib/ReaderWriter/ELF/Writer.cpp +++ lib/ReaderWriter/ELF/Writer.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#include "lld/ReaderWriter/Writer.h" +#include "lld/Core/Writer.h" #include "DynamicLibraryWriter.h" #include "ExecutableWriter.h" Index: lib/ReaderWriter/MachO/MachOLinkingContext.cpp =================================================================== --- lib/ReaderWriter/MachO/MachOLinkingContext.cpp +++ lib/ReaderWriter/MachO/MachOLinkingContext.cpp @@ -14,11 +14,11 @@ #include "MachOPasses.h" #include "lld/Core/ArchiveLibraryFile.h" #include "lld/Core/PassManager.h" +#include "lld/Core/Reader.h" +#include "lld/Core/Writer.h" #include "lld/Driver/Driver.h" #include "lld/Passes/LayoutPass.h" #include "lld/Passes/RoundTripYAMLPass.h" -#include "lld/ReaderWriter/Reader.h" -#include "lld/ReaderWriter/Writer.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Triple.h" #include "llvm/Config/config.h" Index: lib/ReaderWriter/MachO/WriterMachO.cpp =================================================================== --- lib/ReaderWriter/MachO/WriterMachO.cpp +++ lib/ReaderWriter/MachO/WriterMachO.cpp @@ -7,10 +7,10 @@ // //===----------------------------------------------------------------------===// -#include "lld/ReaderWriter/Writer.h" #include "ExecutableAtoms.hpp" #include "MachONormalizedFile.h" #include "lld/Core/File.h" +#include "lld/Core/Writer.h" #include "lld/ReaderWriter/MachOLinkingContext.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" Index: lib/ReaderWriter/Native/CMakeLists.txt =================================================================== --- lib/ReaderWriter/Native/CMakeLists.txt +++ lib/ReaderWriter/Native/CMakeLists.txt @@ -2,6 +2,6 @@ ReaderNative.cpp WriterNative.cpp LINK_LIBS - lldReaderWriter + lldCore LLVMSupport ) Index: lib/ReaderWriter/Native/Makefile =================================================================== --- lib/ReaderWriter/Native/Makefile +++ lib/ReaderWriter/Native/Makefile @@ -9,6 +9,6 @@ LLD_LEVEL := ../../.. LIBRARYNAME := lldNative -USEDLIBS = lldReaderWriter.a lldCore.a +USEDLIBS = lldCore.a include $(LLD_LEVEL)/Makefile Index: lib/ReaderWriter/Native/ReaderNative.cpp =================================================================== --- lib/ReaderWriter/Native/ReaderNative.cpp +++ lib/ReaderWriter/Native/ReaderNative.cpp @@ -11,8 +11,8 @@ #include "lld/Core/Atom.h" #include "lld/Core/Error.h" #include "lld/Core/File.h" +#include "lld/Core/Reader.h" #include "lld/Core/Simple.h" -#include "lld/ReaderWriter/Reader.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Debug.h" Index: lib/ReaderWriter/Native/WriterNative.cpp =================================================================== --- lib/ReaderWriter/Native/WriterNative.cpp +++ lib/ReaderWriter/Native/WriterNative.cpp @@ -7,10 +7,10 @@ // //===----------------------------------------------------------------------===// -#include "lld/ReaderWriter/Writer.h" #include "NativeFileFormat.h" #include "lld/Core/File.h" #include "lld/Core/LinkingContext.h" +#include "lld/Core/Writer.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringRef.h" Index: lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp =================================================================== --- lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp +++ lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp @@ -16,13 +16,13 @@ #include "LoadConfigPass.h" #include "PDBPass.h" #include "lld/Core/PassManager.h" +#include "lld/Core/Reader.h" #include "lld/Core/Simple.h" +#include "lld/Core/Writer.h" #include "lld/Passes/LayoutPass.h" #include "lld/Passes/RoundTripNativePass.h" #include "lld/Passes/RoundTripYAMLPass.h" #include "lld/ReaderWriter/PECOFFLinkingContext.h" -#include "lld/ReaderWriter/Reader.h" -#include "lld/ReaderWriter/Writer.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Path.h" Index: lib/ReaderWriter/PECOFF/ReaderCOFF.cpp =================================================================== --- lib/ReaderWriter/PECOFF/ReaderCOFF.cpp +++ lib/ReaderWriter/PECOFF/ReaderCOFF.cpp @@ -10,9 +10,9 @@ #include "Atoms.h" #include "lld/Core/Alias.h" #include "lld/Core/File.h" +#include "lld/Core/Reader.h" #include "lld/Driver/Driver.h" #include "lld/ReaderWriter/PECOFFLinkingContext.h" -#include "lld/ReaderWriter/Reader.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Object/COFF.h" Index: lib/ReaderWriter/PECOFF/WriterPECOFF.cpp =================================================================== --- lib/ReaderWriter/PECOFF/WriterPECOFF.cpp +++ lib/ReaderWriter/PECOFF/WriterPECOFF.cpp @@ -23,9 +23,9 @@ #include "WriterImportLibrary.h" #include "lld/Core/DefinedAtom.h" #include "lld/Core/File.h" +#include "lld/Core/Writer.h" #include "lld/ReaderWriter/AtomLayout.h" #include "lld/ReaderWriter/PECOFFLinkingContext.h" -#include "lld/ReaderWriter/Writer.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/Object/COFF.h" #include "llvm/Support/COFF.h" Index: lib/ReaderWriter/Reader.cpp =================================================================== --- lib/ReaderWriter/Reader.cpp +++ /dev/null @@ -1,119 +0,0 @@ -//===- lib/ReaderWriter/Reader.cpp ----------------------------------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "lld/Core/File.h" -#include "lld/ReaderWriter/Reader.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/Errc.h" -#include "llvm/Support/FileUtilities.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/Path.h" -#include -#include - -namespace lld { - -YamlIOTaggedDocumentHandler::~YamlIOTaggedDocumentHandler() {} - -void Registry::add(std::unique_ptr reader) { - _readers.push_back(std::move(reader)); -} - -void Registry::add(std::unique_ptr handler) { - _yamlHandlers.push_back(std::move(handler)); -} - -std::error_code -Registry::loadFile(std::unique_ptr mb, - std::vector> &result) const { - // Get file type. - StringRef content(mb->getBufferStart(), mb->getBufferSize()); - llvm::sys::fs::file_magic fileType = llvm::sys::fs::identify_magic(content); - // Get file extension. - StringRef extension = llvm::sys::path::extension(mb->getBufferIdentifier()); - - // Ask each registered reader if it can handle this file type or extension. - for (const std::unique_ptr &reader : _readers) { - if (!reader->canParse(fileType, extension, *mb)) - continue; - if (std::error_code ec = reader->loadFile(std::move(mb), *this, result)) - return ec; - return std::error_code(); - } - - // No Reader could parse this file. - return make_error_code(llvm::errc::executable_format_error); -} - -static const Registry::KindStrings kindStrings[] = { - {Reference::kindInGroup, "in-group"}, - {Reference::kindLayoutAfter, "layout-after"}, - {Reference::kindLayoutBefore, "layout-before"}, - {Reference::kindGroupChild, "group-child"}, - {Reference::kindAssociate, "associate"}, - LLD_KIND_STRING_END}; - -Registry::Registry() { - addKindTable(Reference::KindNamespace::all, Reference::KindArch::all, - kindStrings); -} - -bool Registry::handleTaggedDoc(llvm::yaml::IO &io, - const lld::File *&file) const { - for (const std::unique_ptr &h : _yamlHandlers) - if (h->handledDocTag(io, file)) - return true; - return false; -} - - -void Registry::addKindTable(Reference::KindNamespace ns, - Reference::KindArch arch, - const KindStrings array[]) { - KindEntry entry = { ns, arch, array }; - _kindEntries.push_back(entry); -} - -bool Registry::referenceKindFromString(StringRef inputStr, - Reference::KindNamespace &ns, - Reference::KindArch &arch, - Reference::KindValue &value) const { - for (const KindEntry &entry : _kindEntries) { - for (const KindStrings *pair = entry.array; !pair->name.empty(); ++pair) { - if (!inputStr.equals(pair->name)) - continue; - ns = entry.ns; - arch = entry.arch; - value = pair->value; - return true; - } - } - return false; -} - -bool Registry::referenceKindToString(Reference::KindNamespace ns, - Reference::KindArch arch, - Reference::KindValue value, - StringRef &str) const { - for (const KindEntry &entry : _kindEntries) { - if (entry.ns != ns) - continue; - if (entry.arch != arch) - continue; - for (const KindStrings *pair = entry.array; !pair->name.empty(); ++pair) { - if (pair->value != value) - continue; - str = pair->name; - return true; - } - } - return false; -} - -} // end namespace lld Index: lib/ReaderWriter/Writer.cpp =================================================================== --- lib/ReaderWriter/Writer.cpp +++ /dev/null @@ -1,23 +0,0 @@ -//===- lib/ReaderWriter/Writer.cpp ----------------------------------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "lld/Core/File.h" -#include "lld/ReaderWriter/Writer.h" - -namespace lld { -Writer::Writer() { -} - -Writer::~Writer() { -} - -bool Writer::createImplicitFiles(std::vector > &) { - return true; -} -} // end namespace lld Index: lib/ReaderWriter/YAML/CMakeLists.txt =================================================================== --- lib/ReaderWriter/YAML/CMakeLists.txt +++ lib/ReaderWriter/YAML/CMakeLists.txt @@ -1,6 +1,6 @@ add_llvm_library(lldYAML ReaderWriterYAML.cpp LINK_LIBS - lldReaderWriter + lldCore LLVMSupport ) Index: lib/ReaderWriter/YAML/Makefile =================================================================== --- lib/ReaderWriter/YAML/Makefile +++ lib/ReaderWriter/YAML/Makefile @@ -9,6 +9,6 @@ LLD_LEVEL := ../../.. LIBRARYNAME := lldYAML -USEDLIBS = lldReaderWriter.a lldCore.a +USEDLIBS = lldCore.a include $(LLD_LEVEL)/Makefile Index: lib/ReaderWriter/YAML/ReaderWriterYAML.cpp =================================================================== --- lib/ReaderWriter/YAML/ReaderWriterYAML.cpp +++ lib/ReaderWriter/YAML/ReaderWriterYAML.cpp @@ -12,10 +12,10 @@ #include "lld/Core/Error.h" #include "lld/Core/File.h" #include "lld/Core/LLVM.h" +#include "lld/Core/Reader.h" #include "lld/Core/Reference.h" #include "lld/Core/Simple.h" -#include "lld/ReaderWriter/Reader.h" -#include "lld/ReaderWriter/Writer.h" +#include "lld/Core/Writer.h" #include "lld/ReaderWriter/YamlContext.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringMap.h"