Coverage Report

Created: 2018-10-20 12:32

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/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 "lld/Common/ErrorHandler.h"
15
#include "lld/Common/LLVM.h"
16
#include "lld/Common/Reproduce.h"
17
#include "llvm/ADT/CachedHashString.h"
18
#include "llvm/ADT/DenseSet.h"
19
#include "llvm/ADT/STLExtras.h"
20
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
21
#include "llvm/IR/Comdat.h"
22
#include "llvm/Object/Archive.h"
23
#include "llvm/Object/ELF.h"
24
#include "llvm/Object/IRObjectFile.h"
25
#include "llvm/Support/Threading.h"
26
#include <map>
27
28
namespace llvm {
29
class TarWriter;
30
struct DILineInfo;
31
namespace lto {
32
class InputFile;
33
}
34
} // namespace llvm
35
36
namespace lld {
37
namespace elf {
38
class InputFile;
39
class InputSectionBase;
40
}
41
42
// Returns "<internal>", "foo.a(bar.o)" or "baz.o".
43
std::string toString(const elf::InputFile *F);
44
45
namespace elf {
46
47
using llvm::object::Archive;
48
49
class Symbol;
50
51
// If -reproduce option is given, all input files are written
52
// to this tar archive.
53
extern llvm::TarWriter *Tar;
54
55
// Opens a given file.
56
llvm::Optional<MemoryBufferRef> readFile(StringRef Path);
57
58
// The root class of input files.
59
class InputFile {
60
public:
61
  enum Kind {
62
    ObjKind,
63
    SharedKind,
64
    LazyObjKind,
65
    ArchiveKind,
66
    BitcodeKind,
67
    BinaryKind,
68
  };
69
70
40.0k
  Kind kind() const { return FileKind; }
71
72
4.12k
  bool isElf() const {
73
4.12k
    Kind K = kind();
74
4.12k
    return K == ObjKind || 
K == SharedKind929
;
75
4.12k
  }
76
77
134k
  StringRef getName() const { return MB.getBufferIdentifier(); }
78
  MemoryBufferRef MB;
79
80
  // Returns sections. It is a runtime error to call this function
81
  // on files that don't have the notion of sections.
82
3.56k
  ArrayRef<InputSectionBase *> getSections() const {
83
3.56k
    assert(FileKind == ObjKind || FileKind == BinaryKind);
84
3.56k
    return Sections;
85
3.56k
  }
86
87
  // Returns object file symbols. It is a runtime error to call this
88
  // function on files of other types.
89
2.49k
  ArrayRef<Symbol *> getSymbols() { return getMutableSymbols(); }
90
91
2.51k
  std::vector<Symbol *> &getMutableSymbols() {
92
2.51k
    assert(FileKind == BinaryKind || FileKind == ObjKind ||
93
2.51k
           FileKind == BitcodeKind);
94
2.51k
    return Symbols;
95
2.51k
  }
96
97
  // Filename of .a which contained this file. If this file was
98
  // not in an archive file, it is the empty string. We use this
99
  // string for creating error messages.
100
  std::string ArchiveName;
101
102
  // If this is an architecture-specific file, the following members
103
  // have ELF type (i.e. ELF{32,64}{LE,BE}) and target machine type.
104
  ELFKind EKind = ELFNoneKind;
105
  uint16_t EMachine = llvm::ELF::EM_NONE;
106
  uint8_t OSABI = 0;
107
108
  // Cache for toString(). Only toString() should use this member.
109
  mutable std::string ToStringCache;
110
111
  std::string getSrcMsg(const Symbol &Sym, InputSectionBase &Sec,
112
                        uint64_t Offset);
113
114
  // True if this is an argument for --just-symbols. Usually false.
115
  bool JustSymbols = false;
116
117
  // GroupId is used for --warn-backrefs which is an optional error
118
  // checking feature. All files within the same --{start,end}-group or
119
  // --{start,end}-lib get the same group ID. Otherwise, each file gets a new
120
  // group ID. For more info, see checkDependency() in SymbolTable.cpp.
121
  uint32_t GroupId;
122
  static bool IsInGroup;
123
  static uint32_t NextGroupId;
124
125
  // Index of MIPS GOT built for this file.
126
  llvm::Optional<size_t> MipsGotIndex;
127
128
protected:
129
  InputFile(Kind K, MemoryBufferRef M);
130
  std::vector<InputSectionBase *> Sections;
131
  std::vector<Symbol *> Symbols;
132
133
private:
134
  const Kind FileKind;
135
};
136
137
template <typename ELFT> class ELFFileBase : public InputFile {
138
public:
139
  typedef typename ELFT::Shdr Elf_Shdr;
140
  typedef typename ELFT::Sym Elf_Sym;
141
  typedef typename ELFT::Word Elf_Word;
142
  typedef typename ELFT::SymRange Elf_Sym_Range;
143
144
  ELFFileBase(Kind K, MemoryBufferRef M);
145
520
  static bool classof(const InputFile *F) { return F->isElf(); }
lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)1, false> >::classof(lld::elf::InputFile const*)
Line
Count
Source
145
44
  static bool classof(const InputFile *F) { return F->isElf(); }
lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)0, false> >::classof(lld::elf::InputFile const*)
Line
Count
Source
145
361
  static bool classof(const InputFile *F) { return F->isElf(); }
lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)1, true> >::classof(lld::elf::InputFile const*)
Line
Count
Source
145
3
  static bool classof(const InputFile *F) { return F->isElf(); }
lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)0, true> >::classof(lld::elf::InputFile const*)
Line
Count
Source
145
112
  static bool classof(const InputFile *F) { return F->isElf(); }
146
147
780k
  llvm::object::ELFFile<ELFT> getObj() const {
148
780k
    return check(llvm::object::ELFFile<ELFT>::create(MB.getBuffer()));
149
780k
  }
lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)1, true> >::getObj() const
Line
Count
Source
147
756k
  llvm::object::ELFFile<ELFT> getObj() const {
148
756k
    return check(llvm::object::ELFFile<ELFT>::create(MB.getBuffer()));
149
756k
  }
lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)1, false> >::getObj() const
Line
Count
Source
147
7.35k
  llvm::object::ELFFile<ELFT> getObj() const {
148
7.35k
    return check(llvm::object::ELFFile<ELFT>::create(MB.getBuffer()));
149
7.35k
  }
lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)0, false> >::getObj() const
Line
Count
Source
147
3.83k
  llvm::object::ELFFile<ELFT> getObj() const {
148
3.83k
    return check(llvm::object::ELFFile<ELFT>::create(MB.getBuffer()));
149
3.83k
  }
lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)0, true> >::getObj() const
Line
Count
Source
147
12.5k
  llvm::object::ELFFile<ELFT> getObj() const {
148
12.5k
    return check(llvm::object::ELFFile<ELFT>::create(MB.getBuffer()));
149
12.5k
  }
150
151
85
  StringRef getStringTable() const { return StringTable; }
lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)1, false> >::getStringTable() const
Line
Count
Source
151
6
  StringRef getStringTable() const { return StringTable; }
lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)0, false> >::getStringTable() const
Line
Count
Source
151
6
  StringRef getStringTable() const { return StringTable; }
lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)1, true> >::getStringTable() const
Line
Count
Source
151
73
  StringRef getStringTable() const { return StringTable; }
Unexecuted instantiation: lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)0, true> >::getStringTable() const
152
153
  uint32_t getSectionIndex(const Elf_Sym &Sym) const;
154
155
  Elf_Sym_Range getGlobalELFSyms();
156
95
  Elf_Sym_Range getELFSyms() const { return ELFSyms; }
lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)1, false> >::getELFSyms() const
Line
Count
Source
156
6
  Elf_Sym_Range getELFSyms() const { return ELFSyms; }
Unexecuted instantiation: lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)0, false> >::getELFSyms() const
lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)1, true> >::getELFSyms() const
Line
Count
Source
156
89
  Elf_Sym_Range getELFSyms() const { return ELFSyms; }
Unexecuted instantiation: lld::elf::ELFFileBase<llvm::object::ELFType<(llvm::support::endianness)0, true> >::getELFSyms() const
157
158
protected:
159
  ArrayRef<Elf_Sym> ELFSyms;
160
  uint32_t FirstGlobal = 0;
161
  ArrayRef<Elf_Word> SymtabSHNDX;
162
  StringRef StringTable;
163
  void initSymtab(ArrayRef<Elf_Shdr> Sections, const Elf_Shdr *Symtab);
