xref: /openbsd-src/gnu/llvm/lld/ELF/LinkerScript.h (revision dfe94b169149f14cc1aee2cf6dad58a8d9a1860c)
1ece8a530Spatrick //===- LinkerScript.h -------------------------------------------*- C++ -*-===//
2ece8a530Spatrick //
3ece8a530Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4ece8a530Spatrick // See https://llvm.org/LICENSE.txt for license information.
5ece8a530Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ece8a530Spatrick //
7ece8a530Spatrick //===----------------------------------------------------------------------===//
8ece8a530Spatrick 
9ece8a530Spatrick #ifndef LLD_ELF_LINKER_SCRIPT_H
10ece8a530Spatrick #define LLD_ELF_LINKER_SCRIPT_H
11ece8a530Spatrick 
12ece8a530Spatrick #include "Config.h"
13ece8a530Spatrick #include "Writer.h"
14ece8a530Spatrick #include "lld/Common/LLVM.h"
15ece8a530Spatrick #include "lld/Common/Strings.h"
16ece8a530Spatrick #include "llvm/ADT/ArrayRef.h"
17ece8a530Spatrick #include "llvm/ADT/DenseMap.h"
18ece8a530Spatrick #include "llvm/ADT/MapVector.h"
19ece8a530Spatrick #include "llvm/ADT/StringRef.h"
20*dfe94b16Srobert #include "llvm/Support/Compiler.h"
21ece8a530Spatrick #include <cstddef>
22ece8a530Spatrick #include <cstdint>
23ece8a530Spatrick #include <functional>
24ece8a530Spatrick #include <memory>
25ece8a530Spatrick 
26*dfe94b16Srobert namespace lld::elf {
27ece8a530Spatrick 
28ece8a530Spatrick class Defined;
291cf9926bSpatrick class InputFile;
30ece8a530Spatrick class InputSection;
31ece8a530Spatrick class InputSectionBase;
32ece8a530Spatrick class OutputSection;
33ece8a530Spatrick class SectionBase;
34ece8a530Spatrick class ThunkSection;
35*dfe94b16Srobert struct OutputDesc;
36ece8a530Spatrick 
37ece8a530Spatrick // This represents an r-value in the linker script.
38ece8a530Spatrick struct ExprValue {
ExprValueExprValue39ece8a530Spatrick   ExprValue(SectionBase *sec, bool forceAbsolute, uint64_t val,
40ece8a530Spatrick             const Twine &loc)
41*dfe94b16Srobert       : sec(sec), val(val), forceAbsolute(forceAbsolute), loc(loc.str()) {}
42ece8a530Spatrick 
ExprValueExprValue43ece8a530Spatrick   ExprValue(uint64_t val) : ExprValue(nullptr, false, val, "") {}
44ece8a530Spatrick 
isAbsoluteExprValue45ece8a530Spatrick   bool isAbsolute() const { return forceAbsolute || sec == nullptr; }
46ece8a530Spatrick   uint64_t getValue() const;
47ece8a530Spatrick   uint64_t getSecAddr() const;
48ece8a530Spatrick   uint64_t getSectionOffset() const;
49ece8a530Spatrick 
50ece8a530Spatrick   // If a value is relative to a section, it has a non-null Sec.
51ece8a530Spatrick   SectionBase *sec;
52ece8a530Spatrick 
53ece8a530Spatrick   uint64_t val;
54ece8a530Spatrick   uint64_t alignment = 1;
55ece8a530Spatrick 
56bb684c34Spatrick   // The original st_type if the expression represents a symbol. Any operation
57bb684c34Spatrick   // resets type to STT_NOTYPE.
58bb684c34Spatrick   uint8_t type = llvm::ELF::STT_NOTYPE;
59bb684c34Spatrick 
60*dfe94b16Srobert   // True if this expression is enclosed in ABSOLUTE().
61*dfe94b16Srobert   // This flag affects the return value of getValue().
62*dfe94b16Srobert   bool forceAbsolute;
63*dfe94b16Srobert 
64ece8a530Spatrick   // Original source location. Used for error messages.
65ece8a530Spatrick   std::string loc;
66ece8a530Spatrick };
67ece8a530Spatrick 
68ece8a530Spatrick // This represents an expression in the linker script.
69ece8a530Spatrick // ScriptParser::readExpr reads an expression and returns an Expr.
70ece8a530Spatrick // Later, we evaluate the expression by calling the function.
71ece8a530Spatrick using Expr = std::function<ExprValue()>;
72ece8a530Spatrick 
73ece8a530Spatrick // This enum is used to implement linker script SECTIONS command.
74ece8a530Spatrick // https://sourceware.org/binutils/docs/ld/SECTIONS.html#SECTIONS
75ece8a530Spatrick enum SectionsCommandKind {
76ece8a530Spatrick   AssignmentKind, // . = expr or <sym> = expr
77ece8a530Spatrick   OutputSectionKind,
78ece8a530Spatrick   InputSectionKind,
79ece8a530Spatrick   ByteKind    // BYTE(expr), SHORT(expr), LONG(expr) or QUAD(expr)
80ece8a530Spatrick };
81ece8a530Spatrick 
82*dfe94b16Srobert struct SectionCommand {
SectionCommandSectionCommand83*dfe94b16Srobert   SectionCommand(int k) : kind(k) {}
84ece8a530Spatrick   int kind;
85ece8a530Spatrick };
86ece8a530Spatrick 
87ece8a530Spatrick // This represents ". = <expr>" or "<symbol> = <expr>".
88*dfe94b16Srobert struct SymbolAssignment : SectionCommand {
SymbolAssignmentSymbolAssignment89ece8a530Spatrick   SymbolAssignment(StringRef name, Expr e, std::string loc)
90*dfe94b16Srobert       : SectionCommand(AssignmentKind), name(name), expression(e),
91*dfe94b16Srobert         location(loc) {}
92ece8a530Spatrick 
classofSymbolAssignment93*dfe94b16Srobert   static bool classof(const SectionCommand *c) {
94ece8a530Spatrick     return c->kind == AssignmentKind;
95ece8a530Spatrick   }
96ece8a530Spatrick 
97ece8a530Spatrick   // The LHS of an expression. Name is either a symbol name or ".".
98ece8a530Spatrick   StringRef name;
99ece8a530Spatrick   Defined *sym = nullptr;
100ece8a530Spatrick 
101ece8a530Spatrick   // The RHS of an expression.
102ece8a530Spatrick   Expr expression;
103ece8a530Spatrick 
104ece8a530Spatrick   // Command attributes for PROVIDE, HIDDEN and PROVIDE_HIDDEN.
105ece8a530Spatrick   bool provide = false;
106ece8a530Spatrick   bool hidden = false;
107ece8a530Spatrick 
108ece8a530Spatrick   // Holds file name and line number for error reporting.
109ece8a530Spatrick   std::string location;
110ece8a530Spatrick 
111ece8a530Spatrick   // A string representation of this command. We use this for -Map.
112ece8a530Spatrick   std::string commandString;
113ece8a530Spatrick 
114ece8a530Spatrick   // Address of this assignment command.
115bb684c34Spatrick   uint64_t addr;
116ece8a530Spatrick 
117ece8a530Spatrick   // Size of this assignment command. This is usually 0, but if
118ece8a530Spatrick   // you move '.' this may be greater than 0.
119bb684c34Spatrick   uint64_t size;
120ece8a530Spatrick };
121ece8a530Spatrick 
122ece8a530Spatrick // Linker scripts allow additional constraints to be put on output sections.
123ece8a530Spatrick // If an output section is marked as ONLY_IF_RO, the section is created
124ece8a530Spatrick // only if its input sections are read-only. Likewise, an output section
125ece8a530Spatrick // with ONLY_IF_RW is created if all input sections are RW.
126ece8a530Spatrick enum class ConstraintKind { NoConstraint, ReadOnly, ReadWrite };
127ece8a530Spatrick 
128ece8a530Spatrick // This struct is used to represent the location and size of regions of
129ece8a530Spatrick // target memory. Instances of the struct are created by parsing the
130ece8a530Spatrick // MEMORY command.
131ece8a530Spatrick struct MemoryRegion {
MemoryRegionMemoryRegion132bb684c34Spatrick   MemoryRegion(StringRef name, Expr origin, Expr length, uint32_t flags,
133*dfe94b16Srobert                uint32_t invFlags, uint32_t negFlags, uint32_t negInvFlags)
134bb684c34Spatrick       : name(std::string(name)), origin(origin), length(length), flags(flags),
135*dfe94b16Srobert         invFlags(invFlags), negFlags(negFlags), negInvFlags(negInvFlags) {}
136ece8a530Spatrick 
137ece8a530Spatrick   std::string name;
138bb684c34Spatrick   Expr origin;
139bb684c34Spatrick   Expr length;
140*dfe94b16Srobert   // A section can be assigned to the region if any of these ELF section flags
141*dfe94b16Srobert   // are set...
142ece8a530Spatrick   uint32_t flags;
143*dfe94b16Srobert   // ... or any of these flags are not set.
144*dfe94b16Srobert   // For example, the memory region attribute "r" maps to SHF_WRITE.
145*dfe94b16Srobert   uint32_t invFlags;
146*dfe94b16Srobert   // A section cannot be assigned to the region if any of these ELF section
147*dfe94b16Srobert   // flags are set...
148ece8a530Spatrick   uint32_t negFlags;
149*dfe94b16Srobert   // ... or any of these flags are not set.
150*dfe94b16Srobert   // For example, the memory region attribute "!r" maps to SHF_WRITE.
151*dfe94b16Srobert   uint32_t negInvFlags;
152ece8a530Spatrick   uint64_t curPos = 0;
153*dfe94b16Srobert 
compatibleWithMemoryRegion154*dfe94b16Srobert   bool compatibleWith(uint32_t secFlags) const {
155*dfe94b16Srobert     if ((secFlags & negFlags) || (~secFlags & negInvFlags))
156*dfe94b16Srobert       return false;
157*dfe94b16Srobert     return (secFlags & flags) || (~secFlags & invFlags);
158*dfe94b16Srobert   }
159ece8a530Spatrick };
160ece8a530Spatrick 
161ece8a530Spatrick // This struct represents one section match pattern in SECTIONS() command.
162ece8a530Spatrick // It can optionally have negative match pattern for EXCLUDED_FILE command.
163ece8a530Spatrick // Also it may be surrounded with SORT() command, so contains sorting rules.
1641cf9926bSpatrick class SectionPattern {
1651cf9926bSpatrick   StringMatcher excludedFilePat;
1661cf9926bSpatrick 
1671cf9926bSpatrick   // Cache of the most recent input argument and result of excludesFile().
168*dfe94b16Srobert   mutable std::optional<std::pair<const InputFile *, bool>> excludesFileCache;
1691cf9926bSpatrick 
1701cf9926bSpatrick public:
SectionPattern(StringMatcher && pat1,StringMatcher && pat2)171ece8a530Spatrick   SectionPattern(StringMatcher &&pat1, StringMatcher &&pat2)
172ece8a530Spatrick       : excludedFilePat(pat1), sectionPat(pat2),
173ece8a530Spatrick         sortOuter(SortSectionPolicy::Default),
174ece8a530Spatrick         sortInner(SortSectionPolicy::Default) {}
175ece8a530Spatrick 
1761cf9926bSpatrick   bool excludesFile(const InputFile *file) const;
1771cf9926bSpatrick 
178ece8a530Spatrick   StringMatcher sectionPat;
179ece8a530Spatrick   SortSectionPolicy sortOuter;
180ece8a530Spatrick   SortSectionPolicy sortInner;
181ece8a530Spatrick };
182ece8a530Spatrick 
183*dfe94b16Srobert class InputSectionDescription : public SectionCommand {
1841cf9926bSpatrick   SingleStringMatcher filePat;
1851cf9926bSpatrick 
1861cf9926bSpatrick   // Cache of the most recent input argument and result of matchesFile().
187*dfe94b16Srobert   mutable std::optional<std::pair<const InputFile *, bool>> matchesFileCache;
1881cf9926bSpatrick 
1891cf9926bSpatrick public:
190bb684c34Spatrick   InputSectionDescription(StringRef filePattern, uint64_t withFlags = 0,
191bb684c34Spatrick                           uint64_t withoutFlags = 0)
SectionCommand(InputSectionKind)192*dfe94b16Srobert       : SectionCommand(InputSectionKind), filePat(filePattern),
193bb684c34Spatrick         withFlags(withFlags), withoutFlags(withoutFlags) {}
194ece8a530Spatrick 
classof(const SectionCommand * c)195*dfe94b16Srobert   static bool classof(const SectionCommand *c) {
196ece8a530Spatrick     return c->kind == InputSectionKind;
197ece8a530Spatrick   }
198ece8a530Spatrick 
1991cf9926bSpatrick   bool matchesFile(const InputFile *file) const;
200ece8a530Spatrick 
201ece8a530Spatrick   // Input sections that matches at least one of SectionPatterns
202ece8a530Spatrick   // will be associated with this InputSectionDescription.
203*dfe94b16Srobert   SmallVector<SectionPattern, 0> sectionPatterns;
204ece8a530Spatrick 
205ece8a530Spatrick   // Includes InputSections and MergeInputSections. Used temporarily during
206ece8a530Spatrick   // assignment of input sections to output sections.
207*dfe94b16Srobert   SmallVector<InputSectionBase *, 0> sectionBases;
208ece8a530Spatrick 
209ece8a530Spatrick   // Used after the finalizeInputSections() pass. MergeInputSections have been
210ece8a530Spatrick   // merged into MergeSyntheticSections.
211*dfe94b16Srobert   SmallVector<InputSection *, 0> sections;
212ece8a530Spatrick 
213ece8a530Spatrick   // Temporary record of synthetic ThunkSection instances and the pass that
214ece8a530Spatrick   // they were created in. This is used to insert newly created ThunkSections
215ece8a530Spatrick   // into Sections at the end of a createThunks() pass.
216*dfe94b16Srobert   SmallVector<std::pair<ThunkSection *, uint32_t>, 0> thunkSections;
217bb684c34Spatrick 
218bb684c34Spatrick   // SectionPatterns can be filtered with the INPUT_SECTION_FLAGS command.
219bb684c34Spatrick   uint64_t withFlags;
220bb684c34Spatrick   uint64_t withoutFlags;
221ece8a530Spatrick };
222ece8a530Spatrick 
223ece8a530Spatrick // Represents BYTE(), SHORT(), LONG(), or QUAD().
224*dfe94b16Srobert struct ByteCommand : SectionCommand {
ByteCommandByteCommand225ece8a530Spatrick   ByteCommand(Expr e, unsigned size, std::string commandString)
226*dfe94b16Srobert       : SectionCommand(ByteKind), commandString(commandString), expression(e),
227ece8a530Spatrick         size(size) {}
228ece8a530Spatrick 
classofByteCommand229*dfe94b16Srobert   static bool classof(const SectionCommand *c) { return c->kind == ByteKind; }
230ece8a530Spatrick 
231ece8a530Spatrick   // Keeps string representing the command. Used for -Map" is perhaps better.
232ece8a530Spatrick   std::string commandString;
233ece8a530Spatrick 
234ece8a530Spatrick   Expr expression;
235ece8a530Spatrick 
236ece8a530Spatrick   // This is just an offset of this assignment command in the output section.
237ece8a530Spatrick   unsigned offset;
238ece8a530Spatrick 
239ece8a530Spatrick   // Size of this data command.
240ece8a530Spatrick   unsigned size;
241ece8a530Spatrick };
242ece8a530Spatrick 
243bb684c34Spatrick struct InsertCommand {
244*dfe94b16Srobert   SmallVector<StringRef, 0> names;
245bb684c34Spatrick   bool isAfter;
246bb684c34Spatrick   StringRef where;
247bb684c34Spatrick };
248bb684c34Spatrick 
249ece8a530Spatrick struct PhdrsCommand {
250ece8a530Spatrick   StringRef name;
251ece8a530Spatrick   unsigned type = llvm::ELF::PT_NULL;
252ece8a530Spatrick   bool hasFilehdr = false;
253ece8a530Spatrick   bool hasPhdrs = false;
254*dfe94b16Srobert   std::optional<unsigned> flags;
255ece8a530Spatrick   Expr lmaExpr = nullptr;
256ece8a530Spatrick };
257ece8a530Spatrick 
258ece8a530Spatrick class LinkerScript final {
259ece8a530Spatrick   // Temporary state used in processSectionCommands() and assignAddresses()
260ece8a530Spatrick   // that must be reinitialized for each call to the above functions, and must
261ece8a530Spatrick   // not be used outside of the scope of a call to the above functions.
262ece8a530Spatrick   struct AddressState {
263ece8a530Spatrick     AddressState();
264ece8a530Spatrick     OutputSection *outSec = nullptr;
265ece8a530Spatrick     MemoryRegion *memRegion = nullptr;
266ece8a530Spatrick     MemoryRegion *lmaRegion = nullptr;
267ece8a530Spatrick     uint64_t lmaOffset = 0;
2681cf9926bSpatrick     uint64_t tbssAddr = 0;
269ece8a530Spatrick   };
270ece8a530Spatrick 
271*dfe94b16Srobert   llvm::DenseMap<llvm::CachedHashStringRef, OutputDesc *> nameToOutputSection;
272ece8a530Spatrick 
273ece8a530Spatrick   void addSymbol(SymbolAssignment *cmd);
274ece8a530Spatrick   void assignSymbol(SymbolAssignment *cmd, bool inSec);
275ece8a530Spatrick   void setDot(Expr e, const Twine &loc, bool inSec);
276ece8a530Spatrick   void expandOutputSection(uint64_t size);
277ece8a530Spatrick   void expandMemoryRegions(uint64_t size);
278ece8a530Spatrick 
279*dfe94b16Srobert   SmallVector<InputSectionBase *, 0>
280bb684c34Spatrick   computeInputSections(const InputSectionDescription *,
281bb684c34Spatrick                        ArrayRef<InputSectionBase *>);
282ece8a530Spatrick 
283*dfe94b16Srobert   SmallVector<InputSectionBase *, 0> createInputSectionList(OutputSection &cmd);
284ece8a530Spatrick 
285bb684c34Spatrick   void discardSynthetic(OutputSection &);
286bb684c34Spatrick 
287*dfe94b16Srobert   SmallVector<size_t, 0> getPhdrIndices(OutputSection *sec);
288ece8a530Spatrick 
289*dfe94b16Srobert   std::pair<MemoryRegion *, MemoryRegion *>
290*dfe94b16Srobert   findMemoryRegion(OutputSection *sec, MemoryRegion *hint);
291ece8a530Spatrick 
292ece8a530Spatrick   void assignOffsets(OutputSection *sec);
293ece8a530Spatrick 
294*dfe94b16Srobert   // This captures the local AddressState and makes it accessible
295ece8a530Spatrick   // deliberately. This is needed as there are some cases where we cannot just
296ece8a530Spatrick   // thread the current state through to a lambda function created by the
297ece8a530Spatrick   // script parser.
298ece8a530Spatrick   // This should remain a plain pointer as its lifetime is smaller than
299ece8a530Spatrick   // LinkerScript.
300*dfe94b16Srobert   AddressState *state = nullptr;
301ece8a530Spatrick 
302ece8a530Spatrick   OutputSection *aether;
303ece8a530Spatrick 
304ece8a530Spatrick   uint64_t dot;
305ece8a530Spatrick 
306ece8a530Spatrick public:
307*dfe94b16Srobert   OutputDesc *createOutputSection(StringRef name, StringRef location);
308*dfe94b16Srobert   OutputDesc *getOrCreateOutputSection(StringRef name);
309ece8a530Spatrick 
hasPhdrsCommands()310ece8a530Spatrick   bool hasPhdrsCommands() { return !phdrsCommands.empty(); }
getDot()311ece8a530Spatrick   uint64_t getDot() { return dot; }
312*dfe94b16Srobert   void discard(InputSectionBase &s);
313ece8a530Spatrick 
314ece8a530Spatrick   ExprValue getSymbolValue(StringRef name, const Twine &loc);
315ece8a530Spatrick 
316ece8a530Spatrick   void addOrphanSections();
317bb684c34Spatrick   void diagnoseOrphanHandling() const;
318*dfe94b16Srobert   void adjustOutputSections();
319ece8a530Spatrick   void adjustSectionsAfterSorting();
320ece8a530Spatrick 
321*dfe94b16Srobert   SmallVector<PhdrEntry *, 0> createPhdrs();
322ece8a530Spatrick   bool needsInterpSection();
323ece8a530Spatrick 
324ece8a530Spatrick   bool shouldKeep(InputSectionBase *s);
325ece8a530Spatrick   const Defined *assignAddresses();
326*dfe94b16Srobert   void allocateHeaders(SmallVector<PhdrEntry *, 0> &phdrs);
327ece8a530Spatrick   void processSectionCommands();
328ece8a530Spatrick   void processSymbolAssignments();
329ece8a530Spatrick   void declareSymbols();
330ece8a530Spatrick 
331*dfe94b16Srobert   bool isDiscarded(const OutputSection *sec) const;
332*dfe94b16Srobert 
333ece8a530Spatrick   // Used to handle INSERT AFTER statements.
334ece8a530Spatrick   void processInsertCommands();
335ece8a530Spatrick 
336ece8a530Spatrick   // SECTIONS command list.
337*dfe94b16Srobert   SmallVector<SectionCommand *, 0> sectionCommands;
338ece8a530Spatrick 
339ece8a530Spatrick   // PHDRS command list.
340*dfe94b16Srobert   SmallVector<PhdrsCommand, 0> phdrsCommands;
341ece8a530Spatrick 
342ece8a530Spatrick   bool hasSectionsCommand = false;
343ece8a530Spatrick   bool errorOnMissingSection = false;
344ece8a530Spatrick 
345ece8a530Spatrick   // List of section patterns specified with KEEP commands. They will
346ece8a530Spatrick   // be kept even if they are unused and --gc-sections is specified.
347*dfe94b16Srobert   SmallVector<InputSectionDescription *, 0> keptSections;
348ece8a530Spatrick 
349ece8a530Spatrick   // A map from memory region name to a memory region descriptor.
350ece8a530Spatrick   llvm::MapVector<llvm::StringRef, MemoryRegion *> memoryRegions;
351ece8a530Spatrick 
352ece8a530Spatrick   // A list of symbols referenced by the script.
353*dfe94b16Srobert   SmallVector<llvm::StringRef, 0> referencedSymbols;
354ece8a530Spatrick 
355bb684c34Spatrick   // Used to implement INSERT [AFTER|BEFORE]. Contains output sections that need
356bb684c34Spatrick   // to be reordered.
357*dfe94b16Srobert   SmallVector<InsertCommand, 0> insertCommands;
358bb684c34Spatrick 
3591cf9926bSpatrick   // OutputSections specified by OVERWRITE_SECTIONS.
360*dfe94b16Srobert   SmallVector<OutputDesc *, 0> overwriteSections;
3611cf9926bSpatrick 
362bb684c34Spatrick   // Sections that will be warned/errored by --orphan-handling.
363*dfe94b16Srobert   SmallVector<const InputSectionBase *, 0> orphanSections;
364ece8a530Spatrick };
365ece8a530Spatrick 
366*dfe94b16Srobert LLVM_LIBRARY_VISIBILITY extern std::unique_ptr<LinkerScript> script;
367ece8a530Spatrick 
368*dfe94b16Srobert } // end namespace lld::elf
369ece8a530Spatrick 
370ece8a530Spatrick #endif // LLD_ELF_LINKER_SCRIPT_H
371