Coverage Report

Created: 2018-08-19 14:04

/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
140k
  const OutputSection *getOutputSection() const {
77
140k
    return const_cast<SectionBase *>(this)->getOutputSection();
78
140k
  }
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
763k
        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
83.3k
  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
25.6k
  template <class ELFT> ObjFile<ELFT> *getFile() const {
115
25.6k
    return cast_or_null<ObjFile<ELFT>>(File);
116
25.6k
  }
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.70k
  template <class ELFT> ObjFile<ELFT> *getFile() const {
115
1.70k
    return cast_or_null<ObjFile<ELFT>>(File);
116
1.70k
  }
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
687
  template <class ELFT> ObjFile<ELFT> *getFile() const {
115
687
    return cast_or_null<ObjFile<ELFT>>(File);
116
687
  }
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
7.40k
  template <class ELFT> ObjFile<ELFT> *getFile() const {
115
7.40k
    return cast_or_null<ObjFile<ELFT>>(File);
116
7.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.8k
  template <class ELFT> ObjFile<ELFT> *getFile() const {
115
15.8k
    return cast_or_null<ObjFile<ELFT>>(File);
116
15.8k
  }
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
299k
  template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
146
299k
    assert(!AreRelocsRela);
147
299k
    return llvm::makeArrayRef(
148
299k
        static_cast<const typename ELFT::Rel *>(FirstRelocation),
149
299k
        NumRelocations);
150
299k
  }
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.89k
  template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
146
4.89k
    assert(!AreRelocsRela);
147
4.89k
    return llvm::makeArrayRef(
148
4.89k
        static_cast<const typename ELFT::Rel *>(FirstRelocation),
149
4.89k
        NumRelocations);
150
4.89k
  }
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.29k
  template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
146
2.29k
    assert(!AreRelocsRela);
147
2.29k
    return llvm::makeArrayRef(
148
2.29k
        static_cast<const typename ELFT::Rel *>(FirstRelocation),
149
2.29k
        NumRelocations);
150
2.29k
  }
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
290k
  template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
146
290k
    assert(!AreRelocsRela);
147
290k
    return llvm::makeArrayRef(
148
290k
        static_cast<const typename ELFT::Rel *>(FirstRelocation),
149
290k
        NumRelocations);
150
290k
  }
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.50k
  template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
146
1.50k
    assert(!AreRelocsRela);
147
1.50k
    return llvm::makeArrayRef(
148
1.50k
        static_cast<const typename ELFT::Rel *>(FirstRelocation),
149
1.50k
        NumRelocations);
150
1.50k
  }
151
152
1.50k
  template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const {
153
1.50k
    assert(AreRelocsRela);
154
1.50k
    return llvm::makeArrayRef(
155
1.50k
        static_cast<const typename ELFT::Rela *>(FirstRelocation),
156
1.50k
        NumRelocations);
157
1.50k
  }
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.40k
  template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const {
153
1.40k
    assert(AreRelocsRela);
154
1.40k
    return llvm::makeArrayRef(
155
1.40k
        static_cast<const typename ELFT::Rela *>(FirstRelocation),
156
1.40k
        NumRelocations);
157
1.40k
  }
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
84
  template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const {
153
84
    assert(AreRelocsRela);
154
84
    return llvm::makeArrayRef(
155
84
        static_cast<const typename ELFT::Rela *>(FirstRelocation),
156
84
        NumRelocations);
157
84
  }
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
  // Get the function symbol that encloses this offset from within the
168
  // section.
169
  template <class ELFT>
170
  Defined *getEnclosingFunction(uint64_t Offset);
171
172
  // Compilers emit zlib-compressed debug sections if the -gz option
173
  // is given. This function checks if this section is compressed, and
174
  // if so, decompress in memory.
175
  void maybeDecompress();
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
116
  template <typename T> llvm::ArrayRef<T> getDataAs() const {
203
116
    size_t S = Data.size();
204
116
    assert(S % sizeof(T) == 0);
205
116
    return llvm::makeArrayRef<T>((const T *)Data.data(), S / sizeof(T));
206
116
  }
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
15
  template <typename T> llvm::ArrayRef<T> getDataAs() const {
203
15
    size_t S = Data.size();
204
15
    assert(S % sizeof(T) == 0);
205
15
    return llvm::makeArrayRef<T>((const T *)Data.data(), S / sizeof(T));
206
15
  }
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
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::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
63
  template <typename T> llvm::ArrayRef<T> getDataAs() const {
203
63
    size_t S = Data.size();
204
63
    assert(S % sizeof(T) == 0);
205
63
    return llvm::makeArrayRef<T>((const T *)Data.data(), S / sizeof(T));
206
63
  }
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
private:
209
  // A pointer that owns decompressed data if a section is compressed by zlib.
210
  // Since the feature is not used often, this is usually a nullptr.
211
  std::unique_ptr<char[]> DecompressBuf;
212
};
213
214
// SectionPiece represents a piece of splittable section contents.
215
// We allocate a lot of these and binary search on them. This means that they
216
// have to be as compact as possible, which is why we don't store the size (can
217
// be found by looking at the next one).
218
struct SectionPiece {
219
  SectionPiece(size_t Off, uint32_t Hash, bool Live)
220
      : InputOff(Off), Hash(Hash), OutputOff(0),
221
2.34k
        Live(Live || !Config->GcSections) {}
222
223
  uint32_t InputOff;
224
  uint32_t Hash;
225
  int64_t OutputOff : 63;
226
  uint64_t Live : 1;
227
};
228
229
static_assert(sizeof(SectionPiece) == 16, "SectionPiece is too big");
230
231
// This corresponds to a SHF_MERGE section of an input file.
232
class MergeInputSection : public InputSectionBase {
233
public:
234
  template <class ELFT>
235
  MergeInputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header,
236
                    StringRef Name);
