Coverage Report

Created: 2017-09-19 22:28

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/lld/ELF/InputFiles.h
Line
Count
Source (jump to first uncovered line)
1
//===- InputFiles.h ---------------------------------------------*- C++ -*-===//
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_ELF_INPUT_FILES_H
11
#define LLD_ELF_INPUT_FILES_H
12
13
#include "Config.h"
14
#include "Error.h"
15
#include "InputSection.h"
16
#include "Symbols.h"
17
18
#include "lld/Core/LLVM.h"
19
#include "lld/Core/Reproduce.h"
20
#include "llvm/ADT/CachedHashString.h"
21
#include "llvm/ADT/DenseSet.h"
22
#include "llvm/ADT/STLExtras.h"
23
#include "llvm/IR/Comdat.h"
24
#include "llvm/Object/Archive.h"
25
#include "llvm/Object/ELF.h"
26
#include "llvm/Object/IRObjectFile.h"
27
#include "llvm/Support/Threading.h"
28
29
#include <map>
30
31
namespace llvm {
32
class DWARFDebugLine;
33
class TarWriter;
34
struct DILineInfo;
35
namespace lto {
36
class InputFile;
37
}
38
} // namespace llvm
39
40
namespace lld {
41
namespace elf {
42
class InputFile;
43
}
44
45
// Returns "(internal)", "foo.a(bar.o)" or "baz.o".
46
std::string toString(const elf::InputFile *F);
47
48
namespace elf {
49
50
using llvm::object::Archive;
51
52
class Lazy;
53
class SymbolBody;
54
55
// If -reproduce option is given, all input files are written
56
// to this tar archive.
57
extern llvm::TarWriter *Tar;
58
59
// Opens a given file.
60
llvm::Optional<MemoryBufferRef> readFile(StringRef Path);
61
62
// The root class of input files.
63
class InputFile {
64
public:
65
  enum Kind {
66
    ObjKind,
67
    SharedKind,
68
    LazyObjKind,
69
    ArchiveKind,
70
    BitcodeKind,
71
    BinaryKind,
72
  };
73
74
19.9k
  Kind kind() const { return FileKind; }
75
76
134k
  StringRef getName() const { return MB.getBufferIdentifier(); }
77
  MemoryBufferRef MB;
78
79
  // Returns sections. It is a runtime error to call this function
80
  // on files that don't have the notion of sections.
81
2.33k
  ArrayRef<InputSectionBase *> getSections() const {
82
2.33k
    assert(FileKind == ObjKind || FileKind == BinaryKind);
83
2.33k
    return Sections;
84
2.33k
  }
85
86
  // Returns object file symbols. It is a runtime error to call this
87
  // function on files of other types.
88
350
  ArrayRef<SymbolBody *> getSymbols() {
89
350
    assert(FileKind == ObjKind || FileKind == BitcodeKind ||
90
350
           FileKind == ArchiveKind);
91
350
    return Symbols;
92
350
  }
93
94
  // Filename of .a which contained this file. If this file was
95
  // not in an archive file, it is the empty string. We use this
96
  // string for creating error messages.
97
  StringRef ArchiveName;
98
99
  // If this is an architecture-specific file, the following members
100
  // have ELF type (i.e. ELF{32,64}{LE,BE}) and target machine type.
101
  ELFKind EKind = ELFNoneKind;
102
  uint16_t EMachine = llvm::ELF::EM_NONE;
103
  uint8_t OSABI = 0;
104
105
  // Cache for toString(). Only toString() should use this member.
106
  mutable std::string ToStringCache;
107
108
protected:
109
  InputFile(Kind K, MemoryBufferRef M);
110
  std::vector<InputSectionBase *> Sections;
111
  std::vector<SymbolBody *> Symbols;
112
113
private:
114
  const Kind FileKind;
115
};
116
117
template <typename ELFT> class ELFFileBase : public InputFile {
118
public:
119
  typedef typename ELFT::Shdr Elf_Shdr;
120
  typedef typename ELFT::Sym Elf_Sym;
121
  typedef typename ELFT::Word Elf_Word;
122
  typedef typename ELFT::SymRange Elf_Sym_Range;
123
124
  ELFFileBase(Kind K, MemoryBufferRef M);
125
4.38k
  static bool classof(const InputFile *F) {
126
4.38k
    Kind K = F->kind();
127
693
    return K == ObjKind || K == SharedKind;
128
4.38k
  }
lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)1, true> >::classof(lld::elf::InputFile const*)
Line
Count
Source
125
3.17k
  static bool classof(const InputFile *F) {
126
3.17k
    Kind K = F->kind();
127
586
    return K == ObjKind || K == SharedKind;
128
3.17k
  }
lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)1, false> >::classof(lld::elf::InputFile const*)
Line
Count
Source
125
506
  static bool classof(const InputFile *F) {
126
506
    Kind K = F->kind();
127
59
    return K == ObjKind || K == SharedKind;
128
506
  }
lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)0, false> >::classof(lld::elf::InputFile const*)
Line
Count
Source
125
532
  static bool classof(const InputFile *F) {
126
532
    Kind K = F->kind();
127
36
    return K == ObjKind || K == SharedKind;
128
532
  }
lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)0, true> >::classof(lld::elf::InputFile const*)
Line
Count
Source
125
174
  static bool classof(const InputFile *F) {
126
174
    Kind K = F->kind();
127
12
    return K == ObjKind || K == SharedKind;
128
174
  }
129
130
423k
  llvm::object::ELFFile<ELFT> getObj() const {
131
423k
    return llvm::object::ELFFile<ELFT>(MB.getBuffer());
132
423k
  }
lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)0, true> >::getObj() const
Line
Count
Source
130
1.18k
  llvm::object::ELFFile<ELFT> getObj() const {
131
1.18k
    return llvm::object::ELFFile<ELFT>(MB.getBuffer());
132
1.18k
  }
lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)1, true> >::getObj() const
Line
Count
Source
130
414k
  llvm::object::ELFFile<ELFT> getObj() const {
131
414k
    return llvm::object::ELFFile<ELFT>(MB.getBuffer());
132
414k
  }
lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)0, false> >::getObj() const
Line
Count
Source
130
3.27k
  llvm::object::ELFFile<ELFT> getObj() const {
131
3.27k
    return llvm::object::ELFFile<ELFT>(MB.getBuffer());
132
3.27k
  }
lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)1, false> >::getObj() const
Line
Count
Source
130
4.14k
  llvm::object::ELFFile<ELFT> getObj() const {
131
4.14k
    return llvm::object::ELFFile<ELFT>(MB.getBuffer());
132
4.14k
  }
133
134
44
  StringRef getStringTable() const { return StringTable; }
lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)1, false> >::getStringTable() const
Line
Count
Source
134
6
  StringRef getStringTable() const { return StringTable; }
lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)0, false> >::getStringTable() const
Line
Count
Source
134
5
  StringRef getStringTable() const { return StringTable; }
lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)1, true> >::getStringTable() const
Line
Count
Source
134
33
  StringRef getStringTable() const { return StringTable; }
Unexecuted instantiation: lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)0, true> >::getStringTable() const
135
136
  uint32_t getSectionIndex(const Elf_Sym &Sym) const;
137
138
  Elf_Sym_Range getGlobalELFSyms();
139
26
  Elf_Sym_Range getELFSyms() const { return ELFSyms; }
Unexecuted instantiation: lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)1, false> >::getELFSyms() const
Unexecuted instantiation: lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)0, true> >::getELFSyms() const
lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)1, true> >::getELFSyms() const
Line
Count
Source
139
26
  Elf_Sym_Range getELFSyms() const { return ELFSyms; }
Unexecuted instantiation: lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)0, false> >::getELFSyms() const
140
141
protected:
142
  ArrayRef<Elf_Sym> ELFSyms;
143
  uint32_t FirstNonLocal = 0;
144
  ArrayRef<Elf_Word> SymtabSHNDX;
145
  StringRef StringTable;
146
  void initSymtab(ArrayRef<Elf_Shdr> Sections, const Elf_Shdr *Symtab);
