Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/lld/ELF/SyntheticSections.h
Line
Count
Source (jump to first uncovered line)
1
//===- SyntheticSection.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
// Synthetic sections represent chunks of linker-created data. If you
11
// need to create a chunk of data that to be included in some section
12
// in the result, you probably want to create that as a synthetic section.
13
//
14
// Synthetic sections are designed as input sections as opposed to
15
// output sections because we want to allow them to be manipulated
16
// using linker scripts just like other input sections from regular
17
// files.
18
//
19
//===----------------------------------------------------------------------===//
20
21
#ifndef LLD_ELF_SYNTHETIC_SECTION_H
22
#define LLD_ELF_SYNTHETIC_SECTION_H
23
24
#include "EhFrame.h"
25
#include "GdbIndex.h"
26
#include "InputSection.h"
27
#include "llvm/ADT/MapVector.h"
28
#include "llvm/MC/StringTableBuilder.h"
29
30
namespace lld {
31
namespace elf {
32
33
class SyntheticSection : public InputSection {
34
public:
35
  SyntheticSection(uint64_t Flags, uint32_t Type, uint32_t Alignment,
36
                   StringRef Name)
37
      : InputSection(Flags, Type, Alignment, {}, Name,
38
30.8k
                     InputSectionBase::Synthetic) {
39
30.8k
    this->Live = true;
40
30.8k
  }
41
42
30.8k
  virtual ~SyntheticSection() = default;
43
  virtual void writeTo(uint8_t *Buf) = 0;
44
  virtual size_t getSize() const = 0;
45
4.13k
  virtual void finalizeContents() {}
46
  // If the section has the SHF_ALLOC flag and the size may be changed if
47
  // thunks are added, update the section size.
48
0
  virtual void updateAllocSize() {}
49
  // If any additional finalization of contents are needed post thunk creation.
50
3.06k
  virtual void postThunkContents() {}
51
32.9k
  virtual bool empty() const { return false; }
52
  uint64_t getVA() const;
53
54
1.33M
  static bool classof(const SectionBase *D) {
55
1.33M
    return D->kind() == InputSectionBase::Synthetic;
56
1.33M
  }
57
};
58
59
struct CieRecord {
60
  EhSectionPiece *Cie = nullptr;
61
  std::vector<EhSectionPiece *> Fdes;
62
};
63
64
// Section for .eh_frame.
65
template <class ELFT> class EhFrameSection final : public SyntheticSection {
66
  typedef typename ELFT::Shdr Elf_Shdr;
67
  typedef typename ELFT::Rel Elf_Rel;
68
  typedef typename ELFT::Rela Elf_Rela;
69
70
95
  void updateAlignment(uint64_t Val) {
71
95
    if (Val > this->Alignment)
72
75
      this->Alignment = Val;
73
95
  }
lld::elf::EhFrameSection<llvm::object::ELFType<(llvm::support::endianness)1, true> >::updateAlignment(unsigned long long)
Line
Count
Source
70
87
  void updateAlignment(uint64_t Val) {
71
87
    if (Val > this->Alignment)
72
69
      this->Alignment = Val;
73
87
  }
lld::elf::EhFrameSection<llvm::object::ELFType<(llvm::support::endianness)0, true> >::updateAlignment(unsigned long long)
Line
Count
Source
70
3
  void updateAlignment(uint64_t Val) {
71
3
    if (Val > this->Alignment)
72
2
      this->Alignment = Val;
73
3
  }
lld::elf::EhFrameSection<llvm::object::ELFType<(llvm::support::endianness)0, false> >::updateAlignment(unsigned long long)
Line
Count
Source
70
1
  void updateAlignment(uint64_t Val) {
71
1
    if (Val > this->Alignment)
72
1
      this->Alignment = Val;
73
1
  }
lld::elf::EhFrameSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >::updateAlignment(unsigned long long)
Line
Count
Source
70
4
  void updateAlignment(uint64_t Val) {
71
4
    if (Val > this->Alignment)
72
3
      this->Alignment = Val;
73
4
  }
74
75
public:
76
  EhFrameSection();
77
  void writeTo(uint8_t *Buf) override;
78
  void finalizeContents() override;
79
4.60k
  bool empty() const override { return Sections.empty(); }
lld::elf::EhFrameSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >::empty() const
Line
Count
Source
79
551
  bool empty() const override { return Sections.empty(); }
lld::elf::EhFrameSection<llvm::object::ELFType<(llvm::support::endianness)0, true> >::empty() const
Line
Count
Source
79
150
  bool empty() const override { return Sections.empty(); }
lld::elf::EhFrameSection<llvm::object::ELFType<(llvm::support::endianness)0, false> >::empty() const
Line
Count
Source
79
266
  bool empty() const override { return Sections.empty(); }
lld::elf::EhFrameSection<llvm::object::ELFType<(llvm::support::endianness)1, true> >::empty() const
Line
Count
Source
79
3.63k
  bool empty() const override { return Sections.empty(); }
80
1.70k
  size_t getSize() const override { return Size; }
lld::elf::EhFrameSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >::getSize() const
Line
Count
Source
80
193
  size_t getSize() const override { return Size; }
lld::elf::EhFrameSection<llvm::object::ELFType<(llvm::support::endianness)0, true> >::getSize() const
Line
Count
Source
80
55
  size_t getSize() const override { return Size; }
lld::elf::EhFrameSection<llvm::object::ELFType<(llvm::support::endianness)0, false> >::getSize() const
Line
Count
Source
80
91
  size_t getSize() const override { return Size; }
lld::elf::EhFrameSection<llvm::object::ELFType<(llvm::support::endianness)1, true> >::getSize() const
Line
Count
Source
80
1.36k
  size_t getSize() const override { return Size; }
81
82
  void addSection(InputSectionBase *S);
83
84
  size_t NumFdes = 0;
85
86
  std::vector<EhInputSection *> Sections;
87
88
private:
89
  uint64_t Size = 0;
90
  template <class RelTy>
91
  void addSectionAux(EhInputSection *S, llvm::ArrayRef<RelTy> Rels);
92
93
  template <class RelTy>
94
  CieRecord *addCie(EhSectionPiece &Piece, ArrayRef<RelTy> Rels);
95
96
  template <class RelTy>
97
  bool isFdeLive(EhSectionPiece &Piece, ArrayRef<RelTy> Rels);
98
99
  uint64_t getFdePc(uint8_t *Buf, size_t Off, uint8_t Enc);
100
101
  std::vector<CieRecord *> CieRecords;
102
103
  // CIE records are uniquified by their contents and personality functions.
104
  llvm::DenseMap<std::pair<ArrayRef<uint8_t>, SymbolBody *>, CieRecord *>
105
      CieMap;
106
};
107
108
class GotSection : public SyntheticSection {
109
public:
110
  GotSection();
111
1.74k
  size_t getSize() const override { return Size; }
112
  void finalizeContents() override;
113
  bool empty() const override;
114
  void writeTo(uint8_t *Buf) override;
115
116
  void addEntry(SymbolBody &Sym);
117
  bool addDynTlsEntry(SymbolBody &Sym);
118
  bool addTlsIndex();
119
  uint64_t getGlobalDynAddr(const SymbolBody &B) const;
120
  uint64_t getGlobalDynOffset(const SymbolBody &B) const;
121
122
4
  uint64_t getTlsIndexVA() { return this->getVA() + TlsIndexOff; }
123
6
  uint32_t getTlsIndexOff() const { return TlsIndexOff; }
124
125
  // Flag to force GOT to be in output if we have relocations
126
  // that relies on its address.
127
  bool HasGotOffRel = false;
128
129
protected:
130
  size_t NumEntries = 0;
131
  uint32_t TlsIndexOff = -1;
132
  uint64_t Size = 0;
133
};
134
135
// .note.gnu.build-id section.
136
class BuildIdSection : public SyntheticSection {
137
  // First 16 bytes are a header.
138
  static const unsigned HeaderSize = 16;
139
140
public:
141
  BuildIdSection();
142
  void writeTo(uint8_t *Buf) override;
143
36
  size_t getSize() const override { return HeaderSize + HashSize; }
144
  void writeBuildId(llvm::ArrayRef<uint8_t> Buf);
145
146
private:
147
  void computeHash(llvm::ArrayRef<uint8_t> Buf,
148
                   std::function<void(uint8_t *, ArrayRef<uint8_t>)> Hash);
149
150
  size_t HashSize;
151
  uint8_t *HashBuf;
152
};
153
154
// BssSection is used to reserve space for copy relocations and common symbols.
155
// We create three instances of this class for .bss, .bss.rel.ro and "COMMON",
156
// that are used for writable symbols, read-only symbols and common symbols,
157
// respectively.
158
class BssSection final : public SyntheticSection {
159
public:
160
  BssSection(StringRef Name);
161
0
  void writeTo(uint8_t *) override {}
162
6.32k
  bool empty() const override { return getSize() == 0; }
163
  size_t reserveSpace(uint64_t Size, uint32_t Alignment);
164
9.87k
  size_t getSize() const override { return Size; }
165
166
private:
167
  uint64_t Size = 0;
168
};
169
170
class MipsGotSection final : public SyntheticSection {
171
public:
172
  MipsGotSection();
173
  void writeTo(uint8_t *Buf) override;
174
645
  size_t getSize() const override { return Size; }
175
  void updateAllocSize() override;
176
  void finalizeContents() override;
177
  bool empty() const override;
178
  void addEntry(SymbolBody &Sym, int64_t Addend, RelExpr Expr);
179
  bool addDynTlsEntry(SymbolBody &Sym);
180
  bool addTlsIndex();
181
  uint64_t getPageEntryOffset(const SymbolBody &B, int64_t Addend) const;
182
  uint64_t getBodyEntryOffset(const SymbolBody &B, int64_t Addend) const;
183
  uint64_t getGlobalDynOffset(const SymbolBody &B) const;
184
185
  // Returns the symbol which corresponds to the first entry of the global part
186
  // of GOT on MIPS platform. It is required to fill up MIPS-specific dynamic
187
  // table properties.
188
  // Returns nullptr if the global part is empty.
189
  const SymbolBody *getFirstGlobalEntry() const;
190
191
  // Returns the number of entries in the local part of GOT including
192
  // the number of reserved entries.
193
  unsigned getLocalEntriesNum() const;
194
195
  // Returns offset of TLS part of the MIPS GOT table. This part goes
196
  // after 'local' and 'global' entries.
197
  uint64_t getTlsOffset() const;
198
199
7
  uint32_t getTlsIndexOff() const { return TlsIndexOff; }
200
201
  uint64_t getGp() const;
202
203
private:
204
  // MIPS GOT consists of three parts: local, global and tls. Each part
205
  // contains different types of entries. Here is a layout of GOT:
206
  // - Header entries                |
207
  // - Page entries                  |   Local part
208
  // - Local entries (16-bit access) |
209
  // - Local entries (32-bit access) |
210
  // - Normal global entries         ||  Global part
211
  // - Reloc-only global entries     ||
212
  // - TLS entries                   ||| TLS part
213
  //
214
  // Header:
215
  //   Two entries hold predefined value 0x0 and 0x80000000.
216
  // Page entries:
217
  //   These entries created by R_MIPS_GOT_PAGE relocation and R_MIPS_GOT16
218
  //   relocation against local symbols. They are initialized by higher 16-bit
219
  //   of the corresponding symbol's value. So each 64kb of address space
220
  //   requires a single GOT entry.
221
  // Local entries (16-bit access):
222
  //   These entries created by GOT relocations against global non-preemptible
223
  //   symbols so dynamic linker is not necessary to resolve the symbol's
224
  //   values. "16-bit access" means that corresponding relocations address
225
  //   GOT using 16-bit index. Each unique Symbol-Addend pair has its own
226
  //   GOT entry.
227
  // Local entries (32-bit access):
228
  //   These entries are the same as above but created by relocations which
229
  //   address GOT using 32-bit index (R_MIPS_GOT_HI16/LO16 etc).
230
  // Normal global entries:
231
  //   These entries created by GOT relocations against preemptible global
232
  //   symbols. They need to be initialized by dynamic linker and they ordered
233
  //   exactly as the corresponding entries in the dynamic symbols table.
234
  // Reloc-only global entries:
235
  //   These entries created for symbols that are referenced by dynamic
236
  //   relocations R_MIPS_REL32. These entries are not accessed with gp-relative
237
  //   addressing, but MIPS ABI requires that these entries be present in GOT.
238
  // TLS entries:
239
  //   Entries created by TLS relocations.
240
241
  // Number of "Header" entries.
242
  static const unsigned HeaderEntriesNum = 2;
243
  // Number of allocated "Page" entries.
244
  uint32_t PageEntriesNum = 0;
245
  // Map output sections referenced by MIPS GOT relocations
246
  // to the first index of "Page" entries allocated for this section.
247
  llvm::SmallMapVector<const OutputSection *, size_t, 16> PageIndexMap;
248
249
  typedef std::pair<const SymbolBody *, uint64_t> GotEntry;
250
  typedef std::vector<GotEntry> GotEntries;
251
  // Map from Symbol-Addend pair to the GOT index.
252
  llvm::DenseMap<GotEntry, size_t> EntryIndexMap;
253
  // Local entries (16-bit access).
254
  GotEntries LocalEntries;
255
  // Local entries (32-bit access).
256
  GotEntries LocalEntries32;
257
258
  // Normal and reloc-only global entries.
259
  GotEntries GlobalEntries;
260
261
  // TLS entries.
262
  std::vector<const SymbolBody *> TlsEntries;
263
264
  uint32_t TlsIndexOff = -1;
265
  uint64_t Size = 0;
266
};
267
268
class GotPltSection final : public SyntheticSection {
269
public:
270
  GotPltSection();
271
  void addEntry(SymbolBody &Sym);
272
  size_t getSize() const override;
273
  void writeTo(uint8_t *Buf) override;
274
3.21k
  bool empty() const override { return Entries.empty(); }
275
276
private:
277
  std::vector<const SymbolBody *> Entries;
278
};
279
280
// The IgotPltSection is a Got associated with the PltSection for GNU Ifunc
281
// Symbols that will be relocated by Target->IRelativeRel.
282
// On most Targets the IgotPltSection will immediately follow the GotPltSection
283
// on ARM the IgotPltSection will immediately follow the GotSection.
284
class IgotPltSection final : public SyntheticSection {
285
public:
286
  IgotPltSection();
287
  void addEntry(SymbolBody &Sym);
288
  size_t getSize() const override;
289
  void writeTo(uint8_t *Buf) override;
290
3.08k
  bool empty() const override { return Entries.empty(); }
291
292
private:
293
  std::vector<const SymbolBody *> Entries;
294
};
295
296
class StringTableSection final : public SyntheticSection {
297
public:
298
  StringTableSection(StringRef Name, bool Dynamic);
299
  unsigned addString(StringRef S, bool HashIt = true);
300
  void writeTo(uint8_t *Buf) override;
301
13.4k
  size_t getSize() const override { return Size; }
302
7.20k
  bool isDynamic() const { return Dynamic; }
303
304
private:
305
  const bool Dynamic;
306
307
  uint64_t Size = 0;
308
309
  llvm::DenseMap<StringRef, unsigned> StringMap;
310
  std::vector<StringRef> Strings;
311
};
312
313
class DynamicReloc {
314
public:
315
  DynamicReloc(uint32_t Type, const InputSectionBase *InputSec,
316
               uint64_t OffsetInSec, bool UseSymVA, SymbolBody *Sym,
317
               int64_t Addend)
318
      : Type(Type), Sym(Sym), InputSec(InputSec), OffsetInSec(OffsetInSec),
319
547
        UseSymVA(UseSymVA), Addend(Addend) {}
320
321
  uint64_t getOffset() const;
322
  int64_t getAddend() const;
323
  uint32_t getSymIndex() const;
324
43
  const InputSectionBase *getInputSec() const { return InputSec; }
325
326
  uint32_t Type;
327
328
private:
329
  SymbolBody *Sym;
330
  const InputSectionBase *InputSec = nullptr;
331
  uint64_t OffsetInSec;
332
  bool UseSymVA;
333
  int64_t Addend;
334
};
335
336
template <class ELFT> class DynamicSection final : public SyntheticSection {
337
  typedef typename ELFT::Dyn Elf_Dyn;
338
  typedef typename ELFT::Rel Elf_Rel;
339
  typedef typename ELFT::Rela Elf_Rela;
340
  typedef typename ELFT::Shdr Elf_Shdr;
341
  typedef typename ELFT::Sym Elf_Sym;
342
343
  // The .dynamic section contains information for the dynamic linker.
344
  // The section consists of fixed size entries, which consist of
345
  // type and value fields. Value are one of plain integers, symbol
346
  // addresses, or section addresses. This struct represents the entry.
347
  struct Entry {
348
    int32_t Tag;
349
    union {
350
      OutputSection *OutSec;
351
      InputSection *InSec;
352
      uint64_t Val;
353
      const SymbolBody *Sym;
354
    };
355
    enum KindT { SecAddr, SecSize, SymAddr, PlainInt, InSecAddr } Kind;
356
    Entry(int32_t Tag, OutputSection *OutSec, KindT Kind = SecAddr)
357
296
        : Tag(Tag), OutSec(OutSec), Kind(Kind) {}
lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)1, true> >::Entry::Entry(int, lld::elf::OutputSection*, lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)1, true> >::Entry::KindT)
Line
Count
Source
357
211
        : Tag(Tag), OutSec(OutSec), Kind(Kind) {}
lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)0, true> >::Entry::Entry(int, lld::elf::OutputSection*, lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)0, true> >::Entry::KindT)
Line
Count
Source
357
12
        : Tag(Tag), OutSec(OutSec), Kind(Kind) {}
lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)0, false> >::Entry::Entry(int, lld::elf::OutputSection*, lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)0, false> >::Entry::KindT)
Line
Count
Source
357
12
        : Tag(Tag), OutSec(OutSec), Kind(Kind) {}
lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >::Entry::Entry(int, lld::elf::OutputSection*, lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >::Entry::KindT)
Line
Count
Source
357
61
        : Tag(Tag), OutSec(OutSec), Kind(Kind) {}
358
    Entry(int32_t Tag, InputSection *Sec)
359
2.88k
        : Tag(Tag), InSec(Sec), Kind(InSecAddr) {}
lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)0, true> >::Entry::Entry(int, lld::elf::InputSection*)
Line
Count
Source
359
111
        : Tag(Tag), InSec(Sec), Kind(InSecAddr) {}
lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)0, false> >::Entry::Entry(int, lld::elf::InputSection*)
Line
Count
Source
359
246
        : Tag(Tag), InSec(Sec), Kind(InSecAddr) {}
lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)1, true> >::Entry::Entry(int, lld::elf::InputSection*)
Line
Count
Source
359
2.12k
        : Tag(Tag), InSec(Sec), Kind(InSecAddr) {}
lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >::Entry::Entry(int, lld::elf::InputSection*)
Line
Count
Source
359
407
        : Tag(Tag), InSec(Sec), Kind(InSecAddr) {}
