Coverage Report

Created: 2019-05-19 14:56

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