brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.8 KiB · 77654f8 Raw
179 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLD_ELF_OUTPUT_SECTIONS_H10#define LLD_ELF_OUTPUT_SECTIONS_H11 12#include "InputSection.h"13#include "LinkerScript.h"14#include "lld/Common/LLVM.h"15#include "llvm/Support/Compiler.h"16#include "llvm/Support/Parallel.h"17 18#include <array>19 20namespace lld::elf {21 22struct PhdrEntry;23 24struct CompressedData {25  std::unique_ptr<SmallVector<uint8_t, 0>[]> shards;26  uint32_t type = 0;27  uint32_t numShards = 0;28  uint32_t checksum = 0;29  uint64_t uncompressedSize;30};31 32// This represents a section in an output file.33// It is composed of multiple InputSections.34// The writer creates multiple OutputSections and assign them unique,35// non-overlapping file offsets and VAs.36class OutputSection final : public SectionBase {37public:38  OutputSection(Ctx &, StringRef name, uint32_t type, uint64_t flags);39 40  static bool classof(const SectionBase *s) {41    return s->kind() == SectionBase::Output;42  }43 44  uint64_t getLMA() const;45  template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr *sHdr);46 47  Ctx &ctx;48  uint32_t sectionIndex = UINT32_MAX;49  unsigned sortRank;50 51  uint32_t getPhdrFlags() const;52 53  // Pointer to the PT_LOAD segment, which this section resides in. This field54  // is used to correctly compute file offset of a section. When two sections55  // share the same load segment, difference between their file offsets should56  // be equal to difference between their virtual addresses. To compute some57  // section offset we use the following formula: Off = Off_first + VA -58  // VA_first, where Off_first and VA_first is file offset and VA of first59  // section in PT_LOAD.60  PhdrEntry *ptLoad = nullptr;61 62  // Pointer to a relocation section for this section. Usually nullptr because63  // we consume relocations, but if --emit-relocs is specified (which is rare),64  // it may have a non-null value.65  OutputSection *relocationSection = nullptr;66 67  // Initially this field is the number of InputSections that have been added to68  // the OutputSection so far. Later on, after a call to assignAddresses, it69  // corresponds to the Elf_Shdr member.70  uint64_t size = 0;71 72  // The following fields correspond to Elf_Shdr members.73  uint64_t offset = 0;74  uint64_t addr = 0;75  uint32_t shName = 0;76 77  void recordSection(InputSectionBase *isec);78  void commitSection(InputSection *isec);79  void finalizeInputSections();80 81  // The following members are normally only used in linker scripts.82  MemoryRegion *memRegion = nullptr;83  MemoryRegion *lmaRegion = nullptr;84  Expr addrExpr;85  Expr alignExpr;86  Expr lmaExpr;87  Expr subalignExpr;88 89  // Used by non-alloc SHT_CREL to hold the header and content byte stream.90  uint64_t crelHeader = 0;91  SmallVector<char, 0> crelBody;92 93  SmallVector<SectionCommand *, 0> commands;94  SmallVector<StringRef, 0> phdrs;95  std::optional<std::array<uint8_t, 4>> filler;96  ConstraintKind constraint = ConstraintKind::NoConstraint;97  std::string location;98  std::string memoryRegionName;99  std::string lmaRegionName;100  bool nonAlloc = false;101  bool typeIsSet = false;102  bool expressionsUseSymbols = false;103  bool usedInExpression = false;104  bool inOverlay = false;105  bool firstInOverlay = false;106 107  // Tracks whether the section has ever had an input section added to it, even108  // if the section was later removed (e.g. because it is a synthetic section109  // that wasn't needed). This is needed for orphan placement.110  bool hasInputSections = false;111 112  // The output section description is specified between DATA_SEGMENT_ALIGN and113  // DATA_RELRO_END.114  bool relro = false;115 116  template <bool is64> void finalizeNonAllocCrel(Ctx &);117  void finalize(Ctx &);118  template <class ELFT>119  void writeTo(Ctx &, uint8_t *buf, llvm::parallel::TaskGroup &tg);120  // Check that the addends for dynamic relocations were written correctly.121  void checkDynRelAddends(Ctx &);122  template <class ELFT> void maybeCompress(Ctx &);123 124  void sort(llvm::function_ref<int(InputSectionBase *s)> order);125  void sortInitFini();126  void sortCtorsDtors();127 128  std::array<uint8_t, 4> getFiller(Ctx &);129 130  // Used for implementation of --compress-debug-sections and131  // --compress-sections.132  CompressedData compressed;133 134private:135  SmallVector<InputSection *, 0> storage;136};137 138struct OutputDesc final : SectionCommand {139  OutputSection osec;140  OutputDesc(Ctx &ctx, StringRef name, uint32_t type, uint64_t flags)141      : SectionCommand(OutputSectionKind), osec(ctx, name, type, flags) {}142 143  static bool classof(const SectionCommand *c) {144    return c->kind == OutputSectionKind;145  }146};147 148// This represents a CLASS(class_name) { ... } that can be referenced by output149// section descriptions. If referenced more than once, the sections can be150// spilled to the next reference like --enable-non-contiguous-regions.151struct SectionClass final : public SectionBase {152  SmallVector<InputSectionDescription *, 0> commands;153  bool assigned = false;154 155  SectionClass(StringRef name)156      : SectionBase(Class, nullptr, name, 0, 0, 0, 0, 0, 0) {}157  static bool classof(const SectionBase *s) { return s->kind() == Class; }158};159 160struct SectionClassDesc : SectionCommand {161  SectionClass sc;162 163  SectionClassDesc(StringRef name) : SectionCommand(ClassKind), sc(name) {}164 165  static bool classof(const SectionCommand *c) { return c->kind == ClassKind; }166};167 168int getPriority(StringRef s);169 170InputSection *getFirstInputSection(const OutputSection *os);171llvm::ArrayRef<InputSection *>172getInputSections(const OutputSection &os,173                 SmallVector<InputSection *, 0> &storage);174 175uint64_t getHeaderSize(Ctx &);176} // namespace lld::elf177 178#endif179