360
3.53k
    Entry(int32_t Tag, uint64_t Val) : Tag(Tag), Val(Val), Kind(PlainInt) {}
lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)0, true> >::Entry::Entry(int, unsigned long long)
Line
Count
Source
360
196
    Entry(int32_t Tag, uint64_t Val) : Tag(Tag), Val(Val), Kind(PlainInt) {}
lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >::Entry::Entry(int, unsigned long long)
Line
Count
Source
360
477
    Entry(int32_t Tag, uint64_t Val) : Tag(Tag), Val(Val), Kind(PlainInt) {}
lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)1, true> >::Entry::Entry(int, unsigned long long)
Line
Count
Source
360
2.36k
    Entry(int32_t Tag, uint64_t Val) : Tag(Tag), Val(Val), Kind(PlainInt) {}
lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)0, false> >::Entry::Entry(int, unsigned long long)
Line
Count
Source
360
502
    Entry(int32_t Tag, uint64_t Val) : Tag(Tag), Val(Val), Kind(PlainInt) {}
361
    Entry(int32_t Tag, const SymbolBody *Sym)
362
8
        : Tag(Tag), Sym(Sym), Kind(SymAddr) {}
Unexecuted instantiation: lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >::Entry::Entry(int, lld::elf::SymbolBody const*)
lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)1, true> >::Entry::Entry(int, lld::elf::SymbolBody const*)
Line
Count
Source
362
8
        : Tag(Tag), Sym(Sym), Kind(SymAddr) {}
