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