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 "lld/Core/LLVM.h" 15 #include "llvm/ADT/TinyPtrVector.h" 16 #include "llvm/Object/ELF.h" 17 18 namespace lld { 19 namespace elf { 20 21 template <class ELFT> class ICF; 22 template <class ELFT> class ObjectFile; 23 template <class ELFT> class OutputSection; 24 template <class ELFT> class OutputSectionBase; 25 26 // This corresponds to a section of an input file. 27 template <class ELFT> class InputSectionBase { 28 protected: 29 typedef typename ELFT::Rel Elf_Rel; 30 typedef typename ELFT::Rela Elf_Rela; 31 typedef typename ELFT::Shdr Elf_Shdr; 32 typedef typename ELFT::Sym Elf_Sym; 33 typedef typename ELFT::uint uintX_t; 34 const Elf_Shdr *Header; 35 36 // The file this section is from. 37 ObjectFile<ELFT> *File; 38 39 public: 40 enum Kind { Regular, EHFrame, Merge, MipsReginfo }; 41 Kind SectionKind; 42 43 InputSectionBase(ObjectFile<ELFT> *File, const Elf_Shdr *Header, 44 Kind SectionKind); 45 OutputSectionBase<ELFT> *OutSec = nullptr; 46 uint32_t Align; 47 48 // Used for garbage collection. 49 bool Live; 50 51 // This pointer points to the "real" instance of this instance. 52 // Usually Repl == this. However, if ICF merges two sections, 53 // Repl pointer of one section points to another section. So, 54 // if you need to get a pointer to this instance, do not use 55 // this but instead this->Repl. 56 InputSectionBase<ELFT> *Repl; 57 58 // Returns the size of this section (even if this is a common or BSS.) 59 size_t getSize() const { return Header->sh_size; } 60 61 static InputSectionBase<ELFT> *Discarded; 62 63 StringRef getSectionName() const; 64 const Elf_Shdr *getSectionHdr() const { return Header; } 65 ObjectFile<ELFT> *getFile() const { return File; } 66 uintX_t getOffset(const Elf_Sym &Sym); 67 68 // Translate an offset in the input section to an offset in the output 69 // section. 70 uintX_t getOffset(uintX_t Offset); 71 72 ArrayRef<uint8_t> getSectionData() const; 73 74 // Returns a section that Rel is pointing to. Used by the garbage collector. 75 InputSectionBase<ELFT> *getRelocTarget(const Elf_Rel &Rel) const; 76 InputSectionBase<ELFT> *getRelocTarget(const Elf_Rela &Rel) const; 77 78 template <class RelTy> 79 void relocate(uint8_t *Buf, uint8_t *BufEnd, 80 llvm::iterator_range<const RelTy *> Rels); 81 82 private: 83 template <class RelTy> 84 uint8_t *findMipsPairedReloc(uint8_t *Buf, const RelTy *Rel, 85 const RelTy *End); 86 }; 87 88 template <class ELFT> 89 InputSectionBase<ELFT> * 90 InputSectionBase<ELFT>::Discarded = (InputSectionBase<ELFT> *)-1ULL; 91 92 // Usually sections are copied to the output as atomic chunks of data, 93 // but some special types of sections are split into small pieces of data 94 // and each piece is copied to a different place in the output. 95 // This class represents such special sections. 96 template <class ELFT> class SplitInputSection : public InputSectionBase<ELFT> { 97 typedef typename ELFT::Shdr Elf_Shdr; 98 typedef typename ELFT::uint uintX_t; 99 100 public: 101 SplitInputSection(ObjectFile<ELFT> *File, const Elf_Shdr *Header, 102 typename InputSectionBase<ELFT>::Kind SectionKind); 103 104 // For each piece of data, we maintain the offsets in the input section and 105 // in the output section. The latter may be -1 if it is not assigned yet. 106 std::vector<std::pair<uintX_t, uintX_t>> Offsets; 107 108 std::pair<std::pair<uintX_t, uintX_t> *, uintX_t> 109 getRangeAndSize(uintX_t Offset); 110 }; 111 112 // This corresponds to a SHF_MERGE section of an input file. 113 template <class ELFT> class MergeInputSection : public SplitInputSection<ELFT> { 114 typedef typename ELFT::uint uintX_t; 115 typedef typename ELFT::Sym Elf_Sym; 116 typedef typename ELFT::Shdr Elf_Shdr; 117 118 public: 119 MergeInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header); 120 static bool classof(const InputSectionBase<ELFT> *S); 121 // Translate an offset in the input section to an offset in the output 122 // section. 123 uintX_t getOffset(uintX_t Offset); 124 }; 125 126 // This corresponds to a .eh_frame section of an input file. 127 template <class ELFT> class EHInputSection : public SplitInputSection<ELFT> { 128 public: 129 typedef typename ELFT::Shdr Elf_Shdr; 130 typedef typename ELFT::uint uintX_t; 131 EHInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header); 132 static bool classof(const InputSectionBase<ELFT> *S); 133 134 // Translate an offset in the input section to an offset in the output 135 // section. 136 uintX_t getOffset(uintX_t Offset); 137 138 // Relocation section that refer to this one. 139 const Elf_Shdr *RelocSection = nullptr; 140 }; 141 142 // This corresponds to a non SHF_MERGE section of an input file. 143 template <class ELFT> class InputSection : public InputSectionBase<ELFT> { 144 friend ICF<ELFT>; 145 typedef InputSectionBase<ELFT> Base; 146 typedef typename ELFT::Shdr Elf_Shdr; 147 typedef typename ELFT::Rela Elf_Rela; 148 typedef typename ELFT::Rel Elf_Rel; 149 typedef typename ELFT::Sym Elf_Sym; 150 typedef typename ELFT::uint uintX_t; 151 152 public: 153 InputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header); 154 155 // Write this section to a mmap'ed file, assuming Buf is pointing to 156 // beginning of the output section. 157 void writeTo(uint8_t *Buf); 158 159 // Relocation sections that refer to this one. 160 llvm::TinyPtrVector<const Elf_Shdr *> RelocSections; 161 162 // The offset from beginning of the output sections this section was assigned 163 // to. The writer sets a value. 164 uint64_t OutSecOff = 0; 165 166 static bool classof(const InputSectionBase<ELFT> *S); 167 168 InputSectionBase<ELFT> *getRelocatedSection(); 169 170 private: 171 template <class RelTy> 172 void copyRelocations(uint8_t *Buf, llvm::iterator_range<const RelTy *> Rels); 173 174 // Called by ICF to merge two input sections. 175 void replace(InputSection<ELFT> *Other); 176 177 // Used by ICF. 178 uint64_t GroupId = 0; 179 }; 180 181 // MIPS .reginfo section provides information on the registers used by the code 182 // in the object file. Linker should collect this information and write a single 183 // .reginfo section in the output file. The output section contains a union of 184 // used registers masks taken from input .reginfo sections and final value 185 // of the `_gp` symbol. For details: Chapter 4 / "Register Information" at 186 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf 187 template <class ELFT> 188 class MipsReginfoInputSection : public InputSectionBase<ELFT> { 189 typedef typename ELFT::Shdr Elf_Shdr; 190 191 public: 192 MipsReginfoInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Hdr); 193 static bool classof(const InputSectionBase<ELFT> *S); 194 195 const llvm::object::Elf_Mips_RegInfo<ELFT> *Reginfo; 196 }; 197 198 } // namespace elf 199 } // namespace lld 200 201 #endif 202