Unexecuted instantiation: lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)0, true> >::Entry::Entry(int, lld::elf::SymbolBody const*)
Unexecuted instantiation: lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)0, false> >::Entry::Entry(int, lld::elf::SymbolBody const*)
363
  };
364
365
  // finalizeContents() fills this vector with the section contents.
366
  std::vector<Entry> Entries;
367
368
public:
369
  DynamicSection();
370
  void finalizeContents() override;
371
  void writeTo(uint8_t *Buf) override;
372
2.56k
  size_t getSize() const override { return Size; }
lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >::getSize() const
Line
Count
Source
372
404
  size_t getSize() const override { return Size; }
lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)0, true> >::getSize() const
Line
Count
Source
372
107
  size_t getSize() const override { return Size; }
lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)0, false> >::getSize() const
Line
Count
Source
372
268
  size_t getSize() const override { return Size; }
lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)1, true> >::getSize() const
Line
Count
Source
372
1.78k
  size_t getSize() const override { return Size; }
373
374
private:
375
  void addEntries();
376
6.72k
  void add(Entry E) { Entries.push_back(E); }
lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >::add(lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >::Entry)
Line
Count
Source
376
945
  void add(Entry E) { Entries.push_back(E); }
lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)0, false> >::add(lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)0, false> >::Entry)
Line
Count
Source
376
760
  void add(Entry E) { Entries.push_back(E); }
lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)0, true> >::add(lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)0, true> >::Entry)
Line
Count
Source
376
319
  void add(Entry E) { Entries.push_back(E); }
lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)1, true> >::add(lld::elf::DynamicSection<llvm::object::ELFType<(llvm::support::endianness)1, true> >::Entry)
Line
Count
Source
376
4.70k
  void add(Entry E) { Entries.push_back(E); }
377
  uint64_t Size = 0;
