1 //===- lld/Core/Reader.h - Abstract File Format Reading Interface ---------===// 2 // 3 // The LLVM Linker 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLD_CORE_READER_H 11 #define LLD_CORE_READER_H 12 13 #include "lld/Core/LLVM.h" 14 #include "lld/Core/Reference.h" 15 #include "llvm/ADT/StringRef.h" 16 #include "llvm/BinaryFormat/Magic.h" 17 #include "llvm/Support/ErrorOr.h" 18 #include "llvm/Support/FileSystem.h" 19 #include "llvm/Support/MemoryBuffer.h" 20 #include <memory> 21 #include <vector> 22 23 namespace llvm { 24 namespace yaml { 25 class IO; 26 } // end namespace yaml 27 } // end namespace llvm 28 29 namespace lld { 30 31 class File; 32 class LinkingContext; 33 class MachOLinkingContext; 34 35 /// \brief An abstract class for reading object files, library files, and 36 /// executable files. 37 /// 38 /// Each file format (e.g. mach-o, etc) has a concrete subclass of Reader. 39 class Reader { 40 public: 41 virtual ~Reader() = default; 42 43 /// Sniffs the file to determine if this Reader can parse it. 44 /// The method is called with: 45 /// 1) the file_magic enumeration returned by identify_magic() 46 /// 2) the whole file content buffer if the above is not enough. 47 virtual bool canParse(llvm::file_magic magic, MemoryBufferRef mb) const = 0; 48 49 /// \brief Parse a supplied buffer (already filled with the contents of a 50 /// file) and create a File object. 51 /// The resulting File object takes ownership of the MemoryBuffer. 52 virtual ErrorOr<std::unique_ptr<File>> 53 loadFile(std::unique_ptr<MemoryBuffer> mb, const class Registry &) const = 0; 54 }; 55 56 /// \brief An abstract class for handling alternate yaml representations 57 /// of object files. 58 /// 59 /// The YAML syntax allows "tags" which are used to specify the type of 60 /// the YAML node. In lld, top level YAML documents can be in many YAML 61 /// representations (e.g mach-o encoded as yaml, etc). A tag is used to 62 /// specify which representation is used in the following YAML document. 63 /// To work, there must be a YamlIOTaggedDocumentHandler registered that 64 /// handles each tag type. 65 class YamlIOTaggedDocumentHandler { 66 public: 67 virtual ~YamlIOTaggedDocumentHandler(); 68 69 /// This method is called on each registered YamlIOTaggedDocumentHandler 70 /// until one returns true. If the subclass handles tag type !xyz, then 71 /// this method should call io.mapTag("!xzy") to see if that is the current 72 /// document type, and if so, process the rest of the document using 73 /// YAML I/O, then convert the result into an lld::File* and return it. 74 virtual bool handledDocTag(llvm::yaml::IO &io, const lld::File *&f) const = 0; 75 }; 76 77 /// A registry to hold the list of currently registered Readers and 78 /// tables which map Reference kind values to strings. 79 /// The linker does not directly invoke Readers. Instead, it registers 80 /// Readers based on it configuration and command line options, then calls 81 /// the Registry object to parse files. 82 class Registry { 83 public: 84 Registry(); 85 86 /// Walk the list of registered Readers and find one that can parse the 87 /// supplied file and parse it. 88 ErrorOr<std::unique_ptr<File>> 89 loadFile(std::unique_ptr<MemoryBuffer> mb) const; 90 91 /// Walk the list of registered kind tables to convert a Reference Kind 92 /// name to a value. 93 bool referenceKindFromString(StringRef inputStr, Reference::KindNamespace &ns, 94 Reference::KindArch &a, 95 Reference::KindValue &value) const; 96 97 /// Walk the list of registered kind tables to convert a Reference Kind 98 /// value to a string. 99 bool referenceKindToString(Reference::KindNamespace ns, Reference::KindArch a, 100 Reference::KindValue value, StringRef &) const; 101 102 /// Walk the list of registered tag handlers and have the one that handles 103 /// the current document type process the yaml into an lld::File*. 104 bool handleTaggedDoc(llvm::yaml::IO &io, const lld::File *&file) const; 105 106 // These methods are called to dynamically add support for various file 107 // formats. The methods are also implemented in the appropriate lib*.a 108 // library, so that the code for handling a format is only linked in, if this 109 // method is used. Any options that a Reader might need must be passed 110 // as parameters to the addSupport*() method. 111 void addSupportArchives(bool logLoading); 112 void addSupportYamlFiles(); 113 void addSupportMachOObjects(MachOLinkingContext &); 114 115 /// To convert between kind values and names, the registry walks the list 116 /// of registered kind tables. Each table is a zero terminated array of 117 /// KindStrings elements. 118 struct KindStrings { 119 Reference::KindValue value; 120 StringRef name; 121 }; 122 123 /// A Reference Kind value is a tuple of <namespace, arch, value>. All 124 /// entries in a conversion table have the same <namespace, arch>. The 125 /// array then contains the value/name pairs. 126 void addKindTable(Reference::KindNamespace ns, Reference::KindArch arch, 127 const KindStrings array[]); 128 129 private: 130 struct KindEntry { 131 Reference::KindNamespace ns; 132 Reference::KindArch arch; 133 const KindStrings *array; 134 }; 135 136 void add(std::unique_ptr<Reader>); 137 void add(std::unique_ptr<YamlIOTaggedDocumentHandler>); 138 139 std::vector<std::unique_ptr<Reader>> _readers; 140 std::vector<std::unique_ptr<YamlIOTaggedDocumentHandler>> _yamlHandlers; 141 std::vector<KindEntry> _kindEntries; 142 }; 143 144 // Utilities for building a KindString table. For instance: 145 // static const Registry::KindStrings table[] = { 146 // LLD_KIND_STRING_ENTRY(R_VAX_ADDR16), 147 // LLD_KIND_STRING_ENTRY(R_VAX_DATA16), 148 // LLD_KIND_STRING_END 149 // }; 150 #define LLD_KIND_STRING_ENTRY(name) { name, #name } 151 #define LLD_KIND_STRING_END { 0, "" } 152 153 } // end namespace lld 154 155 #endif // LLD_CORE_READER_H 156