]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lld/ELF/InputSection.h
MFV r309587:
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lld / ELF / InputSection.h
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/DenseSet.h"
18 #include "llvm/ADT/TinyPtrVector.h"
19 #include "llvm/Object/ELF.h"
20
21 namespace lld {
22 namespace elf {
23
24 template <class ELFT> bool isDiscarded(InputSectionBase<ELFT> *S);
25
26 class SymbolBody;
27
28 template <class ELFT> class ICF;
29 template <class ELFT> class DefinedRegular;
30 template <class ELFT> class ObjectFile;
31 template <class ELFT> class OutputSection;
32 template <class ELFT> class OutputSectionBase;
33
34 // This corresponds to a section of an input file.
35 template <class ELFT> class InputSectionBase {
36 protected:
37   typedef typename ELFT::Chdr Elf_Chdr;
38   typedef typename ELFT::Rel Elf_Rel;
39   typedef typename ELFT::Rela Elf_Rela;
40   typedef typename ELFT::Shdr Elf_Shdr;
41   typedef typename ELFT::Sym Elf_Sym;
42   typedef typename ELFT::uint uintX_t;
43   const Elf_Shdr *Header;
44
45   // The file this section is from.
46   ObjectFile<ELFT> *File;
47
48   // If a section is compressed, this vector has uncompressed section data.
49   SmallVector<char, 0> Uncompressed;
50
51 public:
52   enum Kind { Regular, EHFrame, Merge, MipsReginfo, MipsOptions };
53   Kind SectionKind;
54
55   InputSectionBase() : Repl(this) {}
56
57   InputSectionBase(ObjectFile<ELFT> *File, const Elf_Shdr *Header,
58                    Kind SectionKind);
59   OutputSectionBase<ELFT> *OutSec = nullptr;
60   uint32_t Alignment;
61
62   // Used for garbage collection.
63   bool Live;
64
65   // This pointer points to the "real" instance of this instance.
66   // Usually Repl == this. However, if ICF merges two sections,
67   // Repl pointer of one section points to another section. So,
68   // if you need to get a pointer to this instance, do not use
69   // this but instead this->Repl.
70   InputSectionBase<ELFT> *Repl;
71
72   // Returns the size of this section (even if this is a common or BSS.)
73   size_t getSize() const;
74
75   static InputSectionBase<ELFT> Discarded;
76
77   StringRef getSectionName() const;
78   const Elf_Shdr *getSectionHdr() const { return Header; }
79   ObjectFile<ELFT> *getFile() const { return File; }
80   uintX_t getOffset(const DefinedRegular<ELFT> &Sym) const;
81
82   // Translate an offset in the input section to an offset in the output
83   // section.
84   uintX_t getOffset(uintX_t Offset) const;
85
86   ArrayRef<uint8_t> getSectionData() const;
87
88   void uncompress();
89
90   void relocate(uint8_t *Buf, uint8_t *BufEnd);
91   std::vector<Relocation<ELFT>> Relocations;
92
93   bool Compressed;
94 };
95
96 template <class ELFT> InputSectionBase<ELFT> InputSectionBase<ELFT>::Discarded;
97
98 // SectionPiece represents a piece of splittable section contents.
99 struct SectionPiece {
100   SectionPiece(size_t Off, ArrayRef<uint8_t> Data)
101       : InputOff(Off), Data((const uint8_t *)Data.data()), Size(Data.size()),
102         Live(!Config->GcSections) {}
103
104   ArrayRef<uint8_t> data() { return {Data, Size}; }
105   size_t size() const { return Size; }
106
107   size_t InputOff;
108   size_t OutputOff = -1;
109
110 private:
111   // We use bitfields because SplitInputSection is accessed by
112   // std::upper_bound very often.
113   // We want to save bits to make it cache friendly.
114   const uint8_t *Data;
115   uint32_t Size : 31;
116
117 public:
118   uint32_t Live : 1;
119 };
120
121 // Usually sections are copied to the output as atomic chunks of data,
122 // but some special types of sections are split into small pieces of data
123 // and each piece is copied to a different place in the output.
124 // This class represents such special sections.
125 template <class ELFT> class SplitInputSection : public InputSectionBase<ELFT> {
126   typedef typename ELFT::Shdr Elf_Shdr;
127   typedef typename ELFT::uint uintX_t;
128
129 public:
130   SplitInputSection(ObjectFile<ELFT> *File, const Elf_Shdr *Header,
131                     typename InputSectionBase<ELFT>::Kind SectionKind);
132
133   // Splittable sections are handled as a sequence of data
134   // rather than a single large blob of data.
135   std::vector<SectionPiece> Pieces;
136
137   // Returns the SectionPiece at a given input section offset.
138   SectionPiece *getSectionPiece(uintX_t Offset);
139   const SectionPiece *getSectionPiece(uintX_t Offset) const;
140 };
141
142 // This corresponds to a SHF_MERGE section of an input file.
143 template <class ELFT> class MergeInputSection : public SplitInputSection<ELFT> {
144   typedef typename ELFT::uint uintX_t;
145   typedef typename ELFT::Sym Elf_Sym;
146   typedef typename ELFT::Shdr Elf_Shdr;
147
148 public:
149   MergeInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header);
150   static bool classof(const InputSectionBase<ELFT> *S);
151   void splitIntoPieces();
152
153   // Mark the piece at a given offset live. Used by GC.
154   void markLiveAt(uintX_t Offset) { LiveOffsets.insert(Offset); }
155
156   // Translate an offset in the input section to an offset
157   // in the output section.
158   uintX_t getOffset(uintX_t Offset) const;
159
160   void finalizePieces();
161
162 private:
163   llvm::DenseMap<uintX_t, uintX_t> OffsetMap;
164   llvm::DenseSet<uintX_t> LiveOffsets;
165 };
166
167 // This corresponds to a .eh_frame section of an input file.
168 template <class ELFT> class EhInputSection : public SplitInputSection<ELFT> {
169 public:
170   typedef typename ELFT::Shdr Elf_Shdr;
171   typedef typename ELFT::uint uintX_t;
172   EhInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header);
173   static bool classof(const InputSectionBase<ELFT> *S);
174   void split();
175
176   // Translate an offset in the input section to an offset in the output
177   // section.
178   uintX_t getOffset(uintX_t Offset) const;
179
180   // Relocation section that refer to this one.
181   const Elf_Shdr *RelocSection = nullptr;
182 };
183
184 // This corresponds to a non SHF_MERGE section of an input file.
185 template <class ELFT> class InputSection : public InputSectionBase<ELFT> {
186   friend ICF<ELFT>;
187   typedef InputSectionBase<ELFT> Base;
188   typedef typename ELFT::Shdr Elf_Shdr;
189   typedef typename ELFT::Rela Elf_Rela;
190   typedef typename ELFT::Rel Elf_Rel;
191   typedef typename ELFT::Sym Elf_Sym;
192   typedef typename ELFT::uint uintX_t;
193
194 public:
195   InputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header);
196
197   // Write this section to a mmap'ed file, assuming Buf is pointing to
198   // beginning of the output section.
199   void writeTo(uint8_t *Buf);
200
201   // Relocation sections that refer to this one.
202   llvm::TinyPtrVector<const Elf_Shdr *> RelocSections;
203
204   // The offset from beginning of the output sections this section was assigned
205   // to. The writer sets a value.
206   uint64_t OutSecOff = 0;
207
208   static bool classof(const InputSectionBase<ELFT> *S);
209
210   InputSectionBase<ELFT> *getRelocatedSection();
211
212   // Register thunk related to the symbol. When the section is written
213   // to a mmap'ed file, target is requested to write an actual thunk code.
214   // Now thunks is supported for MIPS and ARM target only.
215   void addThunk(const Thunk<ELFT> *T);
216
217   // The offset of synthetic thunk code from beginning of this section.
218   uint64_t getThunkOff() const;
219
220   // Size of chunk with thunks code.
221   uint64_t getThunksSize() const;
222
223   template <class RelTy>
224   void relocateNonAlloc(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
225
226 private:
227   template <class RelTy>
228   void copyRelocations(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
229
230   // Called by ICF to merge two input sections.
231   void replace(InputSection<ELFT> *Other);
232
233   // Used by ICF.
234   uint64_t GroupId = 0;
235
236   llvm::TinyPtrVector<const Thunk<ELFT> *> Thunks;
237 };
238
239 // MIPS .reginfo section provides information on the registers used by the code
240 // in the object file. Linker should collect this information and write a single
241 // .reginfo section in the output file. The output section contains a union of
242 // used registers masks taken from input .reginfo sections and final value
243 // of the `_gp` symbol.  For details: Chapter 4 / "Register Information" at
244 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
245 template <class ELFT>
246 class MipsReginfoInputSection : public InputSectionBase<ELFT> {
247   typedef typename ELFT::Shdr Elf_Shdr;
248
249 public:
250   MipsReginfoInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Hdr);
251   static bool classof(const InputSectionBase<ELFT> *S);
252
253   const llvm::object::Elf_Mips_RegInfo<ELFT> *Reginfo = nullptr;
254 };
255
256 template <class ELFT>
257 class MipsOptionsInputSection : public InputSectionBase<ELFT> {
258   typedef typename ELFT::Shdr Elf_Shdr;
259
260 public:
261   MipsOptionsInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Hdr);
262   static bool classof(const InputSectionBase<ELFT> *S);
263
264   const llvm::object::Elf_Mips_RegInfo<ELFT> *Reginfo = nullptr;
265 };
266
267 } // namespace elf
268 } // namespace lld
269
270 #endif