Coverage Report

Created: 2019-05-19 14:56

/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
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#ifndef LLD_ELF_INPUT_SECTION_H
10
#define LLD_ELF_INPUT_SECTION_H
11
12
#include "Config.h"
13
#include "Relocations.h"
14
#include "Thunks.h"
15
#include "lld/Common/LLVM.h"
16
#include "llvm/ADT/CachedHashString.h"
17
#include "llvm/ADT/DenseSet.h"
18
#include "llvm/ADT/TinyPtrVector.h"
19
#include "llvm/Object/ELF.h"
20
21
namespace lld {
22
namespace elf {
23
24
class Symbol;
25
struct SectionPiece;
26
27
class Defined;
28
class SyntheticSection;
29
class MergeSyntheticSection;
30
template <class ELFT> class ObjFile;
31
class OutputSection;
32
33
// This is the base class of all sections that lld handles. Some are sections in
34
// input files, some are sections in the produced output file and some exist
35
// just as a convenience for implementing special ways of combining some
36
// sections.
37
class SectionBase {
38
public:
39
  enum Kind { Regular, EHFrame, Merge, Synthetic, Output };
40
41
14.3M
  Kind kind() const { return (Kind)SectionKind; }
42
43
  StringRef Name;
44
45
  // This pointer points to the "real" instance of this instance.
46
  // Usually Repl == this. However, if ICF merges two sections,
47
  // Repl pointer of one section points to another section. So,
48
  // if you need to get a pointer to this instance, do not use
49
  // this but instead this->Repl.
50
  SectionBase *Repl;
51
52
  unsigned SectionKind : 3;
53
54
  // The next three bit fields are only used by InputSectionBase, but we
55
  // put them here so the struct packs better.
56
57
  // The garbage collector sets sections' Live bits.
58
  // If GC is disabled, all sections are considered live by default.
59
  unsigned Live : 1;
60
61
  // True if this section has already been placed to a linker script
62
  // output section. This is needed because, in a linker script, you
63
  // can refer to the same section more than once. For example, in
64
  // the following linker script,
65
  //
66
  //   .foo : { *(.text) }
67
  //   .bar : { *(.text) }
68
  //
69
  // .foo takes all .text sections, and .bar becomes empty. To achieve
70
  // this, we need to memorize whether a section has been placed or
71
  // not for each input section.
72
  unsigned Assigned : 1;
73
74
  unsigned Bss : 1;
75
76
  // Set for sections that should not be folded by ICF.
77
  unsigned KeepUnique : 1;
78
79
  // These corresponds to the fields in Elf_Shdr.
80
  uint32_t Alignment;
81
  uint64_t Flags;
82
  uint64_t Entsize;
83
  uint32_t Type;
84
  uint32_t Link;
85
  uint32_t Info;
86
87
  OutputSection *getOutputSection();
88
144k
  const OutputSection *getOutputSection() const {
89
144k
    return const_cast<SectionBase *>(this)->getOutputSection();
90
144k
  }
91
92
  // Translate an offset in the input section to an offset in the output
93
  // section.
94
  uint64_t getOffset(uint64_t Offset) const;
95
96
  uint64_t getVA(uint64_t Offset = 0) const;
97
98
protected:
99
  SectionBase(Kind SectionKind, StringRef Name, uint64_t Flags,
100
              uint64_t Entsize, uint64_t Alignment, uint32_t Type,
101
              uint32_t Info, uint32_t Link)
102
      : Name(Name), Repl(this), SectionKind(SectionKind), Live(false),
103
        Assigned(false), Bss(false), KeepUnique(false), Alignment(Alignment),
104
778k
        Flags(Flags), Entsize(Entsize), Type(Type), Link(Link), Info(Info) {}
105
};
106
107
// This corresponds to a section of an input file.
108
class InputSectionBase : public SectionBase {
109
public:
110
  template <class ELFT>
111
  InputSectionBase(ObjFile<ELFT> &File, const typename ELFT::Shdr &Header,
112
                   StringRef Name, Kind SectionKind);
113
114
  InputSectionBase(InputFile *File, uint64_t Flags, uint32_t Type,
115
                   uint64_t Entsize, uint32_t Link, uint32_t Info,
116
                   uint32_t Alignment, ArrayRef<uint8_t> Data, StringRef Name,
117
                   Kind SectionKind);
118
119
84.4k
  static bool classof(const SectionBase *S) { return S->kind() != Output; }
120
121
  // Relocations that refer to this section.
122
  unsigned NumRelocations : 31;
123
  unsigned AreRelocsRela : 1;
124
  const void *FirstRelocation = nullptr;
125
126
  // The file which contains this section. Its dynamic type is always
127
  // ObjFile<ELFT>, but in order to avoid ELFT, we use InputFile as
128
  // its static type.
129
  InputFile *File;
130
131
27.4k
  template <class ELFT> ObjFile<ELFT> *getFile() const {
132
27.4k
    return cast_or_null<ObjFile<ELFT>>(File);
133
27.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
131
1.93k
  template <class ELFT> ObjFile<ELFT> *getFile() const {
132
1.93k
    return cast_or_null<ObjFile<ELFT>>(File);
133
1.93k
  }
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
131
776
  template <class ELFT> ObjFile<ELFT> *getFile() const {
132
776
    return cast_or_null<ObjFile<ELFT>>(File);
133
776
  }
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
131
8.60k
  template <class ELFT> ObjFile<ELFT> *getFile() const {
132
8.60k
    return cast_or_null<ObjFile<ELFT>>(File);
133
8.60k
  }
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
131
16.1k
  template <class ELFT> ObjFile<ELFT> *getFile() const {
132
16.1k
    return cast_or_null<ObjFile<ELFT>>(File);
133
16.1k
  }
134
135
5.22M
  ArrayRef<uint8_t> data() const {
136
5.22M
    if (UncompressedSize >= 0)
137
7
      uncompress();
138
5.22M
    return RawData;
139
5.22M
  }
140
141
  uint64_t getOffsetInFile() const;
142
143
  // Input sections are part of an output section. Special sections
144
  // like .eh_frame and merge sections are first combined into a
145
  // synthetic section that is then added to an output section. In all
146
  // cases this points one level up.
147
  SectionBase *Parent = nullptr;
148
149
308k
  template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
150
308k
    assert(!AreRelocsRela);
151
308k
    return llvm::makeArrayRef(
152
308k
        static_cast<const typename ELFT::Rel *>(FirstRelocation),
153
308k
        NumRelocations);
154
308k
  }
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
149
5.73k
  template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
150
5.73k
    assert(!AreRelocsRela);
151
5.73k
    return llvm::makeArrayRef(
152
5.73k
        static_cast<const typename ELFT::Rel *>(FirstRelocation),
153
5.73k
        NumRelocations);
154
5.73k
  }
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
149
2.48k
  template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
150
2.48k
    assert(!AreRelocsRela);
151
2.48k
    return llvm::makeArrayRef(
152
2.48k
        static_cast<const typename ELFT::Rel *>(FirstRelocation),
153
2.48k
        NumRelocations);
154
2.48k
  }
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
149
298k
  template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
150
298k
    assert(!AreRelocsRela);
151
298k
    return llvm::makeArrayRef(
152
298k
        static_cast<const typename ELFT::Rel *>(FirstRelocation),
153
298k
        NumRelocations);
154
298k
  }
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
149
1.93k
  template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