237
  MergeInputSection(uint64_t Flags, uint32_t Type, uint64_t Entsize,
238
                    ArrayRef<uint8_t> Data, StringRef Name);
239
240
746k
  static bool classof(const SectionBase *S) { return S->kind() == Merge; }
241
  void splitIntoPieces();
242
243
  // Translate an offset in the input section to an offset in the parent
244
  // MergeSyntheticSection.
245
  uint64_t getParentOffset(uint64_t Offset) const;
246
247
  // Splittable sections are handled as a sequence of data
248
  // rather than a single large blob of data.
249
  std::vector<SectionPiece> Pieces;
250
  llvm::DenseMap<uint32_t, uint32_t> OffsetMap;
251
252
  // Returns I'th piece's data. This function is very hot when
253
  // string merging is enabled, so we want to inline.
254
  LLVM_ATTRIBUTE_ALWAYS_INLINE
255
2.34k
  llvm::CachedHashStringRef getData(size_t I) const {
256
2.34k
    size_t Begin = Pieces[I].InputOff;
257
2.34k
    size_t End =
258
2.34k
        (Pieces.size() - 1 == I) ? 
Data.size()2.26k
:
Pieces[I + 1].InputOff85
;
259
2.34k
    return {toStringRef(Data.slice(Begin, End - Begin)), Pieces[I].Hash};
260
2.34k
  }
261
262
  // Returns the SectionPiece at a given input section offset.
263
  SectionPiece *getSectionPiece(uint64_t Offset);
264
0
  const SectionPiece *getSectionPiece(uint64_t Offset) const {
265
0
    return const_cast<MergeInputSection *>(this)->getSectionPiece(Offset);
266
0
  }
267
268
  SyntheticSection *getParent() const;
269
270
private:
271
  void splitStrings(ArrayRef<uint8_t> A, size_t Size);
272
  void splitNonStrings(ArrayRef<uint8_t> A, size_t Size);
273
};
274
275
struct EhSectionPiece {
276
  EhSectionPiece(size_t Off, InputSectionBase *Sec, uint32_t Size,
277
                 unsigned FirstRelocation)
278
238
      : InputOff(Off), Sec(Sec), Size(Size), FirstRelocation(FirstRelocation) {}
279
280
572
  ArrayRef<uint8_t> data() { return {Sec->Data.data() + this->InputOff, Size}; }
281
282
  size_t InputOff;
283
  ssize_t OutputOff = -1;
284
  InputSectionBase *Sec;
285
  uint32_t Size;
286
  unsigned FirstRelocation;
287
};
288
289
// This corresponds to a .eh_frame section of an input file.
290
class EhInputSection : public InputSectionBase {
291
public:
292
  template <class ELFT>
293
  EhInputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header,
294
                 StringRef Name);
295
737k
  static bool classof(const SectionBase *S) { return S->kind() == EHFrame; }
296
  template <class ELFT> void split();
297
  template <class ELFT, class RelTy> void split(ArrayRef<RelTy> Rels);
298
299
  // Splittable sections are handled as a sequence of data
300
  // rather than a single large blob of data.
301
  std::vector<EhSectionPiece> Pieces;
302
303
  SyntheticSection *getParent() const;
304
};
305
306
// This is a section that is added directly to an output section
307
// instead of needing special combination via a synthetic section. This
308
// includes all input sections with the exceptions of SHF_MERGE and
309
// .eh_frame. It also includes the synthetic sections themselves.
310
class InputSection : public InputSectionBase {
311
public:
312
  InputSection(InputFile *F, uint64_t Flags, uint32_t Type, uint32_t Alignment,
313
               ArrayRef<uint8_t> Data, StringRef Name, Kind K = Regular);
314
  template <class ELFT>
315
  InputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header,
316
               StringRef Name);
317
318
  // Write this section to a mmap'ed file, assuming Buf is pointing to
319
  // beginning of the output section.
320
  template <class ELFT> void writeTo(uint8_t *Buf);
321
322
139k
  uint64_t getOffset(uint64_t Offset) const { return OutSecOff + Offset; }
323
324
  OutputSection *getParent() const;
325
326
  // This variable has two usages. Initially, it represents an index in the
327
  // OutputSection's InputSection list, and is used when ordering SHF_LINK_ORDER
328
  // sections. After assignAddresses is called, it represents the offset from
329
  // the beginning of the output section this section was assigned to.
330
  uint64_t OutSecOff = 0;
331
332
  static bool classof(const SectionBase *S);
333
334
  InputSectionBase *getRelocatedSection() const;
335
336
  template <class ELFT, class RelTy>
337
  void relocateNonAlloc(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
338
339
  // Used by ICF.
340
  uint32_t Class[2] = {0, 0};
341
342
  // Called by ICF to merge two input sections.
343
  void replace(InputSection *Other);
344
345
  static InputSection Discarded;
346
347
private:
348
  template <class ELFT, class RelTy>
349
  void copyRelocations(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
350
351
  template <class ELFT> void copyShtGroup(uint8_t *Buf);
352
};
353
354
// The list of all input sections.
355
extern std::vector<InputSectionBase *> InputSections;
356
357
Relocation *getRISCVPCRelHi20(const Symbol *Sym, const uint64_t Addend);
358
} // namespace elf
359
360
std::string toString(const elf::InputSectionBase *);
361
} // namespace lld
362
363
#endif