xref: /freebsd/contrib/llvm-project/lld/ELF/LinkerScript.h (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
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"
200b57cec5SDimitry Andric #include <cstddef>
210b57cec5SDimitry Andric #include <cstdint>
220b57cec5SDimitry Andric #include <functional>
230b57cec5SDimitry Andric #include <memory>
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric namespace lld {
260b57cec5SDimitry Andric namespace 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;
35*81ad6265SDimitry 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 
1544824e7fdSDimitry Andric   bool compatibleWith(uint32_t secFlags) const {
1554824e7fdSDimitry Andric     if ((secFlags & negFlags) || (~secFlags & negInvFlags))
1564824e7fdSDimitry Andric       return false;
1574824e7fdSDimitry Andric     return (secFlags & flags) || (~secFlags & invFlags);
1584824e7fdSDimitry Andric   }
1590b57cec5SDimitry Andric };
1600b57cec5SDimitry Andric 
1610b57cec5SDimitry Andric // This struct represents one section match pattern in SECTIONS() command.
1620b57cec5SDimitry Andric // It can optionally have negative match pattern for EXCLUDED_FILE command.
1630b57cec5SDimitry Andric // Also it may be surrounded with SORT() command, so contains sorting rules.
164e8d8bef9SDimitry Andric class SectionPattern {
165e8d8bef9SDimitry Andric   StringMatcher excludedFilePat;
166e8d8bef9SDimitry Andric 
167e8d8bef9SDimitry Andric   // Cache of the most recent input argument and result of excludesFile().
168e8d8bef9SDimitry Andric   mutable llvm::Optional<std::pair<const InputFile *, bool>> excludesFileCache;
169e8d8bef9SDimitry Andric 
170e8d8bef9SDimitry Andric public:
1710b57cec5SDimitry Andric   SectionPattern(StringMatcher &&pat1, StringMatcher &&pat2)
1720b57cec5SDimitry Andric       : excludedFilePat(pat1), sectionPat(pat2),
1730b57cec5SDimitry Andric         sortOuter(SortSectionPolicy::Default),
1740b57cec5SDimitry Andric         sortInner(SortSectionPolicy::Default) {}
1750b57cec5SDimitry Andric 
176e8d8bef9SDimitry Andric   bool excludesFile(const InputFile *file) const;
177e8d8bef9SDimitry Andric 
1780b57cec5SDimitry Andric   StringMatcher sectionPat;
1790b57cec5SDimitry Andric   SortSectionPolicy sortOuter;
1800b57cec5SDimitry Andric   SortSectionPolicy sortInner;
1810b57cec5SDimitry Andric };
1820b57cec5SDimitry Andric 
1834824e7fdSDimitry Andric class InputSectionDescription : public SectionCommand {
184e8d8bef9SDimitry Andric   SingleStringMatcher filePat;
185e8d8bef9SDimitry Andric 
186e8d8bef9SDimitry Andric   // Cache of the most recent input argument and result of matchesFile().
187e8d8bef9SDimitry Andric   mutable llvm::Optional<std::pair<const InputFile *, bool>> matchesFileCache;
188e8d8bef9SDimitry Andric 
189e8d8bef9SDimitry Andric public:
1905ffd83dbSDimitry Andric   InputSectionDescription(StringRef filePattern, uint64_t withFlags = 0,
1915ffd83dbSDimitry Andric                           uint64_t withoutFlags = 0)
1924824e7fdSDimitry Andric       : SectionCommand(InputSectionKind), filePat(filePattern),
1935ffd83dbSDimitry Andric         withFlags(withFlags), withoutFlags(withoutFlags) {}
1940b57cec5SDimitry Andric 
1954824e7fdSDimitry Andric   static bool classof(const SectionCommand *c) {
1960b57cec5SDimitry Andric     return c->kind == InputSectionKind;
1970b57cec5SDimitry Andric   }
1980b57cec5SDimitry Andric 
199e8d8bef9SDimitry Andric   bool matchesFile(const InputFile *file) const;
2000b57cec5SDimitry Andric 
2010b57cec5SDimitry Andric   // Input sections that matches at least one of SectionPatterns
2020b57cec5SDimitry Andric   // will be associated with this InputSectionDescription.
20304eeddc0SDimitry Andric   SmallVector<SectionPattern, 0> sectionPatterns;
2040b57cec5SDimitry Andric 
20585868e8aSDimitry Andric   // Includes InputSections and MergeInputSections. Used temporarily during
20685868e8aSDimitry Andric   // assignment of input sections to output sections.
20704eeddc0SDimitry Andric   SmallVector<InputSectionBase *, 0> sectionBases;
20885868e8aSDimitry Andric 
20985868e8aSDimitry Andric   // Used after the finalizeInputSections() pass. MergeInputSections have been
21085868e8aSDimitry Andric   // merged into MergeSyntheticSections.
21104eeddc0SDimitry Andric   SmallVector<InputSection *, 0> sections;
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric   // Temporary record of synthetic ThunkSection instances and the pass that
2140b57cec5SDimitry Andric   // they were created in. This is used to insert newly created ThunkSections
2150b57cec5SDimitry Andric   // into Sections at the end of a createThunks() pass.
21604eeddc0SDimitry Andric   SmallVector<std::pair<ThunkSection *, uint32_t>, 0> thunkSections;
2175ffd83dbSDimitry Andric 
2185ffd83dbSDimitry Andric   // SectionPatterns can be filtered with the INPUT_SECTION_FLAGS command.
2195ffd83dbSDimitry Andric   uint64_t withFlags;
2205ffd83dbSDimitry Andric   uint64_t withoutFlags;
2210b57cec5SDimitry Andric };
2220b57cec5SDimitry Andric 
2230b57cec5SDimitry Andric // Represents BYTE(), SHORT(), LONG(), or QUAD().
2244824e7fdSDimitry Andric struct ByteCommand : SectionCommand {
2250b57cec5SDimitry Andric   ByteCommand(Expr e, unsigned size, std::string commandString)
2264824e7fdSDimitry Andric       : SectionCommand(ByteKind), commandString(commandString), expression(e),
2270b57cec5SDimitry Andric         size(size) {}
2280b57cec5SDimitry Andric 
2294824e7fdSDimitry Andric   static bool classof(const SectionCommand *c) { return c->kind == ByteKind; }
2300b57cec5SDimitry Andric 
2310b57cec5SDimitry Andric   // Keeps string representing the command. Used for -Map" is perhaps better.
2320b57cec5SDimitry Andric   std::string commandString;
2330b57cec5SDimitry Andric 
2340b57cec5SDimitry Andric   Expr expression;
2350b57cec5SDimitry Andric 
2360b57cec5SDimitry Andric   // This is just an offset of this assignment command in the output section.
2370b57cec5SDimitry Andric   unsigned offset;
2380b57cec5SDimitry Andric 
2390b57cec5SDimitry Andric   // Size of this data command.
2400b57cec5SDimitry Andric   unsigned size;
2410b57cec5SDimitry Andric };
2420b57cec5SDimitry Andric 
2435ffd83dbSDimitry Andric struct InsertCommand {
24404eeddc0SDimitry Andric   SmallVector<StringRef, 0> names;
2455ffd83dbSDimitry Andric   bool isAfter;
2465ffd83dbSDimitry Andric   StringRef where;
2475ffd83dbSDimitry Andric };
2485ffd83dbSDimitry Andric 
2490b57cec5SDimitry Andric struct PhdrsCommand {
2500b57cec5SDimitry Andric   StringRef name;
2510b57cec5SDimitry Andric   unsigned type = llvm::ELF::PT_NULL;
2520b57cec5SDimitry Andric   bool hasFilehdr = false;
2530b57cec5SDimitry Andric   bool hasPhdrs = false;
2540b57cec5SDimitry Andric   llvm::Optional<unsigned> flags;
2550b57cec5SDimitry Andric   Expr lmaExpr = nullptr;
2560b57cec5SDimitry Andric };
2570b57cec5SDimitry Andric 
2580b57cec5SDimitry Andric class LinkerScript final {
2590b57cec5SDimitry Andric   // Temporary state used in processSectionCommands() and assignAddresses()
2600b57cec5SDimitry Andric   // that must be reinitialized for each call to the above functions, and must
2610b57cec5SDimitry Andric   // not be used outside of the scope of a call to the above functions.
2620b57cec5SDimitry Andric   struct AddressState {
2630b57cec5SDimitry Andric     AddressState();
2640b57cec5SDimitry Andric     OutputSection *outSec = nullptr;
2650b57cec5SDimitry Andric     MemoryRegion *memRegion = nullptr;
2660b57cec5SDimitry Andric     MemoryRegion *lmaRegion = nullptr;
2670b57cec5SDimitry Andric     uint64_t lmaOffset = 0;
2686e75b2fbSDimitry Andric     uint64_t tbssAddr = 0;
2690b57cec5SDimitry Andric   };
2700b57cec5SDimitry Andric 
271*81ad6265SDimitry Andric   llvm::DenseMap<llvm::CachedHashStringRef, OutputDesc *> nameToOutputSection;
2720b57cec5SDimitry Andric 
2730b57cec5SDimitry Andric   void addSymbol(SymbolAssignment *cmd);
2740b57cec5SDimitry Andric   void assignSymbol(SymbolAssignment *cmd, bool inSec);
2750b57cec5SDimitry Andric   void setDot(Expr e, const Twine &loc, bool inSec);
2760b57cec5SDimitry Andric   void expandOutputSection(uint64_t size);
2770b57cec5SDimitry Andric   void expandMemoryRegions(uint64_t size);
2780b57cec5SDimitry Andric 
27904eeddc0SDimitry Andric   SmallVector<InputSectionBase *, 0>
2805ffd83dbSDimitry Andric   computeInputSections(const InputSectionDescription *,
2815ffd83dbSDimitry Andric                        ArrayRef<InputSectionBase *>);
2820b57cec5SDimitry Andric 
28304eeddc0SDimitry Andric   SmallVector<InputSectionBase *, 0> createInputSectionList(OutputSection &cmd);
2840b57cec5SDimitry Andric 
2855ffd83dbSDimitry Andric   void discardSynthetic(OutputSection &);
2865ffd83dbSDimitry Andric 
28704eeddc0SDimitry Andric   SmallVector<size_t, 0> getPhdrIndices(OutputSection *sec);
2880b57cec5SDimitry Andric 
289349cc55cSDimitry Andric   std::pair<MemoryRegion *, MemoryRegion *>
290349cc55cSDimitry Andric   findMemoryRegion(OutputSection *sec, MemoryRegion *hint);
2910b57cec5SDimitry Andric 
2920b57cec5SDimitry Andric   void assignOffsets(OutputSection *sec);
2930b57cec5SDimitry Andric 
2940b57cec5SDimitry Andric   // Ctx captures the local AddressState and makes it accessible
2950b57cec5SDimitry Andric   // deliberately. This is needed as there are some cases where we cannot just
2960b57cec5SDimitry Andric   // thread the current state through to a lambda function created by the
2970b57cec5SDimitry Andric   // script parser.
2980b57cec5SDimitry Andric   // This should remain a plain pointer as its lifetime is smaller than
2990b57cec5SDimitry Andric   // LinkerScript.
3000b57cec5SDimitry Andric   AddressState *ctx = nullptr;
3010b57cec5SDimitry Andric 
3020b57cec5SDimitry Andric   OutputSection *aether;
3030b57cec5SDimitry Andric 
3040b57cec5SDimitry Andric   uint64_t dot;
3050b57cec5SDimitry Andric 
3060b57cec5SDimitry Andric public:
307*81ad6265SDimitry Andric   OutputDesc *createOutputSection(StringRef name, StringRef location);
308*81ad6265SDimitry Andric   OutputDesc *getOrCreateOutputSection(StringRef name);
3090b57cec5SDimitry Andric 
3100b57cec5SDimitry Andric   bool hasPhdrsCommands() { return !phdrsCommands.empty(); }
3110b57cec5SDimitry Andric   uint64_t getDot() { return dot; }
3120eae32dcSDimitry Andric   void discard(InputSectionBase &s);
3130b57cec5SDimitry Andric 
3140b57cec5SDimitry Andric   ExprValue getSymbolValue(StringRef name, const Twine &loc);
3150b57cec5SDimitry Andric 
3160b57cec5SDimitry Andric   void addOrphanSections();
3175ffd83dbSDimitry Andric   void diagnoseOrphanHandling() const;
3181fd87a68SDimitry Andric   void adjustOutputSections();
3190b57cec5SDimitry Andric   void adjustSectionsAfterSorting();
3200b57cec5SDimitry Andric 
32104eeddc0SDimitry Andric   SmallVector<PhdrEntry *, 0> createPhdrs();
3220b57cec5SDimitry Andric   bool needsInterpSection();
3230b57cec5SDimitry Andric 
3240b57cec5SDimitry Andric   bool shouldKeep(InputSectionBase *s);
32585868e8aSDimitry Andric   const Defined *assignAddresses();
32604eeddc0SDimitry Andric   void allocateHeaders(SmallVector<PhdrEntry *, 0> &phdrs);
3270b57cec5SDimitry Andric   void processSectionCommands();
32885868e8aSDimitry Andric   void processSymbolAssignments();
3290b57cec5SDimitry Andric   void declareSymbols();
3300b57cec5SDimitry Andric 
331349cc55cSDimitry Andric   bool isDiscarded(const OutputSection *sec) const;
332349cc55cSDimitry Andric 
3330b57cec5SDimitry Andric   // Used to handle INSERT AFTER statements.
3340b57cec5SDimitry Andric   void processInsertCommands();
3350b57cec5SDimitry Andric 
3360b57cec5SDimitry Andric   // SECTIONS command list.
33704eeddc0SDimitry Andric   SmallVector<SectionCommand *, 0> sectionCommands;
3380b57cec5SDimitry Andric 
3390b57cec5SDimitry Andric   // PHDRS command list.
34004eeddc0SDimitry Andric   SmallVector<PhdrsCommand, 0> phdrsCommands;
3410b57cec5SDimitry Andric 
3420b57cec5SDimitry Andric   bool hasSectionsCommand = false;
3430b57cec5SDimitry Andric   bool errorOnMissingSection = false;
3440b57cec5SDimitry Andric 
3450b57cec5SDimitry Andric   // List of section patterns specified with KEEP commands. They will
3460b57cec5SDimitry Andric   // be kept even if they are unused and --gc-sections is specified.
34704eeddc0SDimitry Andric   SmallVector<InputSectionDescription *, 0> keptSections;
3480b57cec5SDimitry Andric 
3490b57cec5SDimitry Andric   // A map from memory region name to a memory region descriptor.
3500b57cec5SDimitry Andric   llvm::MapVector<llvm::StringRef, MemoryRegion *> memoryRegions;
3510b57cec5SDimitry Andric 
3520b57cec5SDimitry Andric   // A list of symbols referenced by the script.
35304eeddc0SDimitry Andric   SmallVector<llvm::StringRef, 0> referencedSymbols;
3540b57cec5SDimitry Andric 
3555ffd83dbSDimitry Andric   // Used to implement INSERT [AFTER|BEFORE]. Contains output sections that need
3565ffd83dbSDimitry Andric   // to be reordered.
35704eeddc0SDimitry Andric   SmallVector<InsertCommand, 0> insertCommands;
3585ffd83dbSDimitry Andric 
359fe6060f1SDimitry Andric   // OutputSections specified by OVERWRITE_SECTIONS.
360*81ad6265SDimitry Andric   SmallVector<OutputDesc *, 0> overwriteSections;
361fe6060f1SDimitry Andric 
3625ffd83dbSDimitry Andric   // Sections that will be warned/errored by --orphan-handling.
36304eeddc0SDimitry Andric   SmallVector<const InputSectionBase *, 0> orphanSections;
3640b57cec5SDimitry Andric };
3650b57cec5SDimitry Andric 
3660eae32dcSDimitry Andric extern std::unique_ptr<LinkerScript> script;
3670b57cec5SDimitry Andric 
3680b57cec5SDimitry Andric } // end namespace elf
3690b57cec5SDimitry Andric } // end namespace lld
3700b57cec5SDimitry Andric 
3710b57cec5SDimitry Andric #endif // LLD_ELF_LINKER_SCRIPT_H
372