150
1.93k
    assert(!AreRelocsRela);
151
1.93k
    return llvm::makeArrayRef(
152
1.93k
        static_cast<const typename ELFT::Rel *>(FirstRelocation),
153
1.93k
        NumRelocations);
154
1.93k
  }
155
156
1.96k
  template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const {
157
1.96k
    assert(AreRelocsRela);
158
1.96k
    return llvm::makeArrayRef(
159
1.96k
        static_cast<const typename ELFT::Rela *>(FirstRelocation),
160
1.96k
        NumRelocations);
161
1.96k
  }
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
156
1.81k
  template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const {
157
1.81k
    assert(AreRelocsRela);
158
1.81k
    return llvm::makeArrayRef(
159
1.81k
        static_cast<const typename ELFT::Rela *>(FirstRelocation),
160
1.81k
        NumRelocations);
161
1.81k
  }
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
156
140
  template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const {
157
140
    assert(AreRelocsRela);
158
140
    return llvm::makeArrayRef(
159
140
        static_cast<const typename ELFT::Rela *>(FirstRelocation),
160
140
        NumRelocations);
161
140
  }
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
156
5
  template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const {
157
5
    assert(AreRelocsRela);
158
5
    return llvm::makeArrayRef(
159
5
        static_cast<const typename ELFT::Rela *>(FirstRelocation),
160
5
        NumRelocations);
161
5
  }
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
156
13
  template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const {
157
13
    assert(AreRelocsRela);
158
13
    return llvm::makeArrayRef(
159
13
        static_cast<const typename ELFT::Rela *>(FirstRelocation),
160
13
        NumRelocations);
161
13
  }
162
163
  // InputSections that are dependent on us (reverse dependency for GC)
164
  llvm::TinyPtrVector<InputSection *> DependentSections;
165
166
  // Returns the size of this section (even if this is a common or BSS.)
167
  size_t getSize() const;
168
169
  InputSection *getLinkOrderDep() const;
170
171
  // Get the function symbol that encloses this offset from within the
172
  // section.
173
  template <class ELFT>
174
  Defined *getEnclosingFunction(uint64_t Offset);
175
176
  // Returns a source location string. Used to construct an error message.
