Coverage Report

Created: 2018-06-18 20:01

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/ELF/InputSection.h
Line
Count
Source (jump to first uncovered line)
1
//===- InputSection.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_SECTION_H
11
#define LLD_ELF_INPUT_SECTION_H
12
13
#include "Config.h"
14
#include "Relocations.h"
15
#include "Thunks.h"
16
#include "lld/Common/LLVM.h"
17
#include "llvm/ADT/CachedHashString.h"
18
#include "llvm/ADT/DenseSet.h"
19
#include "llvm/ADT/TinyPtrVector.h"
20
#include "llvm/Object/ELF.h"
21
22
namespace lld {
23
namespace elf {
24
25
class Symbol;
26
struct SectionPiece;
27
28
class Defined;
29
class SyntheticSection;
30
class MergeSyntheticSection;
31
template <class ELFT> class ObjFile;
32
class OutputSection;
33
34
// This is the base class of all sections that lld handles. Some are sections in
35
// input files, some are sections in the produced output file and some exist
36
// just as a convenience for implementing special ways of combining some
37
// sections.
38
class SectionBase {
39
public:
40
  enum Kind { Regular, EHFrame, Merge, Synthetic, Output };
41
42
3.38M
  Kind kind() const { return (Kind)SectionKind; }
43
44
  StringRef Name;
45
46
  // This pointer points to the "real" instance of this instance.
47
  // Usually Repl == this. However, if ICF merges two sections,
48
  // Repl pointer of one section points to another section. So,
49
  // if you need to get a pointer to this instance, do not use
50
  // this but instead this->Repl.
51
  SectionBase *Repl;
52
53
  unsigned SectionKind : 3;
54
55
  // The next two bit fields are only used by InputSectionBase, but we
56
  // put them here so the struct packs better.
57
58
  // The garbage collector sets sections' Live bits.
59
  // If GC is disabled, all sections are considered live by default.
60
  unsigned Live : 1;
61
62
  unsigned Bss : 1;
63
64
  // Set for sections that should not be folded by ICF.
65
  unsigned KeepUnique : 1;
66
67
  // These corresponds to the fields in Elf_Shdr.
68
  uint32_t Alignment;
69
  uint64_t Flags;
70
  uint64_t Entsize;
71
  uint32_t Type;
72
  uint32_t Link;
73
  uint32_t Info;
74
75
  OutputSection *getOutputSection();
76
73.4k
  const OutputSection *getOutputSection() const {
77
73.4k
    return const_cast<SectionBase *>(this)->getOutputSection();
78
73.4k
  }
79
80
  // Translate an offset in the input section to an offset in the output
81
  // section.
82
  uint64_t getOffset(uint64_t Offset) const;
83
84
  uint64_t getVA(uint64_t Offset = 0) const;
85
86
protected:
87
  SectionBase(Kind SectionKind, StringRef Name, uint64_t Flags,
88
              uint64_t Entsize, uint64_t Alignment, uint32_t Type,
89
              uint32_t Info, uint32_t Link)
90
      : Name(Name), Repl(this), SectionKind(SectionKind), Live(false),
91
        Bss(false), KeepUnique(false), Alignment(Alignment), Flags(Flags),
92
488k
        Entsize(Entsize), Type(Type), Link(Link), Info(Info) {}
93
};
94
95
// This corresponds to a section of an input file.
96
class InputSectionBase : public SectionBase {
97
public:
98
  template <class ELFT>
99
  InputSectionBase(ObjFile<ELFT> &File, const typename ELFT::Shdr &Header,
100
                   StringRef Name, Kind SectionKind);
101
102
  InputSectionBase(InputFile *File, uint64_t Flags, uint32_t Type,
103
                   uint64_t Entsize, uint32_t Link, uint32_t Info,
104
                   uint32_t Alignment, ArrayRef<uint8_t> Data, StringRef Name,
105
                   Kind SectionKind);
106
107
17.4k
  static bool classof(const SectionBase *S) { return S->kind() != Output; }
108
109
  // The file which contains this section. It's dynamic type is always
110
  // ObjFile<ELFT>, but in order to avoid ELFT, we use InputFile as
111
  // its static type.
112
  InputFile *File;
113
114
19.4k
  template <class ELFT> ObjFile<ELFT> *getFile() const {
115
19.4k
    return cast_or_null<ObjFile<ELFT>>(File);
116
19.4k
  }
lld::elf::ObjFile<llvm::object::ELFType<(llvm::support::endianness)1, false> >* lld::elf::InputSectionBase::getFile<llvm::object::ELFType<(llvm::support::endianness)1, false> >() const
Line
Count
Source
114
820
  template <class ELFT> ObjFile<ELFT> *getFile() const {
115
820
    return cast_or_null<ObjFile<ELFT>>(File);
116
820
  }
lld::elf::ObjFile<llvm::object::ELFType<(llvm::support::endianness)0, false> >* lld::elf::InputSectionBase::getFile<llvm::object::ELFType<(llvm::support::endianness)0, false> >() const
Line
Count
Source
114
510
  template <class ELFT> ObjFile<ELFT> *getFile() const {
115
510
    return cast_or_null<ObjFile<ELFT>>(File);
116
510
  }
lld::elf::ObjFile<llvm::object::ELFType<(llvm::support::endianness)1, true> >* lld::elf::InputSectionBase::getFile<llvm::object::ELFType<(llvm::support::endianness)1, true> >() const
Line
Count
Source
114
2.40k
  template <class ELFT> ObjFile<ELFT> *getFile() const {
115
2.40k
    return cast_or_null<ObjFile<ELFT>>(File);
116
2.40k
  }
lld::elf::ObjFile<llvm::object::ELFType<(llvm::support::endianness)0, true> >* lld::elf::InputSectionBase::getFile<llvm::object::ELFType<(llvm::support::endianness)0, true> >() const
Line
Count
Source
114
15.7k
  template <class ELFT> ObjFile<ELFT> *getFile() const {
115
15.7k
    return cast_or_null<ObjFile<ELFT>>(File);
116
15.7k
  }
117
118
  ArrayRef<uint8_t> Data;
119
  uint64_t getOffsetInFile() const;
120
121
  // True if this section has already been placed to a linker script
122
  // output section. This is needed because, in a linker script, you
123
  // can refer to the same section more than once. For example, in
124
  // the following linker script,
125
  //
126
  //   .foo : { *(.text) }
127
  //   .bar : { *(.text) }
128
  //
129
  // .foo takes all .text sections, and .bar becomes empty. To achieve
130
  // this, we need to memorize whether a section has been placed or
131
  // not for each input section.
132
  bool Assigned = false;
133
134
  // Input sections are part of an output section. Special sections
135
  // like .eh_frame and merge sections are first combined into a
136
  // synthetic section that is then added to an output section. In all
137
  // cases this points one level up.
138
  SectionBase *Parent = nullptr;
139
140
  // Relocations that refer to this section.
141
  const void *FirstRelocation = nullptr;
142
  unsigned NumRelocations : 31;
143
  unsigned AreRelocsRela : 1;
144
145
230k
  template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
146
230k
    assert(!AreRelocsRela);
147
230k
    return llvm::makeArrayRef(
148
230k
        static_cast<const typename ELFT::Rel *>(FirstRelocation),
149
230k
        NumRelocations);
150
230k
  }
llvm::ArrayRef<llvm::object::ELFType<(llvm::support::endianness)1, false>::Rel> lld::elf::InputSectionBase::rels<llvm::object::ELFType<(llvm::support::endianness)1, false> >() const
Line
Count
Source
145
4.70k
  template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
146
4.70k
    assert(!AreRelocsRela);
147
4.70k
    return llvm::makeArrayRef(
148
4.70k
        static_cast<const typename ELFT::Rel *>(FirstRelocation),
149
4.70k
        NumRelocations);
150
4.70k
  }
llvm::ArrayRef<llvm::object::ELFType<(llvm::support::endianness)0, false>::Rel> lld::elf::InputSectionBase::rels<llvm::object::ELFType<(llvm::support::endianness)0, false> >() const
Line
Count
Source
145
2.30k
  template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
146
2.30k
    assert(!AreRelocsRela);
147
2.30k
    return llvm::makeArrayRef(
148
2.30k
        static_cast<const typename ELFT::Rel *>(FirstRelocation),
149
2.30k
        NumRelocations);
150
2.30k
  }
