Coverage Report

Created: 2017-10-03 07:32

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