]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lld/ELF/OutputSections.h
Merge llvm, clang, lld and lldb release_40 branch r292009. Also update
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lld / ELF / OutputSections.h
1 //===- OutputSections.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_OUTPUT_SECTIONS_H
11 #define LLD_ELF_OUTPUT_SECTIONS_H
12
13 #include "Config.h"
14 #include "Relocations.h"
15
16 #include "lld/Core/LLVM.h"
17 #include "llvm/MC/StringTableBuilder.h"
18 #include "llvm/Object/ELF.h"
19
20 namespace lld {
21 namespace elf {
22
23 struct PhdrEntry;
24 class SymbolBody;
25 struct EhSectionPiece;
26 template <class ELFT> class EhInputSection;
27 template <class ELFT> class InputSection;
28 template <class ELFT> class InputSectionBase;
29 template <class ELFT> class MergeInputSection;
30 template <class ELFT> class OutputSection;
31 template <class ELFT> class ObjectFile;
32 template <class ELFT> class SharedFile;
33 template <class ELFT> class SharedSymbol;
34 template <class ELFT> class DefinedRegular;
35
36 // This represents a section in an output file.
37 // Different sub classes represent different types of sections. Some contain
38 // input sections, others are created by the linker.
39 // The writer creates multiple OutputSections and assign them unique,
40 // non-overlapping file offsets and VAs.
41 class OutputSectionBase {
42 public:
43   enum Kind {
44     Base,
45     EHFrame,
46     Merge,
47     Regular,
48   };
49
50   OutputSectionBase(StringRef Name, uint32_t Type, uint64_t Flags);
51   void setLMAOffset(uint64_t LMAOff) { LMAOffset = LMAOff; }
52   uint64_t getLMA() const { return Addr + LMAOffset; }
53   template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr *SHdr);
54   StringRef getName() const { return Name; }
55
56   virtual void addSection(InputSectionData *C) {}
57   virtual Kind getKind() const { return Base; }
58   static bool classof(const OutputSectionBase *B) {
59     return B->getKind() == Base;
60   }
61
62   unsigned SectionIndex;
63
64   uint32_t getPhdrFlags() const;
65
66   void updateAlignment(uint64_t Alignment) {
67     if (Alignment > Addralign)
68       Addralign = Alignment;
69   }
70
71   // If true, this section will be page aligned on disk.
72   // Typically the first section of each PT_LOAD segment has this flag.
73   bool PageAlign = false;
74
75   // Pointer to the first section in PT_LOAD segment, which this section
76   // also resides in. This field is used to correctly compute file offset
77   // of a section. When two sections share the same load segment, difference
78   // between their file offsets should be equal to difference between their
79   // virtual addresses. To compute some section offset we use the following
80   // formula: Off = Off_first + VA - VA_first.
81   OutputSectionBase *FirstInPtLoad = nullptr;
82
83   virtual void finalize() {}
84   virtual void assignOffsets() {}
85   virtual void writeTo(uint8_t *Buf) {}
86   virtual ~OutputSectionBase() = default;
87
88   StringRef Name;
89
90   // The following fields correspond to Elf_Shdr members.
91   uint64_t Size = 0;
92   uint64_t Entsize = 0;
93   uint64_t Addralign = 0;
94   uint64_t Offset = 0;
95   uint64_t Flags = 0;
96   uint64_t LMAOffset = 0;
97   uint64_t Addr = 0;
98   uint32_t ShName = 0;
99   uint32_t Type = 0;
100   uint32_t Info = 0;
101   uint32_t Link = 0;
102 };
103
104 template <class ELFT> class OutputSection final : public OutputSectionBase {
105
106 public:
107   typedef typename ELFT::Shdr Elf_Shdr;
108   typedef typename ELFT::Sym Elf_Sym;
109   typedef typename ELFT::Rel Elf_Rel;
110   typedef typename ELFT::Rela Elf_Rela;
111   typedef typename ELFT::uint uintX_t;
112   OutputSection(StringRef Name, uint32_t Type, uintX_t Flags);
113   void addSection(InputSectionData *C) override;
114   void sort(std::function<int(InputSection<ELFT> *S)> Order);
115   void sortInitFini();
116   void sortCtorsDtors();
117   void writeTo(uint8_t *Buf) override;
118   void finalize() override;
119   void assignOffsets() override;
120   Kind getKind() const override { return Regular; }
121   static bool classof(const OutputSectionBase *B) {
122     return B->getKind() == Regular;
123   }
124   std::vector<InputSection<ELFT> *> Sections;
125
126   // Location in the output buffer.
127   uint8_t *Loc = nullptr;
128 };
129
130 template <class ELFT>
131 class MergeOutputSection final : public OutputSectionBase {
132   typedef typename ELFT::uint uintX_t;
133
134 public:
135   MergeOutputSection(StringRef Name, uint32_t Type, uintX_t Flags,
136                      uintX_t Alignment);
137   void addSection(InputSectionData *S) override;
138   void writeTo(uint8_t *Buf) override;
139   void finalize() override;
140   bool shouldTailMerge() const;
141   Kind getKind() const override { return Merge; }
142   static bool classof(const OutputSectionBase *B) {
143     return B->getKind() == Merge;
144   }
145
146 private:
147   void finalizeTailMerge();
148   void finalizeNoTailMerge();
149
150   llvm::StringTableBuilder Builder;
151   std::vector<MergeInputSection<ELFT> *> Sections;
152 };
153
154 struct CieRecord {
155   EhSectionPiece *Piece = nullptr;
156   std::vector<EhSectionPiece *> FdePieces;
157 };
158
159 // Output section for .eh_frame.
160 template <class ELFT> class EhOutputSection final : public OutputSectionBase {
161   typedef typename ELFT::uint uintX_t;
162   typedef typename ELFT::Shdr Elf_Shdr;
163   typedef typename ELFT::Rel Elf_Rel;
164   typedef typename ELFT::Rela Elf_Rela;
165
166 public:
167   EhOutputSection();
168   void writeTo(uint8_t *Buf) override;
169   void finalize() override;
170   bool empty() const { return Sections.empty(); }
171
172   void addSection(InputSectionData *S) override;
173   Kind getKind() const override { return EHFrame; }
174   static bool classof(const OutputSectionBase *B) {
175     return B->getKind() == EHFrame;
176   }
177
178   size_t NumFdes = 0;
179
180 private:
181   template <class RelTy>
182   void addSectionAux(EhInputSection<ELFT> *S, llvm::ArrayRef<RelTy> Rels);
183
184   template <class RelTy>
185   CieRecord *addCie(EhSectionPiece &Piece, ArrayRef<RelTy> Rels);
186
187   template <class RelTy>
188   bool isFdeLive(EhSectionPiece &Piece, ArrayRef<RelTy> Rels);
189
190   uintX_t getFdePc(uint8_t *Buf, size_t Off, uint8_t Enc);
191
192   std::vector<EhInputSection<ELFT> *> Sections;
193   std::vector<CieRecord *> Cies;
194
195   // CIE records are uniquified by their contents and personality functions.
196   llvm::DenseMap<std::pair<ArrayRef<uint8_t>, SymbolBody *>, CieRecord> CieMap;
197 };
198
199 // All output sections that are hadnled by the linker specially are
200 // globally accessible. Writer initializes them, so don't use them
201 // until Writer is initialized.
202 template <class ELFT> struct Out {
203   typedef typename ELFT::uint uintX_t;
204   typedef typename ELFT::Phdr Elf_Phdr;
205
206   static uint8_t First;
207   static EhOutputSection<ELFT> *EhFrame;
208   static OutputSection<ELFT> *Bss;
209   static OutputSection<ELFT> *BssRelRo;
210   static OutputSectionBase *Opd;
211   static uint8_t *OpdBuf;
212   static PhdrEntry *TlsPhdr;
213   static OutputSectionBase *DebugInfo;
214   static OutputSectionBase *ElfHeader;
215   static OutputSectionBase *ProgramHeaders;
216   static OutputSectionBase *PreinitArray;
217   static OutputSectionBase *InitArray;
218   static OutputSectionBase *FiniArray;
219 };
220
221 struct SectionKey {
222   StringRef Name;
223   uint64_t Flags;
224   uint64_t Alignment;
225 };
226
227 // This class knows how to create an output section for a given
228 // input section. Output section type is determined by various
229 // factors, including input section's sh_flags, sh_type and
230 // linker scripts.
231 template <class ELFT> class OutputSectionFactory {
232   typedef typename ELFT::Shdr Elf_Shdr;
233   typedef typename ELFT::uint uintX_t;
234
235 public:
236   OutputSectionFactory();
237   ~OutputSectionFactory();
238   std::pair<OutputSectionBase *, bool> create(InputSectionBase<ELFT> *C,
239                                               StringRef OutsecName);
240   std::pair<OutputSectionBase *, bool> create(const SectionKey &Key,
241                                               InputSectionBase<ELFT> *C);
242
243 private:
244   llvm::SmallDenseMap<SectionKey, OutputSectionBase *> Map;
245 };
246
247 template <class ELFT> uint64_t getHeaderSize() {
248   if (Config->OFormatBinary)
249     return 0;
250   return Out<ELFT>::ElfHeader->Size + Out<ELFT>::ProgramHeaders->Size;
251 }
252
253 template <class ELFT> uint8_t Out<ELFT>::First;
254 template <class ELFT> EhOutputSection<ELFT> *Out<ELFT>::EhFrame;
255 template <class ELFT> OutputSection<ELFT> *Out<ELFT>::Bss;
256 template <class ELFT> OutputSection<ELFT> *Out<ELFT>::BssRelRo;
257 template <class ELFT> OutputSectionBase *Out<ELFT>::Opd;
258 template <class ELFT> uint8_t *Out<ELFT>::OpdBuf;
259 template <class ELFT> PhdrEntry *Out<ELFT>::TlsPhdr;
260 template <class ELFT> OutputSectionBase *Out<ELFT>::DebugInfo;
261 template <class ELFT> OutputSectionBase *Out<ELFT>::ElfHeader;
262 template <class ELFT> OutputSectionBase *Out<ELFT>::ProgramHeaders;
263 template <class ELFT> OutputSectionBase *Out<ELFT>::PreinitArray;
264 template <class ELFT> OutputSectionBase *Out<ELFT>::InitArray;
265 template <class ELFT> OutputSectionBase *Out<ELFT>::FiniArray;
266 } // namespace elf
267 } // namespace lld
268
269
270 #endif