llvm::ArrayRef<llvm::object::ELFType<(llvm::support::endianness)1, true>::Rel> lld::elf::InputSectionBase::rels<llvm::object::ELFType<(llvm::support::endianness)1, true> >() const
Line
Count
Source
145
222k
  template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
146
222k
    assert(!AreRelocsRela);
147
222k
    return llvm::makeArrayRef(
148
222k
        static_cast<const typename ELFT::Rel *>(FirstRelocation),
149
222k
        NumRelocations);
150
222k
  }
llvm::ArrayRef<llvm::object::ELFType<(llvm::support::endianness)0, true>::Rel> lld::elf::InputSectionBase::rels<llvm::object::ELFType<(llvm::support::endianness)0, true> >() const
Line
Count
Source
145
1.33k
  template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
146
1.33k
    assert(!AreRelocsRela);
147
1.33k
    return llvm::makeArrayRef(
148
1.33k
        static_cast<const typename ELFT::Rel *>(FirstRelocation),
149
1.33k
        NumRelocations);
150
1.33k
  }
151
152
1.39k
  template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const {
153
1.39k
    assert(AreRelocsRela);
154
1.39k
    return llvm::makeArrayRef(
155
1.39k
        static_cast<const typename ELFT::Rela *>(FirstRelocation),
156
1.39k
        NumRelocations);
157
1.39k
  }