147
};
148
149
// .o file.
150
template <class ELFT> class ObjFile : public ELFFileBase<ELFT> {
151
  typedef ELFFileBase<ELFT> Base;
152
  typedef typename ELFT::Rel Elf_Rel;
153
  typedef typename ELFT::Rela Elf_Rela;
154
  typedef typename ELFT::Sym Elf_Sym;
155
  typedef typename ELFT::Shdr Elf_Shdr;
156
  typedef typename ELFT::Word Elf_Word;
157
158
  StringRef getShtGroupSignature(ArrayRef<Elf_Shdr> Sections,
159
                                 const Elf_Shdr &Sec);
160
  ArrayRef<Elf_Word> getShtGroupEntries(const Elf_Shdr &Sec);
161
162
public:
163
0
  static bool classof(const InputFile *F) { return F->kind() == Base::ObjKind; }
Unexecuted instantiation: lld::elf::ObjFile<llvm::object::ELFType<(llvm::support::endianness)0, true> >::classof(lld::elf::InputFile const*)
Unexecuted instantiation: lld::elf::ObjFile<llvm::object::ELFType<(llvm::support::endianness)1, true> >::classof(lld::elf::InputFile const*)
Unexecuted instantiation: lld::elf::ObjFile<llvm::object::ELFType<(llvm::support::endianness)0, false> >::classof(lld::elf::InputFile const*)
Unexecuted instantiation: lld::elf::ObjFile<llvm::object::ELFType<(llvm::support::endianness)1, false> >::classof(lld::elf::InputFile const*)
164
165
  ArrayRef<SymbolBody *> getLocalSymbols();
166
167
  ObjFile(MemoryBufferRef M, StringRef ArchiveName);
168
  void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
169
170
  InputSectionBase *getSection(const Elf_Sym &Sym) const;
171
172
2.38k
  SymbolBody &getSymbolBody(uint32_t SymbolIndex) const {
173
2.38k
    if (SymbolIndex >= this->Symbols.size())
174
0
      fatal(toString(this) + ": invalid symbol index");
175
2.38k
    return *this->Symbols[SymbolIndex];
176
2.38k
  }
lld::elf::ObjFile<llvm::object::ELFType<(llvm::support::endianness)0, true> >::getSymbolBody(unsigned int) const
Line
Count
Source
172
99
  SymbolBody &getSymbolBody(uint32_t SymbolIndex) const {
173
99
    if (SymbolIndex >= this->Symbols.size())
174
0
      fatal(toString(this) + ": invalid symbol index");
175
99
    return *this->Symbols[SymbolIndex];
176
99
  }
lld::elf::ObjFile<llvm::object::ELFType<(llvm::support::endianness)1, false> >::getSymbolBody(unsigned int) const
Line
Count
Source
172
540
  SymbolBody &getSymbolBody(uint32_t SymbolIndex) const {
173
540
    if (SymbolIndex >= this->Symbols.size())
174
0
      fatal(toString(this) + ": invalid symbol index");
175
540
    return *this->Symbols[SymbolIndex];
176
540
  }
lld::elf::ObjFile<llvm::object::ELFType<(llvm::support::endianness)0, false> >::getSymbolBody(unsigned int) const
Line
Count
Source
172
240
  SymbolBody &getSymbolBody(uint32_t SymbolIndex) const {
173
240
    if (SymbolIndex >= this->Symbols.size())
174
0
      fatal(toString(this) + ": invalid symbol index");
175
240
    return *this->Symbols[SymbolIndex];
176
240
  }
lld::elf::ObjFile<llvm::object::ELFType<(llvm::support::endianness)1, true> >::getSymbolBody(unsigned int) const
Line
Count
Source
172
1.50k
  SymbolBody &getSymbolBody(uint32_t SymbolIndex) const {
173
1.50k
    if (SymbolIndex >= this->Symbols.size())
174
0
      fatal(toString(this) + ": invalid symbol index");
175
1.50k
    return *this->Symbols[SymbolIndex];
176
1.50k
  }
177
178
  template <typename RelT>
179
2.38k
  SymbolBody &getRelocTargetSym(const RelT &Rel) const {
180
2.38k
    uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
181
2.38k
    return getSymbolBody(SymIndex);
182
2.38k
  }
lld::elf::SymbolBody& lld::elf::ObjFile<llvm::object::ELFType<(llvm::support::endianness)1, true> >::getRelocTargetSym<llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)1, true>, true> >(llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)1, true>, true> const&) const
Line
Count
Source
179
1.49k
  SymbolBody &getRelocTargetSym(const RelT &Rel) const {
180
1.49k
    uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
181
1.49k
    return getSymbolBody(SymIndex);
182
1.49k
  }