164
};
165
166
// .o file.
167
template <class ELFT> class ObjFile : public ELFFileBase<ELFT> {
168
  typedef ELFFileBase<ELFT> Base;
169
  typedef typename ELFT::Rel Elf_Rel;
170
  typedef typename ELFT::Rela Elf_Rela;
171
  typedef typename ELFT::Sym Elf_Sym;
172
  typedef typename ELFT::Shdr Elf_Shdr;
173
  typedef typename ELFT::Word Elf_Word;
174
  typedef typename ELFT::CGProfile Elf_CGProfile;
175
176
  StringRef getShtGroupSignature(ArrayRef<Elf_Shdr> Sections,
177
                                 const Elf_Shdr &Sec);
178
  ArrayRef<Elf_Word> getShtGroupEntries(const Elf_Shdr &Sec);
179
180
public:
181
0
  static bool classof(const InputFile *F) { return F->kind() == Base::ObjKind; }
Unexecuted instantiation: lld::elf::ObjFile<llvm::object::ELFType<(llvm::support::endianness)1, false> >::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, true> >::classof(lld::elf::InputFile const*)
Unexecuted instantiation: lld::elf::ObjFile<llvm::object::ELFType<(llvm::support::endianness)0, true> >::classof(lld::elf::InputFile const*)
182
183
  ArrayRef<Symbol *> getLocalSymbols();
184
  ArrayRef<Symbol *> getGlobalSymbols();
185
186
  ObjFile(MemoryBufferRef M, StringRef ArchiveName);
187
  void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
188
189
14.4k
  Symbol &getSymbol(uint32_t SymbolIndex) const {
190
14.4k
    if (SymbolIndex >= this->Symbols.size())
191
0
      fatal(toString(this) + ": invalid symbol index");
192
14.4k
    return *this->Symbols[SymbolIndex];
193
14.4k
  }
lld::elf::ObjFile<llvm::object::ELFType<(llvm::support::endianness)1, false> >::getSymbol(unsigned int) const
Line
Count
Source
189
960
  Symbol &getSymbol(uint32_t SymbolIndex) const {
190
960
    if (SymbolIndex >= this->Symbols.size())
191
0
      fatal(toString(this) + ": invalid symbol index");
192
960
    return *this->Symbols[SymbolIndex];
193
960
  }
lld::elf::ObjFile<llvm::object::ELFType<(llvm::support::endianness)0, false> >::getSymbol(unsigned int) const
Line
Count
Source
189
285
  Symbol &getSymbol(uint32_t SymbolIndex) const {
190
285
    if (SymbolIndex >= this->Symbols.size())
191
0
      fatal(toString(this) + ": invalid symbol index");
192
285
    return *this->Symbols[SymbolIndex];
193
285
  }
lld::elf::ObjFile<llvm::object::ELFType<(llvm::support::endianness)1, true> >::getSymbol(unsigned int) const
Line
Count
Source
189
2.82k
  Symbol &getSymbol(uint32_t SymbolIndex) const {
190
2.82k
    if (SymbolIndex >= this->Symbols.size())
191
0
      fatal(toString(this) + ": invalid symbol index");
192
2.82k
    return *this->Symbols[SymbolIndex];
193
2.82k
  }
lld::elf::ObjFile<llvm::object::ELFType<(llvm::support::endianness)0, true> >::getSymbol(unsigned int) const
Line
Count
Source
189
10.3k
  Symbol &getSymbol(uint32_t SymbolIndex) const {
190
10.3k
    if (SymbolIndex >= this->Symbols.size())
191
0
      fatal(toString(this) + ": invalid symbol index");
192
10.3k
    return *this->Symbols[SymbolIndex];
193
10.3k
  }
194
195
14.4k
  template <typename RelT> Symbol &getRelocTargetSym(const RelT &Rel) const {
196
14.4k
    uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
197
14.4k
    return getSymbol(SymIndex);
198
14.4k
  }
lld::elf::Symbol& 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
195
103
  template <typename RelT> Symbol &getRelocTargetSym(const RelT &Rel) const {
196
103
    uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
197
103
    return getSymbol(SymIndex);
198
103
  }
lld::elf::Symbol& 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
195
857
  template <typename RelT> Symbol &getRelocTargetSym(const RelT &Rel) const {
196
857
    uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
197
857
    return getSymbol(SymIndex);
198
857
  }
lld::elf::Symbol& 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
195
13
  template <typename RelT> Symbol &getRelocTargetSym(const RelT &Rel) const {
196
13
    uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
197
13
    return getSymbol(SymIndex);
198
13
  }
lld::elf::Symbol& 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
195
272
  template <typename RelT> Symbol &getRelocTargetSym(const RelT &Rel) const {
196
272
    uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
197
272
    return getSymbol(SymIndex);
198
272
  }
lld::elf::Symbol& 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
195
2.77k
  template <typename RelT> Symbol &getRelocTargetSym(const RelT &Rel) const {
196
2.77k
    uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
197
2.77k
    return getSymbol(SymIndex);
198
2.77k
  }
lld::elf::Symbol& 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
195
2
  template <typename RelT> Symbol &getRelocTargetSym(const RelT &Rel) const {
196
2
    uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
197
2
    return getSymbol(SymIndex);
198
2
  }
lld::elf::Symbol& 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
195
10.3k
  template <typename RelT> Symbol &getRelocTargetSym(const RelT &Rel) const {
196
10.3k
    uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
197
10.3k
    return getSymbol(SymIndex);
198
10.3k
  }
Unexecuted instantiation: lld::elf::Symbol& 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
199
200
  llvm::Optional<llvm::DILineInfo> getDILineInfo(InputSectionBase *, uint64_t);
201
  llvm::Optional<std::pair<std::string, unsigned>> getVariableLoc(StringRef Name);
202
203
  // MIPS GP0 value defined by this file. This value represents the gp value
204
  // used to create the relocatable object and required to support
205
  // R_MIPS_GPREL16 / R_MIPS_GPREL32 relocations.
206
  uint32_t MipsGp0 = 0;
207
208
  // Name of source file obtained from STT_FILE symbol value,
209
  // or empty string if there is no such symbol in object file
210
  // symbol table.
211
  StringRef SourceFile;
212
213
  // True if the file defines functions compiled with
214
  // -fsplit-stack. Usually false.
215
  bool SplitStack = false;
216
217
  // True if the file defines functions compiled with -fsplit-stack,
218
  // but had one or more functions with the no_split_stack attribute.
219
  bool SomeNoSplitStack = false;
220
221
  // Pointer to this input file's .llvm_addrsig section, if it has one.
222
  const Elf_Shdr *AddrsigSec = nullptr;
223
224
  // SHT_LLVM_CALL_GRAPH_PROFILE table
225
  ArrayRef<Elf_CGProfile> CGProfile;
226
227
private:
228
  void
229
  initializeSections(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
230
  void initializeSymbols();
231
  void initializeJustSymbols();
232
  void initializeDwarf();
233
  InputSectionBase *getRelocTarget(const Elf_Shdr &Sec);
234
  InputSectionBase *createInputSection(const Elf_Shdr &Sec);
235
  StringRef getSectionName(const Elf_Shdr &Sec);
236
237
  bool shouldMerge(const Elf_Shdr &Sec);
238
  Symbol *createSymbol(const Elf_Sym *Sym);
239
240
  // .shstrtab contents.
241
  StringRef SectionStringTable;
242
243
  // Debugging information to retrieve source file and line for error
244
  // reporting. Linker may find reasonable number of errors in a
245
  // single object file, so we cache debugging information in order to
246
  // parse it only once for each object file we link.
247
  std::unique_ptr<llvm::DWARFContext> Dwarf;
248
  std::vector<const llvm::DWARFDebugLine::LineTable *> LineTables;
249
  struct VarLoc {
250
    const llvm::DWARFDebugLine::LineTable *LT;
251
    unsigned File;
252
    unsigned Line;
253
  };
254
  llvm::DenseMap<StringRef, VarLoc> VariableLoc;
255
  llvm::once_flag InitDwarfLine;
256
};
257
258
// LazyObjFile is analogous to ArchiveFile in the sense that
259
// the file contains lazy symbols. The difference is that
260
// LazyObjFile wraps a single file instead of multiple files.
261
//
262
// This class is used for --start-lib and --end-lib options which
263
// instruct the linker to link object files between them with the
264
// archive file semantics.
265
class LazyObjFile : public InputFile {
266
public:
267
  LazyObjFile(MemoryBufferRef M, StringRef ArchiveName,
268
              uint64_t OffsetInArchive)
269
30
      : InputFile(LazyObjKind, M), OffsetInArchive(OffsetInArchive) {
270
30
    this->ArchiveName = ArchiveName;
271
30
  }
272
273
3.31k
  static bool classof(const InputFile *F) { return F->kind() == LazyObjKind; }
274
275
  template <class ELFT> void parse();
276
  MemoryBufferRef getBuffer();
277
  InputFile *fetch();
278
  bool AddedToLink = false;
279
280
private:
281
  uint64_t OffsetInArchive;
282
};
283
284
// An ArchiveFile object represents a .a file.
285
class ArchiveFile : public InputFile {
286
public:
287
  explicit ArchiveFile(std::unique_ptr<Archive> &&File);
288
3.41k
  static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; }
289
  template <class ELFT> void parse();
290
291
  // Pulls out an object file that contains a definition for Sym and
292
  // returns it. If the same file was instantiated before, this
293
  // function returns a nullptr (so we don't instantiate the same file
294
  // more than once.)
295
  InputFile *fetch(const Archive::Symbol &Sym);
296
297
private:
298
  std::unique_ptr<Archive> File;
299
  llvm::DenseSet<uint64_t> Seen;
300
};
301
302
class BitcodeFile : public InputFile {
303
public:
304
  BitcodeFile(MemoryBufferRef M, StringRef ArchiveName,
305
              uint64_t OffsetInArchive);
306
3.32k
  static bool classof(const InputFile *F) { return F->kind() == BitcodeKind; }
307
  template <class ELFT>
308
  void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
309
  std::unique_ptr<llvm::lto::InputFile> Obj;
310
};
311
312
// .so file.
313
template <class ELFT> class SharedFile : public ELFFileBase<ELFT> {
314
  typedef ELFFileBase<ELFT> Base;
315
  typedef typename ELFT::Dyn Elf_Dyn;
316
  typedef typename ELFT::Shdr Elf_Shdr;
317
  typedef typename ELFT::Sym Elf_Sym;
318
  typedef typename ELFT::SymRange Elf_Sym_Range;
319
  typedef typename ELFT::Verdef Elf_Verdef;
320
  typedef typename ELFT::Versym Elf_Versym;
321
322
  const Elf_Shdr *VersymSec = nullptr;
323
  const Elf_Shdr *VerdefSec = nullptr;
324
325
public:
326
  std::vector<const Elf_Verdef *> Verdefs;
327
  std::string SoName;
328
329
5.14k
  static bool classof(const InputFile *F) {
330
5.14k
    return F->kind() == Base::SharedKind;
331
5.14k
  }
lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)1, false> >::classof(lld::elf::InputFile const*)
Line
Count
Source
329
706
  static bool classof(const InputFile *F) {
330
706
    return F->kind() == Base::SharedKind;
331
706
  }
lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)0, false> >::classof(lld::elf::InputFile const*)
Line
Count
Source
329
342
  static bool classof(const InputFile *F) {
330
342
    return F->kind() == Base::SharedKind;
331
342
  }
lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)1, true> >::classof(lld::elf::InputFile const*)
Line
Count
Source
329
3.83k
  static bool classof(const InputFile *F) {
330
3.83k
    return F->kind() == Base::SharedKind;
331
3.83k
  }
lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)0, true> >::classof(lld::elf::InputFile const*)
Line
Count
Source
329
258
  static bool classof(const InputFile *F) {
330
258
    return F->kind() == Base::SharedKind;
331
258
  }
332
333
  SharedFile(MemoryBufferRef M, StringRef DefaultSoName);
334
335
  void parseSoName();
336
  void parseRest();
337
  uint32_t getAlignment(ArrayRef<Elf_Shdr> Sections, const Elf_Sym &Sym);
338
  std::vector<const Elf_Verdef *> parseVerdefs();
339
  std::vector<uint32_t> parseVersyms();
340
341
  struct NeededVer {
342
    // The string table offset of the version name in the output file.
343
    size_t StrTab;
344
345
    // The version identifier for this version name.
346
    uint16_t Index;
347
  };
348
349
  // Mapping from Elf_Verdef data structures to information about Elf_Vernaux