llvm::ArrayRef<llvm::object::ELFType<(llvm::support::endianness)1, false>::Rela> lld::elf::InputSectionBase::relas<llvm::object::ELFType<(llvm::support::endianness)1, false> >() const
Line
Count
Source
152
3
  template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const {
153
3
    assert(AreRelocsRela);
154
3
    return llvm::makeArrayRef(
155
3
        static_cast<const typename ELFT::Rela *>(FirstRelocation),
156
3
        NumRelocations);
157
3
  }
llvm::ArrayRef<llvm::object::ELFType<(llvm::support::endianness)0, false>::Rela> lld::elf::InputSectionBase::relas<llvm::object::ELFType<(llvm::support::endianness)0, false> >() const
Line
Count
Source
152
12
  template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const {
153
12
    assert(AreRelocsRela);
154
12
    return llvm::makeArrayRef(
155
12
        static_cast<const typename ELFT::Rela *>(FirstRelocation),
156
12
        NumRelocations);
157
12
  }
llvm::ArrayRef<llvm::object::ELFType<(llvm::support::endianness)1, true>::Rela> lld::elf::InputSectionBase::relas<llvm::object::ELFType<(llvm::support::endianness)1, true> >() const
Line
Count
Source
152
1.30k
  template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const {
153
1.30k
    assert(AreRelocsRela);
154
1.30k
    return llvm::makeArrayRef(
155
1.30k
        static_cast<const typename ELFT::Rela *>(FirstRelocation),
156
1.30k
        NumRelocations);
157
1.30k
  }
llvm::ArrayRef<llvm::object::ELFType<(llvm::support::endianness)0, true>::Rela> lld::elf::InputSectionBase::relas<llvm::object::ELFType<(llvm::support::endianness)0, true> >() const
Line
Count
Source
152
78
  template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const {
153
78
    assert(AreRelocsRela);
154
78
    return llvm::makeArrayRef(
155
78
        static_cast<const typename ELFT::Rela *>(FirstRelocation),
156
78
        NumRelocations);
157
78
  }