lld::elf::SymbolBody& lld::elf::ObjFile<llvm::object::ELFType<(llvm::support::endianness)0, false> >::getRelocTargetSym<llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)0, false>, false> >(llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)0, false>, false> const&) const
Line
Count
Source
179
232
  SymbolBody &getRelocTargetSym(const RelT &Rel) const {
180
232
    uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
181
232
    return getSymbolBody(SymIndex);
182
232
  }
lld::elf::SymbolBody& lld::elf::ObjFile<llvm::object::ELFType<(llvm::support::endianness)0, true> >::getRelocTargetSym<llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)0, true>, true> >(llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)0, true>, true> const&) const
Line
Count
Source
179
99
  SymbolBody &getRelocTargetSym(const RelT &Rel) const {
180
99
    uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
181
99
    return getSymbolBody(SymIndex);
182
99
  }
lld::elf::SymbolBody& lld::elf::ObjFile<llvm::object::ELFType<(llvm::support::endianness)1, false> >::getRelocTargetSym<llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)1, false>, false> >(llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)1, false>, false> const&) const
Line
Count
Source
179
538
  SymbolBody &getRelocTargetSym(const RelT &Rel) const {
180
538
    uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
181
538
    return getSymbolBody(SymIndex);
182
538
  }
lld::elf::SymbolBody& lld::elf::ObjFile<llvm::object::ELFType<(llvm::support::endianness)1, false> >::getRelocTargetSym<llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)1, false>, true> >(llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)1, false>, true> const&) const
Line
Count
Source
179
2
  SymbolBody &getRelocTargetSym(const RelT &Rel) const {
180
2
    uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
181
2
    return getSymbolBody(SymIndex);
182
2
  }
lld::elf::SymbolBody& lld::elf::ObjFile<llvm::object::ELFType<(llvm::support::endianness)1, true> >::getRelocTargetSym<llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)1, true>, false> >(llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)1, true>, false> const&) const
Line
Count
Source
179
2
  SymbolBody &getRelocTargetSym(const RelT &Rel) const {
180
2
    uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
181
2
    return getSymbolBody(SymIndex);
182
2
  }
Unexecuted instantiation: lld::elf::SymbolBody& lld::elf::ObjFile<llvm::object::ELFType<(llvm::support::endianness)0, true> >::getRelocTargetSym<llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)0, true>, false> >(llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)0, true>, false> const&) const
lld::elf::SymbolBody& lld::elf::ObjFile<llvm::object::ELFType<(llvm::support::endianness)0, false> >::getRelocTargetSym<llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)0, false>, true> >(llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)0, false>, true> const&) const
Line
Count
Source
179
8
  SymbolBody &getRelocTargetSym(const RelT &Rel) const {
180
8
    uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
181
8
    return getSymbolBody(SymIndex);
182
8
  }
183
184
  // Returns source line information for a given offset.
185
  // If no information is available, returns "".
186
  std::string getLineInfo(InputSectionBase *S, uint64_t Offset);
187
  llvm::Optional<llvm::DILineInfo> getDILineInfo(InputSectionBase *, uint64_t);
188
189
  // MIPS GP0 value defined by this file. This value represents the gp value
190
  // used to create the relocatable object and required to support
191
  // R_MIPS_GPREL16 / R_MIPS_GPREL32 relocations.
192
  uint32_t MipsGp0 = 0;
193
194
  // Name of source file obtained from STT_FILE symbol value,
195
  // or empty string if there is no such symbol in object file
196
  // symbol table.
197
  StringRef SourceFile;
198
199
private:
200
  void