378
};
379
380
template <class ELFT> class RelocationSection final : public SyntheticSection {
381
  typedef typename ELFT::Rel Elf_Rel;
382
  typedef typename ELFT::Rela Elf_Rela;
383
384
public:
385
  RelocationSection(StringRef Name, bool Sort);
386
  void addReloc(const DynamicReloc &Reloc);
387
  unsigned getRelocOffset();
388
  void finalizeContents() override;
389
  void writeTo(uint8_t *Buf) override;
390
9.53k
  bool empty() const override { return Relocs.empty(); }
lld::elf::RelocationSection<llvm::object::ELFType<(llvm::support::endianness)1, true> >::empty() const
Line
Count
Source
390
7.36k
  bool empty() const override { return Relocs.empty(); }
lld::elf::RelocationSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >::empty() const
Line
Count
Source
390
1.26k
  bool empty() const override { return Relocs.empty(); }
lld::elf::RelocationSection<llvm::object::ELFType<(llvm::support::endianness)0, false> >::empty() const
Line
Count
Source
390
612
  bool empty() const override { return Relocs.empty(); }
lld::elf::RelocationSection<llvm::object::ELFType<(llvm::support::endianness)0, true> >::empty() const
Line
Count
Source
390
293
  bool empty() const override { return Relocs.empty(); }
391
4.69k
  size_t getSize() const override { return Relocs.size() * this->Entsize; }
lld::elf::RelocationSection<llvm::object::ELFType<(llvm::support::endianness)0, false> >::getSize() const
Line
Count
Source
391
292
  size_t getSize() const override { return Relocs.size() * this->Entsize; }
lld::elf::RelocationSection<llvm::object::ELFType<(llvm::support::endianness)0, true> >::getSize() const
Line
Count
Source
391
147
  size_t getSize() const override { return Relocs.size() * this->Entsize; }
lld::elf::RelocationSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >::getSize() const
Line
Count
Source
391
693
  size_t getSize() const override { return Relocs.size() * this->Entsize; }
lld::elf::RelocationSection<llvm::object::ELFType<(llvm::support::endianness)1, true> >::getSize() const
Line
Count
Source
391
3.56k
  size_t getSize() const override { return Relocs.size() * this->Entsize; }
392
136
  size_t getRelativeRelocCount() const { return NumRelativeRelocs; }
lld::elf::RelocationSection<llvm::object::ELFType<(llvm::support::endianness)0, true> >::getRelativeRelocCount() const
Line
Count
Source
392
5
  size_t getRelativeRelocCount() const { return NumRelativeRelocs; }
lld::elf::RelocationSection<llvm::object::ELFType<(llvm::support::endianness)1, true> >::getRelativeRelocCount() const
Line
Count
Source
392
95
  size_t getRelativeRelocCount() const { return NumRelativeRelocs; }
Unexecuted instantiation: lld::elf::RelocationSection<llvm::object::ELFType<(llvm::support::endianness)0, false> >::getRelativeRelocCount() const
lld::elf::RelocationSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >::getRelativeRelocCount() const
Line
Count
Source
392
36
  size_t getRelativeRelocCount() const { return NumRelativeRelocs; }
393
394
private:
395
  bool Sort;
396
  size_t NumRelativeRelocs = 0;
397
  std::vector<DynamicReloc> Relocs;
398
};
399
400
struct SymbolTableEntry {
401
  SymbolBody *Symbol;
402
  size_t StrTabOffset;
403
};
404
405
class SymbolTableBaseSection : public SyntheticSection {
406
public:
407
  SymbolTableBaseSection(StringTableSection &StrTabSec);
408
  void finalizeContents() override;
409
  void postThunkContents() override;
410
7.64k
  size_t getSize() const override { return getNumSymbols() * Entsize; }
411
  void addSymbol(SymbolBody *Body);
412
10.0k
  unsigned getNumSymbols() const { return Symbols.size() + 1; }
413
  size_t getSymbolIndex(SymbolBody *Body);
414
1.68k
  ArrayRef<SymbolTableEntry> getSymbols() const { return Symbols; }
415
416
protected:
417
  // A vector of symbols and their string table offsets.
418
  std::vector<SymbolTableEntry> Symbols;
419
420
  StringTableSection &StrTabSec;
421
422
  llvm::once_flag OnceFlag;
423
  llvm::DenseMap<SymbolBody *, size_t> SymbolIndexMap;
424
  llvm::DenseMap<OutputSection *, size_t> SectionIndexMap;
425
};
426
427
template <class ELFT>
428
class SymbolTableSection final : public SymbolTableBaseSection {
429
  typedef typename ELFT::Sym Elf_Sym;
430
431
public:
432
  SymbolTableSection(StringTableSection &StrTabSec);
433
  void writeTo(uint8_t *Buf) override;
434
};
435
436
// Outputs GNU Hash section. For detailed explanation see:
437
// https://blogs.oracle.com/ali/entry/gnu_hash_elf_sections
438
class GnuHashTableSection final : public SyntheticSection {
439
public:
440
  GnuHashTableSection();
441
  void finalizeContents() override;
442
  void writeTo(uint8_t *Buf) override;
443
15
  size_t getSize() const override { return Size; }
444
445
  // Adds symbols to the hash table.
446
  // Sorts the input to satisfy GNU hash section requirements.
447
  void addSymbols(std::vector<SymbolTableEntry> &Symbols);
448
449
private:
450
12
  size_t getShift2() const 
{ return Config->Is64 ? 12
68
:
54
; }
451
452
  void writeBloomFilter(uint8_t *Buf);
453
  void writeHashTable(uint8_t *Buf);
454
455
  struct Entry {
456
    SymbolBody *Body;
457
    size_t StrTabOffset;
458
    uint32_t Hash;
459
  };
460
461
  std::vector<Entry> Symbols;
462
  size_t MaskWords;
463
  size_t NBuckets = 0;
464
  size_t Size = 0;
465
};
466
467
class HashTableSection final : public SyntheticSection {
468
public:
469
  HashTableSection();
470
  void finalizeContents() override;
471
  void writeTo(uint8_t *Buf) override;
472
2.54k
  size_t getSize() const override { return Size; }
473
474
private:
475
  size_t Size = 0;
476
};
477
478
// The PltSection is used for both the Plt and Iplt. The former always has a
479
// header as its first entry that is used at run-time to resolve lazy binding.
480
// The latter is used for GNU Ifunc symbols, that will be subject to a
481
// Target->IRelativeRel.
482
class PltSection : public SyntheticSection {
483
public:
484
  PltSection(size_t HeaderSize);
485
  void writeTo(uint8_t *Buf) override;
486
  size_t getSize() const override;
487
9.49k
  bool empty() const override { return Entries.empty(); }
488
  void addSymbols();
489
490
  template <class ELFT> void addEntry(SymbolBody &Sym);
491
492
private:
493
  unsigned getPltRelocOff() const;
494
  std::vector<std::pair<const SymbolBody *, unsigned>> Entries;
495
  // Iplt always has HeaderSize of 0, the Plt HeaderSize is always non-zero
496
  size_t HeaderSize;
497
};
498
499
// GdbIndexChunk is created for each .debug_info section and contains
500
// information to create a part of .gdb_index for a given input section.
501
struct GdbIndexChunk {
502
  struct AddressEntry {
503
    InputSection *Section;
504
    uint64_t LowAddress;
505
    uint64_t HighAddress;
506
    uint32_t CuIndex;
507
  };
508
509
  struct CuEntry {
510
    uint64_t CuOffset;
511
    uint64_t CuLength;
512
  };
513
514
  struct NameTypeEntry {
515
    llvm::CachedHashStringRef Name;
516
    uint8_t Type;
517
  };
518
519
  InputSection *DebugInfoSec;
520
  std::vector<AddressEntry> AddressAreas;
521
  std::vector<CuEntry> CompilationUnits;
522
  std::vector<NameTypeEntry> NamesAndTypes;
523
};
524
525
// The symbol type for the .gdb_index section.
526
struct GdbSymbol {
527
  uint32_t NameHash;
528
  size_t NameOffset;
529
  size_t CuVectorIndex;
530
};
531
532
class GdbIndexSection final : public SyntheticSection {
533
public:
534
  GdbIndexSection(std::vector<GdbIndexChunk> &&Chunks);
535
  void writeTo(uint8_t *Buf) override;
536
  size_t getSize() const override;
537
  bool empty() const override;
538
539
private:
540
  void fixCuIndex();
541
  std::vector<std::vector<uint32_t>> createCuVectors();
542
  std::vector<GdbSymbol *> createGdbSymtab();
543
544
  // A symbol table for this .gdb_index section.
545
  std::vector<GdbSymbol *> GdbSymtab;
546
547
  // CU vector is a part of constant pool area of section.
548
  std::vector<std::vector<uint32_t>> CuVectors;
549
550
  // Symbol table contents.
551
  llvm::DenseMap<llvm::CachedHashStringRef, GdbSymbol *> Symbols;
552
553
  // Each chunk contains information gathered from a debug sections of single
554
  // object and used to build different areas of gdb index.
555
  std::vector<GdbIndexChunk> Chunks;
556
557
  static constexpr uint32_t CuListOffset = 24;
558
  uint32_t CuTypesOffset;
559
  uint32_t SymtabOffset;
560
  uint32_t ConstantPoolOffset;
561
  uint32_t StringPoolOffset;
562
  uint32_t StringPoolSize;
563
564
  std::vector<size_t> CuVectorOffsets;
565
};
566
567
template <class ELFT> GdbIndexSection *createGdbIndex();
568
569
// --eh-frame-hdr option tells linker to construct a header for all the
570
// .eh_frame sections. This header is placed to a section named .eh_frame_hdr
571
// and also to a PT_GNU_EH_FRAME segment.
572
// At runtime the unwinder then can find all the PT_GNU_EH_FRAME segments by
573
// calling dl_iterate_phdr.
574
// This section contains a lookup table for quick binary search of FDEs.
575
// Detailed info about internals can be found in Ian Lance Taylor's blog:
576
// http://www.airs.com/blog/archives/460 (".eh_frame")
577
// http://www.airs.com/blog/archives/462 (".eh_frame_hdr")
578
template <class ELFT> class EhFrameHeader final : public SyntheticSection {
579
public:
580
  EhFrameHeader();
581
  void writeTo(uint8_t *Buf) override;
582
  size_t getSize() const override;
583
  void addFde(uint32_t Pc, uint32_t FdeVA);
584
  bool empty() const override;
585
586
private:
587
  struct FdeData {
588
    uint32_t Pc;
589
    uint32_t FdeVA;
590
  };
591
592
  std::vector<FdeData> Fdes;
593
};
594
595
// For more information about .gnu.version and .gnu.version_r see:
596
// https://www.akkadia.org/drepper/symbol-versioning
597
598
// The .gnu.version_d section which has a section type of SHT_GNU_verdef shall
599
// contain symbol version definitions. The number of entries in this section
600
// shall be contained in the DT_VERDEFNUM entry of the .dynamic section.
601
// The section shall contain an array of Elf_Verdef structures, optionally
602
// followed by an array of Elf_Verdaux structures.
603
template <class ELFT>
604
class VersionDefinitionSection final : public SyntheticSection {
605
  typedef typename ELFT::Verdef Elf_Verdef;
606
  typedef typename ELFT::Verdaux Elf_Verdaux;
607
608
public:
609
  VersionDefinitionSection();
610
  void finalizeContents() override;
611
  size_t getSize() const override;
612
  void writeTo(uint8_t *Buf) override;
613
614
private:
615
  void writeOne(uint8_t *Buf, uint32_t Index, StringRef Name, size_t NameOff);
616
617
  unsigned FileDefNameOff;
618
};
619
620
// The .gnu.version section specifies the required version of each symbol in the
621
// dynamic symbol table. It contains one Elf_Versym for each dynamic symbol
622
// table entry. An Elf_Versym is just a 16-bit integer that refers to a version
623
// identifier defined in the either .gnu.version_r or .gnu.version_d section.
624
// The values 0 and 1 are reserved. All other values are used for versions in
625
// the own object or in any of the dependencies.
626
template <class ELFT>
627
class VersionTableSection final : public SyntheticSection {
628
  typedef typename ELFT::Versym Elf_Versym;
629
630
public:
631
  VersionTableSection();
632
  void finalizeContents() override;
633
  size_t getSize() const override;
634
  void writeTo(uint8_t *Buf) override;
635
  bool empty() const override;
636
};
637
638
// The .gnu.version_r section defines the version identifiers used by
639
// .gnu.version. It contains a linked list of Elf_Verneed data structures. Each
640
// Elf_Verneed specifies the version requirements for a single DSO, and contains
641
// a reference to a linked list of Elf_Vernaux data structures which define the
642
// mapping from version identifiers to version names.
643
template <class ELFT> class VersionNeedSection final : public SyntheticSection {
644
  typedef typename ELFT::Verneed Elf_Verneed;
645
  typedef typename ELFT::Vernaux Elf_Vernaux;
646
647
  // A vector of shared files that need Elf_Verneed data structures and the
648
  // string table offsets of their sonames.
649
  std::vector<std::pair<SharedFile<ELFT> *, size_t>> Needed;
650
651
  // The next available version identifier.
652
  unsigned NextIndex;
653
654
public:
655
  VersionNeedSection();
656
  void addSymbol(SharedSymbol *SS);
657
  void finalizeContents() override;
658
  void writeTo(uint8_t *Buf) override;
659
  size_t getSize() const override;
660
3.77k
  size_t getNeedNum() const { return Needed.size(); }
lld::elf::VersionNeedSection<llvm::object::ELFType<(llvm::support::endianness)0, true> >::getNeedNum() const
Line
Count
Source
660
125
  size_t getNeedNum() const { return Needed.size(); }
lld::elf::VersionNeedSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >::getNeedNum() const
Line
Count
Source
660
520
  size_t getNeedNum() const { return Needed.size(); }
lld::elf::VersionNeedSection<llvm::object::ELFType<(llvm::support::endianness)0, false> >::getNeedNum() const
Line
Count
Source
660
270
  size_t getNeedNum() const { return Needed.size(); }
lld::elf::VersionNeedSection<llvm::object::ELFType<(llvm::support::endianness)1, true> >::getNeedNum() const
Line
Count
Source
660
2.85k
  size_t getNeedNum() const { return Needed.size(); }
661
  bool empty() const override;
662
};
663
664
// MergeSyntheticSection is a class that allows us to put mergeable sections
665
// with different attributes in a single output sections. To do that
666
// we put them into MergeSyntheticSection synthetic input sections which are
667
// attached to regular output sections.
668
class MergeSyntheticSection : public SyntheticSection {
669
public:
670
  void addSection(MergeInputSection *MS);
671
  size_t getSize() const override;
672
  void writeTo(uint8_t *Buf) override;
673
674
protected:
675
  MergeSyntheticSection(StringRef Name, uint32_t Type, uint64_t Flags,
676
                        uint32_t Alignment);
677
678
  std::vector<MergeInputSection *> Sections;
679
  llvm::StringTableBuilder Builder;
680
};
681
682
class MergeTailSection final : public MergeSyntheticSection {
683
public:
684
  MergeTailSection(StringRef Name, uint32_t Type, uint64_t Flags,
685
                   uint32_t Alignment)
686
9
      : MergeSyntheticSection(Name, Type, Flags, Alignment) {}
687
688
  void finalizeContents() override;
689
};
690
691
class MergeNoTailSection final : public MergeSyntheticSection {
692
public:
693
  MergeNoTailSection(StringRef Name, uint32_t Type, uint64_t Flags,
694
                     uint32_t Alignment)
695
1.57k
      : MergeSyntheticSection(Name, Type, Flags, Alignment) {}
696
697
  void finalizeContents() override;
698
};
699
700
// .MIPS.abiflags section.
701
template <class ELFT>
702
class MipsAbiFlagsSection final : public SyntheticSection {
703
  typedef llvm::object::Elf_Mips_ABIFlags<ELFT> Elf_Mips_ABIFlags;
704
705
public:
706
  static MipsAbiFlagsSection *create();
707
708
  MipsAbiFlagsSection(Elf_Mips_ABIFlags Flags);
709
667
  size_t getSize() const override { return sizeof(Elf_Mips_ABIFlags); }
lld::elf::MipsAbiFlagsSection<llvm::object::ELFType<(llvm::support::endianness)0, false> >::getSize() const
Line
Count
Source
709
452
  size_t getSize() const override { return sizeof(Elf_Mips_ABIFlags); }
lld::elf::MipsAbiFlagsSection<llvm::object::ELFType<(llvm::support::endianness)0, true> >::getSize() const
Line
Count
Source
709
140
  size_t getSize() const override { return sizeof(Elf_Mips_ABIFlags); }
lld::elf::MipsAbiFlagsSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >::getSize() const
Line
Count
Source
709
65
  size_t getSize() const override { return sizeof(Elf_Mips_ABIFlags); }
lld::elf::MipsAbiFlagsSection<llvm::object::ELFType<(llvm::support::endianness)1, true> >::getSize() const
Line
Count
Source
709
10
  size_t getSize() const override { return sizeof(Elf_Mips_ABIFlags); }
710
  void writeTo(uint8_t *Buf) override;
711
712
private:
713
  Elf_Mips_ABIFlags Flags;
714
};
715
716
// .MIPS.options section.
717
template <class ELFT> class MipsOptionsSection final : public SyntheticSection {
718
  typedef llvm::object::Elf_Mips_Options<ELFT> Elf_Mips_Options;
719
  typedef llvm::object::Elf_Mips_RegInfo<ELFT> Elf_Mips_RegInfo;
720
721
public:
722
  static MipsOptionsSection *create();
723
724
  MipsOptionsSection(Elf_Mips_RegInfo Reginfo);
725
  void writeTo(uint8_t *Buf) override;
726
727
180
  size_t getSize() const override {
728
180
    return sizeof(Elf_Mips_Options) + sizeof(Elf_Mips_RegInfo);
729
180
  }
lld::elf::MipsOptionsSection<llvm::object::ELFType<(llvm::support::endianness)1, true> >::getSize() const
Line
Count
Source
727
12
  size_t getSize() const override {
728
12
    return sizeof(Elf_Mips_Options) + sizeof(Elf_Mips_RegInfo);
729
12
  }
Unexecuted instantiation: lld::elf::MipsOptionsSection<llvm::object::ELFType<(llvm::support::endianness)0, false> >::getSize() const
Unexecuted instantiation: lld::elf::MipsOptionsSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >::getSize() const
lld::elf::MipsOptionsSection<llvm::object::ELFType<(llvm::support::endianness)0, true> >::getSize() const
Line
Count
Source
727
168
  size_t getSize() const override {
728
168
    return sizeof(Elf_Mips_Options) + sizeof(Elf_Mips_RegInfo);
729
168
  }
730
731
private:
732
  Elf_Mips_RegInfo Reginfo;
733
};
734
735
// MIPS .reginfo section.
736
template <class ELFT> class MipsReginfoSection final : public SyntheticSection {
737
  typedef llvm::object::Elf_Mips_RegInfo<ELFT> Elf_Mips_RegInfo;
738
739
public:
740
  static MipsReginfoSection *create();
741
742
  MipsReginfoSection(Elf_Mips_RegInfo Reginfo);
743
517
  size_t getSize() const override { return sizeof(Elf_Mips_RegInfo); }
Unexecuted instantiation: lld::elf::MipsReginfoSection<llvm::object::ELFType<(llvm::support::endianness)0, true> >::getSize() const
lld::elf::MipsReginfoSection<llvm::object::ELFType<(llvm::support::endianness)0, false> >::getSize() const
Line
Count
Source
743
452
  size_t getSize() const override { return sizeof(Elf_Mips_RegInfo); }
lld::elf::MipsReginfoSection<llvm::object::ELFType<(llvm::support::endianness)1, false> >::getSize() const
Line
Count
Source
743
65
  size_t getSize() const override { return sizeof(Elf_Mips_RegInfo); }
Unexecuted instantiation: lld::elf::MipsReginfoSection<llvm::object::ELFType<(llvm::support::endianness)1, true> >::getSize() const
744
  void writeTo(uint8_t *Buf) override;
745
746
private:
747
  Elf_Mips_RegInfo Reginfo;
748
};
749
750
// This is a MIPS specific section to hold a space within the data segment
751
// of executable file which is pointed to by the DT_MIPS_RLD_MAP entry.
752
// See "Dynamic section" in Chapter 5 in the following document:
753
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
754
class MipsRldMapSection : public SyntheticSection {
755
public:
756
  MipsRldMapSection();
757
100
  size_t getSize() const override { return Config->Wordsize; }
758
20
  void writeTo(uint8_t *Buf) override {}
759
};
760
761
class ARMExidxSentinelSection : public SyntheticSection {
762
public:
763
  ARMExidxSentinelSection();
764
80
  size_t getSize() const override { return 8; }
765
  void writeTo(uint8_t *Buf) override;
766
};
767
768
// A container for one or more linker generated thunks. Instances of these
769
// thunks including ARM interworking and Mips LA25 PI to non-PI thunks.
770
class ThunkSection : public SyntheticSection {
771
public:
772
  // ThunkSection in OS, with desired OutSecOff of Off
773
  ThunkSection(OutputSection *OS, uint64_t Off);
774
775
  // Add a newly created Thunk to this container:
776
  // Thunk is given offset from start of this InputSection
777
  // Thunk defines a symbol in this InputSection that can be used as target
778
  // of a relocation
779
  void addThunk(Thunk *T);
780
102
  size_t getSize() const override { return Size; }
781
  void writeTo(uint8_t *Buf) override;
782
  InputSection *getTargetInputSection() const;
783
784
private:
785
  std::vector<const Thunk *> Thunks;
786
  size_t Size = 0;
787
};
788
789
std::vector<InputSection *> createCommonSections();
790
InputSection *createInterpSection();
791
template <class ELFT> MergeInputSection *createCommentSection();
792
void decompressAndMergeSections();
793
794
SymbolBody *addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value,
795
                              uint64_t Size, InputSectionBase *Section);
