Coverage Report

Created: 2019-01-18 03:29

/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
13.3M
  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
143k
  const OutputSection *getOutputSection() const {
77
143k
    return const_cast<SectionBase *>(this)->getOutputSection();
78
143k
  }
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
772k
        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
84.0k
  static bool classof(const SectionBase *S) { return S->kind() != Output; }
108
109
  // The file which contains this section. Its 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
26.7k
  template <class ELFT> ObjFile<ELFT> *getFile() const {
115
26.7k
    return cast_or_null<ObjFile<ELFT>>(File);
116
26.7k
  }
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
1.84k
  template <class ELFT> ObjFile<ELFT> *getFile() const {
115
1.84k
    return cast_or_null<ObjFile<ELFT>>(File);
116
1.84k
  }
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
705
  template <class ELFT> ObjFile<ELFT> *getFile() const {
115
705
    return cast_or_null<ObjFile<ELFT>>(File);
116
705
  }
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
8.11k
  template <class ELFT> ObjFile<ELFT> *getFile() const {
115
8.11k
    return cast_or_null<ObjFile<ELFT>>(File);
116
8.11k
  }
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
16.1k
  template <class ELFT> ObjFile<ELFT> *getFile() const {
115
16.1k
    return cast_or_null<ObjFile<ELFT>>(File);
116
16.1k
  }
117
118
5.22M
  ArrayRef<uint8_t> data() const {
119
5.22M
    if (UncompressedSize >= 0 && 
!UncompressedBuf28
)
120
7
      uncompress();
121
5.22M
    return RawData;
122
5.22M
  }
123
124
  uint64_t getOffsetInFile() const;
125
126
  // True if this section has already been placed to a linker script
127
  // output section. This is needed because, in a linker script, you
128
  // can refer to the same section more than once. For example, in
129
  // the following linker script,
130
  //
131
  //   .foo : { *(.text) }
132
  //   .bar : { *(.text) }
133
  //
134
  // .foo takes all .text sections, and .bar becomes empty. To achieve
135
  // this, we need to memorize whether a section has been placed or
136
  // not for each input section.
137
  bool Assigned = false;
138
139
  // Input sections are part of an output section. Special sections
140
  // like .eh_frame and merge sections are first combined into a
141
  // synthetic section that is then added to an output section. In all
142
  // cases this points one level up.
143
  SectionBase *Parent = nullptr;
144
145
  // Relocations that refer to this section.
146
  const void *FirstRelocation = nullptr;
147
  unsigned NumRelocations : 31;
148
  unsigned AreRelocsRela : 1;
149
150
304k
  template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
151
304k
    assert(!AreRelocsRela);
152
304k
    return llvm::makeArrayRef(
153
304k
        static_cast<const typename ELFT::Rel *>(FirstRelocation),
154
304k
        NumRelocations);
155
304k
  }
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
150
5.41k
  template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
151
5.41k
    assert(!AreRelocsRela);
152
5.41k
    return llvm::makeArrayRef(
153
5.41k
        static_cast<const typename ELFT::Rel *>(FirstRelocation),
154
5.41k
        NumRelocations);
155
5.41k
  }
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
150
2.35k
  template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
151
2.35k
    assert(!AreRelocsRela);
152
2.35k
    return llvm::makeArrayRef(
153
2.35k
        static_cast<const typename ELFT::Rel *>(FirstRelocation),
154
2.35k
        NumRelocations);
155
2.35k
  }
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
150
294k
  template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
151
294k
    assert(!AreRelocsRela);
152
294k
    return llvm::makeArrayRef(
153
294k
        static_cast<const typename ELFT::Rel *>(FirstRelocation),
154
294k
        NumRelocations);
155
294k
  }
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
150
1.90k
  template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
151
1.90k
    assert(!AreRelocsRela);
152
1.90k
    return llvm::makeArrayRef(
153
1.90k
        static_cast<const typename ELFT::Rel *>(FirstRelocation),
154
1.90k
        NumRelocations);
155
1.90k
  }