177
  template <class ELFT> std::string getLocation(uint64_t Offset);
178
  std::string getSrcMsg(const Symbol &Sym, uint64_t Offset);
179
  std::string getObjMsg(uint64_t Offset);
180
181
  // Each section knows how to relocate itself. These functions apply
182
  // relocations, assuming that Buf points to this section's copy in
183
  // the mmap'ed output buffer.
184
  template <class ELFT> void relocate(uint8_t *Buf, uint8_t *BufEnd);
185
  void relocateAlloc(uint8_t *Buf, uint8_t *BufEnd);
186
187
  // The native ELF reloc data type is not very convenient to handle.
188
  // So we convert ELF reloc records to our own records in Relocations.cpp.
189
  // This vector contains such "cooked" relocations.
190
  std::vector<Relocation> Relocations;
191
192
  // A function compiled with -fsplit-stack calling a function
193
  // compiled without -fsplit-stack needs its prologue adjusted. Find
194
  // such functions and adjust their prologues.  This is very similar
195
  // to relocation. See https://gcc.gnu.org/wiki/SplitStacks for more
196
  // information.
197
  template <typename ELFT>
198
  void adjustSplitStackFunctionPrologues(uint8_t *Buf, uint8_t *End);
199
200
201
155
  template <typename T> llvm::ArrayRef<T> getDataAs() const {
202
155
    size_t S = data().size();
203
155
    assert(S % sizeof(T) == 0);
204
155
    return llvm::makeArrayRef<T>((const T *)data().data(), S / sizeof(T));
205
155
  }
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
201
20
  template <typename T> llvm::ArrayRef<T> getDataAs() const {
202
20
    size_t S = data().size();
203
20
    assert(S % sizeof(T) == 0);
204
20
    return llvm::makeArrayRef<T>((const T *)data().data(), S / sizeof(T));
205
20
  }
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
201
9
  template <typename T> llvm::ArrayRef<T> getDataAs() const {
202
9
    size_t S = data().size();
203
9
    assert(S % sizeof(T) == 0);
204
9
    return llvm::makeArrayRef<T>((const T *)data().data(), S / sizeof(T));
205
9
  }
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
201
10
  template <typename T> llvm::ArrayRef<T> getDataAs() const {
202
10
    size_t S = data().size();
203
10
    assert(S % sizeof(T) == 0);
204
10
    return llvm::makeArrayRef<T>((const T *)data().data(), S / sizeof(T));
205
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
201
74
  template <typename T> llvm::ArrayRef<T> getDataAs() const {
202
74
    size_t S = data().size();
203
74
    assert(S % sizeof(T) == 0);
204
74
    return llvm::makeArrayRef<T>((const T *)data().data(), S / sizeof(T));
205
74
  }
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
201
2
  template <typename T> llvm::ArrayRef<T> getDataAs() const {
202
2
    size_t S = data().size();
203
2
    assert(S % sizeof(T) == 0);
204
2
    return llvm::makeArrayRef<T>((const T *)data().data(), S / sizeof(T));
205
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
SyntheticSections.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
201
40
  template <typename T> llvm::ArrayRef<T> getDataAs() const {
202
40
    size_t S = data().size();
203
40
    assert(S % sizeof(T) == 0);
204
40
    return llvm::makeArrayRef<T>((const T *)data().data(), S / sizeof(T));
205
40
  }
206
207
protected:
208
  void parseCompressedHeader();
209
  void uncompress() const;
210
211
  mutable ArrayRef<uint8_t> RawData;
212
213
  // This field stores the uncompressed size of the compressed data in RawData,
214
  // or -1 if RawData is not compressed (either because the section wasn't
215
  // compressed in the first place, or because we ended up uncompressing it).
216
  // Since the feature is not used often, this is usually -1.
217
  mutable 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
2.64k
      : InputOff(Off), Live(Live || !Config->GcSections), Hash(Hash >> 1) {}
227
228
  uint32_t InputOff;
229
  uint32_t Live : 1;
230
  uint32_t Hash : 31;
231
  uint64_t OutputOff = 0;
232
};
233
234
static_assert(sizeof(SectionPiece) == 16, "SectionPiece is too big");
235
236
// This corresponds to a SHF_MERGE section of an input file.
237
class MergeInputSection : public InputSectionBase {
238
public:
239
  template <class ELFT>
240
  MergeInputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header,
241
                    StringRef Name);
242
  MergeInputSection(uint64_t Flags, uint32_t Type, uint64_t Entsize,
243
                    ArrayRef<uint8_t> Data, StringRef Name);
244
245
735k
  static bool classof(const SectionBase *S) { return S->kind() == Merge; }
246
  void splitIntoPieces();
247
248
  // Translate an offset in the input section to an offset in the parent
249
  // MergeSyntheticSection.
250
  uint64_t getParentOffset(uint64_t Offset) const;
251
252
  // Splittable sections are handled as a sequence of data
253
  // rather than a single large blob of data.
254
  std::vector<SectionPiece> Pieces;
255
256
  // Returns I'th piece's data. This function is very hot when
257
  // string merging is enabled, so we want to inline.
258
  LLVM_ATTRIBUTE_ALWAYS_INLINE
259
2.64k
  llvm::CachedHashStringRef getData(size_t I) const {
260
2.64k
    size_t Begin = Pieces[I].InputOff;
261
2.64k
    size_t End =
262
2.64k
        (Pieces.size() - 1 == I) ? 
data().size()2.55k
:
Pieces[I + 1].InputOff89
;
263
2.64k
    return {toStringRef(data().slice(Begin, End - Begin)), Pieces[I].Hash};
264
2.64k
  }
265
266
  // Returns the SectionPiece at a given input section offset.
267
  SectionPiece *getSectionPiece(uint64_t Offset);
268
0
  const SectionPiece *getSectionPiece(uint64_t Offset) const {
269
0
    return const_cast<MergeInputSection *>(this)->getSectionPiece(Offset);
270
0
  }
271
272
  SyntheticSection *getParent() const;
273
274
private:
275
  void splitStrings(ArrayRef<uint8_t> A, size_t Size);
276
  void splitNonStrings(ArrayRef<uint8_t> A, size_t Size);
277
};
278
279
struct EhSectionPiece {
280
  EhSectionPiece(size_t Off, InputSectionBase *Sec, uint32_t Size,
281
                 unsigned FirstRelocation)
282
246
      : InputOff(Off), Sec(Sec), Size(Size), FirstRelocation(FirstRelocation) {}
283
284
591
  ArrayRef<uint8_t> data() {
285
591
    return {Sec->data().data() + this->InputOff, Size};
286
591
  }
287
288
  size_t InputOff;
289
  ssize_t OutputOff = -1;
290
  InputSectionBase *Sec;
291
  uint32_t Size;
292
  unsigned FirstRelocation;
293
};
294
295
// This corresponds to a .eh_frame section of an input file.
296
class EhInputSection : public InputSectionBase {
297
public:
298
  template <class ELFT>
299
  EhInputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header,
300
                 StringRef Name);