158
159
  // InputSections that are dependent on us (reverse dependency for GC)
160
  llvm::TinyPtrVector<InputSection *> DependentSections;
161
162
  // Returns the size of this section (even if this is a common or BSS.)
163
  size_t getSize() const;
164
165
  InputSection *getLinkOrderDep() const;
166
167
  // Compilers emit zlib-compressed debug sections if the -gz option
168
  // is given. This function checks if this section is compressed, and
169
  // if so, decompress in memory.
170
  void maybeDecompress();
171
172
  // Returns a source location string. Used to construct an error message.
173
  template <class ELFT> std::string getLocation(uint64_t Offset);
174
  std::string getSrcMsg(const Symbol &Sym, uint64_t Offset);
175
  std::string getObjMsg(uint64_t Offset);
176
177
  // Each section knows how to relocate itself. These functions apply
178
  // relocations, assuming that Buf points to this section's copy in
179
  // the mmap'ed output buffer.
180
  template <class ELFT> void relocate(uint8_t *Buf, uint8_t *BufEnd);
181
  void relocateAlloc(uint8_t *Buf, uint8_t *BufEnd);
182
183
  // The native ELF reloc data type is not very convenient to handle.
184
  // So we convert ELF reloc records to our own records in Relocations.cpp.
185
  // This vector contains such "cooked" relocations.
186
  std::vector<Relocation> Relocations;
187
188
92
  template <typename T> llvm::ArrayRef<T> getDataAs() const {
189
92
    size_t S = Data.size();
190
92
    assert(S % sizeof(T) == 0);
191
92
    return llvm::makeArrayRef<T>((const T *)Data.data(), S / sizeof(T));
192
92
  }
Unexecuted instantiation: llvm::ArrayRef<llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)1, false>, true> > lld::elf::InputSectionBase::getDataAs<llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)1, false>, true> >() const
llvm::ArrayRef<llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)1, false>, false> > lld::elf::InputSectionBase::getDataAs<llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)1, false>, false> >() const
Line
Count
Source
188
13
  template <typename T> llvm::ArrayRef<T> getDataAs() const {
189
13
    size_t S = Data.size();
190
13
    assert(S % sizeof(T) == 0);
191
13
    return llvm::makeArrayRef<T>((const T *)Data.data(), S / sizeof(T));
192
13
  }
llvm::ArrayRef<llvm::support::detail::packed_endian_specific_integral<unsigned int, (llvm::support::endianness)1, 1ul> > lld::elf::InputSectionBase::getDataAs<llvm::support::detail::packed_endian_specific_integral<unsigned int, (llvm::support::endianness)1, 1ul> >() const
Line
Count
Source
188
8
  template <typename T> llvm::ArrayRef<T> getDataAs() const {
189
8
    size_t S = Data.size();
190
8
    assert(S % sizeof(T) == 0);
191
8
    return llvm::makeArrayRef<T>((const T *)Data.data(), S / sizeof(T));
192
8
  }
Unexecuted instantiation: llvm::ArrayRef<llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)0, false>, true> > lld::elf::InputSectionBase::getDataAs<llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)0, false>, true> >() const
llvm::ArrayRef<llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)0, false>, false> > lld::elf::InputSectionBase::getDataAs<llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)0, false>, false> >() const
Line
Count
Source
188
8
  template <typename T> llvm::ArrayRef<T> getDataAs() const {
189
8
    size_t S = Data.size();
190
8
    assert(S % sizeof(T) == 0);
191
8
    return llvm::makeArrayRef<T>((const T *)Data.data(), S / sizeof(T));
192
8
  }