156
157
1.71k
  template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const {
158
1.71k
    assert(AreRelocsRela);
159
1.71k
    return llvm::makeArrayRef(
160
1.71k
        static_cast<const typename ELFT::Rela *>(FirstRelocation),
161
1.71k
        NumRelocations);
162
1.71k
  }
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
157
6
  template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const {
158
6
    assert(AreRelocsRela);
159
6
    return llvm::makeArrayRef(
160
6
        static_cast<const typename ELFT::Rela *>(FirstRelocation),
161
6
        NumRelocations);
162
6
  }
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
157
13
  template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const {
158
13
    assert(AreRelocsRela);
159
13
    return llvm::makeArrayRef(
160
13
        static_cast<const typename ELFT::Rela *>(FirstRelocation),
161
13
        NumRelocations);
162
13
  }
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
157
1.57k
  template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const {
158
1.57k
    assert(AreRelocsRela);
159
1.57k
    return llvm::makeArrayRef(
160
1.57k
        static_cast<const typename ELFT::Rela *>(FirstRelocation),
161
1.57k
        NumRelocations);
162
1.57k
  }
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
157
113
  template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const {
158
113
    assert(AreRelocsRela);
159
113
    return llvm::makeArrayRef(
160
113
        static_cast<const typename ELFT::Rela *>(FirstRelocation),
161
113
        NumRelocations);
162
113
  }
163
164
  // InputSections that are dependent on us (reverse dependency for GC)
165
  llvm::TinyPtrVector<InputSection *> DependentSections;
166
167
  // Returns the size of this section (even if this is a common or BSS.)
168
  size_t getSize() const;
169
170
  InputSection *getLinkOrderDep() const;
171
172
  // Get the function symbol that encloses this offset from within the
173
  // section.
174
  template <class ELFT>
175
  Defined *getEnclosingFunction(uint64_t Offset);
176
177
  // Returns a source location string. Used to construct an error message.
178
  template <class ELFT> std::string getLocation(uint64_t Offset);
179
  std::string getSrcMsg(const Symbol &Sym, uint64_t Offset);
180
  std::string getObjMsg(uint64_t Offset);
181
182
  // Each section knows how to relocate itself. These functions apply
183
  // relocations, assuming that Buf points to this section's copy in
184
  // the mmap'ed output buffer.
185
  template <class ELFT> void relocate(uint8_t *Buf, uint8_t *BufEnd);
186
  void relocateAlloc(uint8_t *Buf, uint8_t *BufEnd);
187
188
  // The native ELF reloc data type is not very convenient to handle.
189
  // So we convert ELF reloc records to our own records in Relocations.cpp.
190
  // This vector contains such "cooked" relocations.
191
  std::vector<Relocation> Relocations;
192
193
  // A function compiled with -fsplit-stack calling a function
194
  // compiled without -fsplit-stack needs its prologue adjusted. Find
195
  // such functions and adjust their prologues.  This is very similar
196
  // to relocation. See https://gcc.gnu.org/wiki/SplitStacks for more
197
  // information.
198
  template <typename ELFT>
199
  void adjustSplitStackFunctionPrologues(uint8_t *Buf, uint8_t *End);
