Coverage Report

Created: 2018-01-17 21:32

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