Unexecuted instantiation: llvm::ArrayRef<llvm::support::detail::packed_endian_specific_integral<unsigned int, (llvm::support::endianness)0, 1ul> > lld::elf::InputSectionBase::getDataAs<llvm::support::detail::packed_endian_specific_integral<unsigned int, (llvm::support::endianness)0, 1ul> >() const
llvm::ArrayRef<llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)1, true>, true> > lld::elf::InputSectionBase::getDataAs<llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)1, true>, true> >() const
Line
Count
Source
188
61
  template <typename T> llvm::ArrayRef<T> getDataAs() const {
189
61
    size_t S = Data.size();
190
61
    assert(S % sizeof(T) == 0);
191
61
    return llvm::makeArrayRef<T>((const T *)Data.data(), S / sizeof(T));
192
61
  }
Unexecuted instantiation: llvm::ArrayRef<llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)1, true>, false> > lld::elf::InputSectionBase::getDataAs<llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)1, true>, false> >() const
llvm::ArrayRef<llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)0, true>, true> > lld::elf::InputSectionBase::getDataAs<llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)0, true>, true> >() const
Line
Count
Source
188
2
  template <typename T> llvm::ArrayRef<T> getDataAs() const {
189
2
    size_t S = Data.size();
190
2
    assert(S % sizeof(T) == 0);
191
2
    return llvm::makeArrayRef<T>((const T *)Data.data(), S / sizeof(T));
192
2
  }
Unexecuted instantiation: llvm::ArrayRef<llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)0, true>, false> > lld::elf::InputSectionBase::getDataAs<llvm::object::Elf_Rel_Impl<llvm::object::ELFType<(llvm::support::endianness)0, true>, false> >() const
193
194
private:
195
  // A pointer that owns decompressed data if a section is compressed by zlib.
196
  // Since the feature is not used often, this is usually a nullptr.
197
  std::unique_ptr<char[]> DecompressBuf;
198
};
199
200
// SectionPiece represents a piece of splittable section contents.
201
// We allocate a lot of these and binary search on them. This means that they
202
// have to be as compact as possible, which is why we don't store the size (can
203
// be found by looking at the next one).
204
struct SectionPiece {
205
  SectionPiece(size_t Off, uint32_t Hash, bool Live)
206
      : InputOff(Off), Hash(Hash), OutputOff(0),
207
2.24k
        Live(Live || !Config->GcSections) {}
208
209
  uint32_t InputOff;
210
  uint32_t Hash;
211
  int64_t OutputOff : 63;
212
  uint64_t Live : 1;
213
};
214
215
static_assert(sizeof(SectionPiece) == 16, "SectionPiece is too big");
216
217
// This corresponds to a SHF_MERGE section of an input file.
218
class MergeInputSection : public InputSectionBase {
219
public:
220
  template <class ELFT>
221
  MergeInputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header,
222
                    StringRef Name);
223
  MergeInputSection(uint64_t Flags, uint32_t Type, uint64_t Entsize,
224
                    ArrayRef<uint8_t> Data, StringRef Name);
225
226
428k
  static bool classof(const SectionBase *S) { return S->kind() == Merge; }
227
  void splitIntoPieces();
228
229
  // Translate an offset in the input section to an offset in the parent
230
  // MergeSyntheticSection.
231
  uint64_t getParentOffset(uint64_t Offset) const;
232
233
  // Splittable sections are handled as a sequence of data
234
  // rather than a single large blob of data.
235
  std::vector<SectionPiece> Pieces;
236
  llvm::DenseMap<uint32_t, uint32_t> OffsetMap;
237
238
  // Returns I'th piece's data. This function is very hot when
239
  // string merging is enabled, so we want to inline.
240
  LLVM_ATTRIBUTE_ALWAYS_INLINE
241
2.24k
  llvm::CachedHashStringRef getData(size_t I) const {
242
2.24k
    size_t Begin = Pieces[I].InputOff;
243
2.24k
    size_t End =
244
2.24k
        (Pieces.size() - 1 == I) ? 
Data.size()2.15k
:
Pieces[I + 1].InputOff85
;
245
2.24k
    return {toStringRef(Data.slice(Begin, End - Begin)), Pieces[I].Hash};
246
2.24k
  }