796
797
// Linker generated sections which can be used as inputs.
798
struct InX {
799
  static InputSection *ARMAttributes;
800
  static BssSection *Bss;
801
  static BssSection *BssRelRo;
802
  static BuildIdSection *BuildId;
803
  static SyntheticSection *Dynamic;
804
  static StringTableSection *DynStrTab;
805
  static SymbolTableBaseSection *DynSymTab;
806
  static GnuHashTableSection *GnuHashTab;
807
  static HashTableSection *HashTab;
808
  static InputSection *Interp;
809
  static GdbIndexSection *GdbIndex;
810
  static GotSection *Got;
811
  static GotPltSection *GotPlt;
812
  static IgotPltSection *IgotPlt;
813
  static MipsGotSection *MipsGot;
814
  static MipsRldMapSection *MipsRldMap;
815
  static PltSection *Plt;
816
  static PltSection *Iplt;
817
  static StringTableSection *ShStrTab;
818
  static StringTableSection *StrTab;
819
  static SymbolTableBaseSection *SymTab;
820
};
821
822
template <class ELFT> struct In : public InX {
823
  static EhFrameHeader<ELFT> *EhFrameHdr;
824
  static EhFrameSection<ELFT> *EhFrame;
825
  static RelocationSection<ELFT> *RelaDyn;
826
  static RelocationSection<ELFT> *RelaPlt;
827
  static RelocationSection<ELFT> *RelaIplt;
828
  static VersionDefinitionSection<ELFT> *VerDef;
829
  static VersionTableSection<ELFT> *VerSym;
830
  static VersionNeedSection<ELFT> *VerNeed;
831
};
832
833
template <class ELFT> EhFrameHeader<ELFT> *In<ELFT>::EhFrameHdr;
834
template <class ELFT> EhFrameSection<ELFT> *In<ELFT>::EhFrame;
835
template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaDyn;
836
template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaPlt;
837
template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaIplt;
838
template <class ELFT> VersionDefinitionSection<ELFT> *In<ELFT>::VerDef;
839
template <class ELFT> VersionTableSection<ELFT> *In<ELFT>::VerSym;
840
template <class ELFT> VersionNeedSection<ELFT> *In<ELFT>::VerNeed;
841
} // namespace elf
842
} // namespace lld
843
844
#endif