201
  initializeSections(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
202
  void initializeSymbols();
203
  void initializeDwarfLine();
204
  InputSectionBase *getRelocTarget(const Elf_Shdr &Sec);
205
  InputSectionBase *createInputSection(const Elf_Shdr &Sec);
206
  StringRef getSectionName(const Elf_Shdr &Sec);
207
208
  bool shouldMerge(const Elf_Shdr &Sec);
209
  SymbolBody *createSymbolBody(const Elf_Sym *Sym);
210
211
  // .shstrtab contents.
212
  StringRef SectionStringTable;
213
214
  // Debugging information to retrieve source file and line for error
215
  // reporting. Linker may find reasonable number of errors in a
216
  // single object file, so we cache debugging information in order to
217
  // parse it only once for each object file we link.
218
  std::unique_ptr<llvm::DWARFDebugLine> DwarfLine;
219
  llvm::once_flag InitDwarfLine;
220
};
221
222
// LazyObjFile is analogous to ArchiveFile in the sense that
223
// the file contains lazy symbols. The difference is that
224
// LazyObjFile wraps a single file instead of multiple files.
225
//
226
// This class is used for --start-lib and --end-lib options which
227
// instruct the linker to link object files between them with the
228
// archive file semantics.
229
class LazyObjFile : public InputFile {
230
public:
231
  LazyObjFile(MemoryBufferRef M, StringRef ArchiveName,
232
              uint64_t OffsetInArchive)
233
19
      : InputFile(LazyObjKind, M), OffsetInArchive(OffsetInArchive) {
234
19
    this->ArchiveName = ArchiveName;
235
19
  }
236
237
2.20k
  static bool classof(const InputFile *F) { return F->kind() == LazyObjKind; }
238
239
  template <class ELFT> void parse();
240
  MemoryBufferRef getBuffer();
241
  InputFile *fetch();
242
243
private:
244
  std::vector<StringRef> getSymbolNames();
245
  template <class ELFT> std::vector<StringRef> getElfSymbols();
246
  std::vector<StringRef> getBitcodeSymbols();
247
248
  bool Seen = false;
249
  uint64_t OffsetInArchive;
250
};
251
252
// An ArchiveFile object represents a .a file.
253
class ArchiveFile : public InputFile {
254
public:
255
  explicit ArchiveFile(std::unique_ptr<Archive> &&File);
256
2.27k
  static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; }
257
  template <class ELFT> void parse();
258
259
  // Returns a memory buffer for a given symbol and the offset in the archive
260
  // for the member. An empty memory buffer and an offset of zero
261
  // is returned if we have already returned the same memory buffer.
262
  // (So that we don't instantiate same members more than once.)
263
  std::pair<MemoryBufferRef, uint64_t> getMember(const Archive::Symbol *Sym);
264
265
private:
266
  std::unique_ptr<Archive> File;
267
  llvm::DenseSet<uint64_t> Seen;
268
};
269
270
class BitcodeFile : public InputFile {
271
public:
272
  BitcodeFile(MemoryBufferRef M, StringRef ArchiveName,
273
              uint64_t OffsetInArchive);
274
2.21k
  static bool classof(const InputFile *F) { return F->kind() == BitcodeKind; }
275
  template <class ELFT>
276
  void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
277
  std::unique_ptr<llvm::lto::InputFile> Obj;
278
};
279
280
// .so file.
281
template <class ELFT> class SharedFile : public ELFFileBase<ELFT> {
282
  typedef ELFFileBase<ELFT> Base;
283
  typedef typename ELFT::Dyn Elf_Dyn;
284
  typedef typename ELFT::Shdr Elf_Shdr;
285
  typedef typename ELFT::Sym Elf_Sym;
286
  typedef typename ELFT::SymRange Elf_Sym_Range;
287
  typedef typename ELFT::Verdef Elf_Verdef;
288
  typedef typename ELFT::Versym Elf_Versym;
289
290
  std::vector<StringRef> Undefs;
291
  const Elf_Shdr *VersymSec = nullptr;
292
  const Elf_Shdr *VerdefSec = nullptr;
293
294
public:
295
  std::string SoName;
296
297
  const Elf_Shdr *getSection(const Elf_Sym &Sym) const;
298
213
  llvm::ArrayRef<StringRef> getUndefinedSymbols() { return Undefs; }
lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)1, false> >::getUndefinedSymbols()
Line
Count
Source
298
38
  llvm::ArrayRef<StringRef> getUndefinedSymbols() { return Undefs; }
lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)0, false> >::getUndefinedSymbols()
Line
Count
Source
298
17
  llvm::ArrayRef<StringRef> getUndefinedSymbols() { return Undefs; }
lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)0, true> >::getUndefinedSymbols()
Line
Count
Source
298
7
  llvm::ArrayRef<StringRef> getUndefinedSymbols() { return Undefs; }
lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)1, true> >::getUndefinedSymbols()
Line
Count
Source
298
151
  llvm::ArrayRef<StringRef> getUndefinedSymbols() { return Undefs; }
299
300
2.18k
  static bool classof(const InputFile *F) {
301
2.18k
    return F->kind() == Base::SharedKind;
302
2.18k
  }
lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)1, false> >::classof(lld::elf::InputFile const*)
Line
Count
Source
300
265
  static bool classof(const InputFile *F) {
301
265
    return F->kind() == Base::SharedKind;
302
265
  }
lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)0, false> >::classof(lld::elf::InputFile const*)
Line
Count
Source
300
142
  static bool classof(const InputFile *F) {
301
142
    return F->kind() == Base::SharedKind;
302
142
  }
lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)1, true> >::classof(lld::elf::InputFile const*)
Line
Count
Source
300
1.71k
  static bool classof(const InputFile *F) {
301
1.71k
    return F->kind() == Base::SharedKind;
302
1.71k
  }
lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)0, true> >::classof(lld::elf::InputFile const*)
Line
Count
Source
300
58
  static bool classof(const InputFile *F) {
301
58
    return F->kind() == Base::SharedKind;
302
58
  }
303
304
  SharedFile(MemoryBufferRef M, StringRef DefaultSoName);
305
306
  void parseSoName();
307
  void parseRest();
308
  std::vector<const Elf_Verdef *> parseVerdefs(const Elf_Versym *&Versym);
309
310
  struct NeededVer {
311
    // The string table offset of the version name in the output file.
312
    size_t StrTab;
313
314
    // The version identifier for this version name.
315
    uint16_t Index;
316
  };
317
318
  // Mapping from Elf_Verdef data structures to information about Elf_Vernaux
319
  // data structures in the output file.
320
  std::map<const Elf_Verdef *, NeededVer> VerdefMap;
321
322
  // Used for --as-needed
323
  bool AsNeeded = false;
324
  bool IsUsed = false;
325
449
  bool isNeeded() const 
{ return !AsNeeded || 449
IsUsed21
; }
lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)0, false> >::isNeeded() const
Line
Count
Source
325
37
  bool isNeeded() const 
{ return !AsNeeded || 37
IsUsed0
; }
lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)0, true> >::isNeeded() const
Line
Count
Source
325
15
  bool isNeeded() const 
{ return !AsNeeded || 15
IsUsed0
; }
lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)1, true> >::isNeeded() const
Line
Count
Source
325
307
  bool isNeeded() const 
{ return !AsNeeded || 307
IsUsed6
; }
lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)1, false> >::isNeeded() const
Line
Count
Source
325
90
  bool isNeeded() const 
{ return !AsNeeded || 90
IsUsed15
; }
326
};
327
328
class BinaryFile : public InputFile {
329
public:
330
5
  explicit BinaryFile(MemoryBufferRef M) : InputFile(BinaryKind, M) {}
331
2.27k
  static bool classof(const InputFile *F) { return F->kind() == BinaryKind; }
332
  template <class ELFT> void parse();
333
};
334
335
InputFile *createObjectFile(MemoryBufferRef MB, StringRef ArchiveName = "",
336
                            uint64_t OffsetInArchive = 0);
337
InputFile *createSharedFile(MemoryBufferRef MB, StringRef DefaultSoName);
338
339
extern std::vector<BinaryFile *> BinaryFiles;
340
extern std::vector<BitcodeFile *> BitcodeFiles;
341
extern std::vector<InputFile *> ObjectFiles;
342
extern std::vector<InputFile *> SharedFiles;
343
344
} // namespace elf
345
} // namespace lld
346
347
#endif