10b57cec5SDimitry Andric //===- LinkerScript.h -------------------------------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #ifndef LLD_ELF_LINKER_SCRIPT_H 100b57cec5SDimitry Andric #define LLD_ELF_LINKER_SCRIPT_H 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include "Config.h" 13*0fca6ea1SDimitry Andric #include "InputSection.h" 140b57cec5SDimitry Andric #include "Writer.h" 150b57cec5SDimitry Andric #include "lld/Common/LLVM.h" 160b57cec5SDimitry Andric #include "lld/Common/Strings.h" 170b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 180b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 190b57cec5SDimitry Andric #include "llvm/ADT/MapVector.h" 20*0fca6ea1SDimitry Andric #include "llvm/ADT/SmallVector.h" 210b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 22bdd1243dSDimitry Andric #include "llvm/Support/Compiler.h" 230b57cec5SDimitry Andric #include <cstddef> 240b57cec5SDimitry Andric #include <cstdint> 250b57cec5SDimitry Andric #include <functional> 260b57cec5SDimitry Andric #include <memory> 270b57cec5SDimitry Andric 28bdd1243dSDimitry Andric namespace lld::elf { 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric class Defined; 31e8d8bef9SDimitry Andric class InputFile; 320b57cec5SDimitry Andric class InputSection; 330b57cec5SDimitry Andric class InputSectionBase; 340b57cec5SDimitry Andric class OutputSection; 350b57cec5SDimitry Andric class SectionBase; 360b57cec5SDimitry Andric class ThunkSection; 3781ad6265SDimitry Andric struct OutputDesc; 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric // This represents an r-value in the linker script. 400b57cec5SDimitry Andric struct ExprValue { ExprValueExprValue410b57cec5SDimitry Andric ExprValue(SectionBase *sec, bool forceAbsolute, uint64_t val, 420b57cec5SDimitry Andric const Twine &loc) 434824e7fdSDimitry Andric : sec(sec), val(val), forceAbsolute(forceAbsolute), loc(loc.str()) {} 440b57cec5SDimitry Andric ExprValueExprValue450b57cec5SDimitry Andric ExprValue(uint64_t val) : ExprValue(nullptr, false, val, "") {} 460b57cec5SDimitry Andric isAbsoluteExprValue470b57cec5SDimitry Andric bool isAbsolute() const { return forceAbsolute || sec == nullptr; } 480b57cec5SDimitry Andric uint64_t getValue() const; 490b57cec5SDimitry Andric uint64_t getSecAddr() const; 500b57cec5SDimitry Andric uint64_t getSectionOffset() const; 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric // If a value is relative to a section, it has a non-null Sec. 530b57cec5SDimitry Andric SectionBase *sec; 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric uint64_t val; 560b57cec5SDimitry Andric uint64_t alignment = 1; 570b57cec5SDimitry Andric 5816d6b3b3SDimitry Andric // The original st_type if the expression represents a symbol. Any operation 5916d6b3b3SDimitry Andric // resets type to STT_NOTYPE. 6016d6b3b3SDimitry Andric uint8_t type = llvm::ELF::STT_NOTYPE; 6116d6b3b3SDimitry Andric 624824e7fdSDimitry Andric // True if this expression is enclosed in ABSOLUTE(). 634824e7fdSDimitry Andric // This flag affects the return value of getValue(). 644824e7fdSDimitry Andric bool forceAbsolute; 654824e7fdSDimitry Andric 660b57cec5SDimitry Andric // Original source location. Used for error messages. 670b57cec5SDimitry Andric std::string loc; 680b57cec5SDimitry Andric }; 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric // This represents an expression in the linker script. 710b57cec5SDimitry Andric // ScriptParser::readExpr reads an expression and returns an Expr. 720b57cec5SDimitry Andric // Later, we evaluate the expression by calling the function. 730b57cec5SDimitry Andric using Expr = std::function<ExprValue()>; 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric // This enum is used to implement linker script SECTIONS command. 760b57cec5SDimitry Andric // https://sourceware.org/binutils/docs/ld/SECTIONS.html#SECTIONS 770b57cec5SDimitry Andric enum SectionsCommandKind { 780b57cec5SDimitry Andric AssignmentKind, // . = expr or <sym> = expr 790b57cec5SDimitry Andric OutputSectionKind, 800b57cec5SDimitry Andric InputSectionKind, 810b57cec5SDimitry Andric ByteKind // BYTE(expr), SHORT(expr), LONG(expr) or QUAD(expr) 820b57cec5SDimitry Andric }; 830b57cec5SDimitry Andric 844824e7fdSDimitry Andric struct SectionCommand { SectionCommandSectionCommand854824e7fdSDimitry Andric SectionCommand(int k) : kind(k) {} 860b57cec5SDimitry Andric int kind; 870b57cec5SDimitry Andric }; 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric // This represents ". = <expr>" or "<symbol> = <expr>". 904824e7fdSDimitry Andric struct SymbolAssignment : SectionCommand { SymbolAssignmentSymbolAssignment915f757f3fSDimitry Andric SymbolAssignment(StringRef name, Expr e, unsigned symOrder, std::string loc) 924824e7fdSDimitry Andric : SectionCommand(AssignmentKind), name(name), expression(e), 935f757f3fSDimitry Andric symOrder(symOrder), location(loc) {} 940b57cec5SDimitry Andric classofSymbolAssignment954824e7fdSDimitry Andric static bool classof(const SectionCommand *c) { 960b57cec5SDimitry Andric return c->kind == AssignmentKind; 970b57cec5SDimitry Andric } 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric // The LHS of an expression. Name is either a symbol name or ".". 1000b57cec5SDimitry Andric StringRef name; 1010b57cec5SDimitry Andric Defined *sym = nullptr; 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric // The RHS of an expression. 1040b57cec5SDimitry Andric Expr expression; 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric // Command attributes for PROVIDE, HIDDEN and PROVIDE_HIDDEN. 1070b57cec5SDimitry Andric bool provide = false; 1080b57cec5SDimitry Andric bool hidden = false; 1090b57cec5SDimitry Andric 1105f757f3fSDimitry Andric // This assignment references DATA_SEGMENT_RELRO_END. 1115f757f3fSDimitry Andric bool dataSegmentRelroEnd = false; 1125f757f3fSDimitry Andric 1135f757f3fSDimitry Andric unsigned symOrder; 1145f757f3fSDimitry Andric 1150b57cec5SDimitry Andric // Holds file name and line number for error reporting. 1160b57cec5SDimitry Andric std::string location; 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric // A string representation of this command. We use this for -Map. 1190b57cec5SDimitry Andric std::string commandString; 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric // Address of this assignment command. 1225ffd83dbSDimitry Andric uint64_t addr; 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric // Size of this assignment command. This is usually 0, but if 1250b57cec5SDimitry Andric // you move '.' this may be greater than 0. 1265ffd83dbSDimitry Andric uint64_t size; 1270b57cec5SDimitry Andric }; 1280b57cec5SDimitry Andric 129480093f4SDimitry Andric // Linker scripts allow additional constraints to be put on output sections. 1300b57cec5SDimitry Andric // If an output section is marked as ONLY_IF_RO, the section is created 1310b57cec5SDimitry Andric // only if its input sections are read-only. Likewise, an output section 1320b57cec5SDimitry Andric // with ONLY_IF_RW is created if all input sections are RW. 1330b57cec5SDimitry Andric enum class ConstraintKind { NoConstraint, ReadOnly, ReadWrite }; 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric // This struct is used to represent the location and size of regions of 1360b57cec5SDimitry Andric // target memory. Instances of the struct are created by parsing the 1370b57cec5SDimitry Andric // MEMORY command. 1380b57cec5SDimitry Andric struct MemoryRegion { MemoryRegionMemoryRegion1395ffd83dbSDimitry Andric MemoryRegion(StringRef name, Expr origin, Expr length, uint32_t flags, 1404824e7fdSDimitry Andric uint32_t invFlags, uint32_t negFlags, uint32_t negInvFlags) 1415ffd83dbSDimitry Andric : name(std::string(name)), origin(origin), length(length), flags(flags), 1424824e7fdSDimitry Andric invFlags(invFlags), negFlags(negFlags), negInvFlags(negInvFlags) {} 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric std::string name; 1455ffd83dbSDimitry Andric Expr origin; 1465ffd83dbSDimitry Andric Expr length; 1474824e7fdSDimitry Andric // A section can be assigned to the region if any of these ELF section flags 1484824e7fdSDimitry Andric // are set... 1490b57cec5SDimitry Andric uint32_t flags; 1504824e7fdSDimitry Andric // ... or any of these flags are not set. 1514824e7fdSDimitry Andric // For example, the memory region attribute "r" maps to SHF_WRITE. 1524824e7fdSDimitry Andric uint32_t invFlags; 1534824e7fdSDimitry Andric // A section cannot be assigned to the region if any of these ELF section 1544824e7fdSDimitry Andric // flags are set... 1550b57cec5SDimitry Andric uint32_t negFlags; 1564824e7fdSDimitry Andric // ... or any of these flags are not set. 1574824e7fdSDimitry Andric // For example, the memory region attribute "!r" maps to SHF_WRITE. 1584824e7fdSDimitry Andric uint32_t negInvFlags; 1590b57cec5SDimitry Andric uint64_t curPos = 0; 1604824e7fdSDimitry Andric getOriginMemoryRegion16106c3fb27SDimitry Andric uint64_t getOrigin() const { return origin().getValue(); } getLengthMemoryRegion16206c3fb27SDimitry Andric uint64_t getLength() const { return length().getValue(); } 16306c3fb27SDimitry Andric compatibleWithMemoryRegion1644824e7fdSDimitry Andric bool compatibleWith(uint32_t secFlags) const { 1654824e7fdSDimitry Andric if ((secFlags & negFlags) || (~secFlags & negInvFlags)) 1664824e7fdSDimitry Andric return false; 1674824e7fdSDimitry Andric return (secFlags & flags) || (~secFlags & invFlags); 1684824e7fdSDimitry Andric } 1690b57cec5SDimitry Andric }; 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andric // This struct represents one section match pattern in SECTIONS() command. 1720b57cec5SDimitry Andric // It can optionally have negative match pattern for EXCLUDED_FILE command. 1730b57cec5SDimitry Andric // Also it may be surrounded with SORT() command, so contains sorting rules. 174e8d8bef9SDimitry Andric class SectionPattern { 175e8d8bef9SDimitry Andric StringMatcher excludedFilePat; 176e8d8bef9SDimitry Andric 177e8d8bef9SDimitry Andric // Cache of the most recent input argument and result of excludesFile(). 178bdd1243dSDimitry Andric mutable std::optional<std::pair<const InputFile *, bool>> excludesFileCache; 179e8d8bef9SDimitry Andric 180e8d8bef9SDimitry Andric public: SectionPattern(StringMatcher && pat1,StringMatcher && pat2)1810b57cec5SDimitry Andric SectionPattern(StringMatcher &&pat1, StringMatcher &&pat2) 1820b57cec5SDimitry Andric : excludedFilePat(pat1), sectionPat(pat2), 1830b57cec5SDimitry Andric sortOuter(SortSectionPolicy::Default), 1840b57cec5SDimitry Andric sortInner(SortSectionPolicy::Default) {} 1850b57cec5SDimitry Andric 186e8d8bef9SDimitry Andric bool excludesFile(const InputFile *file) const; 187e8d8bef9SDimitry Andric 1880b57cec5SDimitry Andric StringMatcher sectionPat; 1890b57cec5SDimitry Andric SortSectionPolicy sortOuter; 1900b57cec5SDimitry Andric SortSectionPolicy sortInner; 1910b57cec5SDimitry Andric }; 1920b57cec5SDimitry Andric 1934824e7fdSDimitry Andric class InputSectionDescription : public SectionCommand { 194e8d8bef9SDimitry Andric SingleStringMatcher filePat; 195e8d8bef9SDimitry Andric 196e8d8bef9SDimitry Andric // Cache of the most recent input argument and result of matchesFile(). 197bdd1243dSDimitry Andric mutable std::optional<std::pair<const InputFile *, bool>> matchesFileCache; 198e8d8bef9SDimitry Andric 199e8d8bef9SDimitry Andric public: 2005ffd83dbSDimitry Andric InputSectionDescription(StringRef filePattern, uint64_t withFlags = 0, 2015ffd83dbSDimitry Andric uint64_t withoutFlags = 0) SectionCommand(InputSectionKind)2024824e7fdSDimitry Andric : SectionCommand(InputSectionKind), filePat(filePattern), 2035ffd83dbSDimitry Andric withFlags(withFlags), withoutFlags(withoutFlags) {} 2040b57cec5SDimitry Andric classof(const SectionCommand * c)2054824e7fdSDimitry Andric static bool classof(const SectionCommand *c) { 2060b57cec5SDimitry Andric return c->kind == InputSectionKind; 2070b57cec5SDimitry Andric } 2080b57cec5SDimitry Andric 209e8d8bef9SDimitry Andric bool matchesFile(const InputFile *file) const; 2100b57cec5SDimitry Andric 2110b57cec5SDimitry Andric // Input sections that matches at least one of SectionPatterns 2120b57cec5SDimitry Andric // will be associated with this InputSectionDescription. 21304eeddc0SDimitry Andric SmallVector<SectionPattern, 0> sectionPatterns; 2140b57cec5SDimitry Andric 21585868e8aSDimitry Andric // Includes InputSections and MergeInputSections. Used temporarily during 21685868e8aSDimitry Andric // assignment of input sections to output sections. 21704eeddc0SDimitry Andric SmallVector<InputSectionBase *, 0> sectionBases; 21885868e8aSDimitry Andric 21985868e8aSDimitry Andric // Used after the finalizeInputSections() pass. MergeInputSections have been 22085868e8aSDimitry Andric // merged into MergeSyntheticSections. 22104eeddc0SDimitry Andric SmallVector<InputSection *, 0> sections; 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric // Temporary record of synthetic ThunkSection instances and the pass that 2240b57cec5SDimitry Andric // they were created in. This is used to insert newly created ThunkSections 2250b57cec5SDimitry Andric // into Sections at the end of a createThunks() pass. 22604eeddc0SDimitry Andric SmallVector<std::pair<ThunkSection *, uint32_t>, 0> thunkSections; 2275ffd83dbSDimitry Andric 2285ffd83dbSDimitry Andric // SectionPatterns can be filtered with the INPUT_SECTION_FLAGS command. 2295ffd83dbSDimitry Andric uint64_t withFlags; 2305ffd83dbSDimitry Andric uint64_t withoutFlags; 2310b57cec5SDimitry Andric }; 2320b57cec5SDimitry Andric 2330b57cec5SDimitry Andric // Represents BYTE(), SHORT(), LONG(), or QUAD(). 2344824e7fdSDimitry Andric struct ByteCommand : SectionCommand { ByteCommandByteCommand2350b57cec5SDimitry Andric ByteCommand(Expr e, unsigned size, std::string commandString) 2364824e7fdSDimitry Andric : SectionCommand(ByteKind), commandString(commandString), expression(e), 2370b57cec5SDimitry Andric size(size) {} 2380b57cec5SDimitry Andric classofByteCommand2394824e7fdSDimitry Andric static bool classof(const SectionCommand *c) { return c->kind == ByteKind; } 2400b57cec5SDimitry Andric 2410b57cec5SDimitry Andric // Keeps string representing the command. Used for -Map" is perhaps better. 2420b57cec5SDimitry Andric std::string commandString; 2430b57cec5SDimitry Andric 2440b57cec5SDimitry Andric Expr expression; 2450b57cec5SDimitry Andric 2460b57cec5SDimitry Andric // This is just an offset of this assignment command in the output section. 2470b57cec5SDimitry Andric unsigned offset; 2480b57cec5SDimitry Andric 2490b57cec5SDimitry Andric // Size of this data command. 2500b57cec5SDimitry Andric unsigned size; 2510b57cec5SDimitry Andric }; 2520b57cec5SDimitry Andric 2535ffd83dbSDimitry Andric struct InsertCommand { 25404eeddc0SDimitry Andric SmallVector<StringRef, 0> names; 2555ffd83dbSDimitry Andric bool isAfter; 2565ffd83dbSDimitry Andric StringRef where; 2575ffd83dbSDimitry Andric }; 2585ffd83dbSDimitry Andric 259*0fca6ea1SDimitry Andric // A NOCROSSREFS/NOCROSSREFS_TO command that prohibits references between 260*0fca6ea1SDimitry Andric // certain output sections. 261*0fca6ea1SDimitry Andric struct NoCrossRefCommand { 262*0fca6ea1SDimitry Andric SmallVector<StringRef, 0> outputSections; 263*0fca6ea1SDimitry Andric 264*0fca6ea1SDimitry Andric // When true, this describes a NOCROSSREFS_TO command that probits references 265*0fca6ea1SDimitry Andric // to the first output section from any of the other sections. 266*0fca6ea1SDimitry Andric bool toFirst = false; 267*0fca6ea1SDimitry Andric }; 268*0fca6ea1SDimitry Andric 2690b57cec5SDimitry Andric struct PhdrsCommand { 2700b57cec5SDimitry Andric StringRef name; 2710b57cec5SDimitry Andric unsigned type = llvm::ELF::PT_NULL; 2720b57cec5SDimitry Andric bool hasFilehdr = false; 2730b57cec5SDimitry Andric bool hasPhdrs = false; 274bdd1243dSDimitry Andric std::optional<unsigned> flags; 2750b57cec5SDimitry Andric Expr lmaExpr = nullptr; 2760b57cec5SDimitry Andric }; 2770b57cec5SDimitry Andric 2780b57cec5SDimitry Andric class LinkerScript final { 2790b57cec5SDimitry Andric // Temporary state used in processSectionCommands() and assignAddresses() 2800b57cec5SDimitry Andric // that must be reinitialized for each call to the above functions, and must 2810b57cec5SDimitry Andric // not be used outside of the scope of a call to the above functions. 2820b57cec5SDimitry Andric struct AddressState { 2830b57cec5SDimitry Andric AddressState(); 2840b57cec5SDimitry Andric OutputSection *outSec = nullptr; 2850b57cec5SDimitry Andric MemoryRegion *memRegion = nullptr; 2860b57cec5SDimitry Andric MemoryRegion *lmaRegion = nullptr; 2870b57cec5SDimitry Andric uint64_t lmaOffset = 0; 2886e75b2fbSDimitry Andric uint64_t tbssAddr = 0; 2890b57cec5SDimitry Andric }; 2900b57cec5SDimitry Andric 29181ad6265SDimitry Andric llvm::DenseMap<llvm::CachedHashStringRef, OutputDesc *> nameToOutputSection; 2920b57cec5SDimitry Andric 2930b57cec5SDimitry Andric void addSymbol(SymbolAssignment *cmd); 2940b57cec5SDimitry Andric void assignSymbol(SymbolAssignment *cmd, bool inSec); 2950b57cec5SDimitry Andric void setDot(Expr e, const Twine &loc, bool inSec); 2960b57cec5SDimitry Andric void expandOutputSection(uint64_t size); 2970b57cec5SDimitry Andric void expandMemoryRegions(uint64_t size); 2980b57cec5SDimitry Andric 29904eeddc0SDimitry Andric SmallVector<InputSectionBase *, 0> 3005ffd83dbSDimitry Andric computeInputSections(const InputSectionDescription *, 301*0fca6ea1SDimitry Andric ArrayRef<InputSectionBase *>, 302*0fca6ea1SDimitry Andric const OutputSection &outCmd); 3030b57cec5SDimitry Andric 30404eeddc0SDimitry Andric SmallVector<InputSectionBase *, 0> createInputSectionList(OutputSection &cmd); 3050b57cec5SDimitry Andric 3065ffd83dbSDimitry Andric void discardSynthetic(OutputSection &); 3075ffd83dbSDimitry Andric 30804eeddc0SDimitry Andric SmallVector<size_t, 0> getPhdrIndices(OutputSection *sec); 3090b57cec5SDimitry Andric 310349cc55cSDimitry Andric std::pair<MemoryRegion *, MemoryRegion *> 311349cc55cSDimitry Andric findMemoryRegion(OutputSection *sec, MemoryRegion *hint); 3120b57cec5SDimitry Andric 313*0fca6ea1SDimitry Andric bool assignOffsets(OutputSection *sec); 3140b57cec5SDimitry Andric 315bdd1243dSDimitry Andric // This captures the local AddressState and makes it accessible 3160b57cec5SDimitry Andric // deliberately. This is needed as there are some cases where we cannot just 3170b57cec5SDimitry Andric // thread the current state through to a lambda function created by the 3180b57cec5SDimitry Andric // script parser. 3190b57cec5SDimitry Andric // This should remain a plain pointer as its lifetime is smaller than 3200b57cec5SDimitry Andric // LinkerScript. 321bdd1243dSDimitry Andric AddressState *state = nullptr; 3220b57cec5SDimitry Andric 3230b57cec5SDimitry Andric OutputSection *aether; 3240b57cec5SDimitry Andric 3250b57cec5SDimitry Andric uint64_t dot; 3260b57cec5SDimitry Andric 3270b57cec5SDimitry Andric public: 32881ad6265SDimitry Andric OutputDesc *createOutputSection(StringRef name, StringRef location); 32981ad6265SDimitry Andric OutputDesc *getOrCreateOutputSection(StringRef name); 3300b57cec5SDimitry Andric hasPhdrsCommands()3310b57cec5SDimitry Andric bool hasPhdrsCommands() { return !phdrsCommands.empty(); } getDot()3320b57cec5SDimitry Andric uint64_t getDot() { return dot; } 3330eae32dcSDimitry Andric void discard(InputSectionBase &s); 3340b57cec5SDimitry Andric 3350b57cec5SDimitry Andric ExprValue getSymbolValue(StringRef name, const Twine &loc); 3360b57cec5SDimitry Andric 3370b57cec5SDimitry Andric void addOrphanSections(); 3385ffd83dbSDimitry Andric void diagnoseOrphanHandling() const; 33906c3fb27SDimitry Andric void diagnoseMissingSGSectionAddress() const; 3401fd87a68SDimitry Andric void adjustOutputSections(); 3410b57cec5SDimitry Andric void adjustSectionsAfterSorting(); 3420b57cec5SDimitry Andric 34304eeddc0SDimitry Andric SmallVector<PhdrEntry *, 0> createPhdrs(); 3440b57cec5SDimitry Andric bool needsInterpSection(); 3450b57cec5SDimitry Andric 3460b57cec5SDimitry Andric bool shouldKeep(InputSectionBase *s); 347*0fca6ea1SDimitry Andric std::pair<const OutputSection *, const Defined *> assignAddresses(); 348*0fca6ea1SDimitry Andric bool spillSections(); 349*0fca6ea1SDimitry Andric void erasePotentialSpillSections(); 35004eeddc0SDimitry Andric void allocateHeaders(SmallVector<PhdrEntry *, 0> &phdrs); 3510b57cec5SDimitry Andric void processSectionCommands(); 35285868e8aSDimitry Andric void processSymbolAssignments(); 3530b57cec5SDimitry Andric void declareSymbols(); 3540b57cec5SDimitry Andric 3550b57cec5SDimitry Andric // Used to handle INSERT AFTER statements. 3560b57cec5SDimitry Andric void processInsertCommands(); 3570b57cec5SDimitry Andric 35806c3fb27SDimitry Andric // Describe memory region usage. 35906c3fb27SDimitry Andric void printMemoryUsage(raw_ostream &os); 36006c3fb27SDimitry Andric 361*0fca6ea1SDimitry Andric // Record a pending error during an assignAddresses invocation. 362*0fca6ea1SDimitry Andric // assignAddresses is executed more than once. Therefore, lld::error should be 363*0fca6ea1SDimitry Andric // avoided to not report duplicate errors. 364*0fca6ea1SDimitry Andric void recordError(const Twine &msg); 365*0fca6ea1SDimitry Andric 3665f757f3fSDimitry Andric // Check backward location counter assignment and memory region/LMA overflows. 3675f757f3fSDimitry Andric void checkFinalScriptConditions() const; 36806c3fb27SDimitry Andric 369*0fca6ea1SDimitry Andric // Add symbols that are referenced in the linker script to the symbol table. 370*0fca6ea1SDimitry Andric // Symbols referenced in a PROVIDE command are only added to the symbol table 371*0fca6ea1SDimitry Andric // if the PROVIDE command actually provides the symbol. 372*0fca6ea1SDimitry Andric // It also adds the symbols referenced by the used PROVIDE symbols to the 373*0fca6ea1SDimitry Andric // linker script referenced symbols list. 374*0fca6ea1SDimitry Andric void addScriptReferencedSymbolsToSymTable(); 375*0fca6ea1SDimitry Andric 376*0fca6ea1SDimitry Andric // Returns true if the PROVIDE symbol should be added to the link. 377*0fca6ea1SDimitry Andric // A PROVIDE symbol is added to the link only if it satisfies an 378*0fca6ea1SDimitry Andric // undefined reference. 379*0fca6ea1SDimitry Andric static bool shouldAddProvideSym(StringRef symName); 380*0fca6ea1SDimitry Andric 3810b57cec5SDimitry Andric // SECTIONS command list. 38204eeddc0SDimitry Andric SmallVector<SectionCommand *, 0> sectionCommands; 3830b57cec5SDimitry Andric 3840b57cec5SDimitry Andric // PHDRS command list. 38504eeddc0SDimitry Andric SmallVector<PhdrsCommand, 0> phdrsCommands; 3860b57cec5SDimitry Andric 3870b57cec5SDimitry Andric bool hasSectionsCommand = false; 3885f757f3fSDimitry Andric bool seenDataAlign = false; 3895f757f3fSDimitry Andric bool seenRelroEnd = false; 3900b57cec5SDimitry Andric bool errorOnMissingSection = false; 391*0fca6ea1SDimitry Andric SmallVector<SmallString<0>, 0> recordedErrors; 3920b57cec5SDimitry Andric 3930b57cec5SDimitry Andric // List of section patterns specified with KEEP commands. They will 3940b57cec5SDimitry Andric // be kept even if they are unused and --gc-sections is specified. 39504eeddc0SDimitry Andric SmallVector<InputSectionDescription *, 0> keptSections; 3960b57cec5SDimitry Andric 3970b57cec5SDimitry Andric // A map from memory region name to a memory region descriptor. 3980b57cec5SDimitry Andric llvm::MapVector<llvm::StringRef, MemoryRegion *> memoryRegions; 3990b57cec5SDimitry Andric 4000b57cec5SDimitry Andric // A list of symbols referenced by the script. 40104eeddc0SDimitry Andric SmallVector<llvm::StringRef, 0> referencedSymbols; 4020b57cec5SDimitry Andric 4035ffd83dbSDimitry Andric // Used to implement INSERT [AFTER|BEFORE]. Contains output sections that need 4045ffd83dbSDimitry Andric // to be reordered. 40504eeddc0SDimitry Andric SmallVector<InsertCommand, 0> insertCommands; 4065ffd83dbSDimitry Andric 407fe6060f1SDimitry Andric // OutputSections specified by OVERWRITE_SECTIONS. 40881ad6265SDimitry Andric SmallVector<OutputDesc *, 0> overwriteSections; 409fe6060f1SDimitry Andric 410*0fca6ea1SDimitry Andric // NOCROSSREFS(_TO) commands. 411*0fca6ea1SDimitry Andric SmallVector<NoCrossRefCommand, 0> noCrossRefs; 412*0fca6ea1SDimitry Andric 4135ffd83dbSDimitry Andric // Sections that will be warned/errored by --orphan-handling. 41404eeddc0SDimitry Andric SmallVector<const InputSectionBase *, 0> orphanSections; 415*0fca6ea1SDimitry Andric 416*0fca6ea1SDimitry Andric // Stores the mapping: PROVIDE symbol -> symbols referred in the PROVIDE 417*0fca6ea1SDimitry Andric // expression. For example, if the PROVIDE command is: 418*0fca6ea1SDimitry Andric // 419*0fca6ea1SDimitry Andric // PROVIDE(v = a + b + c); 420*0fca6ea1SDimitry Andric // 421*0fca6ea1SDimitry Andric // then provideMap should contain the mapping: 'v' -> ['a', 'b', 'c'] 422*0fca6ea1SDimitry Andric llvm::MapVector<StringRef, SmallVector<StringRef, 0>> provideMap; 423*0fca6ea1SDimitry Andric 424*0fca6ea1SDimitry Andric // List of potential spill locations (PotentialSpillSection) for an input 425*0fca6ea1SDimitry Andric // section. 426*0fca6ea1SDimitry Andric struct PotentialSpillList { 427*0fca6ea1SDimitry Andric // Never nullptr. 428*0fca6ea1SDimitry Andric PotentialSpillSection *head; 429*0fca6ea1SDimitry Andric PotentialSpillSection *tail; 430*0fca6ea1SDimitry Andric }; 431*0fca6ea1SDimitry Andric llvm::DenseMap<InputSectionBase *, PotentialSpillList> potentialSpillLists; 4320b57cec5SDimitry Andric }; 4330b57cec5SDimitry Andric 434*0fca6ea1SDimitry Andric struct ScriptWrapper { 435*0fca6ea1SDimitry Andric LinkerScript s; 436*0fca6ea1SDimitry Andric LinkerScript *operator->() { return &s; } 437*0fca6ea1SDimitry Andric }; 438*0fca6ea1SDimitry Andric 439*0fca6ea1SDimitry Andric LLVM_LIBRARY_VISIBILITY extern ScriptWrapper script; 4400b57cec5SDimitry Andric 441bdd1243dSDimitry Andric } // end namespace lld::elf 4420b57cec5SDimitry Andric 4430b57cec5SDimitry Andric #endif // LLD_ELF_LINKER_SCRIPT_H 444