Coverage Report

Created: 2018-10-20 12:32

/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
141k
  const OutputSection *getOutputSection() const {
77
141k
    return const_cast<SectionBase *>(this)->getOutputSection();
78
141k
  }
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
768k
        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.7k
  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.3k
  template <class ELFT> ObjFile<ELFT> *getFile() const {
115
26.3k
    return cast_or_null<ObjFile<ELFT>>(File);
116
26.3k
  }
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.75k
  template <class ELFT> ObjFile<ELFT> *getFile() const {
115
1.75k
    return cast_or_null<ObjFile<ELFT>>(File);
116
1.75k
  }
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
684
  template <class ELFT> ObjFile<ELFT> *getFile() const {
115
684
    return cast_or_null<ObjFile<ELFT>>(File);
116
684
  }
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.86k
  template <class ELFT> ObjFile<ELFT> *getFile() const {
115
7.86k
    return cast_or_null<ObjFile<ELFT>>(File);
116
7.86k
  }
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.0k
  template <class ELFT> ObjFile<ELFT> *getFile() const {
115
16.0k
    return cast_or_null<ObjFile<ELFT>>(File);
116
16.0k
  }
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
300k
  template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
151
300k
    assert(!AreRelocsRela);
152
300k
    return llvm::makeArrayRef(
153
300k
        static_cast<const typename ELFT::Rel *>(FirstRelocation),
154
300k
        NumRelocations);
155
300k
  }
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.04k
  template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
151
5.04k
    assert(!AreRelocsRela);
152
5.04k
    return llvm::makeArrayRef(
153
5.04k
        static_cast<const typename ELFT::Rel *>(FirstRelocation),
154
5.04k
        NumRelocations);
155
5.04k
  }
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.29k
  template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
151
2.29k
    assert(!AreRelocsRela);
152
2.29k
    return llvm::makeArrayRef(
153
2.29k
        static_cast<const typename ELFT::Rel *>(FirstRelocation),
154
2.29k
        NumRelocations);
155
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
150
291k
  template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
151
291k
    assert(!AreRelocsRela);
152
291k
    return llvm::makeArrayRef(
153
291k
        static_cast<const typename ELFT::Rel *>(FirstRelocation),
154
291k
        NumRelocations);
155
291k
  }
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.73k
  template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
151
1.73k
    assert(!AreRelocsRela);
152
1.73k
    return llvm::makeArrayRef(
153
1.73k
        static_cast<const typename ELFT::Rel *>(FirstRelocation),
154
1.73k
        NumRelocations);
155
1.73k
  }
156
157
1.59k
  template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const {
158
1.59k
    assert(AreRelocsRela);
159
1.59k
    return llvm::makeArrayRef(
160
1.59k
        static_cast<const typename ELFT::Rela *>(FirstRelocation),
161
1.59k
        NumRelocations);
162
1.59k
  }
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
4
  template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const {
158
4
    assert(AreRelocsRela);
159
4
    return llvm::makeArrayRef(
160
4
        static_cast<const typename ELFT::Rela *>(FirstRelocation),
161
4
        NumRelocations);
162
4
  }
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
12
  template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const {
158
12
    assert(AreRelocsRela);
159
12
    return llvm::makeArrayRef(
160
12
        static_cast<const typename ELFT::Rela *>(FirstRelocation),
161
12
        NumRelocations);
162
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
157
1.47k
  template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const {
158
1.47k
    assert(AreRelocsRela);
159
1.47k
    return llvm::makeArrayRef(
160
1.47k
        static_cast<const typename ELFT::Rela *>(FirstRelocation),
161
1.47k
        NumRelocations);
162
1.47k
  }
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
106
  template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const {
158
106
    assert(AreRelocsRela);
159
106
    return llvm::makeArrayRef(
160
106
        static_cast<const typename ELFT::Rela *>(FirstRelocation),
161
106
        NumRelocations);
162
106
  }
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
118
  template <typename T> llvm::ArrayRef<T> getDataAs() const {
203
118
    size_t S = data().size();
204
118
    assert(S % sizeof(T) == 0);
205
118
    return llvm::makeArrayRef<T>((const T *)data().data(), S / sizeof(T));
206
118
  }
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
65
  template <typename T> llvm::ArrayRef<T> getDataAs() const {
203
65
    size_t S = data().size();
204
65
    assert(S % sizeof(T) == 0);
205
65
    return llvm::makeArrayRef<T>((const T *)data().data(), S / sizeof(T));
206
65
  }
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.43k
        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
760k
  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
  llvm::DenseMap<uint32_t, uint32_t> OffsetMap;
257
258
  // Returns I'th piece's data. This function is very hot when
259
  // string merging is enabled, so we want to inline.
260
  LLVM_ATTRIBUTE_ALWAYS_INLINE
261
2.43k
  llvm::CachedHashStringRef getData(size_t I) const {
262
2.43k
    size_t Begin = Pieces[I].InputOff;
263
2.43k
    size_t End =
264
2.43k
        (Pieces.size() - 1 == I) ? 
data().size()2.34k
:
Pieces[I + 1].InputOff86
;
265
2.43k
    return {toStringRef(data().slice(Begin, End - Begin)), Pieces[I].Hash};
266
2.43k
  }
267
268
  // Returns the SectionPiece at a given input section offset.
269
  SectionPiece *getSectionPiece(uint64_t Offset);
270
0
  const SectionPiece *getSectionPiece(uint64_t Offset) const {
271
0
    return const_cast<MergeInputSection *>(this)->getSectionPiece(Offset);
272
0
  }
273
274
  SyntheticSection *getParent() const;
275
276
private:
277
  void splitStrings(ArrayRef<uint8_t> A, size_t Size);
278
  void splitNonStrings(ArrayRef<uint8_t> A, size_t Size);
279
};
280
281
struct EhSectionPiece {
282
  EhSectionPiece(size_t Off, InputSectionBase *Sec, uint32_t Size,
283
                 unsigned FirstRelocation)
284
238
      : InputOff(Off), Sec(Sec), Size(Size), FirstRelocation(FirstRelocation) {}
285
286
572
  ArrayRef<uint8_t> data() {
287
572
    return {Sec->data().data() + this->InputOff, Size};
288
572
  }
289
290
  size_t InputOff;
291
  ssize_t OutputOff = -1;
292
  InputSectionBase *Sec;
293
  uint32_t Size;
294
  unsigned FirstRelocation;
295
};
296
297
// This corresponds to a .eh_frame section of an input file.
298
class EhInputSection : public InputSectionBase {
299
public:
300
  template <class ELFT>
301
  EhInputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header,
302
                 StringRef Name);
