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