1 //===- LinkerScript.h -------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLD_ELF_LINKER_SCRIPT_H
10 #define LLD_ELF_LINKER_SCRIPT_H
11 
12 #include "Config.h"
13 #include "Writer.h"
14 #include "lld/Common/LLVM.h"
15 #include "lld/Common/Strings.h"
16 #include "llvm/ADT/ArrayRef.h"
17 #include "llvm/ADT/DenseMap.h"
18 #include "llvm/ADT/DenseSet.h"
19 #include "llvm/ADT/MapVector.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/Support/MemoryBuffer.h"
22 #include <cstddef>
23 #include <cstdint>
24 #include <functional>
25 #include <memory>
26 #include <vector>
27 
28 namespace lld {
29 namespace elf {
30 
31 class Defined;
32 class InputSection;
33 class InputSectionBase;
34 class InputSectionBase;
35 class OutputSection;
36 class SectionBase;
37 class Symbol;
38 class ThunkSection;
39 
40 // This represents an r-value in the linker script.
41 struct ExprValue {
42   ExprValue(SectionBase *Sec, bool ForceAbsolute, uint64_t Val,
43             const Twine &Loc)
44       : Sec(Sec), ForceAbsolute(ForceAbsolute), Val(Val), Loc(Loc.str()) {}
45 
46   ExprValue(uint64_t Val) : ExprValue(nullptr, false, Val, "") {}
47 
48   bool isAbsolute() const { return ForceAbsolute || Sec == nullptr; }
49   uint64_t getValue() const;
50   uint64_t getSecAddr() const;
51   uint64_t getSectionOffset() const;
52 
53   // If a value is relative to a section, it has a non-null Sec.
54   SectionBase *Sec;
55 
56   // True if this expression is enclosed in ABSOLUTE().
57   // This flag affects the return value of getValue().
58   bool ForceAbsolute;
59 
60   uint64_t Val;
61   uint64_t Alignment = 1;
62 
63   // Original source location. Used for error messages.
64   std::string Loc;
65 };
66 
67 // This represents an expression in the linker script.
68 // ScriptParser::readExpr reads an expression and returns an Expr.
69 // Later, we evaluate the expression by calling the function.
70 using Expr = std::function<ExprValue()>;
71 
72 // This enum is used to implement linker script SECTIONS command.
73 // https://sourceware.org/binutils/docs/ld/SECTIONS.html#SECTIONS
74 enum SectionsCommandKind {
75   AssignmentKind, // . = expr or <sym> = expr
76   OutputSectionKind,
77   InputSectionKind,
78   ByteKind    // BYTE(expr), SHORT(expr), LONG(expr) or QUAD(expr)
79 };
80 
81 struct BaseCommand {
82   BaseCommand(int K) : Kind(K) {}
83   int Kind;
84 };
85 
86 // This represents ". = <expr>" or "<symbol> = <expr>".
87 struct SymbolAssignment : BaseCommand {
88   SymbolAssignment(StringRef Name, Expr E, std::string Loc)
89       : BaseCommand(AssignmentKind), Name(Name), Expression(E), Location(Loc) {}
90 
91   static bool classof(const BaseCommand *C) {
92     return C->Kind == AssignmentKind;
93   }
94 
95   // The LHS of an expression. Name is either a symbol name or ".".
96   StringRef Name;
97   Defined *Sym = nullptr;
98 
99   // The RHS of an expression.
100   Expr Expression;
101 
102   // Command attributes for PROVIDE, HIDDEN and PROVIDE_HIDDEN.
103   bool Provide = false;
104   bool Hidden = false;
105 
106   // Holds file name and line number for error reporting.
107   std::string Location;
108 
109   // A string representation of this command. We use this for -Map.
110   std::string CommandString;
111 
112   // Address of this assignment command.
113   unsigned Addr;
114 
115   // Size of this assignment command. This is usually 0, but if
116   // you move '.' this may be greater than 0.
117   unsigned Size;
118 };
119 
120 // Linker scripts allow additional constraints to be put on ouput sections.
121 // If an output section is marked as ONLY_IF_RO, the section is created
122 // only if its input sections are read-only. Likewise, an output section
123 // with ONLY_IF_RW is created if all input sections are RW.
124 enum class ConstraintKind { NoConstraint, ReadOnly, ReadWrite };
125 
126 // This struct is used to represent the location and size of regions of
127 // target memory. Instances of the struct are created by parsing the
128 // MEMORY command.
129 struct MemoryRegion {
130   MemoryRegion(StringRef Name, uint64_t Origin, uint64_t Length, uint32_t Flags,
131                uint32_t NegFlags)
132       : Name(Name), Origin(Origin), Length(Length), Flags(Flags),
133         NegFlags(NegFlags) {}
134 
135   std::string Name;
136   uint64_t Origin;
137   uint64_t Length;
138   uint32_t Flags;
139   uint32_t NegFlags;
140   uint64_t CurPos = 0;
141 };
142 
143 // This struct represents one section match pattern in SECTIONS() command.
144 // It can optionally have negative match pattern for EXCLUDED_FILE command.
145 // Also it may be surrounded with SORT() command, so contains sorting rules.
146 struct SectionPattern {
147   SectionPattern(StringMatcher &&Pat1, StringMatcher &&Pat2)
148       : ExcludedFilePat(Pat1), SectionPat(Pat2),
149         SortOuter(SortSectionPolicy::Default),
150         SortInner(SortSectionPolicy::Default) {}
151 
152   StringMatcher ExcludedFilePat;
153   StringMatcher SectionPat;
154   SortSectionPolicy SortOuter;
155   SortSectionPolicy SortInner;
156 };
157 
158 struct InputSectionDescription : BaseCommand {
159   InputSectionDescription(StringRef FilePattern)
160       : BaseCommand(InputSectionKind), FilePat(FilePattern) {}
161 
162   static bool classof(const BaseCommand *C) {
163     return C->Kind == InputSectionKind;
164   }
165 
166   StringMatcher FilePat;
167 
168   // Input sections that matches at least one of SectionPatterns
169   // will be associated with this InputSectionDescription.
170   std::vector<SectionPattern> SectionPatterns;
171 
172   std::vector<InputSection *> Sections;
173 
174   // Temporary record of synthetic ThunkSection instances and the pass that
175   // they were created in. This is used to insert newly created ThunkSections
176   // into Sections at the end of a createThunks() pass.
177   std::vector<std::pair<ThunkSection *, uint32_t>> ThunkSections;
178 };
179 
180 // Represents BYTE(), SHORT(), LONG(), or QUAD().
181 struct ByteCommand : BaseCommand {
182   ByteCommand(Expr E, unsigned Size, std::string CommandString)
183       : BaseCommand(ByteKind), CommandString(CommandString), Expression(E),
184         Size(Size) {}
185 
186   static bool classof(const BaseCommand *C) { return C->Kind == ByteKind; }
187 
188   // Keeps string representing the command. Used for -Map" is perhaps better.
189   std::string CommandString;
190 
191   Expr Expression;
192 
193   // This is just an offset of this assignment command in the output section.
194   unsigned Offset;
195 
196   // Size of this data command.
197   unsigned Size;
198 };
199 
200 struct PhdrsCommand {
201   StringRef Name;
202   unsigned Type = llvm::ELF::PT_NULL;
203   bool HasFilehdr = false;
204   bool HasPhdrs = false;
205   llvm::Optional<unsigned> Flags;
206   Expr LMAExpr = nullptr;
207 };
208 
209 class LinkerScript final {
210   // Temporary state used in processSectionCommands() and assignAddresses()
211   // that must be reinitialized for each call to the above functions, and must
212   // not be used outside of the scope of a call to the above functions.
213   struct AddressState {
214     AddressState();
215     uint64_t ThreadBssOffset = 0;
216     OutputSection *OutSec = nullptr;
217     MemoryRegion *MemRegion = nullptr;
218     MemoryRegion *LMARegion = nullptr;
219     uint64_t LMAOffset = 0;
220   };
221 
222   llvm::DenseMap<StringRef, OutputSection *> NameToOutputSection;
223 
224   void addSymbol(SymbolAssignment *Cmd);
225   void assignSymbol(SymbolAssignment *Cmd, bool InSec);
226   void setDot(Expr E, const Twine &Loc, bool InSec);
227   void expandOutputSection(uint64_t Size);
228   void expandMemoryRegions(uint64_t Size);
229 
230   std::vector<InputSection *>
231   computeInputSections(const InputSectionDescription *);
232 
233   std::vector<InputSection *> createInputSectionList(OutputSection &Cmd);
234 
235   std::vector<size_t> getPhdrIndices(OutputSection *Sec);
236 
237   MemoryRegion *findMemoryRegion(OutputSection *Sec);
238 
239   void switchTo(OutputSection *Sec);
240   uint64_t advance(uint64_t Size, unsigned Align);
241   void output(InputSection *Sec);
242 
243   void assignOffsets(OutputSection *Sec);
244 
245   // Ctx captures the local AddressState and makes it accessible
246   // deliberately. This is needed as there are some cases where we cannot just
247   // thread the current state through to a lambda function created by the
248   // script parser.
249   // This should remain a plain pointer as its lifetime is smaller than
250   // LinkerScript.
251   AddressState *Ctx = nullptr;
252 
253   OutputSection *Aether;
254 
255   uint64_t Dot;
256 
257 public:
258   OutputSection *createOutputSection(StringRef Name, StringRef Location);
259   OutputSection *getOrCreateOutputSection(StringRef Name);
260 
261   bool hasPhdrsCommands() { return !PhdrsCommands.empty(); }
262   uint64_t getDot() { return Dot; }
263   void discard(ArrayRef<InputSection *> V);
264 
265   ExprValue getSymbolValue(StringRef Name, const Twine &Loc);
266 
267   void addOrphanSections();
268   void adjustSectionsBeforeSorting();
269   void adjustSectionsAfterSorting();
270 
271   std::vector<PhdrEntry *> createPhdrs();
272   bool needsInterpSection();
273 
274   bool shouldKeep(InputSectionBase *S);
275   void assignAddresses();
276   void allocateHeaders(std::vector<PhdrEntry *> &Phdrs);
277   void processSectionCommands();
278   void declareSymbols();
279 
280   // Used to handle INSERT AFTER statements.
281   void processInsertCommands();
282 
283   // SECTIONS command list.
284   std::vector<BaseCommand *> SectionCommands;
285 
286   // PHDRS command list.
287   std::vector<PhdrsCommand> PhdrsCommands;
288 
289   bool HasSectionsCommand = false;
290   bool ErrorOnMissingSection = false;
291 
292   // List of section patterns specified with KEEP commands. They will
293   // be kept even if they are unused and --gc-sections is specified.
294   std::vector<InputSectionDescription *> KeptSections;
295 
296   // A map from memory region name to a memory region descriptor.
297   llvm::MapVector<llvm::StringRef, MemoryRegion *> MemoryRegions;
298 
299   // A list of symbols referenced by the script.
300   std::vector<llvm::StringRef> ReferencedSymbols;
301 
302   // Used to implement INSERT [AFTER|BEFORE]. Contains commands that need
303   // to be inserted into SECTIONS commands list.
304   llvm::DenseMap<StringRef, std::vector<BaseCommand *>> InsertAfterCommands;
305   llvm::DenseMap<StringRef, std::vector<BaseCommand *>> InsertBeforeCommands;
306 };
307 
308 extern LinkerScript *Script;
309 
310 } // end namespace elf
311 } // end namespace lld
312 
313 #endif // LLD_ELF_LINKER_SCRIPT_H
314