301
733k
  static bool classof(const SectionBase *S) { return S->kind() == EHFrame; }
302
  template <class ELFT> void split();
303
  template <class ELFT, class RelTy> void split(ArrayRef<RelTy> Rels);
304
305
  // Splittable sections are handled as a sequence of data
306
  // rather than a single large blob of data.
307
  std::vector<EhSectionPiece> Pieces;
308
309
  SyntheticSection *getParent() const;
310
};
311
312
// This is a section that is added directly to an output section
313
// instead of needing special combination via a synthetic section. This
314
// includes all input sections with the exceptions of SHF_MERGE and
315
// .eh_frame. It also includes the synthetic sections themselves.
316
class InputSection : public InputSectionBase {
317
public:
318
  InputSection(InputFile *F, uint64_t Flags, uint32_t Type, uint32_t Alignment,
319
               ArrayRef<uint8_t> Data, StringRef Name, Kind K = Regular);
320
  template <class ELFT>
321
  InputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header,
322
               StringRef Name);
323
324
  // Write this section to a mmap'ed file, assuming Buf is pointing to
325
  // beginning of the output section.
326
  template <class ELFT> void writeTo(uint8_t *Buf);
327
328
144k
  uint64_t getOffset(uint64_t Offset) const { return OutSecOff + Offset; }
329
330
  OutputSection *getParent() const;
331
332
  // This variable has two usages. Initially, it represents an index in the
333
  // OutputSection's InputSection list, and is used when ordering SHF_LINK_ORDER
334
  // sections. After assignAddresses is called, it represents the offset from
335
  // the beginning of the output section this section was assigned to.
336
  uint64_t OutSecOff = 0;
337
338
  static bool classof(const SectionBase *S);
339
340
  InputSectionBase *getRelocatedSection() const;
341
342
  template <class ELFT, class RelTy>
343
  void relocateNonAlloc(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
344
345
  // Used by ICF.
346
  uint32_t Class[2] = {0, 0};
347
348
  // Called by ICF to merge two input sections.
349
  void replace(InputSection *Other);
350
351
  static InputSection Discarded;
352
353
private:
354
  template <class ELFT, class RelTy>
355
  void copyRelocations(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
356
357
  template <class ELFT> void copyShtGroup(uint8_t *Buf);
358
};
359
360
// The list of all input sections.
361
extern std::vector<InputSectionBase *> InputSections;
362
363
} // namespace elf
364
365
std::string toString(const elf::InputSectionBase *);
366
} // namespace lld
367
368
#endif