1 //===- LinkerScript.h -------------------------------------------*- C++ -*-===//
2 //
3 //                             The LLVM Linker
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef LLD_ELF_LINKER_SCRIPT_H
11 #define LLD_ELF_LINKER_SCRIPT_H
12 
13 #include "Config.h"
14 #include "Strings.h"
15 #include "Writer.h"
16 #include "lld/Core/LLVM.h"
17 #include "llvm/ADT/DenseMap.h"
18 #include "llvm/ADT/DenseSet.h"
19 #include "llvm/ADT/MapVector.h"
20 #include "llvm/Support/Allocator.h"
21 #include "llvm/Support/MemoryBuffer.h"
22 #include "llvm/Support/Regex.h"
23 #include <functional>
24 
25 namespace lld {
26 namespace elf {
27 class DefinedCommon;
28 class ScriptParser;
29 class SymbolBody;
30 template <class ELFT> class InputSectionBase;
31 template <class ELFT> class InputSection;
32 template <class ELFT> class OutputSectionBase;
33 template <class ELFT> class OutputSectionFactory;
34 class InputSectionData;
35 
36 // This represents an expression in the linker script.
37 // ScriptParser::readExpr reads an expression and returns an Expr.
38 // Later, we evaluate the expression by calling the function
39 // with the value of special context variable ".".
40 typedef std::function<uint64_t(uint64_t)> Expr;
41 
42 // Parses a linker script. Calling this function updates
43 // Config and ScriptConfig.
44 void readLinkerScript(MemoryBufferRef MB);
45 
46 // Parses a version script.
47 void readVersionScript(MemoryBufferRef MB);
48 
49 // This enum is used to implement linker script SECTIONS command.
50 // https://sourceware.org/binutils/docs/ld/SECTIONS.html#SECTIONS
51 enum SectionsCommandKind {
52   AssignmentKind, // . = expr or <sym> = expr
53   OutputSectionKind,
54   InputSectionKind,
55   AssertKind,   // ASSERT(expr)
56   BytesDataKind // BYTE(expr), SHORT(expr), LONG(expr) or QUAD(expr)
57 };
58 
59 struct BaseCommand {
60   BaseCommand(int K) : Kind(K) {}
61   virtual ~BaseCommand() {}
62   int Kind;
63 };
64 
65 // This represents ". = <expr>" or "<symbol> = <expr>".
66 struct SymbolAssignment : BaseCommand {
67   SymbolAssignment(StringRef Name, Expr E, bool IsAbsolute)
68       : BaseCommand(AssignmentKind), Name(Name), Expression(E),
69         IsAbsolute(IsAbsolute) {}
70   static bool classof(const BaseCommand *C);
71 
72   // The LHS of an expression. Name is either a symbol name or ".".
73   StringRef Name;
74   SymbolBody *Sym = nullptr;
75 
76   // The RHS of an expression.
77   Expr Expression;
78 
79   // Command attributes for PROVIDE, HIDDEN and PROVIDE_HIDDEN.
80   bool Provide = false;
81   bool Hidden = false;
82   bool IsAbsolute;
83 };
84 
85 // Linker scripts allow additional constraints to be put on ouput sections.
86 // If an output section is marked as ONLY_IF_RO, the section is created
87 // only if its input sections are read-only. Likewise, an output section
88 // with ONLY_IF_RW is created if all input sections are RW.
89 enum class ConstraintKind { NoConstraint, ReadOnly, ReadWrite };
90 
91 struct OutputSectionCommand : BaseCommand {
92   OutputSectionCommand(StringRef Name)
93       : BaseCommand(OutputSectionKind), Name(Name) {}
94   static bool classof(const BaseCommand *C);
95   StringRef Name;
96   Expr AddrExpr;
97   Expr AlignExpr;
98   Expr LMAExpr;
99   Expr SubalignExpr;
100   std::vector<std::unique_ptr<BaseCommand>> Commands;
101   std::vector<StringRef> Phdrs;
102   std::vector<uint8_t> Filler;
103   ConstraintKind Constraint = ConstraintKind::NoConstraint;
104 };
105 
106 // This struct represents one section match pattern in SECTIONS() command.
107 // It can optionally have negative match pattern for EXCLUDED_FILE command.
108 // Also it may be surrounded with SORT() command, so contains sorting rules.
109 struct SectionPattern {
110   SectionPattern(llvm::Regex &&Re1, llvm::Regex &&Re2)
111       : ExcludedFileRe(std::forward<llvm::Regex>(Re1)),
112         SectionRe(std::forward<llvm::Regex>(Re2)) {}
113 
114   SectionPattern(SectionPattern &&Other) {
115     std::swap(ExcludedFileRe, Other.ExcludedFileRe);
116     std::swap(SectionRe, Other.SectionRe);
117     std::swap(SortOuter, Other.SortOuter);
118     std::swap(SortInner, Other.SortInner);
119   }
120 
121   llvm::Regex ExcludedFileRe;
122   llvm::Regex SectionRe;
123   SortSectionPolicy SortOuter;
124   SortSectionPolicy SortInner;
125 };
126 
127 struct InputSectionDescription : BaseCommand {
128   InputSectionDescription(StringRef FilePattern)
129       : BaseCommand(InputSectionKind),
130         FileRe(compileGlobPatterns({FilePattern})) {}
131   static bool classof(const BaseCommand *C);
132   llvm::Regex FileRe;
133 
134   // Input sections that matches at least one of SectionPatterns
135   // will be associated with this InputSectionDescription.
136   std::vector<SectionPattern> SectionPatterns;
137 
138   std::vector<InputSectionData *> Sections;
139 };
140 
141 // Represents an ASSERT().
142 struct AssertCommand : BaseCommand {
143   AssertCommand(Expr E) : BaseCommand(AssertKind), Expression(E) {}
144   static bool classof(const BaseCommand *C);
145   Expr Expression;
146 };
147 
148 // Represents BYTE(), SHORT(), LONG(), or QUAD().
149 struct BytesDataCommand : BaseCommand {
150   BytesDataCommand(uint64_t Data, unsigned Size)
151       : BaseCommand(BytesDataKind), Data(Data), Size(Size) {}
152   static bool classof(const BaseCommand *C);
153   uint64_t Data;
154   unsigned Offset;
155   unsigned Size;
156 };
157 
158 struct PhdrsCommand {
159   StringRef Name;
160   unsigned Type;
161   bool HasFilehdr;
162   bool HasPhdrs;
163   unsigned Flags;
164   Expr LMAExpr;
165 };
166 
167 class LinkerScriptBase {
168 protected:
169   ~LinkerScriptBase() = default;
170 
171 public:
172   virtual uint64_t getOutputSectionAddress(StringRef Name) = 0;
173   virtual uint64_t getOutputSectionSize(StringRef Name) = 0;
174   virtual uint64_t getOutputSectionAlign(StringRef Name) = 0;
175   virtual uint64_t getOutputSectionLMA(StringRef Name) = 0;
176   virtual uint64_t getHeaderSize() = 0;
177   virtual uint64_t getSymbolValue(StringRef S) = 0;
178   virtual bool isDefined(StringRef S) = 0;
179 };
180 
181 // ScriptConfiguration holds linker script parse results.
182 struct ScriptConfiguration {
183   // Used to assign addresses to sections.
184   std::vector<std::unique_ptr<BaseCommand>> Commands;
185 
186   // Used to assign sections to headers.
187   std::vector<PhdrsCommand> PhdrsCommands;
188 
189   bool HasSections = false;
190 
191   llvm::BumpPtrAllocator Alloc;
192 
193   // List of section patterns specified with KEEP commands. They will
194   // be kept even if they are unused and --gc-sections is specified.
195   std::vector<InputSectionDescription *> KeptSections;
196 };
197 
198 extern ScriptConfiguration *ScriptConfig;
199 
200 // This is a runner of the linker script.
201 template <class ELFT> class LinkerScript final : public LinkerScriptBase {
202   typedef typename ELFT::uint uintX_t;
203 
204 public:
205   LinkerScript();
206   ~LinkerScript();
207   void processCommands(OutputSectionFactory<ELFT> &Factory);
208   void createSections(OutputSectionFactory<ELFT> &Factory);
209   void adjustSectionsBeforeSorting();
210 
211   std::vector<PhdrEntry<ELFT>> createPhdrs();
212   bool ignoreInterpSection();
213 
214   ArrayRef<uint8_t> getFiller(StringRef Name);
215   void writeDataBytes(StringRef Name, uint8_t *Buf);
216   bool hasLMA(StringRef Name);
217   bool shouldKeep(InputSectionBase<ELFT> *S);
218   void assignOffsets(OutputSectionCommand *Cmd);
219   void assignAddresses(std::vector<PhdrEntry<ELFT>> &Phdrs);
220   bool hasPhdrsCommands();
221   uint64_t getOutputSectionAddress(StringRef Name) override;
222   uint64_t getOutputSectionSize(StringRef Name) override;
223   uint64_t getOutputSectionAlign(StringRef Name) override;
224   uint64_t getOutputSectionLMA(StringRef Name) override;
225   uint64_t getHeaderSize() override;
226   uint64_t getSymbolValue(StringRef S) override;
227   bool isDefined(StringRef S) override;
228 
229   std::vector<OutputSectionBase<ELFT> *> *OutputSections;
230 
231   int getSectionIndex(StringRef Name);
232 
233 private:
234   void computeInputSections(InputSectionDescription *);
235 
236   void addSection(OutputSectionFactory<ELFT> &Factory,
237                   InputSectionBase<ELFT> *Sec, StringRef Name);
238   void discard(ArrayRef<InputSectionBase<ELFT> *> V);
239 
240   std::vector<InputSectionBase<ELFT> *>
241   createInputSectionList(OutputSectionCommand &Cmd);
242 
243   // "ScriptConfig" is a bit too long, so define a short name for it.
244   ScriptConfiguration &Opt = *ScriptConfig;
245 
246   std::vector<size_t> getPhdrIndices(StringRef SectionName);
247   size_t getPhdrIndex(StringRef PhdrName);
248 
249   uintX_t Dot;
250   uintX_t LMAOffset = 0;
251   OutputSectionBase<ELFT> *CurOutSec = nullptr;
252   uintX_t ThreadBssOffset = 0;
253   void switchTo(OutputSectionBase<ELFT> *Sec);
254   void flush();
255   void output(InputSection<ELFT> *Sec);
256   void process(BaseCommand &Base);
257   llvm::DenseSet<OutputSectionBase<ELFT> *> AlreadyOutputOS;
258   llvm::DenseSet<InputSectionData *> AlreadyOutputIS;
259 };
260 
261 // Variable template is a C++14 feature, so we can't template
262 // a global variable. Use a struct to workaround.
263 template <class ELFT> struct Script { static LinkerScript<ELFT> *X; };
264 template <class ELFT> LinkerScript<ELFT> *Script<ELFT>::X;
265 
266 extern LinkerScriptBase *ScriptBase;
267 
268 } // namespace elf
269 } // namespace lld
270 
271 #endif
272