247
248
  // Returns the SectionPiece at a given input section offset.
249
  SectionPiece *getSectionPiece(uint64_t Offset);
250
0
  const SectionPiece *getSectionPiece(uint64_t Offset) const {
251
0
    return const_cast<MergeInputSection *>(this)->getSectionPiece(Offset);
252
0
  }
253
254
  SyntheticSection *getParent() const;
255
256
private:
257
  void splitStrings(ArrayRef<uint8_t> A, size_t Size);
258
  void splitNonStrings(ArrayRef<uint8_t> A, size_t Size);
259
};
260
261
struct EhSectionPiece {
262
  EhSectionPiece(size_t Off, InputSectionBase *Sec, uint32_t Size,
263
                 unsigned FirstRelocation)
264
217
      : InputOff(Off), Sec(Sec), Size(Size), FirstRelocation(FirstRelocation) {}
265
266
598
  ArrayRef<uint8_t> data() { return {Sec->Data.data() + this->InputOff, Size}; }
267
268
  size_t InputOff;
269
  ssize_t OutputOff = -1;
270
  InputSectionBase *Sec;
271
  uint32_t Size;
272
  unsigned FirstRelocation;
273
};
274
275
// This corresponds to a .eh_frame section of an input file.
276
class EhInputSection : public InputSectionBase {
277
public:
278
  template <class ELFT>
279
  EhInputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header,
280
                 StringRef Name);
281
544k
  static bool classof(const SectionBase *S) { return S->kind() == EHFrame; }
282
  template <class ELFT> void split();
283
  template <class ELFT, class RelTy> void split(ArrayRef<RelTy> Rels);
284
285
  // Splittable sections are handled as a sequence of data
286
  // rather than a single large blob of data.
287
  std::vector<EhSectionPiece> Pieces;
288
289
  SyntheticSection *getParent() const;
290
};
291
292
// This is a section that is added directly to an output section
293
// instead of needing special combination via a synthetic section. This
294
// includes all input sections with the exceptions of SHF_MERGE and
295
// .eh_frame. It also includes the synthetic sections themselves.
296
class InputSection : public InputSectionBase {
297
public:
298
  InputSection(InputFile *F, uint64_t Flags, uint32_t Type, uint32_t Alignment,
299
               ArrayRef<uint8_t> Data, StringRef Name, Kind K = Regular);
300
  template <class ELFT>
301
  InputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header,
302
               StringRef Name);
303
304
  // Write this section to a mmap'ed file, assuming Buf is pointing to
305
  // beginning of the output section.
306
  template <class ELFT> void writeTo(uint8_t *Buf);
307
308
72.7k
  uint64_t getOffset(uint64_t Offset) const { return OutSecOff + Offset; }
309
310
  OutputSection *getParent() const;
311
312
  // This variable has two usages. Initially, it represents an index in the
313
  // OutputSection's InputSection list, and is used when ordering SHF_LINK_ORDER
314
  // sections. After assignAddresses is called, it represents the offset from
315
  // the beginning of the output section this section was assigned to.
316
  uint64_t OutSecOff = 0;
317
318
  static bool classof(const SectionBase *S);
319
320
  InputSectionBase *getRelocatedSection() const;
321
322
  template <class ELFT, class RelTy>
323
  void relocateNonAlloc(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
324
325
  // Used by ICF.
326
  uint32_t Class[2] = {0, 0};
327
328
  // Called by ICF to merge two input sections.
329
  void replace(InputSection *Other);
330
331
  static InputSection Discarded;
332
333
private:
334
  template <class ELFT, class RelTy>
335
  void copyRelocations(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
336
337
  template <class ELFT> void copyShtGroup(uint8_t *Buf);
338
};
339
340
// The list of all input sections.
341
extern std::vector<InputSectionBase *> InputSections;
342
} // namespace elf
343
344
std::string toString(const elf::InputSectionBase *);
345
} // namespace lld
346
347
#endif