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