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 "Strings.h"
14 #include "Writer.h"
15 #include "lld/Core/LLVM.h"
16 #include "llvm/ADT/DenseMap.h"
17 #include "llvm/ADT/MapVector.h"
18 #include "llvm/Support/Allocator.h"
19 #include "llvm/Support/MemoryBuffer.h"
20 #include "llvm/Support/Regex.h"
21 #include <functional>
22 
23 namespace lld {
24 namespace elf {
25 class DefinedCommon;
26 class ScriptParser;
27 class SymbolBody;
28 template <class ELFT> class InputSectionBase;
29 template <class ELFT> class OutputSectionBase;
30 template <class ELFT> class OutputSectionFactory;
31 class InputSectionData;
32 
33 typedef std::function<uint64_t(uint64_t)> Expr;
34 
35 // Parses a linker script. Calling this function updates
36 // Config and ScriptConfig.
37 void readLinkerScript(MemoryBufferRef MB);
38 
39 void readVersionScript(MemoryBufferRef MB);
40 
41 // This enum is used to implement linker script SECTIONS command.
42 // https://sourceware.org/binutils/docs/ld/SECTIONS.html#SECTIONS
43 enum SectionsCommandKind {
44   AssignmentKind,
45   OutputSectionKind,
46   InputSectionKind,
47   AssertKind
48 };
49 
50 struct BaseCommand {
51   BaseCommand(int K) : Kind(K) {}
52   virtual ~BaseCommand() {}
53   int Kind;
54 };
55 
56 struct SymbolAssignment : BaseCommand {
57   SymbolAssignment(StringRef Name, Expr E, bool IsAbsolute)
58       : BaseCommand(AssignmentKind), Name(Name), Expression(E),
59         IsAbsolute(IsAbsolute) {}
60   static bool classof(const BaseCommand *C);
61 
62   // The LHS of an expression. Name is either a symbol name or ".".
63   StringRef Name;
64   SymbolBody *Sym = nullptr;
65 
66   // The RHS of an expression.
67   Expr Expression;
68 
69   // Command attributes for PROVIDE, HIDDEN and PROVIDE_HIDDEN.
70   bool Provide = false;
71   bool Hidden = false;
72   bool IsAbsolute;
73   InputSectionData *GoesAfter = nullptr;
74 };
75 
76 // Linker scripts allow additional constraints to be put on ouput sections.
77 // An output section will only be created if all of its input sections are
78 // read-only
79 // or all of its input sections are read-write by using the keyword ONLY_IF_RO
80 // and ONLY_IF_RW respectively.
81 enum class ConstraintKind { NoConstraint, ReadOnly, ReadWrite };
82 
83 struct OutputSectionCommand : BaseCommand {
84   OutputSectionCommand(StringRef Name)
85       : BaseCommand(OutputSectionKind), Name(Name) {}
86   static bool classof(const BaseCommand *C);
87   StringRef Name;
88   Expr AddrExpr;
89   Expr AlignExpr;
90   Expr LmaExpr;
91   Expr SubalignExpr;
92   std::vector<std::unique_ptr<BaseCommand>> Commands;
93   std::vector<StringRef> Phdrs;
94   std::vector<uint8_t> Filler;
95   ConstraintKind Constraint = ConstraintKind::NoConstraint;
96 };
97 
98 enum SortKind { SortNone, SortByName, SortByAlignment };
99 
100 struct InputSectionDescription : BaseCommand {
101   InputSectionDescription(StringRef FilePattern)
102       : BaseCommand(InputSectionKind),
103         FileRe(compileGlobPatterns({FilePattern})) {}
104   static bool classof(const BaseCommand *C);
105   llvm::Regex FileRe;
106   SortKind SortOuter = SortNone;
107   SortKind SortInner = SortNone;
108   llvm::Regex ExcludedFileRe;
109   llvm::Regex SectionRe;
110 };
111 
112 struct AssertCommand : BaseCommand {
113   AssertCommand(Expr E) : BaseCommand(AssertKind), Expression(E) {}
114   static bool classof(const BaseCommand *C);
115   Expr Expression;
116 };
117 
118 struct PhdrsCommand {
119   StringRef Name;
120   unsigned Type;
121   bool HasFilehdr;
122   bool HasPhdrs;
123   unsigned Flags;
124   Expr LMAExpr;
125 };
126 
127 class LinkerScriptBase {
128 protected:
129   ~LinkerScriptBase() = default;
130 
131 public:
132   virtual uint64_t getOutputSectionAddress(StringRef Name) = 0;
133   virtual uint64_t getOutputSectionSize(StringRef Name) = 0;
134   virtual uint64_t getOutputSectionAlign(StringRef Name) = 0;
135   virtual uint64_t getHeaderSize() = 0;
136   virtual uint64_t getSymbolValue(StringRef S) = 0;
137 };
138 
139 // ScriptConfiguration holds linker script parse results.
140 struct ScriptConfiguration {
141   // Used to create symbol assignments outside SECTIONS command.
142   std::vector<std::unique_ptr<SymbolAssignment>> Assignments;
143   // Used to assign addresses to sections.
144   std::vector<std::unique_ptr<BaseCommand>> Commands;
145 
146   // Used to assign sections to headers.
147   std::vector<PhdrsCommand> PhdrsCommands;
148 
149   bool HasContents = false;
150 
151   llvm::BumpPtrAllocator Alloc;
152 
153   // List of section patterns specified with KEEP commands. They will
154   // be kept even if they are unused and --gc-sections is specified.
155   std::vector<llvm::Regex *> KeptSections;
156 };
157 
158 extern ScriptConfiguration *ScriptConfig;
159 
160 // This is a runner of the linker script.
161 template <class ELFT> class LinkerScript final : public LinkerScriptBase {
162   typedef typename ELFT::uint uintX_t;
163 
164 public:
165   LinkerScript();
166   ~LinkerScript();
167   void createAssignments();
168   void createSections(OutputSectionFactory<ELFT> &Factory);
169 
170   std::vector<PhdrEntry<ELFT>> createPhdrs();
171   bool ignoreInterpSection();
172 
173   ArrayRef<uint8_t> getFiller(StringRef Name);
174   Expr getLma(StringRef Name);
175   bool shouldKeep(InputSectionBase<ELFT> *S);
176   void assignAddresses();
177   int compareSections(StringRef A, StringRef B);
178   bool hasPhdrsCommands();
179   uint64_t getOutputSectionAddress(StringRef Name) override;
180   uint64_t getOutputSectionSize(StringRef Name) override;
181   uint64_t getOutputSectionAlign(StringRef Name) override;
182   uint64_t getHeaderSize() override;
183   uint64_t getSymbolValue(StringRef S) override;
184 
185   std::vector<OutputSectionBase<ELFT> *> *OutputSections;
186 
187 private:
188   std::vector<InputSectionBase<ELFT> *>
189   getInputSections(const InputSectionDescription *);
190 
191   void discard(OutputSectionCommand &Cmd);
192 
193   std::vector<InputSectionBase<ELFT> *>
194   createInputSectionList(OutputSectionCommand &Cmd);
195 
196   // "ScriptConfig" is a bit too long, so define a short name for it.
197   ScriptConfiguration &Opt = *ScriptConfig;
198 
199   int getSectionIndex(StringRef Name);
200   std::vector<size_t> getPhdrIndices(StringRef SectionName);
201   size_t getPhdrIndex(StringRef PhdrName);
202 
203   uintX_t Dot;
204 };
205 
206 // Variable template is a C++14 feature, so we can't template
207 // a global variable. Use a struct to workaround.
208 template <class ELFT> struct Script { static LinkerScript<ELFT> *X; };
209 template <class ELFT> LinkerScript<ELFT> *Script<ELFT>::X;
210 
211 extern LinkerScriptBase *ScriptBase;
212 
213 } // namespace elf
214 } // namespace lld
215 
216 #endif
217