1497 lines · c
1//===- SyntheticSection.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// Synthetic sections represent chunks of linker-created data. If you10// need to create a chunk of data that to be included in some section11// in the result, you probably want to create that as a synthetic section.12//13// Synthetic sections are designed as input sections as opposed to14// output sections because we want to allow them to be manipulated15// using linker scripts just like other input sections from regular16// files.17//18//===----------------------------------------------------------------------===//19 20#ifndef LLD_ELF_SYNTHETIC_SECTIONS_H21#define LLD_ELF_SYNTHETIC_SECTIONS_H22 23#include "Config.h"24#include "DWARF.h"25#include "InputSection.h"26#include "Symbols.h"27#include "llvm/ADT/DenseSet.h"28#include "llvm/ADT/FoldingSet.h"29#include "llvm/ADT/MapVector.h"30#include "llvm/ADT/STLFunctionalExtras.h"31#include "llvm/BinaryFormat/ELF.h"32#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"33#include "llvm/MC/StringTableBuilder.h"34#include "llvm/Support/Allocator.h"35#include "llvm/Support/Compiler.h"36#include "llvm/Support/Endian.h"37#include "llvm/Support/Parallel.h"38#include "llvm/Support/Threading.h"39 40namespace lld::elf {41class Defined;42struct PhdrEntry;43class SymbolTableBaseSection;44 45struct CieRecord {46 EhSectionPiece *cie = nullptr;47 SmallVector<EhSectionPiece *, 0> fdes;48};49 50// Section for .eh_frame.51class EhFrameSection final : public SyntheticSection {52public:53 EhFrameSection(Ctx &);54 void writeTo(uint8_t *buf) override;55 void finalizeContents() override;56 bool isNeeded() const override { return !sections.empty(); }57 size_t getSize() const override { return size; }58 59 static bool classof(const SectionBase *d) {60 return SyntheticSection::classof(d) && d->name == ".eh_frame";61 }62 63 SmallVector<EhInputSection *, 0> sections;64 size_t numFdes = 0;65 66 struct FdeData {67 uint32_t pcRel;68 uint32_t fdeVARel;69 };70 71 ArrayRef<CieRecord *> getCieRecords() const { return cieRecords; }72 template <class ELFT>73 void iterateFDEWithLSDA(llvm::function_ref<void(InputSection &)> fn);74 75private:76 // This is used only when parsing EhInputSection. We keep it here to avoid77 // allocating one for each EhInputSection.78 llvm::DenseMap<size_t, CieRecord *> offsetToCie;79 80 template <llvm::endianness E> void addRecords(EhInputSection *s);81 template <class ELFT>82 void iterateFDEWithLSDAAux(EhInputSection &sec,83 llvm::DenseSet<size_t> &ciesWithLSDA,84 llvm::function_ref<void(InputSection &)> fn);85 86 CieRecord *addCie(EhSectionPiece &piece, ArrayRef<Relocation> rels);87 Defined *isFdeLive(EhSectionPiece &piece, ArrayRef<Relocation> rels);88 89 uint64_t getFdePc(uint8_t *buf, size_t off, uint8_t enc) const;90 91 SmallVector<CieRecord *, 0> cieRecords;92 93 // CIE records are uniquified by their contents and personality functions.94 llvm::DenseMap<std::pair<ArrayRef<uint8_t>, Symbol *>, CieRecord *> cieMap;95};96 97// .eh_frame_hdr contains a binary search table for .eh_frame FDEs. The section98// is covered by a PT_GNU_EH_FRAME segment, which allows the runtime unwinder to99// locate it via functions like `dl_iterate_phdr`.100class EhFrameHeader final : public SyntheticSection {101public:102 EhFrameHeader(Ctx &);103 void writeTo(uint8_t *buf) override;104 size_t getSize() const override;105 bool isNeeded() const override;106};107 108class GotSection final : public SyntheticSection {109public:110 GotSection(Ctx &);111 size_t getSize() const override { return size; }112 void finalizeContents() override;113 bool isNeeded() const override;114 void writeTo(uint8_t *buf) override;115 116 void addConstant(const Relocation &r);117 void addEntry(const Symbol &sym);118 void addAuthEntry(const Symbol &sym);119 bool addTlsDescEntry(const Symbol &sym);120 void addTlsDescAuthEntry();121 bool addDynTlsEntry(const Symbol &sym);122 bool addTlsIndex();123 uint32_t getTlsDescOffset(const Symbol &sym) const;124 uint64_t getTlsDescAddr(const Symbol &sym) const;125 uint64_t getGlobalDynAddr(const Symbol &b) const;126 uint64_t getGlobalDynOffset(const Symbol &b) const;127 128 uint64_t getTlsIndexVA() { return this->getVA() + tlsIndexOff; }129 uint32_t getTlsIndexOff() const { return tlsIndexOff; }130 131 // Flag to force GOT to be in output if we have relocations132 // that relies on its address.133 std::atomic<bool> hasGotOffRel = false;134 135protected:136 size_t numEntries = 0;137 uint32_t tlsIndexOff = -1;138 struct AuthEntryInfo {139 size_t offset;140 bool isSymbolFunc;141 };142 SmallVector<AuthEntryInfo, 0> authEntries;143};144 145// .note.GNU-stack section.146class GnuStackSection : public SyntheticSection {147public:148 GnuStackSection(Ctx &ctx)149 : SyntheticSection(ctx, ".note.GNU-stack", llvm::ELF::SHT_PROGBITS, 0,150 1) {}151 void writeTo(uint8_t *buf) override {}152 size_t getSize() const override { return 0; }153};154 155class GnuPropertySection final : public SyntheticSection {156public:157 GnuPropertySection(Ctx &);158 void writeTo(uint8_t *buf) override;159 size_t getSize() const override;160};161 162// .note.gnu.build-id section.163class BuildIdSection : public SyntheticSection {164 // First 16 bytes are a header.165 static const unsigned headerSize = 16;166 167public:168 const size_t hashSize;169 BuildIdSection(Ctx &);170 void writeTo(uint8_t *buf) override;171 size_t getSize() const override { return headerSize + hashSize; }172 void writeBuildId(llvm::ArrayRef<uint8_t> buf);173 174private:175 uint8_t *hashBuf;176};177 178// BssSection is used to reserve space for copy relocations and common symbols.179// We create three instances of this class for .bss, .bss.rel.ro and "COMMON",180// that are used for writable symbols, read-only symbols and common symbols,181// respectively.182class BssSection final : public SyntheticSection {183public:184 BssSection(Ctx &, StringRef name, uint64_t size, uint32_t addralign);185 void writeTo(uint8_t *) override {}186 bool isNeeded() const override { return size != 0; }187 size_t getSize() const override { return size; }188 189 static bool classof(const SectionBase *s) {190 return isa<SyntheticSection>(s) && cast<SyntheticSection>(s)->bss;191 }192};193 194class MipsGotSection final : public SyntheticSection {195public:196 MipsGotSection(Ctx &);197 void writeTo(uint8_t *buf) override;198 size_t getSize() const override { return size; }199 bool updateAllocSize(Ctx &) override;200 void finalizeContents() override;201 bool isNeeded() const override;202 203 // Join separate GOTs built for each input file to generate204 // primary and optional multiple secondary GOTs.205 void build();206 207 void addEntry(InputFile &file, Symbol &sym, int64_t addend, RelExpr expr);208 void addDynTlsEntry(InputFile &file, Symbol &sym);209 void addTlsIndex(InputFile &file);210 211 uint64_t getPageEntryOffset(const InputFile *f, const Symbol &s,212 int64_t addend) const;213 uint64_t getSymEntryOffset(const InputFile *f, const Symbol &s,214 int64_t addend) const;215 uint64_t getGlobalDynOffset(const InputFile *f, const Symbol &s) const;216 uint64_t getTlsIndexOffset(const InputFile *f) const;217 218 // Returns the symbol which corresponds to the first entry of the global part219 // of GOT on MIPS platform. It is required to fill up MIPS-specific dynamic220 // table properties.221 // Returns nullptr if the global part is empty.222 const Symbol *getFirstGlobalEntry() const;223 224 // Returns the number of entries in the local part of GOT including225 // the number of reserved entries.226 unsigned getLocalEntriesNum() const;227 228 // Return _gp value for primary GOT (nullptr) or particular input file.229 uint64_t getGp(const InputFile *f = nullptr) const;230 231private:232 // MIPS GOT consists of three parts: local, global and tls. Each part233 // contains different types of entries. Here is a layout of GOT:234 // - Header entries |235 // - Page entries | Local part236 // - Local entries (16-bit access) |237 // - Local entries (32-bit access) |238 // - Normal global entries || Global part239 // - Reloc-only global entries ||240 // - TLS entries ||| TLS part241 //242 // Header:243 // Two entries hold predefined value 0x0 and 0x80000000.244 // Page entries:245 // These entries created by R_MIPS_GOT_PAGE relocation and R_MIPS_GOT16246 // relocation against local symbols. They are initialized by higher 16-bit247 // of the corresponding symbol's value. So each 64kb of address space248 // requires a single GOT entry.249 // Local entries (16-bit access):250 // These entries created by GOT relocations against global non-preemptible251 // symbols so dynamic linker is not necessary to resolve the symbol's252 // values. "16-bit access" means that corresponding relocations address253 // GOT using 16-bit index. Each unique Symbol-Addend pair has its own254 // GOT entry.255 // Local entries (32-bit access):256 // These entries are the same as above but created by relocations which257 // address GOT using 32-bit index (R_MIPS_GOT_HI16/LO16 etc).258 // Normal global entries:259 // These entries created by GOT relocations against preemptible global260 // symbols. They need to be initialized by dynamic linker and they ordered261 // exactly as the corresponding entries in the dynamic symbols table.262 // Reloc-only global entries:263 // These entries created for symbols that are referenced by dynamic264 // relocations R_MIPS_REL32. These entries are not accessed with gp-relative265 // addressing, but MIPS ABI requires that these entries be present in GOT.266 // TLS entries:267 // Entries created by TLS relocations.268 //269 // If the sum of local, global and tls entries is less than 64K only single270 // got is enough. Otherwise, multi-got is created. Series of primary and271 // multiple secondary GOTs have the following layout:272 // - Primary GOT273 // Header274 // Local entries275 // Global entries276 // Relocation only entries277 // TLS entries278 //279 // - Secondary GOT280 // Local entries281 // Global entries282 // TLS entries283 // ...284 //285 // All GOT entries required by relocations from a single input file entirely286 // belong to either primary or one of secondary GOTs. To reference GOT entries287 // each GOT has its own _gp value points to the "middle" of the GOT.288 // In the code this value loaded to the register which is used for GOT access.289 //290 // MIPS 32 function's prologue:291 // lui v0,0x0292 // 0: R_MIPS_HI16 _gp_disp293 // addiu v0,v0,0294 // 4: R_MIPS_LO16 _gp_disp295 //296 // MIPS 64:297 // lui at,0x0298 // 14: R_MIPS_GPREL16 main299 //300 // Dynamic linker does not know anything about secondary GOTs and cannot301 // use a regular MIPS mechanism for GOT entries initialization. So we have302 // to use an approach accepted by other architectures and create dynamic303 // relocations R_MIPS_REL32 to initialize global entries (and local in case304 // of PIC code) in secondary GOTs. But ironically MIPS dynamic linker305 // requires GOT entries and correspondingly ordered dynamic symbol table306 // entries to deal with dynamic relocations. To handle this problem307 // relocation-only section in the primary GOT contains entries for all308 // symbols referenced in global parts of secondary GOTs. Although the sum309 // of local and normal global entries of the primary got should be less310 // than 64K, the size of the primary got (including relocation-only entries311 // can be greater than 64K, because parts of the primary got that overflow312 // the 64K limit are used only by the dynamic linker at dynamic link-time313 // and not by 16-bit gp-relative addressing at run-time.314 //315 // For complete multi-GOT description see the following link316 // https://dmz-portal.mips.com/wiki/MIPS_Multi_GOT317 318 // Number of "Header" entries.319 static const unsigned headerEntriesNum = 2;320 321 // Symbol and addend.322 using GotEntry = std::pair<Symbol *, int64_t>;323 324 struct FileGot {325 InputFile *file = nullptr;326 size_t startIndex = 0;327 328 struct PageBlock {329 Symbol *repSym; // Representative symbol for the OutputSection330 size_t firstIndex;331 size_t count;332 PageBlock(Symbol *repSym = nullptr)333 : repSym(repSym), firstIndex(0), count(0) {}334 };335 336 // Map output sections referenced by MIPS GOT relocations337 // to the description (index/count) "page" entries allocated338 // for this section.339 llvm::SmallMapVector<const OutputSection *, PageBlock, 16> pagesMap;340 // Maps from Symbol+Addend pair or just Symbol to the GOT entry index.341 llvm::MapVector<GotEntry, size_t> local16;342 llvm::MapVector<GotEntry, size_t> local32;343 llvm::MapVector<Symbol *, size_t> global;344 llvm::MapVector<Symbol *, size_t> relocs;345 llvm::MapVector<Symbol *, size_t> tls;346 // Set of symbols referenced by dynamic TLS relocations.347 llvm::MapVector<Symbol *, size_t> dynTlsSymbols;348 349 // Total number of all entries.350 size_t getEntriesNum() const;351 // Number of "page" entries.352 size_t getPageEntriesNum() const;353 // Number of entries require 16-bit index to access.354 size_t getIndexedEntriesNum() const;355 };356 357 // Container of GOT created for each input file.358 // After building a final series of GOTs this container359 // holds primary and secondary GOT's.360 std::vector<FileGot> gots;361 362 // Return (and create if necessary) `FileGot`.363 FileGot &getGot(InputFile &f);364 365 // Try to merge two GOTs. In case of success the `Dst` contains366 // result of merging and the function returns true. In case of367 // overflow the `Dst` is unchanged and the function returns false.368 bool tryMergeGots(FileGot & dst, FileGot & src, bool isPrimary);369};370 371class GotPltSection final : public SyntheticSection {372public:373 GotPltSection(Ctx &);374 void addEntry(Symbol &sym);375 size_t getSize() const override;376 void writeTo(uint8_t *buf) override;377 bool isNeeded() const override;378 379 // Flag to force GotPlt to be in output if we have relocations380 // that relies on its address.381 std::atomic<bool> hasGotPltOffRel = false;382 383private:384 SmallVector<const Symbol *, 0> entries;385};386 387// The IgotPltSection is a Got associated with the PltSection for GNU Ifunc388// Symbols that will be relocated by Target->IRelativeRel.389// On most Targets the IgotPltSection will immediately follow the GotPltSection390// on ARM the IgotPltSection will immediately follow the GotSection.391class IgotPltSection final : public SyntheticSection {392public:393 IgotPltSection(Ctx &);394 void addEntry(Symbol &sym);395 size_t getSize() const override;396 void writeTo(uint8_t *buf) override;397 bool isNeeded() const override { return !entries.empty(); }398 399private:400 SmallVector<const Symbol *, 0> entries;401};402 403class StringTableSection final : public SyntheticSection {404public:405 StringTableSection(Ctx &, StringRef name, bool dynamic);406 unsigned addString(StringRef s, bool hashIt = true);407 void writeTo(uint8_t *buf) override;408 size_t getSize() const override { return size; }409 bool isDynamic() const { return dynamic; }410 411private:412 const bool dynamic;413 414 llvm::DenseMap<llvm::CachedHashStringRef, unsigned> stringMap;415 SmallVector<StringRef, 0> strings;416};417 418class DynamicReloc {419public:420 /// This constructor records a normal relocation.421 DynamicReloc(RelType type, const InputSectionBase *inputSec,422 uint64_t offsetInSec, bool isAgainstSymbol, Symbol &sym,423 int64_t addend, RelExpr expr)424 : sym(&sym), inputSec(inputSec), offsetInSec(offsetInSec), type(type),425 addend(addend), isAgainstSymbol(isAgainstSymbol), isFinal(false),426 expr(expr) {}427 /// This constructor records a relative relocation with no symbol.428 DynamicReloc(RelType type, const InputSectionBase *inputSec,429 uint64_t offsetInSec, int64_t addend = 0)430 : DynamicReloc(type, inputSec, offsetInSec, false,431 *inputSec->getCtx().dummySym, addend, R_ADDEND) {}432 433 uint64_t getOffset() const;434 uint32_t getSymIndex(SymbolTableBaseSection *symTab) const;435 bool needsDynSymIndex() const { return isAgainstSymbol; }436 437 /// Computes the addend of the dynamic relocation. Note that this is not the438 /// same as the #addend member variable as it may also include the symbol439 /// address/the address of the corresponding GOT entry/etc.440 int64_t computeAddend(Ctx &) const;441 442 void finalize(Ctx &, SymbolTableBaseSection *symt);443 444 Symbol *sym;445 const InputSectionBase *inputSec;446 uint64_t offsetInSec;447 uint64_t r_offset;448 RelType type;449 uint32_t r_sym;450 // Initially input addend, then the output addend after451 // RelocationSection<ELFT>::writeTo.452 int64_t addend;453 454private:455 /// Whether this was constructed with a Kind of AgainstSymbol.456 LLVM_PREFERRED_TYPE(bool)457 uint8_t isAgainstSymbol : 1;458 459 /// The resulting dynamic relocation has already had its addend computed.460 /// Calling computeAddend() is an error.461 LLVM_PREFERRED_TYPE(bool)462 uint8_t isFinal : 1;463 464 // The kind of expression used to calculate the added (required e.g. for465 // relative GOT relocations).466 RelExpr expr;467};468 469template <class ELFT> class DynamicSection final : public SyntheticSection {470 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)471 472public:473 DynamicSection(Ctx &);474 void finalizeContents() override;475 void writeTo(uint8_t *buf) override;476 size_t getSize() const override { return size; }477 478private:479 std::vector<std::pair<int32_t, uint64_t>> computeContents();480};481 482class RelocationBaseSection : public SyntheticSection {483public:484 RelocationBaseSection(Ctx &, StringRef name, uint32_t type,485 int32_t dynamicTag, int32_t sizeDynamicTag,486 bool combreloc, unsigned concurrency);487 /// Add a dynamic relocation without writing an addend to the output section.488 /// This overload can be used if the addends are written directly instead of489 /// using relocations on the input section (e.g. MipsGotSection::writeTo()).490 template <bool shard = false> void addReloc(const DynamicReloc &reloc) {491 relocs.push_back(reloc);492 }493 /// Add a dynamic relocation against \p sym with an optional addend.494 void addSymbolReloc(RelType dynType, InputSectionBase &isec,495 uint64_t offsetInSec, Symbol &sym, int64_t addend = 0,496 std::optional<RelType> addendRelType = {});497 /// Add a relative dynamic relocation that uses the target address of \p sym498 /// (i.e. InputSection::getRelocTargetVA()) + \p addend as the addend.499 /// This function should only be called for non-preemptible symbols or500 /// RelExpr values that refer to an address inside the output file (e.g. the501 /// address of the GOT entry for a potentially preemptible symbol).502 template <bool shard = false>503 void addRelativeReloc(RelType dynType, InputSectionBase &isec,504 uint64_t offsetInSec, Symbol &sym, int64_t addend,505 RelType addendRelType, RelExpr expr) {506 assert(expr != R_ADDEND && "expected non-addend relocation expression");507 addReloc<shard>(false, dynType, isec, offsetInSec, sym, addend, expr,508 addendRelType);509 }510 /// Add a dynamic relocation using the target address of \p sym as the addend511 /// if \p sym is non-preemptible. Otherwise add a relocation against \p sym.512 void addAddendOnlyRelocIfNonPreemptible(RelType dynType,513 InputSectionBase &isec,514 uint64_t offsetInSec, Symbol &sym,515 RelType addendRelType);516 template <bool shard = false>517 void addReloc(bool isAgainstSymbol, RelType dynType, InputSectionBase &sec,518 uint64_t offsetInSec, Symbol &sym, int64_t addend, RelExpr expr,519 RelType addendRelType) {520 // Write the addends to the relocated address if required. We skip521 // it if the written value would be zero.522 if (ctx.arg.writeAddends && (expr != R_ADDEND || addend != 0))523 sec.addReloc({expr, addendRelType, offsetInSec, addend, &sym});524 addReloc<shard>(525 {dynType, &sec, offsetInSec, isAgainstSymbol, sym, addend, expr});526 }527 bool isNeeded() const override {528 return !relocs.empty() ||529 llvm::any_of(relocsVec, [](auto &v) { return !v.empty(); });530 }531 size_t getSize() const override { return relocs.size() * this->entsize; }532 size_t getRelativeRelocCount() const { return numRelativeRelocs; }533 void mergeRels();534 void partitionRels();535 void finalizeContents() override;536 537 int32_t dynamicTag, sizeDynamicTag;538 SmallVector<DynamicReloc, 0> relocs;539 540protected:541 void computeRels();542 // Used when parallel relocation scanning adds relocations. The elements543 // will be moved into relocs by mergeRel().544 SmallVector<SmallVector<DynamicReloc, 0>, 0> relocsVec;545 size_t numRelativeRelocs = 0; // used by -z combreloc546 bool combreloc;547};548 549template <>550inline void RelocationBaseSection::addReloc<true>(const DynamicReloc &reloc) {551 relocsVec[llvm::parallel::getThreadIndex()].push_back(reloc);552}553 554template <class ELFT>555class RelocationSection final : public RelocationBaseSection {556 using Elf_Rel = typename ELFT::Rel;557 using Elf_Rela = typename ELFT::Rela;558 559public:560 RelocationSection(Ctx &, StringRef name, bool combreloc,561 unsigned concurrency);562 void writeTo(uint8_t *buf) override;563};564 565template <class ELFT>566class AndroidPackedRelocationSection final : public RelocationBaseSection {567 using Elf_Rel = typename ELFT::Rel;568 using Elf_Rela = typename ELFT::Rela;569 570public:571 AndroidPackedRelocationSection(Ctx &, StringRef name, unsigned concurrency);572 573 bool updateAllocSize(Ctx &) override;574 size_t getSize() const override { return relocData.size(); }575 void writeTo(uint8_t *buf) override {576 memcpy(buf, relocData.data(), relocData.size());577 }578 579private:580 SmallVector<char, 0> relocData;581};582 583struct RelativeReloc {584 uint64_t getOffset() const {585 return inputSec->getVA(inputSec->relocs()[relocIdx].offset);586 }587 588 const InputSectionBase *inputSec;589 size_t relocIdx;590};591 592class RelrBaseSection : public SyntheticSection {593public:594 RelrBaseSection(Ctx &, unsigned concurrency, bool isAArch64Auth = false);595 void mergeRels();596 bool isNeeded() const override {597 return !relocs.empty() ||598 llvm::any_of(relocsVec, [](auto &v) { return !v.empty(); });599 }600 SmallVector<RelativeReloc, 0> relocs;601 SmallVector<SmallVector<RelativeReloc, 0>, 0> relocsVec;602};603 604// RelrSection is used to encode offsets for relative relocations.605// Proposal for adding SHT_RELR sections to generic-abi is here:606// https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg607// For more details, see the comment in RelrSection::updateAllocSize(Ctx &ctx).608template <class ELFT> class RelrSection final : public RelrBaseSection {609 using Elf_Relr = typename ELFT::Relr;610 611public:612 RelrSection(Ctx &, unsigned concurrency, bool isAArch64Auth = false);613 614 bool updateAllocSize(Ctx &) override;615 size_t getSize() const override { return relrRelocs.size() * this->entsize; }616 void writeTo(uint8_t *buf) override {617 memcpy(buf, relrRelocs.data(), getSize());618 }619 620private:621 SmallVector<Elf_Relr, 0> relrRelocs;622};623 624struct SymbolTableEntry {625 Symbol *sym;626 size_t strTabOffset;627};628 629class SymbolTableBaseSection : public SyntheticSection {630public:631 SymbolTableBaseSection(Ctx &ctx, StringTableSection &strTabSec);632 void finalizeContents() override;633 size_t getSize() const override { return getNumSymbols() * entsize; }634 void addSymbol(Symbol *sym);635 unsigned getNumSymbols() const { return symbols.size() + 1; }636 size_t getSymbolIndex(const Symbol &sym);637 ArrayRef<SymbolTableEntry> getSymbols() const { return symbols; }638 639protected:640 void sortSymTabSymbols();641 642 // A vector of symbols and their string table offsets.643 SmallVector<SymbolTableEntry, 0> symbols;644 645 StringTableSection &strTabSec;646 647 llvm::once_flag onceFlag;648 llvm::DenseMap<Symbol *, size_t> symbolIndexMap;649 llvm::DenseMap<OutputSection *, size_t> sectionIndexMap;650};651 652template <class ELFT>653class SymbolTableSection final : public SymbolTableBaseSection {654 using Elf_Sym = typename ELFT::Sym;655 656public:657 SymbolTableSection(Ctx &, StringTableSection &strTabSec);658 void writeTo(uint8_t *buf) override;659};660 661class SymtabShndxSection final : public SyntheticSection {662public:663 SymtabShndxSection(Ctx &);664 665 void writeTo(uint8_t *buf) override;666 size_t getSize() const override;667 bool isNeeded() const override;668 void finalizeContents() override;669};670 671// Outputs GNU Hash section. For detailed explanation see:672// https://blogs.oracle.com/ali/entry/gnu_hash_elf_sections673class GnuHashTableSection final : public SyntheticSection {674public:675 GnuHashTableSection(Ctx &);676 void finalizeContents() override;677 void writeTo(uint8_t *buf) override;678 size_t getSize() const override { return size; }679 680 // Adds symbols to the hash table.681 // Sorts the input to satisfy GNU hash section requirements.682 void addSymbols(llvm::SmallVectorImpl<SymbolTableEntry> &symbols);683 684private:685 // See the comment in writeBloomFilter.686 enum { Shift2 = 26 };687 688 struct Entry {689 Symbol *sym;690 size_t strTabOffset;691 uint32_t hash;692 uint32_t bucketIdx;693 };694 695 SmallVector<Entry, 0> symbols;696 size_t maskWords;697 size_t nBuckets = 0;698 size_t size = 0;699};700 701class HashTableSection final : public SyntheticSection {702public:703 HashTableSection(Ctx &);704 void finalizeContents() override;705 void writeTo(uint8_t *buf) override;706 size_t getSize() const override { return size; }707 708private:709 size_t size = 0;710};711 712// Used for PLT entries. It usually has a PLT header for lazy binding. Each PLT713// entry is associated with a JUMP_SLOT relocation, which may be resolved lazily714// at runtime.715//716// On PowerPC, this section contains lazy symbol resolvers. A branch instruction717// jumps to a PLT call stub, which will then jump to the target (BIND_NOW) or a718// lazy symbol resolver.719//720// On x86 when IBT is enabled, this section (.plt.sec) contains PLT call stubs.721// A call instruction jumps to a .plt.sec entry, which will then jump to the722// target (BIND_NOW) or a .plt entry.723class PltSection : public SyntheticSection {724public:725 PltSection(Ctx &);726 void writeTo(uint8_t *buf) override;727 size_t getSize() const override;728 bool isNeeded() const override;729 void addSymbols();730 void addEntry(Symbol &sym);731 size_t getNumEntries() const { return entries.size(); }732 733 size_t headerSize;734 735 SmallVector<const Symbol *, 0> entries;736};737 738// Used for non-preemptible ifuncs. It does not have a header. Each entry is739// associated with an IRELATIVE relocation, which will be resolved eagerly at740// runtime. PltSection can only contain entries associated with JUMP_SLOT741// relocations, so IPLT entries are in a separate section.742class IpltSection final : public SyntheticSection {743 SmallVector<const Symbol *, 0> entries;744 745public:746 IpltSection(Ctx &);747 void writeTo(uint8_t *buf) override;748 size_t getSize() const override;749 bool isNeeded() const override { return !entries.empty(); }750 void addSymbols();751 void addEntry(Symbol &sym);752};753 754class PPC32GlinkSection : public PltSection {755public:756 PPC32GlinkSection(Ctx &);757 void writeTo(uint8_t *buf) override;758 size_t getSize() const override;759 760 SmallVector<const Symbol *, 0> canonical_plts;761 static constexpr size_t footerSize = 64;762};763 764// This is x86-only.765class IBTPltSection : public SyntheticSection {766public:767 IBTPltSection(Ctx &);768 void writeTo(uint8_t *Buf) override;769 bool isNeeded() const override;770 size_t getSize() const override;771};772 773// Used to align the end of the PT_GNU_RELRO segment and the associated PT_LOAD774// segment to a common-page-size boundary. This padding section ensures that all775// pages in the PT_LOAD segment is covered by at least one section.776class RelroPaddingSection final : public SyntheticSection {777public:778 RelroPaddingSection(Ctx &);779 size_t getSize() const override { return 0; }780 void writeTo(uint8_t *buf) override {}781};782 783class PaddingSection final : public SyntheticSection {784public:785 PaddingSection(Ctx &ctx, uint64_t amount, OutputSection *parent);786 size_t getSize() const override { return size; }787 void writeTo(uint8_t *buf) override;788};789 790// Used by the merged DWARF32 .debug_names (a per-module index). If we791// move to DWARF64, most of this data will need to be re-sized.792class DebugNamesBaseSection : public SyntheticSection {793public:794 struct Abbrev : llvm::FoldingSetNode {795 uint32_t code;796 uint32_t tag;797 SmallVector<llvm::DWARFDebugNames::AttributeEncoding, 2> attributes;798 799 void Profile(llvm::FoldingSetNodeID &id) const;800 };801 802 struct AttrValue {803 uint32_t attrValue;804 uint8_t attrSize;805 };806 807 struct IndexEntry {808 uint32_t abbrevCode;809 uint32_t poolOffset;810 union {811 uint64_t parentOffset = 0;812 IndexEntry *parentEntry;813 };814 SmallVector<AttrValue, 3> attrValues;815 };816 817 struct NameEntry {818 const char *name;819 uint32_t hashValue;820 uint32_t stringOffset;821 uint32_t entryOffset;822 // Used to relocate `stringOffset` in the merged section.823 uint32_t chunkIdx;824 SmallVector<IndexEntry *, 0> indexEntries;825 826 llvm::iterator_range<827 llvm::pointee_iterator<typename SmallVector<IndexEntry *, 0>::iterator>>828 entries() {829 return llvm::make_pointee_range(indexEntries);830 }831 };832 833 // The contents of one input .debug_names section. An InputChunk834 // typically contains one NameData, but might contain more, especially835 // in LTO builds.836 struct NameData {837 llvm::DWARFDebugNames::Header hdr;838 llvm::DenseMap<uint32_t, uint32_t> abbrevCodeMap;839 SmallVector<NameEntry, 0> nameEntries;840 };841 842 // InputChunk and OutputChunk hold per-file contributions to the merged index.843 // InputChunk instances will be discarded after `init` completes.844 struct InputChunk {845 uint32_t baseCuIdx;846 LLDDWARFSection section;847 SmallVector<NameData, 0> nameData;848 std::optional<llvm::DWARFDebugNames> llvmDebugNames;849 };850 851 struct OutputChunk {852 // Pointer to the .debug_info section that contains compile units, used to853 // compute the relocated CU offsets.854 InputSection *infoSec;855 // This initially holds section offsets. After relocation, the section856 // offsets are changed to CU offsets relative the the output section.857 SmallVector<uint32_t, 0> compUnits;858 };859 860 DebugNamesBaseSection(Ctx &);861 size_t getSize() const override { return size; }862 bool isNeeded() const override { return numChunks > 0; }863 864protected:865 void init(llvm::function_ref<void(InputFile *, InputChunk &, OutputChunk &)>);866 static void867 parseDebugNames(Ctx &, InputChunk &inputChunk, OutputChunk &chunk,868 llvm::DWARFDataExtractor &namesExtractor,869 llvm::DataExtractor &strExtractor,870 llvm::function_ref<SmallVector<uint32_t, 0>(871 uint32_t numCUs, const llvm::DWARFDebugNames::Header &hdr,872 const llvm::DWARFDebugNames::DWARFDebugNamesOffsets &)>873 readOffsets);874 void computeHdrAndAbbrevTable(MutableArrayRef<InputChunk> inputChunks);875 std::pair<uint32_t, uint32_t>876 computeEntryPool(MutableArrayRef<InputChunk> inputChunks);877 878 // Input .debug_names sections for relocating string offsets in the name table879 // in `finalizeContents`.880 SmallVector<InputSection *, 0> inputSections;881 882 llvm::DWARFDebugNames::Header hdr;883 size_t numChunks;884 std::unique_ptr<OutputChunk[]> chunks;885 llvm::SpecificBumpPtrAllocator<Abbrev> abbrevAlloc;886 SmallVector<Abbrev *, 0> abbrevTable;887 SmallVector<char, 0> abbrevTableBuf;888 889 ArrayRef<OutputChunk> getChunks() const {890 return ArrayRef(chunks.get(), numChunks);891 }892 893 // Sharded name entries that will be used to compute bucket_count and the894 // count name table.895 static constexpr size_t numShards = 32;896 SmallVector<NameEntry, 0> nameVecs[numShards];897};898 899// Complement DebugNamesBaseSection for ELFT-aware code: reading offsets,900// relocating string offsets, and writeTo.901template <class ELFT>902class DebugNamesSection final : public DebugNamesBaseSection {903public:904 DebugNamesSection(Ctx &);905 void finalizeContents() override;906 void writeTo(uint8_t *buf) override;907 908 template <class RelTy>909 void getNameRelocs(const InputFile &file,910 llvm::DenseMap<uint32_t, uint32_t> &relocs,911 Relocs<RelTy> rels);912 913private:914 static void readOffsets(InputChunk &inputChunk, OutputChunk &chunk,915 llvm::DWARFDataExtractor &namesExtractor,916 llvm::DataExtractor &strExtractor);917};918 919class GdbIndexSection final : public SyntheticSection {920public:921 struct AddressEntry {922 InputSection *section;923 uint64_t lowAddress;924 uint64_t highAddress;925 uint32_t cuIndex;926 };927 928 struct CuEntry {929 uint64_t cuOffset;930 uint64_t cuLength;931 };932 933 struct NameAttrEntry {934 llvm::CachedHashStringRef name;935 uint32_t cuIndexAndAttrs;936 };937 938 struct GdbChunk {939 InputSection *sec;940 SmallVector<AddressEntry, 0> addressAreas;941 SmallVector<CuEntry, 0> compilationUnits;942 };943 944 struct GdbSymbol {945 llvm::CachedHashStringRef name;946 SmallVector<uint32_t, 0> cuVector;947 uint32_t nameOff;948 uint32_t cuVectorOff;949 };950 951 GdbIndexSection(Ctx &);952 template <typename ELFT>953 static std::unique_ptr<GdbIndexSection> create(Ctx &);954 void writeTo(uint8_t *buf) override;955 size_t getSize() const override { return size; }956 bool isNeeded() const override;957 958private:959 struct GdbIndexHeader {960 llvm::support::ulittle32_t version;961 llvm::support::ulittle32_t cuListOff;962 llvm::support::ulittle32_t cuTypesOff;963 llvm::support::ulittle32_t addressAreaOff;964 llvm::support::ulittle32_t symtabOff;965 llvm::support::ulittle32_t constantPoolOff;966 };967 968 size_t computeSymtabSize() const;969 970 // Each chunk contains information gathered from debug sections of a971 // single object file.972 SmallVector<GdbChunk, 0> chunks;973 974 // A symbol table for this .gdb_index section.975 SmallVector<GdbSymbol, 0> symbols;976 977 size_t size;978};979 980// For more information about .gnu.version and .gnu.version_r see:981// https://www.akkadia.org/drepper/symbol-versioning982 983// The .gnu.version_d section which has a section type of SHT_GNU_verdef shall984// contain symbol version definitions. The number of entries in this section985// shall be contained in the DT_VERDEFNUM entry of the .dynamic section.986// The section shall contain an array of Elf_Verdef structures, optionally987// followed by an array of Elf_Verdaux structures.988class VersionDefinitionSection final : public SyntheticSection {989public:990 VersionDefinitionSection(Ctx &);991 void finalizeContents() override;992 size_t getSize() const override;993 void writeTo(uint8_t *buf) override;994 995private:996 enum { EntrySize = 28 };997 void writeOne(uint8_t *buf, uint32_t index, StringRef name, size_t nameOff);998 StringRef getFileDefName();999 1000 unsigned fileDefNameOff;1001 SmallVector<unsigned, 0> verDefNameOffs;1002};1003 1004// The .gnu.version section specifies the required version of each symbol in the1005// dynamic symbol table. It contains one Elf_Versym for each dynamic symbol1006// table entry. An Elf_Versym is just a 16-bit integer that refers to a version1007// identifier defined in the either .gnu.version_r or .gnu.version_d section.1008// The values 0 and 1 are reserved. All other values are used for versions in1009// the own object or in any of the dependencies.1010class VersionTableSection final : public SyntheticSection {1011public:1012 VersionTableSection(Ctx &);1013 void finalizeContents() override;1014 size_t getSize() const override;1015 void writeTo(uint8_t *buf) override;1016 bool isNeeded() const override;1017};1018 1019// The .gnu.version_r section defines the version identifiers used by1020// .gnu.version. It contains a linked list of Elf_Verneed data structures. Each1021// Elf_Verneed specifies the version requirements for a single DSO, and contains1022// a reference to a linked list of Elf_Vernaux data structures which define the1023// mapping from version identifiers to version names.1024template <class ELFT>1025class VersionNeedSection final : public SyntheticSection {1026 using Elf_Verneed = typename ELFT::Verneed;1027 using Elf_Vernaux = typename ELFT::Vernaux;1028 1029 struct Vernaux {1030 uint64_t hash;1031 uint32_t verneedIndex;1032 uint64_t nameStrTab;1033 };1034 1035 struct Verneed {1036 uint64_t nameStrTab;1037 std::vector<Vernaux> vernauxs;1038 };1039 1040 SmallVector<Verneed, 0> verneeds;1041 1042public:1043 VersionNeedSection(Ctx &);1044 void finalizeContents() override;1045 void writeTo(uint8_t *buf) override;1046 size_t getSize() const override;1047 bool isNeeded() const override;1048};1049 1050// MergeSyntheticSection is a class that allows us to put mergeable sections1051// with different attributes in a single output sections. To do that1052// we put them into MergeSyntheticSection synthetic input sections which are1053// attached to regular output sections.1054class MergeSyntheticSection : public SyntheticSection {1055public:1056 void addSection(MergeInputSection *ms);1057 SmallVector<MergeInputSection *, 0> sections;1058 1059protected:1060 MergeSyntheticSection(Ctx &ctx, StringRef name, uint32_t type, uint64_t flags,1061 uint32_t addralign)1062 : SyntheticSection(ctx, name, type, flags, addralign) {}1063};1064 1065class MergeTailSection final : public MergeSyntheticSection {1066public:1067 MergeTailSection(Ctx &ctx, StringRef name, uint32_t type, uint64_t flags,1068 uint32_t addralign);1069 1070 size_t getSize() const override;1071 void writeTo(uint8_t *buf) override;1072 void finalizeContents() override;1073 1074private:1075 llvm::StringTableBuilder builder;1076};1077 1078class MergeNoTailSection final : public MergeSyntheticSection {1079public:1080 MergeNoTailSection(Ctx &ctx, StringRef name, uint32_t type, uint64_t flags,1081 uint32_t addralign)1082 : MergeSyntheticSection(ctx, name, type, flags, addralign) {}1083 1084 size_t getSize() const override { return size; }1085 void writeTo(uint8_t *buf) override;1086 void finalizeContents() override;1087 1088private:1089 // We use the most significant bits of a hash as a shard ID.1090 // The reason why we don't want to use the least significant bits is1091 // because DenseMap also uses lower bits to determine a bucket ID.1092 // If we use lower bits, it significantly increases the probability of1093 // hash collisions.1094 size_t getShardId(uint32_t hash) {1095 assert((hash >> 31) == 0);1096 return hash >> (31 - llvm::countr_zero(numShards));1097 }1098 1099 // Section size1100 size_t size;1101 1102 // String table contents1103 constexpr static size_t numShards = 32;1104 SmallVector<llvm::StringTableBuilder, 0> shards;1105 size_t shardOffsets[numShards];1106};1107 1108// .MIPS.abiflags section.1109template <class ELFT>1110class MipsAbiFlagsSection final : public SyntheticSection {1111 using Elf_Mips_ABIFlags = llvm::object::Elf_Mips_ABIFlags<ELFT>;1112 1113public:1114 static std::unique_ptr<MipsAbiFlagsSection> create(Ctx &);1115 1116 MipsAbiFlagsSection(Ctx &, Elf_Mips_ABIFlags flags);1117 size_t getSize() const override { return sizeof(Elf_Mips_ABIFlags); }1118 void writeTo(uint8_t *buf) override;1119 1120private:1121 Elf_Mips_ABIFlags flags;1122};1123 1124// .MIPS.options section.1125template <class ELFT> class MipsOptionsSection final : public SyntheticSection {1126 using Elf_Mips_Options = llvm::object::Elf_Mips_Options<ELFT>;1127 using Elf_Mips_RegInfo = llvm::object::Elf_Mips_RegInfo<ELFT>;1128 1129public:1130 static std::unique_ptr<MipsOptionsSection<ELFT>> create(Ctx &);1131 1132 MipsOptionsSection(Ctx &, Elf_Mips_RegInfo reginfo);1133 void writeTo(uint8_t *buf) override;1134 1135 size_t getSize() const override {1136 return sizeof(Elf_Mips_Options) + sizeof(Elf_Mips_RegInfo);1137 }1138 1139private:1140 Elf_Mips_RegInfo reginfo;1141};1142 1143// MIPS .reginfo section.1144template <class ELFT> class MipsReginfoSection final : public SyntheticSection {1145 using Elf_Mips_RegInfo = llvm::object::Elf_Mips_RegInfo<ELFT>;1146 1147public:1148 static std::unique_ptr<MipsReginfoSection> create(Ctx &);1149 1150 MipsReginfoSection(Ctx &, Elf_Mips_RegInfo reginfo);1151 size_t getSize() const override { return sizeof(Elf_Mips_RegInfo); }1152 void writeTo(uint8_t *buf) override;1153 1154private:1155 Elf_Mips_RegInfo reginfo;1156};1157 1158// This is a MIPS specific section to hold a space within the data segment1159// of executable file which is pointed to by the DT_MIPS_RLD_MAP entry.1160// See "Dynamic section" in Chapter 5 in the following document:1161// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf1162class MipsRldMapSection final : public SyntheticSection {1163public:1164 MipsRldMapSection(Ctx &);1165 size_t getSize() const override { return ctx.arg.wordsize; }1166 void writeTo(uint8_t *buf) override {}1167};1168 1169// Representation of the combined .ARM.Exidx input sections. We process these1170// as a SyntheticSection like .eh_frame as we need to merge duplicate entries1171// and add terminating sentinel entries.1172//1173// The .ARM.exidx input sections after SHF_LINK_ORDER processing is done form1174// a table that the unwinder can derive (Addresses are encoded as offsets from1175// table):1176// | Address of function | Unwind instructions for function |1177// where the unwind instructions are either a small number of unwind or the1178// special EXIDX_CANTUNWIND entry representing no unwinding information.1179// When an exception is thrown from an address A, the unwinder searches the1180// table for the closest table entry with Address of function <= A. This means1181// that for two consecutive table entries:1182// | A1 | U1 |1183// | A2 | U2 |1184// The range of addresses described by U1 is [A1, A2)1185//1186// There are two cases where we need a linker generated table entry to fixup1187// the address ranges in the table1188// Case 1:1189// - A sentinel entry added with an address higher than all1190// executable sections. This was needed to work around libunwind bug pr31091.1191// - After address assignment we need to find the highest addressed executable1192// section and use the limit of that section so that the unwinder never1193// matches it.1194// Case 2:1195// - InputSections without a .ARM.exidx section (usually from Assembly)1196// need a table entry so that they terminate the range of the previously1197// function. This is pr40277.1198//1199// Instead of storing pointers to the .ARM.exidx InputSections from1200// InputObjects, we store pointers to the executable sections that need1201// .ARM.exidx sections. We can then use the dependentSections of these to1202// either find the .ARM.exidx section or know that we need to generate one.1203class ARMExidxSyntheticSection : public SyntheticSection {1204public:1205 ARMExidxSyntheticSection(Ctx &);1206 1207 // Add an input section to the ARMExidxSyntheticSection. Returns whether the1208 // section needs to be removed from the main input section list.1209 bool addSection(InputSection *isec);1210 1211 size_t getSize() const override { return size; }1212 void writeTo(uint8_t *buf) override;1213 bool isNeeded() const override;1214 // Sort and remove duplicate entries.1215 void finalizeContents() override;1216 InputSection *getLinkOrderDep() const;1217 1218 static bool classof(const SectionBase *sec) {1219 return sec->kind() == InputSectionBase::Synthetic &&1220 sec->type == llvm::ELF::SHT_ARM_EXIDX;1221 }1222 1223 // Links to the ARMExidxSections so we can transfer the relocations once the1224 // layout is known.1225 SmallVector<InputSection *, 0> exidxSections;1226 1227private:1228 size_t size = 0;1229 1230 // Instead of storing pointers to the .ARM.exidx InputSections from1231 // InputObjects, we store pointers to the executable sections that need1232 // .ARM.exidx sections. We can then use the dependentSections of these to1233 // either find the .ARM.exidx section or know that we need to generate one.1234 SmallVector<InputSection *, 0> executableSections;1235 1236 // Value of executableSecitons before finalizeContents(), so that it can be1237 // run repeateadly during fixed point iteration.1238 SmallVector<InputSection *, 0> originalExecutableSections;1239 1240 // The executable InputSection with the highest address to use for the1241 // sentinel. We store separately from ExecutableSections as merging of1242 // duplicate entries may mean this InputSection is removed from1243 // ExecutableSections.1244 InputSection *sentinel = nullptr;1245};1246 1247// A container for one or more linker generated thunks. Instances of these1248// thunks including ARM interworking and Mips LA25 PI to non-PI thunks.1249class ThunkSection final : public SyntheticSection {1250public:1251 // ThunkSection in OS, with desired outSecOff of Off1252 ThunkSection(Ctx &, OutputSection *os, uint64_t off);1253 1254 // Add a newly created Thunk to this container:1255 // Thunk is given offset from start of this InputSection1256 // Thunk defines a symbol in this InputSection that can be used as target1257 // of a relocation1258 void addThunk(Thunk *t);1259 size_t getSize() const override;1260 void writeTo(uint8_t *buf) override;1261 InputSection *getTargetInputSection() const;1262 bool assignOffsets();1263 1264 // When true, round up reported size of section to 4 KiB. See comment1265 // in addThunkSection() for more details.1266 bool roundUpSizeForErrata = false;1267 1268private:1269 SmallVector<Thunk *, 0> thunks;1270 size_t size = 0;1271};1272 1273// Cortex-M Security Extensions. Prefix for functions that should be exported1274// for the non-secure world.1275const char ACLESESYM_PREFIX[] = "__acle_se_";1276const int ACLESESYM_SIZE = 8;1277 1278class ArmCmseSGVeneer {1279public:1280 ArmCmseSGVeneer(Symbol *sym, Symbol *acleSeSym,1281 std::optional<uint64_t> addr = std::nullopt)1282 : sym(sym), acleSeSym(acleSeSym), entAddr{addr} {}1283 static const size_t size{ACLESESYM_SIZE};1284 std::optional<uint64_t> getAddr() const { return entAddr; };1285 1286 Symbol *sym;1287 Symbol *acleSeSym;1288 uint64_t offset = 0;1289 1290private:1291 const std::optional<uint64_t> entAddr;1292};1293 1294class ArmCmseSGSection final : public SyntheticSection {1295public:1296 ArmCmseSGSection(Ctx &ctx);1297 bool isNeeded() const override { return !entries.empty(); }1298 size_t getSize() const override;1299 void writeTo(uint8_t *buf) override;1300 void addSGVeneer(Symbol *sym, Symbol *ext_sym);1301 void addMappingSymbol();1302 void finalizeContents() override;1303 void exportEntries(SymbolTableBaseSection *symTab);1304 uint64_t impLibMaxAddr = 0;1305 1306private:1307 SmallVector<std::pair<Symbol *, Symbol *>, 0> entries;1308 SmallVector<std::unique_ptr<ArmCmseSGVeneer>, 0> sgVeneers;1309 uint64_t newEntries = 0;1310};1311 1312// Used to compute outSecOff of .got2 in each object file. This is needed to1313// synthesize PLT entries for PPC32 Secure PLT ABI.1314class PPC32Got2Section final : public SyntheticSection {1315public:1316 PPC32Got2Section(Ctx &);1317 size_t getSize() const override { return 0; }1318 bool isNeeded() const override;1319 void finalizeContents() override;1320 void writeTo(uint8_t *buf) override {}1321};1322 1323// This section is used to store the addresses of functions that are called1324// in range-extending thunks on PowerPC64. When producing position dependent1325// code the addresses are link-time constants and the table is written out to1326// the binary. When producing position-dependent code the table is allocated and1327// filled in by the dynamic linker.1328class PPC64LongBranchTargetSection final : public SyntheticSection {1329public:1330 PPC64LongBranchTargetSection(Ctx &);1331 uint64_t getEntryVA(const Symbol *sym, int64_t addend);1332 std::optional<uint32_t> addEntry(const Symbol *sym, int64_t addend);1333 size_t getSize() const override;1334 void writeTo(uint8_t *buf) override;1335 bool isNeeded() const override;1336 void finalizeContents() override { finalized = true; }1337 1338private:1339 SmallVector<std::pair<const Symbol *, int64_t>, 0> entries;1340 llvm::DenseMap<std::pair<const Symbol *, int64_t>, uint32_t> entry_index;1341 bool finalized = false;1342};1343 1344template <typename ELFT>1345class PartitionElfHeaderSection final : public SyntheticSection {1346public:1347 PartitionElfHeaderSection(Ctx &);1348 size_t getSize() const override;1349 void writeTo(uint8_t *buf) override;1350};1351 1352template <typename ELFT>1353class PartitionProgramHeadersSection final : public SyntheticSection {1354public:1355 PartitionProgramHeadersSection(Ctx &);1356 size_t getSize() const override;1357 void writeTo(uint8_t *buf) override;1358};1359 1360class PartitionIndexSection final : public SyntheticSection {1361public:1362 PartitionIndexSection(Ctx &);1363 size_t getSize() const override;1364 void finalizeContents() override;1365 void writeTo(uint8_t *buf) override;1366};1367 1368// See the following link for the Android-specific loader code that operates on1369// this section:1370// https://cs.android.com/android/platform/superproject/+/master:bionic/libc/bionic/libc_init_static.cpp;drc=9425b16978f9c5aa8f2c50c873db470819480d1d;l=1921371class MemtagAndroidNote final : public SyntheticSection {1372public:1373 MemtagAndroidNote(Ctx &ctx)1374 : SyntheticSection(ctx, ".note.android.memtag", llvm::ELF::SHT_NOTE,1375 llvm::ELF::SHF_ALLOC, /*addralign=*/4) {}1376 void writeTo(uint8_t *buf) override;1377 size_t getSize() const override;1378};1379 1380class PackageMetadataNote final : public SyntheticSection {1381public:1382 PackageMetadataNote(Ctx &ctx)1383 : SyntheticSection(ctx, ".note.package", llvm::ELF::SHT_NOTE,1384 llvm::ELF::SHF_ALLOC, /*addralign=*/4) {}1385 void writeTo(uint8_t *buf) override;1386 size_t getSize() const override;1387};1388 1389class MemtagGlobalDescriptors final : public SyntheticSection {1390public:1391 MemtagGlobalDescriptors(Ctx &ctx)1392 : SyntheticSection(ctx, ".memtag.globals.dynamic",1393 llvm::ELF::SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC,1394 llvm::ELF::SHF_ALLOC, /*addralign=*/4) {}1395 void writeTo(uint8_t *buf) override;1396 // The size of the section is non-computable until all addresses are1397 // synthetized, because the section's contents contain a sorted1398 // varint-compressed list of pointers to global variables. We only know the1399 // final size after `finalizeAddressDependentContent()`.1400 size_t getSize() const override;1401 bool updateAllocSize(Ctx &) override;1402 1403 void addSymbol(const Symbol &sym) {1404 symbols.push_back(&sym);1405 }1406 1407 bool isNeeded() const override { return !symbols.empty(); }1408 1409private:1410 SmallVector<const Symbol *, 0> symbols;1411};1412 1413template <class ELFT> void createSyntheticSections(Ctx &);1414InputSection *createInterpSection(Ctx &);1415MergeInputSection *createCommentSection(Ctx &);1416template <class ELFT> void splitSections(Ctx &);1417void combineEhSections(Ctx &);1418 1419bool hasMemtag(Ctx &);1420bool canHaveMemtagGlobals(Ctx &);1421 1422template <typename ELFT> void writeEhdr(Ctx &, uint8_t *buf, Partition &part);1423template <typename ELFT> void writePhdrs(uint8_t *buf, Partition &part);1424 1425Defined *addSyntheticLocal(Ctx &ctx, StringRef name, uint8_t type,1426 uint64_t value, uint64_t size,1427 InputSectionBase §ion);1428 1429void addVerneed(Ctx &, Symbol &ss);1430 1431// This describes a program header entry.1432// Each contains type, access flags and range of output sections that will be1433// placed in it.1434struct PhdrEntry {1435 PhdrEntry(Ctx &ctx, unsigned type, unsigned flags)1436 : p_align(type == llvm::ELF::PT_LOAD ? ctx.arg.maxPageSize : 0),1437 p_type(type), p_flags(flags) {}1438 void add(OutputSection *sec);1439 1440 uint64_t p_paddr = 0;1441 uint64_t p_vaddr = 0;1442 uint64_t p_memsz = 0;1443 uint64_t p_filesz = 0;1444 uint64_t p_offset = 0;1445 uint32_t p_align = 0;1446 uint32_t p_type = 0;1447 uint32_t p_flags = 0;1448 1449 OutputSection *firstSec = nullptr;1450 OutputSection *lastSec = nullptr;1451 bool hasLMA = false;1452 1453 uint64_t lmaOffset = 0;1454};1455 1456// Linker generated per-partition sections.1457struct Partition {1458 Ctx &ctx;1459 StringRef name;1460 uint64_t nameStrTab;1461 1462 std::unique_ptr<SyntheticSection> elfHeader;1463 std::unique_ptr<SyntheticSection> programHeaders;1464 SmallVector<std::unique_ptr<PhdrEntry>, 0> phdrs;1465 1466 std::unique_ptr<ARMExidxSyntheticSection> armExidx;1467 std::unique_ptr<BuildIdSection> buildId;1468 std::unique_ptr<SyntheticSection> dynamic;1469 std::unique_ptr<StringTableSection> dynStrTab;1470 std::unique_ptr<SymbolTableBaseSection> dynSymTab;1471 std::unique_ptr<EhFrameHeader> ehFrameHdr;1472 std::unique_ptr<EhFrameSection> ehFrame;1473 std::unique_ptr<GnuHashTableSection> gnuHashTab;1474 std::unique_ptr<HashTableSection> hashTab;1475 std::unique_ptr<MemtagAndroidNote> memtagAndroidNote;1476 std::unique_ptr<MemtagGlobalDescriptors> memtagGlobalDescriptors;1477 std::unique_ptr<PackageMetadataNote> packageMetadataNote;1478 std::unique_ptr<RelocationBaseSection> relaDyn;1479 std::unique_ptr<RelrBaseSection> relrDyn;1480 std::unique_ptr<RelrBaseSection> relrAuthDyn;1481 std::unique_ptr<VersionDefinitionSection> verDef;1482 std::unique_ptr<SyntheticSection> verNeed;1483 std::unique_ptr<VersionTableSection> verSym;1484 1485 Partition(Ctx &ctx) : ctx(ctx) {}1486 unsigned getNumber(Ctx &ctx) const { return this - &ctx.partitions[0] + 1; }1487};1488 1489inline Partition &SectionBase::getPartition(Ctx &ctx) const {1490 assert(isLive());1491 return ctx.partitions[partition - 1];1492}1493 1494} // namespace lld::elf1495 1496#endif1497