200
201
202
125
  template <typename T> llvm::ArrayRef<T> getDataAs() const {
203
125
    size_t S = data().size();
204
125
    assert(S % sizeof(T) == 0);
205
125
    return llvm::makeArrayRef<T>((const T *)data().data(), S / sizeof(T));
206
125
  }
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
202
18
  template <typename T> llvm::ArrayRef<T> getDataAs() const {
203
18
    size_t S = data().size();
204
18
    assert(S % sizeof(T) == 0);
205
18
    return llvm::makeArrayRef<T>((const T *)data().data(), S / sizeof(T));
206
18
  }
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
202
8
  template <typename T> llvm::ArrayRef<T> getDataAs() const {
203
8
    size_t S = data().size();
204
8
    assert(S % sizeof(T) == 0);
205
8
    return llvm::makeArrayRef<T>((const T *)data().data(), S / sizeof(T));
206
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
202
10
  template <typename T> llvm::ArrayRef<T> getDataAs() const {
203
10
    size_t S = data().size();
204
10
    assert(S % sizeof(T) == 0);
205
10
    return llvm::makeArrayRef<T>((const T *)data().data(), S / sizeof(T));
206
10
  }
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
202
67
  template <typename T> llvm::ArrayRef<T> getDataAs() const {
203
67
    size_t S = data().size();
204
67
    assert(S % sizeof(T) == 0);
205
67
    return llvm::makeArrayRef<T>((const T *)data().data(), S / sizeof(T));
206
67
  }
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
202
1
  template <typename T> llvm::ArrayRef<T> getDataAs() const {
203
1
    size_t S = data().size();
204
1
    assert(S % sizeof(T) == 0);
205
1
    return llvm::makeArrayRef<T>((const T *)data().data(), S / sizeof(T));
206
1
  }
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
Writer.cpp:llvm::ArrayRef<isDuplicateArmExidxSec(lld::elf::InputSection*, lld::elf::InputSection*)::ExidxEntry> lld::elf::InputSectionBase::getDataAs<isDuplicateArmExidxSec(lld::elf::InputSection*, lld::elf::InputSection*)::ExidxEntry>() const
Line
Count
Source
202
21
  template <typename T> llvm::ArrayRef<T> getDataAs() const {
203
21
    size_t S = data().size();
204
21
    assert(S % sizeof(T) == 0);
205
21
    return llvm::makeArrayRef<T>((const T *)data().data(), S / sizeof(T));
206
21
  }
207
208
protected:
209
  void parseCompressedHeader();
210
  void uncompress() const;
211
212
  mutable ArrayRef<uint8_t> RawData;
213
214
  // A pointer that owns uncompressed data if a section is compressed by zlib.
215
  // Since the feature is not used often, this is usually a nullptr.
216
  mutable std::unique_ptr<char[]> UncompressedBuf;
217
  int64_t UncompressedSize = -1;
218
};
219
220
// SectionPiece represents a piece of splittable section contents.
221
// We allocate a lot of these and binary search on them. This means that they
222
// have to be as compact as possible, which is why we don't store the size (can
223
// be found by looking at the next one).
224
struct SectionPiece {
225
  SectionPiece(size_t Off, uint32_t Hash, bool Live)
226
      : InputOff(Off), Hash(Hash), OutputOff(0),
227
2.52k
        Live(Live || !Config->GcSections) {}
228
229
  uint32_t InputOff;
230
  uint32_t Hash;
231
  int64_t OutputOff : 63;
232
  uint64_t Live : 1;
233
};
234
235
static_assert(sizeof(SectionPiece) == 16, "SectionPiece is too big");
236
237
// This corresponds to a SHF_MERGE section of an input file.
238
class MergeInputSection : public InputSectionBase {
239
public:
240
  template <class ELFT>
241
  MergeInputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header,
242
                    StringRef Name);
243
  MergeInputSection(uint64_t Flags, uint32_t Type, uint64_t Entsize,
244
                    ArrayRef<uint8_t> Data, StringRef Name);
245
246
752k
  static bool classof(const SectionBase *S) { return S->kind() == Merge; }
247
  void splitIntoPieces();
248
249
  // Translate an offset in the input section to an offset in the parent
250
  // MergeSyntheticSection.
251
  uint64_t getParentOffset(uint64_t Offset) const;
252
253
  // Splittable sections are handled as a sequence of data
254
  // rather than a single large blob of data.
255
  std::vector<SectionPiece> Pieces;
256
257
  // Returns I'th piece's data. This function is very hot when
258
  // string merging is enabled, so we want to inline.
259
  LLVM_ATTRIBUTE_ALWAYS_INLINE
260
2.51k
  llvm::CachedHashStringRef getData(size_t I) const {
261
2.51k
    size_t Begin = Pieces[I].InputOff;
262
2.51k
    size_t End =
263
2.51k
        (Pieces.size() - 1 == I) ? 
data().size()2.43k
:
Pieces[I + 1].InputOff86
;
264
2.51k
    return {toStringRef(data().slice(Begin, End - Begin)), Pieces[I].Hash};
265
2.51k
  }