350
  // data structures in the output file.
351
  std::map<const Elf_Verdef *, NeededVer> VerdefMap;
352
353
  // Used for --as-needed
354
  bool IsNeeded;
355
};
356
357
class BinaryFile : public InputFile {
358
public:
359
6
  explicit BinaryFile(MemoryBufferRef M) : InputFile(BinaryKind, M) {}
360
3.42k
  static bool classof(const InputFile *F) { return F->kind() == BinaryKind; }
361
  void parse();
362
};
363
364
InputFile *createObjectFile(MemoryBufferRef MB, StringRef ArchiveName = "",
365
                            uint64_t OffsetInArchive = 0);
366
InputFile *createSharedFile(MemoryBufferRef MB, StringRef DefaultSoName);
367
368
3.32k
inline bool isBitcode(MemoryBufferRef MB) {
369
3.32k
  return identify_magic(MB.getBuffer()) == llvm::file_magic::bitcode;
370
3.32k
}
371
372
std::string replaceThinLTOSuffix(StringRef Path);
373
374
extern std::vector<BinaryFile *> BinaryFiles;
375
extern std::vector<BitcodeFile *> BitcodeFiles;
376
extern std::vector<LazyObjFile *> LazyObjFiles;
377
extern std::vector<InputFile *> ObjectFiles;
378
extern std::vector<InputFile *> SharedFiles;
379
380
} // namespace elf
381
} // namespace lld
382
383
#endif