xref: /freebsd/contrib/llvm-project/lld/ELF/LinkerScript.h (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
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/MapVector.h"
190b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
20bdd1243dSDimitry Andric #include "llvm/Support/Compiler.h"
210b57cec5SDimitry Andric #include <cstddef>
220b57cec5SDimitry Andric #include <cstdint>
230b57cec5SDimitry Andric #include <functional>
240b57cec5SDimitry Andric #include <memory>
250b57cec5SDimitry Andric 
26bdd1243dSDimitry Andric namespace lld::elf {
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric class Defined;
29e8d8bef9SDimitry Andric class InputFile;
300b57cec5SDimitry Andric class InputSection;
310b57cec5SDimitry Andric class InputSectionBase;
320b57cec5SDimitry Andric class OutputSection;
330b57cec5SDimitry Andric class SectionBase;
340b57cec5SDimitry Andric class ThunkSection;
3581ad6265SDimitry Andric struct OutputDesc;
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric // This represents an r-value in the linker script.
380b57cec5SDimitry Andric struct ExprValue {
390b57cec5SDimitry Andric   ExprValue(SectionBase *sec, bool forceAbsolute, uint64_t val,
400b57cec5SDimitry Andric             const Twine &loc)
414824e7fdSDimitry Andric       : sec(sec), val(val), forceAbsolute(forceAbsolute), loc(loc.str()) {}
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric   ExprValue(uint64_t val) : ExprValue(nullptr, false, val, "") {}
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric   bool isAbsolute() const { return forceAbsolute || sec == nullptr; }
460b57cec5SDimitry Andric   uint64_t getValue() const;
470b57cec5SDimitry Andric   uint64_t getSecAddr() const;
480b57cec5SDimitry Andric   uint64_t getSectionOffset() const;
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric   // If a value is relative to a section, it has a non-null Sec.
510b57cec5SDimitry Andric   SectionBase *sec;
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric   uint64_t val;
540b57cec5SDimitry Andric   uint64_t alignment = 1;
550b57cec5SDimitry Andric 
5616d6b3b3SDimitry Andric   // The original st_type if the expression represents a symbol. Any operation
5716d6b3b3SDimitry Andric   // resets type to STT_NOTYPE.
5816d6b3b3SDimitry Andric   uint8_t type = llvm::ELF::STT_NOTYPE;
5916d6b3b3SDimitry Andric 
604824e7fdSDimitry Andric   // True if this expression is enclosed in ABSOLUTE().
614824e7fdSDimitry Andric   // This flag affects the return value of getValue().
624824e7fdSDimitry Andric   bool forceAbsolute;
634824e7fdSDimitry Andric 
640b57cec5SDimitry Andric   // Original source location. Used for error messages.
650b57cec5SDimitry Andric   std::string loc;
660b57cec5SDimitry Andric };
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric // This represents an expression in the linker script.
690b57cec5SDimitry Andric // ScriptParser::readExpr reads an expression and returns an Expr.
700b57cec5SDimitry Andric // Later, we evaluate the expression by calling the function.
710b57cec5SDimitry Andric using Expr = std::function<ExprValue()>;
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric // This enum is used to implement linker script SECTIONS command.
740b57cec5SDimitry Andric // https://sourceware.org/binutils/docs/ld/SECTIONS.html#SECTIONS
750b57cec5SDimitry Andric enum SectionsCommandKind {
760b57cec5SDimitry Andric   AssignmentKind, // . = expr or <sym> = expr
770b57cec5SDimitry Andric   OutputSectionKind,
780b57cec5SDimitry Andric   InputSectionKind,
790b57cec5SDimitry Andric   ByteKind    // BYTE(expr), SHORT(expr), LONG(expr) or QUAD(expr)
800b57cec5SDimitry Andric };
810b57cec5SDimitry Andric 
824824e7fdSDimitry Andric struct SectionCommand {
834824e7fdSDimitry Andric   SectionCommand(int k) : kind(k) {}
840b57cec5SDimitry Andric   int kind;
850b57cec5SDimitry Andric };
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric // This represents ". = <expr>" or "<symbol> = <expr>".
884824e7fdSDimitry Andric struct SymbolAssignment : SectionCommand {
890b57cec5SDimitry Andric   SymbolAssignment(StringRef name, Expr e, std::string loc)
904824e7fdSDimitry Andric       : SectionCommand(AssignmentKind), name(name), expression(e),
914824e7fdSDimitry Andric         location(loc) {}
920b57cec5SDimitry Andric 
934824e7fdSDimitry Andric   static bool classof(const SectionCommand *c) {
940b57cec5SDimitry Andric     return c->kind == AssignmentKind;
950b57cec5SDimitry Andric   }
960b57cec5SDimitry Andric 
970b57cec5SDimitry Andric   // The LHS of an expression. Name is either a symbol name or ".".
980b57cec5SDimitry Andric   StringRef name;
990b57cec5SDimitry Andric   Defined *sym = nullptr;
1000b57cec5SDimitry Andric 
1010b57cec5SDimitry Andric   // The RHS of an expression.
1020b57cec5SDimitry Andric   Expr expression;
1030b57cec5SDimitry Andric 
1040b57cec5SDimitry Andric   // Command attributes for PROVIDE, HIDDEN and PROVIDE_HIDDEN.
1050b57cec5SDimitry Andric   bool provide = false;
1060b57cec5SDimitry Andric   bool hidden = false;
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric   // Holds file name and line number for error reporting.
1090b57cec5SDimitry Andric   std::string location;
1100b57cec5SDimitry Andric 
1110b57cec5SDimitry Andric   // A string representation of this command. We use this for -Map.
1120b57cec5SDimitry Andric   std::string commandString;
1130b57cec5SDimitry Andric 
1140b57cec5SDimitry Andric   // Address of this assignment command.
1155ffd83dbSDimitry Andric   uint64_t addr;
1160b57cec5SDimitry Andric 
1170b57cec5SDimitry Andric   // Size of this assignment command. This is usually 0, but if
1180b57cec5SDimitry Andric   // you move '.' this may be greater than 0.
1195ffd83dbSDimitry Andric   uint64_t size;
1200b57cec5SDimitry Andric };
1210b57cec5SDimitry Andric 
122480093f4SDimitry Andric // Linker scripts allow additional constraints to be put on output sections.
1230b57cec5SDimitry Andric // If an output section is marked as ONLY_IF_RO, the section is created
1240b57cec5SDimitry Andric // only if its input sections are read-only. Likewise, an output section
1250b57cec5SDimitry Andric // with ONLY_IF_RW is created if all input sections are RW.
1260b57cec5SDimitry Andric enum class ConstraintKind { NoConstraint, ReadOnly, ReadWrite };
1270b57cec5SDimitry Andric 
1280b57cec5SDimitry Andric // This struct is used to represent the location and size of regions of
1290b57cec5SDimitry Andric // target memory. Instances of the struct are created by parsing the
1300b57cec5SDimitry Andric // MEMORY command.
1310b57cec5SDimitry Andric struct MemoryRegion {
1325ffd83dbSDimitry Andric   MemoryRegion(StringRef name, Expr origin, Expr length, uint32_t flags,
1334824e7fdSDimitry Andric                uint32_t invFlags, uint32_t negFlags, uint32_t negInvFlags)
1345ffd83dbSDimitry Andric       : name(std::string(name)), origin(origin), length(length), flags(flags),
1354824e7fdSDimitry Andric         invFlags(invFlags), negFlags(negFlags), negInvFlags(negInvFlags) {}
1360b57cec5SDimitry Andric 
1370b57cec5SDimitry Andric   std::string name;
1385ffd83dbSDimitry Andric   Expr origin;
1395ffd83dbSDimitry Andric   Expr length;
1404824e7fdSDimitry Andric   // A section can be assigned to the region if any of these ELF section flags
1414824e7fdSDimitry Andric   // are set...
1420b57cec5SDimitry Andric   uint32_t flags;
1434824e7fdSDimitry Andric   // ... or any of these flags are not set.
1444824e7fdSDimitry Andric   // For example, the memory region attribute "r" maps to SHF_WRITE.
1454824e7fdSDimitry Andric   uint32_t invFlags;
1464824e7fdSDimitry Andric   // A section cannot be assigned to the region if any of these ELF section
1474824e7fdSDimitry Andric   // flags are set...
1480b57cec5SDimitry Andric   uint32_t negFlags;
1494824e7fdSDimitry Andric   // ... or any of these flags are not set.
1504824e7fdSDimitry Andric   // For example, the memory region attribute "!r" maps to SHF_WRITE.
1514824e7fdSDimitry Andric   uint32_t negInvFlags;
1520b57cec5SDimitry Andric   uint64_t curPos = 0;
1534824e7fdSDimitry Andric 
154*06c3fb27SDimitry Andric   uint64_t getOrigin() const { return origin().getValue(); }
155*06c3fb27SDimitry Andric   uint64_t getLength() const { return length().getValue(); }
156*06c3fb27SDimitry 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().
171bdd1243dSDimitry Andric   mutable std::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().
190bdd1243dSDimitry Andric   mutable std::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.
20604eeddc0SDimitry Andric   SmallVector<SectionPattern, 0> sectionPatterns;
2070b57cec5SDimitry Andric 
20885868e8aSDimitry Andric   // Includes InputSections and MergeInputSections. Used temporarily during
20985868e8aSDimitry Andric   // assignment of input sections to output sections.
21004eeddc0SDimitry Andric   SmallVector<InputSectionBase *, 0> sectionBases;
21185868e8aSDimitry Andric 
21285868e8aSDimitry Andric   // Used after the finalizeInputSections() pass. MergeInputSections have been
21385868e8aSDimitry Andric   // merged into MergeSyntheticSections.
21404eeddc0SDimitry Andric   SmallVector<InputSection *, 0> 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.
21904eeddc0SDimitry Andric   SmallVector<std::pair<ThunkSection *, uint32_t>, 0> 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 {
24704eeddc0SDimitry Andric   SmallVector<StringRef, 0> 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;
257bdd1243dSDimitry Andric   std::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 
27481ad6265SDimitry Andric   llvm::DenseMap<llvm::CachedHashStringRef, OutputDesc *> 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 
28204eeddc0SDimitry Andric   SmallVector<InputSectionBase *, 0>
2835ffd83dbSDimitry Andric   computeInputSections(const InputSectionDescription *,
2845ffd83dbSDimitry Andric                        ArrayRef<InputSectionBase *>);
2850b57cec5SDimitry Andric 
28604eeddc0SDimitry Andric   SmallVector<InputSectionBase *, 0> createInputSectionList(OutputSection &cmd);
2870b57cec5SDimitry Andric 
2885ffd83dbSDimitry Andric   void discardSynthetic(OutputSection &);
2895ffd83dbSDimitry Andric 
29004eeddc0SDimitry Andric   SmallVector<size_t, 0> 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 
297bdd1243dSDimitry Andric   // This 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.
303bdd1243dSDimitry Andric   AddressState *state = nullptr;
3040b57cec5SDimitry Andric 
3050b57cec5SDimitry Andric   OutputSection *aether;
3060b57cec5SDimitry Andric 
3070b57cec5SDimitry Andric   uint64_t dot;
3080b57cec5SDimitry Andric 
3090b57cec5SDimitry Andric public:
31081ad6265SDimitry Andric   OutputDesc *createOutputSection(StringRef name, StringRef location);
31181ad6265SDimitry Andric   OutputDesc *getOrCreateOutputSection(StringRef name);
3120b57cec5SDimitry Andric 
3130b57cec5SDimitry Andric   bool hasPhdrsCommands() { return !phdrsCommands.empty(); }
3140b57cec5SDimitry Andric   uint64_t getDot() { return dot; }
3150eae32dcSDimitry 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;
321*06c3fb27SDimitry Andric   void diagnoseMissingSGSectionAddress() const;
3221fd87a68SDimitry Andric   void adjustOutputSections();
3230b57cec5SDimitry Andric   void adjustSectionsAfterSorting();
3240b57cec5SDimitry Andric 
32504eeddc0SDimitry Andric   SmallVector<PhdrEntry *, 0> createPhdrs();
3260b57cec5SDimitry Andric   bool needsInterpSection();
3270b57cec5SDimitry Andric 
3280b57cec5SDimitry Andric   bool shouldKeep(InputSectionBase *s);
32985868e8aSDimitry Andric   const Defined *assignAddresses();
33004eeddc0SDimitry Andric   void allocateHeaders(SmallVector<PhdrEntry *, 0> &phdrs);
3310b57cec5SDimitry Andric   void processSectionCommands();
33285868e8aSDimitry Andric   void processSymbolAssignments();
3330b57cec5SDimitry Andric   void declareSymbols();
3340b57cec5SDimitry Andric 
335349cc55cSDimitry Andric   bool isDiscarded(const OutputSection *sec) const;
336349cc55cSDimitry Andric 
3370b57cec5SDimitry Andric   // Used to handle INSERT AFTER statements.
3380b57cec5SDimitry Andric   void processInsertCommands();
3390b57cec5SDimitry Andric 
340*06c3fb27SDimitry Andric   // Describe memory region usage.
341*06c3fb27SDimitry Andric   void printMemoryUsage(raw_ostream &os);
342*06c3fb27SDimitry Andric 
343*06c3fb27SDimitry Andric   // Verify memory/lma overflows.
344*06c3fb27SDimitry Andric   void checkMemoryRegions() const;
345*06c3fb27SDimitry Andric 
3460b57cec5SDimitry Andric   // SECTIONS command list.
34704eeddc0SDimitry Andric   SmallVector<SectionCommand *, 0> sectionCommands;
3480b57cec5SDimitry Andric 
3490b57cec5SDimitry Andric   // PHDRS command list.
35004eeddc0SDimitry Andric   SmallVector<PhdrsCommand, 0> phdrsCommands;
3510b57cec5SDimitry Andric 
3520b57cec5SDimitry Andric   bool hasSectionsCommand = false;
3530b57cec5SDimitry Andric   bool errorOnMissingSection = false;
3540b57cec5SDimitry Andric 
3550b57cec5SDimitry Andric   // List of section patterns specified with KEEP commands. They will
3560b57cec5SDimitry Andric   // be kept even if they are unused and --gc-sections is specified.
35704eeddc0SDimitry Andric   SmallVector<InputSectionDescription *, 0> keptSections;
3580b57cec5SDimitry Andric 
3590b57cec5SDimitry Andric   // A map from memory region name to a memory region descriptor.
3600b57cec5SDimitry Andric   llvm::MapVector<llvm::StringRef, MemoryRegion *> memoryRegions;
3610b57cec5SDimitry Andric 
3620b57cec5SDimitry Andric   // A list of symbols referenced by the script.
36304eeddc0SDimitry Andric   SmallVector<llvm::StringRef, 0> referencedSymbols;
3640b57cec5SDimitry Andric 
3655ffd83dbSDimitry Andric   // Used to implement INSERT [AFTER|BEFORE]. Contains output sections that need
3665ffd83dbSDimitry Andric   // to be reordered.
36704eeddc0SDimitry Andric   SmallVector<InsertCommand, 0> insertCommands;
3685ffd83dbSDimitry Andric 
369fe6060f1SDimitry Andric   // OutputSections specified by OVERWRITE_SECTIONS.
37081ad6265SDimitry Andric   SmallVector<OutputDesc *, 0> overwriteSections;
371fe6060f1SDimitry Andric 
3725ffd83dbSDimitry Andric   // Sections that will be warned/errored by --orphan-handling.
37304eeddc0SDimitry Andric   SmallVector<const InputSectionBase *, 0> orphanSections;
3740b57cec5SDimitry Andric };
3750b57cec5SDimitry Andric 
376bdd1243dSDimitry Andric LLVM_LIBRARY_VISIBILITY extern std::unique_ptr<LinkerScript> script;
3770b57cec5SDimitry Andric 
378bdd1243dSDimitry Andric } // end namespace lld::elf
3790b57cec5SDimitry Andric 
3800b57cec5SDimitry Andric #endif // LLD_ELF_LINKER_SCRIPT_H
381