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 llvm::object::ELFFile<ELFT>::Elf_Rel Elf_Rel; 30 typedef typename llvm::object::ELFFile<ELFT>::Elf_Rela Elf_Rela; 31 typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr; 32 typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym; 33 typedef typename llvm::object::ELFFile<ELFT>::uintX_t 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 <bool isRela> 79 using RelIteratorRange = 80 llvm::iterator_range<const llvm::object::Elf_Rel_Impl<ELFT, isRela> *>; 81 82 template <bool isRela> 83 void relocate(uint8_t *Buf, uint8_t *BufEnd, RelIteratorRange<isRela> Rels); 84 85 private: 86 template <bool isRela> 87 uint8_t *findMipsPairedReloc(uint8_t *Buf, uint32_t SymIndex, uint32_t Type, 88 RelIteratorRange<isRela> Rels); 89 }; 90 91 template <class ELFT> 92 InputSectionBase<ELFT> * 93 InputSectionBase<ELFT>::Discarded = (InputSectionBase<ELFT> *)-1ULL; 94 95 // Usually sections are copied to the output as atomic chunks of data, 96 // but some special types of sections are split into small pieces of data 97 // and each piece is copied to a different place in the output. 98 // This class represents such special sections. 99 template <class ELFT> class SplitInputSection : public InputSectionBase<ELFT> { 100 typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr; 101 typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t; 102 103 public: 104 SplitInputSection(ObjectFile<ELFT> *File, const Elf_Shdr *Header, 105 typename InputSectionBase<ELFT>::Kind SectionKind); 106 107 // For each piece of data, we maintain the offsets in the input section and 108 // in the output section. The latter may be -1 if it is not assigned yet. 109 std::vector<std::pair<uintX_t, uintX_t>> Offsets; 110 111 std::pair<std::pair<uintX_t, uintX_t> *, uintX_t> 112 getRangeAndSize(uintX_t Offset); 113 }; 114 115 // This corresponds to a SHF_MERGE section of an input file. 116 template <class ELFT> class MergeInputSection : public SplitInputSection<ELFT> { 117 typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t; 118 typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym; 119 typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr; 120 121 public: 122 MergeInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header); 123 static bool classof(const InputSectionBase<ELFT> *S); 124 // Translate an offset in the input section to an offset in the output 125 // section. 126 uintX_t getOffset(uintX_t Offset); 127 }; 128 129 // This corresponds to a .eh_frame section of an input file. 130 template <class ELFT> class EHInputSection : public SplitInputSection<ELFT> { 131 public: 132 typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr; 133 typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t; 134 EHInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header); 135 static bool classof(const InputSectionBase<ELFT> *S); 136 137 // Translate an offset in the input section to an offset in the output 138 // section. 139 uintX_t getOffset(uintX_t Offset); 140 141 // Relocation section that refer to this one. 142 const Elf_Shdr *RelocSection = nullptr; 143 }; 144 145 // This corresponds to a non SHF_MERGE section of an input file. 146 template <class ELFT> class InputSection : public InputSectionBase<ELFT> { 147 friend ICF<ELFT>; 148 typedef InputSectionBase<ELFT> Base; 149 typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr; 150 typedef typename llvm::object::ELFFile<ELFT>::Elf_Rela Elf_Rela; 151 typedef typename llvm::object::ELFFile<ELFT>::Elf_Rel Elf_Rel; 152 typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym; 153 typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t; 154 155 public: 156 InputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header); 157 158 // Write this section to a mmap'ed file, assuming Buf is pointing to 159 // beginning of the output section. 160 void writeTo(uint8_t *Buf); 161 162 // Relocation sections that refer to this one. 163 llvm::TinyPtrVector<const Elf_Shdr *> RelocSections; 164 165 // The offset from beginning of the output sections this section was assigned 166 // to. The writer sets a value. 167 uint64_t OutSecOff = 0; 168 169 static bool classof(const InputSectionBase<ELFT> *S); 170 171 InputSectionBase<ELFT> *getRelocatedSection(); 172 173 private: 174 template <bool isRela> 175 using RelIteratorRange = 176 llvm::iterator_range<const llvm::object::Elf_Rel_Impl<ELFT, isRela> *>; 177 178 template <bool isRela> 179 void copyRelocations(uint8_t *Buf, RelIteratorRange<isRela> Rels); 180 181 // Called by ICF to merge two input sections. 182 void replace(InputSection<ELFT> *Other); 183 184 // Used by ICF. 185 uint64_t GroupId = 0; 186 }; 187 188 // MIPS .reginfo section provides information on the registers used by the code 189 // in the object file. Linker should collect this information and write a single 190 // .reginfo section in the output file. The output section contains a union of 191 // used registers masks taken from input .reginfo sections and final value 192 // of the `_gp` symbol. For details: Chapter 4 / "Register Information" at 193 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf 194 template <class ELFT> 195 class MipsReginfoInputSection : public InputSectionBase<ELFT> { 196 typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr; 197 198 public: 199 MipsReginfoInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Hdr); 200 static bool classof(const InputSectionBase<ELFT> *S); 201 202 const llvm::object::Elf_Mips_RegInfo<ELFT> *Reginfo; 203 }; 204 205 } // namespace elf 206 } // namespace lld 207 208 #endif 209