1 //===- OutputSections.h -----------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLD_ELF_OUTPUT_SECTIONS_H 10 #define LLD_ELF_OUTPUT_SECTIONS_H 11 12 #include "Config.h" 13 #include "InputSection.h" 14 #include "LinkerScript.h" 15 #include "Relocations.h" 16 #include "lld/Common/LLVM.h" 17 #include "llvm/MC/StringTableBuilder.h" 18 #include "llvm/Object/ELF.h" 19 #include <array> 20 21 namespace lld { 22 namespace elf { 23 24 struct PhdrEntry; 25 class InputSection; 26 class InputSectionBase; 27 28 // This represents a section in an output file. 29 // It is composed of multiple InputSections. 30 // The writer creates multiple OutputSections and assign them unique, 31 // non-overlapping file offsets and VAs. 32 class OutputSection final : public BaseCommand, public SectionBase { 33 public: 34 OutputSection(StringRef name, uint32_t type, uint64_t flags); 35 classof(const SectionBase * s)36 static bool classof(const SectionBase *s) { 37 return s->kind() == SectionBase::Output; 38 } 39 40 static bool classof(const BaseCommand *c); 41 getLMA()42 uint64_t getLMA() const { return ptLoad ? addr + ptLoad->lmaOffset : addr; } 43 template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr *sHdr); 44 45 uint32_t sectionIndex = UINT32_MAX; 46 unsigned sortRank; 47 48 uint32_t getPhdrFlags() const; 49 50 // Pointer to the PT_LOAD segment, which this section resides in. This field 51 // is used to correctly compute file offset of a section. When two sections 52 // share the same load segment, difference between their file offsets should 53 // be equal to difference between their virtual addresses. To compute some 54 // section offset we use the following formula: Off = Off_first + VA - 55 // VA_first, where Off_first and VA_first is file offset and VA of first 56 // section in PT_LOAD. 57 PhdrEntry *ptLoad = nullptr; 58 59 // Pointer to a relocation section for this section. Usually nullptr because 60 // we consume relocations, but if --emit-relocs is specified (which is rare), 61 // it may have a non-null value. 62 OutputSection *relocationSection = nullptr; 63 64 // Initially this field is the number of InputSections that have been added to 65 // the OutputSection so far. Later on, after a call to assignAddresses, it 66 // corresponds to the Elf_Shdr member. 67 uint64_t size = 0; 68 69 // The following fields correspond to Elf_Shdr members. 70 uint64_t offset = 0; 71 uint64_t addr = 0; 72 uint32_t shName = 0; 73 74 void recordSection(InputSectionBase *isec); 75 void commitSection(InputSection *isec); 76 void finalizeInputSections(); 77 78 // The following members are normally only used in linker scripts. 79 MemoryRegion *memRegion = nullptr; 80 MemoryRegion *lmaRegion = nullptr; 81 Expr addrExpr; 82 Expr alignExpr; 83 Expr lmaExpr; 84 Expr subalignExpr; 85 std::vector<BaseCommand *> sectionCommands; 86 std::vector<StringRef> phdrs; 87 llvm::Optional<std::array<uint8_t, 4>> filler; 88 ConstraintKind constraint = ConstraintKind::NoConstraint; 89 std::string location; 90 std::string memoryRegionName; 91 std::string lmaRegionName; 92 bool nonAlloc = false; 93 bool noload = false; 94 bool expressionsUseSymbols = false; 95 bool usedInExpression = false; 96 bool inOverlay = false; 97 98 // Tracks whether the section has ever had an input section added to it, even 99 // if the section was later removed (e.g. because it is a synthetic section 100 // that wasn't needed). This is needed for orphan placement. 101 bool hasInputSections = false; 102 103 void finalize(); 104 template <class ELFT> void writeTo(uint8_t *buf); 105 template <class ELFT> void maybeCompress(); 106 107 void sort(llvm::function_ref<int(InputSectionBase *s)> order); 108 void sortInitFini(); 109 void sortCtorsDtors(); 110 111 private: 112 // Used for implementation of --compress-debug-sections option. 113 std::vector<uint8_t> zDebugHeader; 114 llvm::SmallVector<char, 0> compressedData; 115 116 std::array<uint8_t, 4> getFiller(); 117 }; 118 119 int getPriority(StringRef s); 120 121 InputSection *getFirstInputSection(const OutputSection *os); 122 std::vector<InputSection *> getInputSections(const OutputSection *os); 123 124 // All output sections that are handled by the linker specially are 125 // globally accessible. Writer initializes them, so don't use them 126 // until Writer is initialized. 127 struct Out { 128 static uint8_t *bufferStart; 129 static uint8_t first; 130 static PhdrEntry *tlsPhdr; 131 static OutputSection *elfHeader; 132 static OutputSection *programHeaders; 133 static OutputSection *preinitArray; 134 static OutputSection *initArray; 135 static OutputSection *finiArray; 136 }; 137 138 } // namespace elf 139 } // namespace lld 140 141 namespace lld { 142 namespace elf { 143 144 uint64_t getHeaderSize(); 145 146 extern std::vector<OutputSection *> outputSections; 147 } // namespace elf 148 } // namespace lld 149 150 #endif 151