xref: /freebsd/contrib/llvm-project/lld/ELF/LinkerScript.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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