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" 130b57cec5SDimitry Andric #include "Writer.h" 140b57cec5SDimitry Andric #include "lld/Common/LLVM.h" 150b57cec5SDimitry Andric #include "lld/Common/Strings.h" 160b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 170b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 180b57cec5SDimitry Andric #include "llvm/ADT/DenseSet.h" 190b57cec5SDimitry Andric #include "llvm/ADT/MapVector.h" 200b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 210b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 220b57cec5SDimitry Andric #include <cstddef> 230b57cec5SDimitry Andric #include <cstdint> 240b57cec5SDimitry Andric #include <functional> 250b57cec5SDimitry Andric #include <memory> 260b57cec5SDimitry Andric #include <vector> 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric namespace lld { 290b57cec5SDimitry Andric namespace elf { 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric class Defined; 32e8d8bef9SDimitry Andric class InputFile; 330b57cec5SDimitry Andric class InputSection; 340b57cec5SDimitry Andric class InputSectionBase; 350b57cec5SDimitry Andric class OutputSection; 360b57cec5SDimitry Andric class SectionBase; 370b57cec5SDimitry Andric class Symbol; 380b57cec5SDimitry Andric class ThunkSection; 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric // This represents an r-value in the linker script. 410b57cec5SDimitry Andric struct ExprValue { 420b57cec5SDimitry Andric ExprValue(SectionBase *sec, bool forceAbsolute, uint64_t val, 430b57cec5SDimitry Andric const Twine &loc) 444824e7fdSDimitry Andric : sec(sec), val(val), forceAbsolute(forceAbsolute), loc(loc.str()) {} 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric ExprValue(uint64_t val) : ExprValue(nullptr, false, val, "") {} 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric bool isAbsolute() const { return forceAbsolute || sec == nullptr; } 490b57cec5SDimitry Andric uint64_t getValue() const; 500b57cec5SDimitry Andric uint64_t getSecAddr() const; 510b57cec5SDimitry Andric uint64_t getSectionOffset() const; 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric // If a value is relative to a section, it has a non-null Sec. 540b57cec5SDimitry Andric SectionBase *sec; 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric uint64_t val; 570b57cec5SDimitry Andric uint64_t alignment = 1; 580b57cec5SDimitry Andric 5916d6b3b3SDimitry Andric // The original st_type if the expression represents a symbol. Any operation 6016d6b3b3SDimitry Andric // resets type to STT_NOTYPE. 6116d6b3b3SDimitry Andric uint8_t type = llvm::ELF::STT_NOTYPE; 6216d6b3b3SDimitry Andric 634824e7fdSDimitry Andric // True if this expression is enclosed in ABSOLUTE(). 644824e7fdSDimitry Andric // This flag affects the return value of getValue(). 654824e7fdSDimitry Andric bool forceAbsolute; 664824e7fdSDimitry Andric 670b57cec5SDimitry Andric // Original source location. Used for error messages. 680b57cec5SDimitry Andric std::string loc; 690b57cec5SDimitry Andric }; 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric // This represents an expression in the linker script. 720b57cec5SDimitry Andric // ScriptParser::readExpr reads an expression and returns an Expr. 730b57cec5SDimitry Andric // Later, we evaluate the expression by calling the function. 740b57cec5SDimitry Andric using Expr = std::function<ExprValue()>; 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric // This enum is used to implement linker script SECTIONS command. 770b57cec5SDimitry Andric // https://sourceware.org/binutils/docs/ld/SECTIONS.html#SECTIONS 780b57cec5SDimitry Andric enum SectionsCommandKind { 790b57cec5SDimitry Andric AssignmentKind, // . = expr or <sym> = expr 800b57cec5SDimitry Andric OutputSectionKind, 810b57cec5SDimitry Andric InputSectionKind, 820b57cec5SDimitry Andric ByteKind // BYTE(expr), SHORT(expr), LONG(expr) or QUAD(expr) 830b57cec5SDimitry Andric }; 840b57cec5SDimitry Andric 854824e7fdSDimitry Andric struct SectionCommand { 864824e7fdSDimitry Andric SectionCommand(int k) : kind(k) {} 870b57cec5SDimitry Andric int kind; 880b57cec5SDimitry Andric }; 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric // This represents ". = <expr>" or "<symbol> = <expr>". 914824e7fdSDimitry Andric struct SymbolAssignment : SectionCommand { 920b57cec5SDimitry Andric SymbolAssignment(StringRef name, Expr e, std::string loc) 934824e7fdSDimitry Andric : SectionCommand(AssignmentKind), name(name), expression(e), 944824e7fdSDimitry Andric location(loc) {} 950b57cec5SDimitry Andric 964824e7fdSDimitry Andric static bool classof(const SectionCommand *c) { 970b57cec5SDimitry Andric return c->kind == AssignmentKind; 980b57cec5SDimitry Andric } 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric // The LHS of an expression. Name is either a symbol name or ".". 1010b57cec5SDimitry Andric StringRef name; 1020b57cec5SDimitry Andric Defined *sym = nullptr; 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric // The RHS of an expression. 1050b57cec5SDimitry Andric Expr expression; 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric // Command attributes for PROVIDE, HIDDEN and PROVIDE_HIDDEN. 1080b57cec5SDimitry Andric bool provide = false; 1090b57cec5SDimitry Andric bool hidden = false; 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric // Holds file name and line number for error reporting. 1120b57cec5SDimitry Andric std::string location; 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric // A string representation of this command. We use this for -Map. 1150b57cec5SDimitry Andric std::string commandString; 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric // Address of this assignment command. 1185ffd83dbSDimitry Andric uint64_t addr; 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric // Size of this assignment command. This is usually 0, but if 1210b57cec5SDimitry Andric // you move '.' this may be greater than 0. 1225ffd83dbSDimitry Andric uint64_t size; 1230b57cec5SDimitry Andric }; 1240b57cec5SDimitry Andric 125480093f4SDimitry Andric // Linker scripts allow additional constraints to be put on output sections. 1260b57cec5SDimitry Andric // If an output section is marked as ONLY_IF_RO, the section is created 1270b57cec5SDimitry Andric // only if its input sections are read-only. Likewise, an output section 1280b57cec5SDimitry Andric // with ONLY_IF_RW is created if all input sections are RW. 1290b57cec5SDimitry Andric enum class ConstraintKind { NoConstraint, ReadOnly, ReadWrite }; 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric // This struct is used to represent the location and size of regions of 1320b57cec5SDimitry Andric // target memory. Instances of the struct are created by parsing the 1330b57cec5SDimitry Andric // MEMORY command. 1340b57cec5SDimitry Andric struct MemoryRegion { 1355ffd83dbSDimitry Andric MemoryRegion(StringRef name, Expr origin, Expr length, uint32_t flags, 1364824e7fdSDimitry Andric uint32_t invFlags, uint32_t negFlags, uint32_t negInvFlags) 1375ffd83dbSDimitry Andric : name(std::string(name)), origin(origin), length(length), flags(flags), 1384824e7fdSDimitry Andric invFlags(invFlags), negFlags(negFlags), negInvFlags(negInvFlags) {} 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric std::string name; 1415ffd83dbSDimitry Andric Expr origin; 1425ffd83dbSDimitry Andric Expr length; 1434824e7fdSDimitry Andric // A section can be assigned to the region if any of these ELF section flags 1444824e7fdSDimitry Andric // are set... 1450b57cec5SDimitry Andric uint32_t flags; 1464824e7fdSDimitry Andric // ... or any of these flags are not set. 1474824e7fdSDimitry Andric // For example, the memory region attribute "r" maps to SHF_WRITE. 1484824e7fdSDimitry Andric uint32_t invFlags; 1494824e7fdSDimitry Andric // A section cannot be assigned to the region if any of these ELF section 1504824e7fdSDimitry Andric // flags are set... 1510b57cec5SDimitry Andric uint32_t negFlags; 1524824e7fdSDimitry Andric // ... or any of these flags are not set. 1534824e7fdSDimitry Andric // For example, the memory region attribute "!r" maps to SHF_WRITE. 1544824e7fdSDimitry Andric uint32_t negInvFlags; 1550b57cec5SDimitry Andric uint64_t curPos = 0; 1564824e7fdSDimitry Andric 1574824e7fdSDimitry Andric bool compatibleWith(uint32_t secFlags) const { 1584824e7fdSDimitry Andric if ((secFlags & negFlags) || (~secFlags & negInvFlags)) 1594824e7fdSDimitry Andric return false; 1604824e7fdSDimitry Andric return (secFlags & flags) || (~secFlags & invFlags); 1614824e7fdSDimitry Andric } 1620b57cec5SDimitry Andric }; 1630b57cec5SDimitry Andric 1640b57cec5SDimitry Andric // This struct represents one section match pattern in SECTIONS() command. 1650b57cec5SDimitry Andric // It can optionally have negative match pattern for EXCLUDED_FILE command. 1660b57cec5SDimitry Andric // Also it may be surrounded with SORT() command, so contains sorting rules. 167e8d8bef9SDimitry Andric class SectionPattern { 168e8d8bef9SDimitry Andric StringMatcher excludedFilePat; 169e8d8bef9SDimitry Andric 170e8d8bef9SDimitry Andric // Cache of the most recent input argument and result of excludesFile(). 171e8d8bef9SDimitry Andric mutable llvm::Optional<std::pair<const InputFile *, bool>> excludesFileCache; 172e8d8bef9SDimitry Andric 173e8d8bef9SDimitry Andric public: 1740b57cec5SDimitry Andric SectionPattern(StringMatcher &&pat1, StringMatcher &&pat2) 1750b57cec5SDimitry Andric : excludedFilePat(pat1), sectionPat(pat2), 1760b57cec5SDimitry Andric sortOuter(SortSectionPolicy::Default), 1770b57cec5SDimitry Andric sortInner(SortSectionPolicy::Default) {} 1780b57cec5SDimitry Andric 179e8d8bef9SDimitry Andric bool excludesFile(const InputFile *file) const; 180e8d8bef9SDimitry Andric 1810b57cec5SDimitry Andric StringMatcher sectionPat; 1820b57cec5SDimitry Andric SortSectionPolicy sortOuter; 1830b57cec5SDimitry Andric SortSectionPolicy sortInner; 1840b57cec5SDimitry Andric }; 1850b57cec5SDimitry Andric 1864824e7fdSDimitry Andric class InputSectionDescription : public SectionCommand { 187e8d8bef9SDimitry Andric SingleStringMatcher filePat; 188e8d8bef9SDimitry Andric 189e8d8bef9SDimitry Andric // Cache of the most recent input argument and result of matchesFile(). 190e8d8bef9SDimitry Andric mutable llvm::Optional<std::pair<const InputFile *, bool>> matchesFileCache; 191e8d8bef9SDimitry Andric 192e8d8bef9SDimitry Andric public: 1935ffd83dbSDimitry Andric InputSectionDescription(StringRef filePattern, uint64_t withFlags = 0, 1945ffd83dbSDimitry Andric uint64_t withoutFlags = 0) 1954824e7fdSDimitry Andric : SectionCommand(InputSectionKind), filePat(filePattern), 1965ffd83dbSDimitry Andric withFlags(withFlags), withoutFlags(withoutFlags) {} 1970b57cec5SDimitry Andric 1984824e7fdSDimitry Andric static bool classof(const SectionCommand *c) { 1990b57cec5SDimitry Andric return c->kind == InputSectionKind; 2000b57cec5SDimitry Andric } 2010b57cec5SDimitry Andric 202e8d8bef9SDimitry Andric bool matchesFile(const InputFile *file) const; 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andric // Input sections that matches at least one of SectionPatterns 2050b57cec5SDimitry Andric // will be associated with this InputSectionDescription. 2060b57cec5SDimitry Andric std::vector<SectionPattern> sectionPatterns; 2070b57cec5SDimitry Andric 20885868e8aSDimitry Andric // Includes InputSections and MergeInputSections. Used temporarily during 20985868e8aSDimitry Andric // assignment of input sections to output sections. 21085868e8aSDimitry Andric std::vector<InputSectionBase *> sectionBases; 21185868e8aSDimitry Andric 21285868e8aSDimitry Andric // Used after the finalizeInputSections() pass. MergeInputSections have been 21385868e8aSDimitry Andric // merged into MergeSyntheticSections. 2140b57cec5SDimitry Andric std::vector<InputSection *> sections; 2150b57cec5SDimitry Andric 2160b57cec5SDimitry Andric // Temporary record of synthetic ThunkSection instances and the pass that 2170b57cec5SDimitry Andric // they were created in. This is used to insert newly created ThunkSections 2180b57cec5SDimitry Andric // into Sections at the end of a createThunks() pass. 2190b57cec5SDimitry Andric std::vector<std::pair<ThunkSection *, uint32_t>> thunkSections; 2205ffd83dbSDimitry Andric 2215ffd83dbSDimitry Andric // SectionPatterns can be filtered with the INPUT_SECTION_FLAGS command. 2225ffd83dbSDimitry Andric uint64_t withFlags; 2235ffd83dbSDimitry Andric uint64_t withoutFlags; 2240b57cec5SDimitry Andric }; 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric // Represents BYTE(), SHORT(), LONG(), or QUAD(). 2274824e7fdSDimitry Andric struct ByteCommand : SectionCommand { 2280b57cec5SDimitry Andric ByteCommand(Expr e, unsigned size, std::string commandString) 2294824e7fdSDimitry Andric : SectionCommand(ByteKind), commandString(commandString), expression(e), 2300b57cec5SDimitry Andric size(size) {} 2310b57cec5SDimitry Andric 2324824e7fdSDimitry Andric static bool classof(const SectionCommand *c) { return c->kind == ByteKind; } 2330b57cec5SDimitry Andric 2340b57cec5SDimitry Andric // Keeps string representing the command. Used for -Map" is perhaps better. 2350b57cec5SDimitry Andric std::string commandString; 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andric Expr expression; 2380b57cec5SDimitry Andric 2390b57cec5SDimitry Andric // This is just an offset of this assignment command in the output section. 2400b57cec5SDimitry Andric unsigned offset; 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric // Size of this data command. 2430b57cec5SDimitry Andric unsigned size; 2440b57cec5SDimitry Andric }; 2450b57cec5SDimitry Andric 2465ffd83dbSDimitry Andric struct InsertCommand { 247fe6060f1SDimitry Andric std::vector<StringRef> names; 2485ffd83dbSDimitry Andric bool isAfter; 2495ffd83dbSDimitry Andric StringRef where; 2505ffd83dbSDimitry Andric }; 2515ffd83dbSDimitry Andric 2520b57cec5SDimitry Andric struct PhdrsCommand { 2530b57cec5SDimitry Andric StringRef name; 2540b57cec5SDimitry Andric unsigned type = llvm::ELF::PT_NULL; 2550b57cec5SDimitry Andric bool hasFilehdr = false; 2560b57cec5SDimitry Andric bool hasPhdrs = false; 2570b57cec5SDimitry Andric llvm::Optional<unsigned> flags; 2580b57cec5SDimitry Andric Expr lmaExpr = nullptr; 2590b57cec5SDimitry Andric }; 2600b57cec5SDimitry Andric 2610b57cec5SDimitry Andric class LinkerScript final { 2620b57cec5SDimitry Andric // Temporary state used in processSectionCommands() and assignAddresses() 2630b57cec5SDimitry Andric // that must be reinitialized for each call to the above functions, and must 2640b57cec5SDimitry Andric // not be used outside of the scope of a call to the above functions. 2650b57cec5SDimitry Andric struct AddressState { 2660b57cec5SDimitry Andric AddressState(); 2670b57cec5SDimitry Andric OutputSection *outSec = nullptr; 2680b57cec5SDimitry Andric MemoryRegion *memRegion = nullptr; 2690b57cec5SDimitry Andric MemoryRegion *lmaRegion = nullptr; 2700b57cec5SDimitry Andric uint64_t lmaOffset = 0; 2716e75b2fbSDimitry Andric uint64_t tbssAddr = 0; 2720b57cec5SDimitry Andric }; 2730b57cec5SDimitry Andric 2740b57cec5SDimitry Andric llvm::DenseMap<StringRef, OutputSection *> nameToOutputSection; 2750b57cec5SDimitry Andric 2760b57cec5SDimitry Andric void addSymbol(SymbolAssignment *cmd); 2770b57cec5SDimitry Andric void assignSymbol(SymbolAssignment *cmd, bool inSec); 2780b57cec5SDimitry Andric void setDot(Expr e, const Twine &loc, bool inSec); 2790b57cec5SDimitry Andric void expandOutputSection(uint64_t size); 2800b57cec5SDimitry Andric void expandMemoryRegions(uint64_t size); 2810b57cec5SDimitry Andric 28285868e8aSDimitry Andric std::vector<InputSectionBase *> 2835ffd83dbSDimitry Andric computeInputSections(const InputSectionDescription *, 2845ffd83dbSDimitry Andric ArrayRef<InputSectionBase *>); 2850b57cec5SDimitry Andric 28685868e8aSDimitry Andric std::vector<InputSectionBase *> createInputSectionList(OutputSection &cmd); 2870b57cec5SDimitry Andric 2885ffd83dbSDimitry Andric void discardSynthetic(OutputSection &); 2895ffd83dbSDimitry Andric 2900b57cec5SDimitry Andric std::vector<size_t> getPhdrIndices(OutputSection *sec); 2910b57cec5SDimitry Andric 292349cc55cSDimitry Andric std::pair<MemoryRegion *, MemoryRegion *> 293349cc55cSDimitry Andric findMemoryRegion(OutputSection *sec, MemoryRegion *hint); 2940b57cec5SDimitry Andric 2950b57cec5SDimitry Andric void assignOffsets(OutputSection *sec); 2960b57cec5SDimitry Andric 2970b57cec5SDimitry Andric // Ctx captures the local AddressState and makes it accessible 2980b57cec5SDimitry Andric // deliberately. This is needed as there are some cases where we cannot just 2990b57cec5SDimitry Andric // thread the current state through to a lambda function created by the 3000b57cec5SDimitry Andric // script parser. 3010b57cec5SDimitry Andric // This should remain a plain pointer as its lifetime is smaller than 3020b57cec5SDimitry Andric // LinkerScript. 3030b57cec5SDimitry Andric AddressState *ctx = nullptr; 3040b57cec5SDimitry Andric 3050b57cec5SDimitry Andric OutputSection *aether; 3060b57cec5SDimitry Andric 3070b57cec5SDimitry Andric uint64_t dot; 3080b57cec5SDimitry Andric 3090b57cec5SDimitry Andric public: 3100b57cec5SDimitry Andric OutputSection *createOutputSection(StringRef name, StringRef location); 3110b57cec5SDimitry Andric OutputSection *getOrCreateOutputSection(StringRef name); 3120b57cec5SDimitry Andric 3130b57cec5SDimitry Andric bool hasPhdrsCommands() { return !phdrsCommands.empty(); } 3140b57cec5SDimitry Andric uint64_t getDot() { return dot; } 315*0eae32dcSDimitry Andric void discard(InputSectionBase &s); 3160b57cec5SDimitry Andric 3170b57cec5SDimitry Andric ExprValue getSymbolValue(StringRef name, const Twine &loc); 3180b57cec5SDimitry Andric 3190b57cec5SDimitry Andric void addOrphanSections(); 3205ffd83dbSDimitry Andric void diagnoseOrphanHandling() const; 3210b57cec5SDimitry Andric void adjustSectionsBeforeSorting(); 3220b57cec5SDimitry Andric void adjustSectionsAfterSorting(); 3230b57cec5SDimitry Andric 3240b57cec5SDimitry Andric std::vector<PhdrEntry *> createPhdrs(); 3250b57cec5SDimitry Andric bool needsInterpSection(); 3260b57cec5SDimitry Andric 3270b57cec5SDimitry Andric bool shouldKeep(InputSectionBase *s); 32885868e8aSDimitry Andric const Defined *assignAddresses(); 3290b57cec5SDimitry Andric void allocateHeaders(std::vector<PhdrEntry *> &phdrs); 3300b57cec5SDimitry Andric void processSectionCommands(); 33185868e8aSDimitry Andric void processSymbolAssignments(); 3320b57cec5SDimitry Andric void declareSymbols(); 3330b57cec5SDimitry Andric 334349cc55cSDimitry Andric bool isDiscarded(const OutputSection *sec) const; 335349cc55cSDimitry Andric 3360b57cec5SDimitry Andric // Used to handle INSERT AFTER statements. 3370b57cec5SDimitry Andric void processInsertCommands(); 3380b57cec5SDimitry Andric 3390b57cec5SDimitry Andric // SECTIONS command list. 3404824e7fdSDimitry Andric std::vector<SectionCommand *> sectionCommands; 3410b57cec5SDimitry Andric 3420b57cec5SDimitry Andric // PHDRS command list. 3430b57cec5SDimitry Andric std::vector<PhdrsCommand> phdrsCommands; 3440b57cec5SDimitry Andric 3450b57cec5SDimitry Andric bool hasSectionsCommand = false; 3460b57cec5SDimitry Andric bool errorOnMissingSection = false; 3470b57cec5SDimitry Andric 3480b57cec5SDimitry Andric // List of section patterns specified with KEEP commands. They will 3490b57cec5SDimitry Andric // be kept even if they are unused and --gc-sections is specified. 3500b57cec5SDimitry Andric std::vector<InputSectionDescription *> keptSections; 3510b57cec5SDimitry Andric 3520b57cec5SDimitry Andric // A map from memory region name to a memory region descriptor. 3530b57cec5SDimitry Andric llvm::MapVector<llvm::StringRef, MemoryRegion *> memoryRegions; 3540b57cec5SDimitry Andric 3550b57cec5SDimitry Andric // A list of symbols referenced by the script. 3560b57cec5SDimitry Andric std::vector<llvm::StringRef> referencedSymbols; 3570b57cec5SDimitry Andric 3585ffd83dbSDimitry Andric // Used to implement INSERT [AFTER|BEFORE]. Contains output sections that need 3595ffd83dbSDimitry Andric // to be reordered. 3605ffd83dbSDimitry Andric std::vector<InsertCommand> insertCommands; 3615ffd83dbSDimitry Andric 362fe6060f1SDimitry Andric // OutputSections specified by OVERWRITE_SECTIONS. 363fe6060f1SDimitry Andric std::vector<OutputSection *> overwriteSections; 364fe6060f1SDimitry Andric 3655ffd83dbSDimitry Andric // Sections that will be warned/errored by --orphan-handling. 3665ffd83dbSDimitry Andric std::vector<const InputSectionBase *> orphanSections; 3670b57cec5SDimitry Andric }; 3680b57cec5SDimitry Andric 369*0eae32dcSDimitry Andric extern std::unique_ptr<LinkerScript> script; 3700b57cec5SDimitry Andric 3710b57cec5SDimitry Andric } // end namespace elf 3720b57cec5SDimitry Andric } // end namespace lld 3730b57cec5SDimitry Andric 3740b57cec5SDimitry Andric #endif // LLD_ELF_LINKER_SCRIPT_H 375