Coverage Report

Created: 2019-05-19 14:56

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