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