Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/lld/include/lld/Core/Reader.h
Line
Count
Source
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
892
  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