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 "InputSection.h" 15 #include "LinkerScript.h" 16 #include "Relocations.h" 17 #include "lld/Common/LLVM.h" 18 #include "llvm/MC/StringTableBuilder.h" 19 #include "llvm/Object/ELF.h" 20 #include <array> 21 22 namespace lld { 23 namespace elf { 24 25 struct PhdrEntry; 26 class Symbol; 27 struct EhSectionPiece; 28 class EhInputSection; 29 class InputSection; 30 class InputSectionBase; 31 class MergeInputSection; 32 class OutputSection; 33 template <class ELFT> class ObjFile; 34 template <class ELFT> class SharedFile; 35 class SharedSymbol; 36 class Defined; 37 38 // This represents a section in an output file. 39 // It is composed of multiple InputSections. 40 // The writer creates multiple OutputSections and assign them unique, 41 // non-overlapping file offsets and VAs. 42 class OutputSection final : public BaseCommand, public SectionBase { 43 public: 44 OutputSection(StringRef Name, uint32_t Type, uint64_t Flags); 45 classof(const SectionBase * S)46 static bool classof(const SectionBase *S) { 47 return S->kind() == SectionBase::Output; 48 } 49 50 static bool classof(const BaseCommand *C); 51 getLMA()52 uint64_t getLMA() const { return PtLoad ? Addr + PtLoad->LMAOffset : Addr; } 53 template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr *SHdr); 54 55 uint32_t SectionIndex = UINT32_MAX; 56 unsigned SortRank; 57 58 uint32_t getPhdrFlags() const; 59 60 // Pointer to the PT_LOAD segment, which this section resides in. This field 61 // is used to correctly compute file offset of a section. When two sections 62 // share the same load segment, difference between their file offsets should 63 // be equal to difference between their virtual addresses. To compute some 64 // section offset we use the following formula: Off = Off_first + VA - 65 // VA_first, where Off_first and VA_first is file offset and VA of first 66 // section in PT_LOAD. 67 PhdrEntry *PtLoad = nullptr; 68 69 // Pointer to a relocation section for this section. Usually nullptr because 70 // we consume relocations, but if --emit-relocs is specified (which is rare), 71 // it may have a non-null value. 72 OutputSection *RelocationSection = nullptr; 73 74 // Initially this field is the number of InputSections that have been added to 75 // the OutputSection so far. Later on, after a call to assignAddresses, it 76 // corresponds to the Elf_Shdr member. 77 uint64_t Size = 0; 78 79 // The following fields correspond to Elf_Shdr members. 80 uint64_t Offset = 0; 81 uint64_t Addr = 0; 82 uint32_t ShName = 0; 83 84 void addSection(InputSection *IS); 85 86 // Location in the output buffer. 87 uint8_t *Loc = nullptr; 88 89 // The following members are normally only used in linker scripts. 90 MemoryRegion *MemRegion = nullptr; 91 MemoryRegion *LMARegion = nullptr; 92 Expr AddrExpr; 93 Expr AlignExpr; 94 Expr LMAExpr; 95 Expr SubalignExpr; 96 std::vector<BaseCommand *> SectionCommands; 97 std::vector<StringRef> Phdrs; 98 llvm::Optional<std::array<uint8_t, 4>> Filler; 99 ConstraintKind Constraint = ConstraintKind::NoConstraint; 100 std::string Location; 101 std::string MemoryRegionName; 102 std::string LMARegionName; 103 bool NonAlloc = false; 104 bool Noload = false; 105 bool ExpressionsUseSymbols = false; 106 bool InOverlay = false; 107 108 template <class ELFT> void finalize(); 109 template <class ELFT> void writeTo(uint8_t *Buf); 110 template <class ELFT> void maybeCompress(); 111 112 void sort(llvm::function_ref<int(InputSectionBase *S)> Order); 113 void sortInitFini(); 114 void sortCtorsDtors(); 115 116 private: 117 // Used for implementation of --compress-debug-sections option. 118 std::vector<uint8_t> ZDebugHeader; 119 llvm::SmallVector<char, 1> CompressedData; 120 121 std::array<uint8_t, 4> getFiller(); 122 }; 123 124 int getPriority(StringRef S); 125 126 std::vector<InputSection *> getInputSections(OutputSection* OS); 127 128 // All output sections that are handled by the linker specially are 129 // globally accessible. Writer initializes them, so don't use them 130 // until Writer is initialized. 131 struct Out { 132 static uint8_t First; 133 static PhdrEntry *TlsPhdr; 134 static OutputSection *ElfHeader; 135 static OutputSection *ProgramHeaders; 136 static OutputSection *PreinitArray; 137 static OutputSection *InitArray; 138 static OutputSection *FiniArray; 139 }; 140 141 } // namespace elf 142 } // namespace lld 143 144 namespace lld { 145 namespace elf { 146 147 uint64_t getHeaderSize(); 148 149 extern std::vector<OutputSection *> OutputSections; 150 } // namespace elf 151 } // namespace lld 152 153 #endif 154