266
267
  // Returns the SectionPiece at a given input section offset.
268
  SectionPiece *getSectionPiece(uint64_t Offset);
269
0
  const SectionPiece *getSectionPiece(uint64_t Offset) const {
270
0
    return const_cast<MergeInputSection *>(this)->getSectionPiece(Offset);
271
0
  }
272
273
  SyntheticSection *getParent() const;
274
275
private:
276
  void splitStrings(ArrayRef<uint8_t> A, size_t Size);
277
  void splitNonStrings(ArrayRef<uint8_t> A, size_t Size);
278
};
279
280
struct EhSectionPiece {
281
  EhSectionPiece(size_t Off, InputSectionBase *Sec, uint32_t Size,
282
                 unsigned FirstRelocation)
283
238
      : InputOff(Off), Sec(Sec), Size(Size), FirstRelocation(FirstRelocation) {}
284
285
572
  ArrayRef<uint8_t> data() {
286
572
    return {Sec->data().data() + this->InputOff, Size};
287
572
  }
288
289
  size_t InputOff;
290
  ssize_t OutputOff = -1;
291
  InputSectionBase *Sec;
292
  uint32_t Size;
293
  unsigned FirstRelocation;
294
};
295
296
// This corresponds to a .eh_frame section of an input file.
297
class EhInputSection : public InputSectionBase {
298
public:
299
  template <class ELFT>
300
  EhInputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header,
301
                 StringRef Name);
302
747k
  static bool classof(const SectionBase *S) { return S->kind() == EHFrame; }
303
  template <class ELFT> void split();
304
  template <class ELFT, class RelTy> void split(ArrayRef<RelTy> Rels);
305
306
  // Splittable sections are handled as a sequence of data
307
  // rather than a single large blob of data.
308
  std::vector<EhSectionPiece> Pieces;
309
310
  SyntheticSection *getParent() const;
311
};
312
313
// This is a section that is added directly to an output section
314
// instead of needing special combination via a synthetic section. This
315
// includes all input sections with the exceptions of SHF_MERGE and
316
// .eh_frame. It also includes the synthetic sections themselves.
317
class InputSection : public InputSectionBase {
318
public:
319
  InputSection(InputFile *F, uint64_t Flags, uint32_t Type, uint32_t Alignment,
320
               ArrayRef<uint8_t> Data, StringRef Name, Kind K = Regular);
321
  template <class ELFT>
322
  InputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header,
323
               StringRef Name);
324
325
  // Write this section to a mmap'ed file, assuming Buf is pointing to
326
  // beginning of the output section.
327
  template <class ELFT> void writeTo(uint8_t *Buf);
328
329
142k
  uint64_t getOffset(uint64_t Offset) const { return OutSecOff + Offset; }
330
331
  OutputSection *getParent() const;
332
333
  // This variable has two usages. Initially, it represents an index in the
334
  // OutputSection's InputSection list, and is used when ordering SHF_LINK_ORDER
335
  // sections. After assignAddresses is called, it represents the offset from
336
  // the beginning of the output section this section was assigned to.
337
  uint64_t OutSecOff = 0;
338
339
  static bool classof(const SectionBase *S);
340
341
  InputSectionBase *getRelocatedSection() const;
342
343
  template <class ELFT, class RelTy>
344
  void relocateNonAlloc(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
345
346
  // Used by ICF.
347
  uint32_t Class[2] = {0, 0};
348
349
  // Called by ICF to merge two input sections.
350
  void replace(InputSection *Other);
351
352
  static InputSection Discarded;
353
354
private:
355
  template <class ELFT, class RelTy>
356
  void copyRelocations(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
357
358
  template <class ELFT> void copyShtGroup(uint8_t *Buf);
359
};
360
361
// The list of all input sections.
362
extern std::vector<InputSectionBase *> InputSections;
363
364
} // namespace elf
365
366
std::string toString(const elf::InputSectionBase *);
367
} // namespace lld
368
369
#endif