303
754k
  static bool classof(const SectionBase *S) { return S->kind() == EHFrame; }
304
  template <class ELFT> void split();
305
  template <class ELFT, class RelTy> void split(ArrayRef<RelTy> Rels);
306
307
  // Splittable sections are handled as a sequence of data
308
  // rather than a single large blob of data.
309
  std::vector<EhSectionPiece> Pieces;
310
311
  SyntheticSection *getParent() const;
312
};
313
314
// This is a section that is added directly to an output section
315
// instead of needing special combination via a synthetic section. This
316
// includes all input sections with the exceptions of SHF_MERGE and
317
// .eh_frame. It also includes the synthetic sections themselves.
318
class InputSection : public InputSectionBase {
319
public:
320
  InputSection(InputFile *F, uint64_t Flags, uint32_t Type, uint32_t Alignment,
321
               ArrayRef<uint8_t> Data, StringRef Name, Kind K = Regular);
322
  template <class ELFT>
323
  InputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header,
324
               StringRef Name);
325
326
  // Write this section to a mmap'ed file, assuming Buf is pointing to
327
  // beginning of the output section.
328
  template <class ELFT> void writeTo(uint8_t *Buf);
329
330
141k
  uint64_t getOffset(uint64_t Offset) const { return OutSecOff + Offset; }
331
332
  OutputSection *getParent() const;
333
334
  // This variable has two usages. Initially, it represents an index in the
335
  // OutputSection's InputSection list, and is used when ordering SHF_LINK_ORDER
336
  // sections. After assignAddresses is called, it represents the offset from
337
  // the beginning of the output section this section was assigned to.
338
  uint64_t OutSecOff = 0;
339
340
  static bool classof(const SectionBase *S);
341
342
  InputSectionBase *getRelocatedSection() const;
343
344
  template <class ELFT, class RelTy>
345
  void relocateNonAlloc(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
346
347
  // Used by ICF.
348
  uint32_t Class[2] = {0, 0};
349
350
  // Called by ICF to merge two input sections.
351
  void replace(InputSection *Other);
352
353
  static InputSection Discarded;
354
355
private:
356
  template <class ELFT, class RelTy>
357
  void copyRelocations(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
358
359
  template <class ELFT> void copyShtGroup(uint8_t *Buf);
360
};
361
362
// The list of all input sections.
363
extern std::vector<InputSectionBase *> InputSections;
364
365
Relocation *getRISCVPCRelHi20(const Symbol *Sym, const uint64_t Addend);
366
} // namespace elf
367
368
std::string toString(const elf::InputSectionBase *);
369
} // namespace lld
370
371
#endif