1f7c5fbb1SRui Ueyama //===- LinkerScript.cpp ---------------------------------------------------===//
2f7c5fbb1SRui Ueyama //
3f7c5fbb1SRui Ueyama //                             The LLVM Linker
4f7c5fbb1SRui Ueyama //
5f7c5fbb1SRui Ueyama // This file is distributed under the University of Illinois Open Source
6f7c5fbb1SRui Ueyama // License. See LICENSE.TXT for details.
7f7c5fbb1SRui Ueyama //
8f7c5fbb1SRui Ueyama //===----------------------------------------------------------------------===//
9f7c5fbb1SRui Ueyama //
10f7c5fbb1SRui Ueyama // This file contains the parser/evaluator of the linker script.
11f7c5fbb1SRui Ueyama // It does not construct an AST but consume linker script directives directly.
1234f29246SRui Ueyama // Results are written to Driver or Config object.
13f7c5fbb1SRui Ueyama //
14f7c5fbb1SRui Ueyama //===----------------------------------------------------------------------===//
15f7c5fbb1SRui Ueyama 
16717677afSRui Ueyama #include "LinkerScript.h"
17f7c5fbb1SRui Ueyama #include "Config.h"
18f7c5fbb1SRui Ueyama #include "Driver.h"
191ebc8ed7SRui Ueyama #include "InputSection.h"
20652852c5SGeorge Rimar #include "OutputSections.h"
21e77b5bf6SAdhemerval Zanella #include "ScriptParser.h"
22f7c5fbb1SRui Ueyama #include "SymbolTable.h"
23960504b9SRui Ueyama #include "llvm/ADT/StringSwitch.h"
24652852c5SGeorge Rimar #include "llvm/Support/ELF.h"
25f7c5fbb1SRui Ueyama #include "llvm/Support/FileSystem.h"
26f7c5fbb1SRui Ueyama #include "llvm/Support/MemoryBuffer.h"
27f03f3cc1SRui Ueyama #include "llvm/Support/Path.h"
28a47ee68dSRui Ueyama #include "llvm/Support/StringSaver.h"
29f7c5fbb1SRui Ueyama 
30f7c5fbb1SRui Ueyama using namespace llvm;
31652852c5SGeorge Rimar using namespace llvm::ELF;
321ebc8ed7SRui Ueyama using namespace llvm::object;
33f7c5fbb1SRui Ueyama using namespace lld;
34e0df00b9SRafael Espindola using namespace lld::elf;
35f7c5fbb1SRui Ueyama 
3607320e40SRui Ueyama ScriptConfiguration *elf::ScriptConfig;
37717677afSRui Ueyama 
38652852c5SGeorge Rimar static uint64_t getInteger(StringRef S) {
39652852c5SGeorge Rimar   uint64_t V;
40652852c5SGeorge Rimar   if (S.getAsInteger(0, V)) {
41652852c5SGeorge Rimar     error("malformed number: " + S);
42652852c5SGeorge Rimar     return 0;
43652852c5SGeorge Rimar   }
44652852c5SGeorge Rimar   return V;
45652852c5SGeorge Rimar }
46652852c5SGeorge Rimar 
47960504b9SRui Ueyama static int precedence(StringRef Op) {
48960504b9SRui Ueyama   return StringSwitch<int>(Op)
49960504b9SRui Ueyama       .Case("*", 4)
50960504b9SRui Ueyama       .Case("/", 3)
51960504b9SRui Ueyama       .Case("+", 2)
52960504b9SRui Ueyama       .Case("-", 2)
53960504b9SRui Ueyama       .Case("&", 1)
54960504b9SRui Ueyama       .Default(-1);
55960504b9SRui Ueyama }
56960504b9SRui Ueyama 
57960504b9SRui Ueyama static StringRef next(ArrayRef<StringRef> &Tokens) {
58960504b9SRui Ueyama   if (Tokens.empty()) {
59960504b9SRui Ueyama     error("no next token");
60960504b9SRui Ueyama     return "";
61960504b9SRui Ueyama   }
62960504b9SRui Ueyama   StringRef Tok = Tokens.front();
63960504b9SRui Ueyama   Tokens = Tokens.slice(1);
64960504b9SRui Ueyama   return Tok;
65960504b9SRui Ueyama }
66960504b9SRui Ueyama 
67*99e519cdSRui Ueyama static uint64_t parseExpr(ArrayRef<StringRef> &Tokens, uint64_t Dot);
68960504b9SRui Ueyama 
69960504b9SRui Ueyama // This is a part of the operator-precedence parser to evaluate
70960504b9SRui Ueyama // arithmetic expressions in SECTIONS command. This function evaluates an
71960504b9SRui Ueyama // integer literal, a parenthesized expression or the special variable ".".
72960504b9SRui Ueyama static uint64_t parsePrimary(ArrayRef<StringRef> &Tokens, uint64_t Dot) {
73960504b9SRui Ueyama   StringRef Tok = next(Tokens);
74960504b9SRui Ueyama   if (Tok == ".")
75960504b9SRui Ueyama     return Dot;
76960504b9SRui Ueyama   if (Tok == "(") {
77*99e519cdSRui Ueyama     uint64_t V = parseExpr(Tokens, Dot);
78960504b9SRui Ueyama     if (Tokens.empty()) {
79960504b9SRui Ueyama       error(") expected");
80960504b9SRui Ueyama     } else {
81960504b9SRui Ueyama       Tok = next(Tokens);
82960504b9SRui Ueyama       if (Tok != ")")
83960504b9SRui Ueyama         error(") expected, but got " + Tok);
84960504b9SRui Ueyama     }
85960504b9SRui Ueyama     return V;
86960504b9SRui Ueyama   }
87960504b9SRui Ueyama   return getInteger(Tok);
88960504b9SRui Ueyama }
89960504b9SRui Ueyama 
90960504b9SRui Ueyama static uint64_t apply(StringRef Op, uint64_t L, uint64_t R) {
91960504b9SRui Ueyama   if (Op == "+")
92960504b9SRui Ueyama     return L + R;
93960504b9SRui Ueyama   if (Op == "-")
94960504b9SRui Ueyama     return L - R;
95960504b9SRui Ueyama   if (Op == "*")
96960504b9SRui Ueyama     return L * R;
97960504b9SRui Ueyama   if (Op == "/") {
98960504b9SRui Ueyama     if (R == 0) {
99960504b9SRui Ueyama       error("division by zero");
100960504b9SRui Ueyama       return 0;
101960504b9SRui Ueyama     }
102960504b9SRui Ueyama     return L / R;
103960504b9SRui Ueyama   }
104960504b9SRui Ueyama   if (Op == "&")
105960504b9SRui Ueyama     return L & R;
1067a81d674SRui Ueyama   llvm_unreachable("invalid operator");
107652852c5SGeorge Rimar   return 0;
108652852c5SGeorge Rimar }
109652852c5SGeorge Rimar 
110960504b9SRui Ueyama // This is an operator-precedence parser to evaluate
111960504b9SRui Ueyama // arithmetic expressions in SECTIONS command.
112*99e519cdSRui Ueyama // Tokens should start with an operator.
113*99e519cdSRui Ueyama static uint64_t parseExpr1(uint64_t Lhs, int MinPrec,
114960504b9SRui Ueyama                            ArrayRef<StringRef> &Tokens, uint64_t Dot) {
115960504b9SRui Ueyama   while (!Tokens.empty()) {
116960504b9SRui Ueyama     // Read an operator and an expression.
117960504b9SRui Ueyama     StringRef Op1 = Tokens.front();
118960504b9SRui Ueyama     if (precedence(Op1) < MinPrec)
119960504b9SRui Ueyama       return Lhs;
120960504b9SRui Ueyama     next(Tokens);
121960504b9SRui Ueyama     uint64_t Rhs = parsePrimary(Tokens, Dot);
122960504b9SRui Ueyama 
123960504b9SRui Ueyama     // Evaluate the remaining part of the expression first if the
124960504b9SRui Ueyama     // next operator has greater precedence than the previous one.
125960504b9SRui Ueyama     // For example, if we have read "+" and "3", and if the next
126960504b9SRui Ueyama     // operator is "*", then we'll evaluate 3 * ... part first.
127960504b9SRui Ueyama     while (!Tokens.empty()) {
128960504b9SRui Ueyama       StringRef Op2 = Tokens.front();
129960504b9SRui Ueyama       if (precedence(Op2) <= precedence(Op1))
130960504b9SRui Ueyama         break;
131*99e519cdSRui Ueyama       Rhs = parseExpr1(Rhs, precedence(Op2), Tokens, Dot);
132652852c5SGeorge Rimar     }
133960504b9SRui Ueyama 
134960504b9SRui Ueyama     Lhs = apply(Op1, Lhs, Rhs);
135960504b9SRui Ueyama   }
136960504b9SRui Ueyama   return Lhs;
137960504b9SRui Ueyama }
138960504b9SRui Ueyama 
139*99e519cdSRui Ueyama static uint64_t parseExpr(ArrayRef<StringRef> &Tokens, uint64_t Dot) {
140*99e519cdSRui Ueyama   uint64_t V = parsePrimary(Tokens, Dot);
141*99e519cdSRui Ueyama   return parseExpr1(V, 0, Tokens, Dot);
142*99e519cdSRui Ueyama }
143*99e519cdSRui Ueyama 
144960504b9SRui Ueyama // Evaluates the expression given by list of tokens.
1450536ec02SRui Ueyama static uint64_t evaluate(ArrayRef<StringRef> Tokens, uint64_t Dot) {
146*99e519cdSRui Ueyama   uint64_t V = parseExpr(Tokens, Dot);
147960504b9SRui Ueyama   if (!Tokens.empty())
148960504b9SRui Ueyama     error("stray token: " + Tokens[0]);
149960504b9SRui Ueyama   return V;
150652852c5SGeorge Rimar }
151652852c5SGeorge Rimar 
1521ebc8ed7SRui Ueyama template <class ELFT>
15307320e40SRui Ueyama SectionRule *LinkerScript<ELFT>::find(InputSectionBase<ELFT> *S) {
15407320e40SRui Ueyama   for (SectionRule &R : Opt.Sections)
1551ebc8ed7SRui Ueyama     if (R.match(S))
156481c2ce6SGeorge Rimar       return &R;
157481c2ce6SGeorge Rimar   return nullptr;
158481c2ce6SGeorge Rimar }
159481c2ce6SGeorge Rimar 
160481c2ce6SGeorge Rimar template <class ELFT>
16107320e40SRui Ueyama StringRef LinkerScript<ELFT>::getOutputSection(InputSectionBase<ELFT> *S) {
162481c2ce6SGeorge Rimar   SectionRule *R = find(S);
163481c2ce6SGeorge Rimar   return R ? R->Dest : "";
164717677afSRui Ueyama }
165717677afSRui Ueyama 
1661ebc8ed7SRui Ueyama template <class ELFT>
16707320e40SRui Ueyama bool LinkerScript<ELFT>::isDiscarded(InputSectionBase<ELFT> *S) {
1681ebc8ed7SRui Ueyama   return getOutputSection(S) == "/DISCARD/";
169717677afSRui Ueyama }
170717677afSRui Ueyama 
17107320e40SRui Ueyama template <class ELFT>
17207320e40SRui Ueyama bool LinkerScript<ELFT>::shouldKeep(InputSectionBase<ELFT> *S) {
173481c2ce6SGeorge Rimar   SectionRule *R = find(S);
174481c2ce6SGeorge Rimar   return R && R->Keep;
175481c2ce6SGeorge Rimar }
176481c2ce6SGeorge Rimar 
177652852c5SGeorge Rimar template <class ELFT>
1787c18c28cSRui Ueyama static OutputSectionBase<ELFT> *
1797c18c28cSRui Ueyama findSection(std::vector<OutputSectionBase<ELFT> *> &V, StringRef Name) {
1807c18c28cSRui Ueyama   for (OutputSectionBase<ELFT> *Sec : V)
1817c18c28cSRui Ueyama     if (Sec->getName() == Name)
1827c18c28cSRui Ueyama       return Sec;
1837c18c28cSRui Ueyama   return nullptr;
1847c18c28cSRui Ueyama }
1857c18c28cSRui Ueyama 
1867c18c28cSRui Ueyama template <class ELFT>
18707320e40SRui Ueyama void LinkerScript<ELFT>::assignAddresses(
1887c18c28cSRui Ueyama     std::vector<OutputSectionBase<ELFT> *> &Sections) {
1897c18c28cSRui Ueyama   typedef typename ELFT::uint uintX_t;
1907c18c28cSRui Ueyama 
191652852c5SGeorge Rimar   // Orphan sections are sections present in the input files which
1927c18c28cSRui Ueyama   // are not explicitly placed into the output file by the linker script.
1937c18c28cSRui Ueyama   // We place orphan sections at end of file.
1947c18c28cSRui Ueyama   // Other linkers places them using some heuristics as described in
195652852c5SGeorge Rimar   // https://sourceware.org/binutils/docs/ld/Orphan-Sections.html#Orphan-Sections.
1967c18c28cSRui Ueyama   for (OutputSectionBase<ELFT> *Sec : Sections) {
197652852c5SGeorge Rimar     StringRef Name = Sec->getName();
19807320e40SRui Ueyama     auto I = std::find(Opt.SectionOrder.begin(), Opt.SectionOrder.end(), Name);
19907320e40SRui Ueyama     if (I == Opt.SectionOrder.end())
20007320e40SRui Ueyama       Opt.Commands.push_back({SectionKind, {}, Name});
201652852c5SGeorge Rimar   }
202652852c5SGeorge Rimar 
2037c18c28cSRui Ueyama   // Assign addresses as instructed by linker script SECTIONS sub-commands.
204652852c5SGeorge Rimar   uintX_t ThreadBssOffset = 0;
205652852c5SGeorge Rimar   uintX_t VA =
206652852c5SGeorge Rimar       Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize();
207652852c5SGeorge Rimar 
20807320e40SRui Ueyama   for (SectionsCommand &Cmd : Opt.Commands) {
2099e957a0aSRui Ueyama     if (Cmd.Kind == ExprKind) {
2109e957a0aSRui Ueyama       VA = evaluate(Cmd.Expr, VA);
211652852c5SGeorge Rimar       continue;
212652852c5SGeorge Rimar     }
213652852c5SGeorge Rimar 
2149e957a0aSRui Ueyama     OutputSectionBase<ELFT> *Sec = findSection(Sections, Cmd.SectionName);
2157c18c28cSRui Ueyama     if (!Sec)
216652852c5SGeorge Rimar       continue;
217652852c5SGeorge Rimar 
218652852c5SGeorge Rimar     if ((Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS) {
219652852c5SGeorge Rimar       uintX_t TVA = VA + ThreadBssOffset;
2207c18c28cSRui Ueyama       TVA = alignTo(TVA, Sec->getAlign());
221652852c5SGeorge Rimar       Sec->setVA(TVA);
222652852c5SGeorge Rimar       ThreadBssOffset = TVA - VA + Sec->getSize();
223652852c5SGeorge Rimar       continue;
224652852c5SGeorge Rimar     }
225652852c5SGeorge Rimar 
226652852c5SGeorge Rimar     if (Sec->getFlags() & SHF_ALLOC) {
2277c18c28cSRui Ueyama       VA = alignTo(VA, Sec->getAlign());
228652852c5SGeorge Rimar       Sec->setVA(VA);
229652852c5SGeorge Rimar       VA += Sec->getSize();
230652852c5SGeorge Rimar       continue;
231652852c5SGeorge Rimar     }
232652852c5SGeorge Rimar   }
233652852c5SGeorge Rimar }
234652852c5SGeorge Rimar 
23507320e40SRui Ueyama template <class ELFT>
23607320e40SRui Ueyama ArrayRef<uint8_t> LinkerScript<ELFT>::getFiller(StringRef Name) {
23707320e40SRui Ueyama   auto I = Opt.Filler.find(Name);
23807320e40SRui Ueyama   if (I == Opt.Filler.end())
239e2ee72b5SGeorge Rimar     return {};
2403e808976SRui Ueyama   return I->second;
241e2ee72b5SGeorge Rimar }
242e2ee72b5SGeorge Rimar 
243e9c58065SRui Ueyama // A compartor to sort output sections. Returns -1 or 1 if both
244e9c58065SRui Ueyama // A and B are mentioned in linker scripts. Otherwise, returns 0
245e9c58065SRui Ueyama // to use the default rule which is implemented in Writer.cpp.
24607320e40SRui Ueyama template <class ELFT>
24707320e40SRui Ueyama int LinkerScript<ELFT>::compareSections(StringRef A, StringRef B) {
24807320e40SRui Ueyama   auto E = Opt.SectionOrder.end();
24907320e40SRui Ueyama   auto I = std::find(Opt.SectionOrder.begin(), E, A);
25007320e40SRui Ueyama   auto J = std::find(Opt.SectionOrder.begin(), E, B);
2513e808976SRui Ueyama   if (I == E || J == E)
252717677afSRui Ueyama     return 0;
253717677afSRui Ueyama   return I < J ? -1 : 1;
254717677afSRui Ueyama }
255717677afSRui Ueyama 
256cb2aeb66SGeorge Rimar // Returns true if S matches T. S can contain glob meta-characters.
257cb2aeb66SGeorge Rimar // The asterisk ('*') matches zero or more characacters, and the question
258cb2aeb66SGeorge Rimar // mark ('?') matches one character.
2591ebc8ed7SRui Ueyama static bool matchStr(StringRef S, StringRef T) {
2601ebc8ed7SRui Ueyama   for (;;) {
2611ebc8ed7SRui Ueyama     if (S.empty())
2621ebc8ed7SRui Ueyama       return T.empty();
2631ebc8ed7SRui Ueyama     if (S[0] == '*') {
2641ebc8ed7SRui Ueyama       S = S.substr(1);
2651ebc8ed7SRui Ueyama       if (S.empty())
2661ebc8ed7SRui Ueyama         // Fast path. If a pattern is '*', it matches anything.
2671ebc8ed7SRui Ueyama         return true;
2681ebc8ed7SRui Ueyama       for (size_t I = 0, E = T.size(); I < E; ++I)
2691ebc8ed7SRui Ueyama         if (matchStr(S, T.substr(I)))
2701ebc8ed7SRui Ueyama           return true;
2711ebc8ed7SRui Ueyama       return false;
2721ebc8ed7SRui Ueyama     }
273cb2aeb66SGeorge Rimar     if (T.empty() || (S[0] != T[0] && S[0] != '?'))
2741ebc8ed7SRui Ueyama       return false;
2751ebc8ed7SRui Ueyama     S = S.substr(1);
2761ebc8ed7SRui Ueyama     T = T.substr(1);
2771ebc8ed7SRui Ueyama   }
2781ebc8ed7SRui Ueyama }
2791ebc8ed7SRui Ueyama 
2801ebc8ed7SRui Ueyama template <class ELFT> bool SectionRule::match(InputSectionBase<ELFT> *S) {
2811ebc8ed7SRui Ueyama   return matchStr(SectionPattern, S->getSectionName());
2821ebc8ed7SRui Ueyama }
2831ebc8ed7SRui Ueyama 
28407320e40SRui Ueyama class elf::ScriptParser : public ScriptParserBase {
285c3794e58SGeorge Rimar   typedef void (ScriptParser::*Handler)();
286c3794e58SGeorge Rimar 
287f7c5fbb1SRui Ueyama public:
28807320e40SRui Ueyama   ScriptParser(StringRef S, bool B) : ScriptParserBase(S), IsUnderSysroot(B) {}
289f23b2320SGeorge Rimar 
290e77b5bf6SAdhemerval Zanella   void run() override;
291f7c5fbb1SRui Ueyama 
292f7c5fbb1SRui Ueyama private:
29352a1509eSRui Ueyama   void addFile(StringRef Path);
29452a1509eSRui Ueyama 
295f7c5fbb1SRui Ueyama   void readAsNeeded();
29690c5099eSDenis Protivensky   void readEntry();
29783f406cfSGeorge Rimar   void readExtern();
298f7c5fbb1SRui Ueyama   void readGroup();
29931aa1f83SRui Ueyama   void readInclude();
300c3794e58SGeorge Rimar   void readNothing() {}
301ee59282bSRui Ueyama   void readOutput();
3029159ce93SDavide Italiano   void readOutputArch();
303f7c5fbb1SRui Ueyama   void readOutputFormat();
30468a39a65SDavide Italiano   void readSearchDir();
3058e3b38abSDenis Protivensky   void readSections();
3068e3b38abSDenis Protivensky 
307652852c5SGeorge Rimar   void readLocationCounterValue();
3088e3b38abSDenis Protivensky   void readOutputSectionDescription();
309481c2ce6SGeorge Rimar   void readSectionPatterns(StringRef OutSec, bool Keep);
310f7c5fbb1SRui Ueyama 
311c3794e58SGeorge Rimar   const static StringMap<Handler> Cmd;
31207320e40SRui Ueyama   ScriptConfiguration &Opt = *ScriptConfig;
31307320e40SRui Ueyama   StringSaver Saver = {ScriptConfig->Alloc};
31416b0cc9eSSimon Atanasyan   bool IsUnderSysroot;
315f7c5fbb1SRui Ueyama };
316f7c5fbb1SRui Ueyama 
317e0df00b9SRafael Espindola const StringMap<elf::ScriptParser::Handler> elf::ScriptParser::Cmd = {
318c3794e58SGeorge Rimar     {"ENTRY", &ScriptParser::readEntry},
319c3794e58SGeorge Rimar     {"EXTERN", &ScriptParser::readExtern},
320c3794e58SGeorge Rimar     {"GROUP", &ScriptParser::readGroup},
321c3794e58SGeorge Rimar     {"INCLUDE", &ScriptParser::readInclude},
322c3794e58SGeorge Rimar     {"INPUT", &ScriptParser::readGroup},
323c3794e58SGeorge Rimar     {"OUTPUT", &ScriptParser::readOutput},
324c3794e58SGeorge Rimar     {"OUTPUT_ARCH", &ScriptParser::readOutputArch},
325c3794e58SGeorge Rimar     {"OUTPUT_FORMAT", &ScriptParser::readOutputFormat},
326c3794e58SGeorge Rimar     {"SEARCH_DIR", &ScriptParser::readSearchDir},
327c3794e58SGeorge Rimar     {"SECTIONS", &ScriptParser::readSections},
328c3794e58SGeorge Rimar     {";", &ScriptParser::readNothing}};
329c3794e58SGeorge Rimar 
330717677afSRui Ueyama void ScriptParser::run() {
331f7c5fbb1SRui Ueyama   while (!atEOF()) {
332f7c5fbb1SRui Ueyama     StringRef Tok = next();
333c3794e58SGeorge Rimar     if (Handler Fn = Cmd.lookup(Tok))
334c3794e58SGeorge Rimar       (this->*Fn)();
335c3794e58SGeorge Rimar     else
3365761042dSGeorge Rimar       setError("unknown directive: " + Tok);
337f7c5fbb1SRui Ueyama   }
338f7c5fbb1SRui Ueyama }
339f7c5fbb1SRui Ueyama 
340717677afSRui Ueyama void ScriptParser::addFile(StringRef S) {
34116b0cc9eSSimon Atanasyan   if (IsUnderSysroot && S.startswith("/")) {
34216b0cc9eSSimon Atanasyan     SmallString<128> Path;
34316b0cc9eSSimon Atanasyan     (Config->Sysroot + S).toStringRef(Path);
34416b0cc9eSSimon Atanasyan     if (sys::fs::exists(Path)) {
34516b0cc9eSSimon Atanasyan       Driver->addFile(Saver.save(Path.str()));
34616b0cc9eSSimon Atanasyan       return;
34716b0cc9eSSimon Atanasyan     }
34816b0cc9eSSimon Atanasyan   }
34916b0cc9eSSimon Atanasyan 
350f03f3cc1SRui Ueyama   if (sys::path::is_absolute(S)) {
35152a1509eSRui Ueyama     Driver->addFile(S);
35252a1509eSRui Ueyama   } else if (S.startswith("=")) {
35352a1509eSRui Ueyama     if (Config->Sysroot.empty())
35452a1509eSRui Ueyama       Driver->addFile(S.substr(1));
35552a1509eSRui Ueyama     else
35652a1509eSRui Ueyama       Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1)));
35752a1509eSRui Ueyama   } else if (S.startswith("-l")) {
35821eecb4fSRui Ueyama     Driver->addLibrary(S.substr(2));
359a1b8fc3bSSimon Atanasyan   } else if (sys::fs::exists(S)) {
360a1b8fc3bSSimon Atanasyan     Driver->addFile(S);
36152a1509eSRui Ueyama   } else {
36252a1509eSRui Ueyama     std::string Path = findFromSearchPaths(S);
36352a1509eSRui Ueyama     if (Path.empty())
364777f9630SGeorge Rimar       setError("unable to find " + S);
365025d59b1SRui Ueyama     else
36652a1509eSRui Ueyama       Driver->addFile(Saver.save(Path));
36752a1509eSRui Ueyama   }
36852a1509eSRui Ueyama }
36952a1509eSRui Ueyama 
370717677afSRui Ueyama void ScriptParser::readAsNeeded() {
371f7c5fbb1SRui Ueyama   expect("(");
37235da9b6eSRui Ueyama   bool Orig = Config->AsNeeded;
37335da9b6eSRui Ueyama   Config->AsNeeded = true;
374025d59b1SRui Ueyama   while (!Error) {
375f7c5fbb1SRui Ueyama     StringRef Tok = next();
376f7c5fbb1SRui Ueyama     if (Tok == ")")
37735da9b6eSRui Ueyama       break;
37852a1509eSRui Ueyama     addFile(Tok);
379f7c5fbb1SRui Ueyama   }
38035da9b6eSRui Ueyama   Config->AsNeeded = Orig;
381f7c5fbb1SRui Ueyama }
382f7c5fbb1SRui Ueyama 
383717677afSRui Ueyama void ScriptParser::readEntry() {
38490c5099eSDenis Protivensky   // -e <symbol> takes predecence over ENTRY(<symbol>).
38590c5099eSDenis Protivensky   expect("(");
38690c5099eSDenis Protivensky   StringRef Tok = next();
38790c5099eSDenis Protivensky   if (Config->Entry.empty())
38890c5099eSDenis Protivensky     Config->Entry = Tok;
38990c5099eSDenis Protivensky   expect(")");
39090c5099eSDenis Protivensky }
39190c5099eSDenis Protivensky 
392717677afSRui Ueyama void ScriptParser::readExtern() {
39383f406cfSGeorge Rimar   expect("(");
394025d59b1SRui Ueyama   while (!Error) {
39583f406cfSGeorge Rimar     StringRef Tok = next();
39683f406cfSGeorge Rimar     if (Tok == ")")
39783f406cfSGeorge Rimar       return;
39883f406cfSGeorge Rimar     Config->Undefined.push_back(Tok);
39983f406cfSGeorge Rimar   }
40083f406cfSGeorge Rimar }
40183f406cfSGeorge Rimar 
402717677afSRui Ueyama void ScriptParser::readGroup() {
403f7c5fbb1SRui Ueyama   expect("(");
404025d59b1SRui Ueyama   while (!Error) {
405f7c5fbb1SRui Ueyama     StringRef Tok = next();
406f7c5fbb1SRui Ueyama     if (Tok == ")")
407f7c5fbb1SRui Ueyama       return;
408f7c5fbb1SRui Ueyama     if (Tok == "AS_NEEDED") {
409f7c5fbb1SRui Ueyama       readAsNeeded();
410f7c5fbb1SRui Ueyama       continue;
411f7c5fbb1SRui Ueyama     }
41252a1509eSRui Ueyama     addFile(Tok);
413f7c5fbb1SRui Ueyama   }
414f7c5fbb1SRui Ueyama }
415f7c5fbb1SRui Ueyama 
416717677afSRui Ueyama void ScriptParser::readInclude() {
41731aa1f83SRui Ueyama   StringRef Tok = next();
41831aa1f83SRui Ueyama   auto MBOrErr = MemoryBuffer::getFile(Tok);
419025d59b1SRui Ueyama   if (!MBOrErr) {
4205761042dSGeorge Rimar     setError("cannot open " + Tok);
421025d59b1SRui Ueyama     return;
422025d59b1SRui Ueyama   }
42331aa1f83SRui Ueyama   std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
424a47ee68dSRui Ueyama   StringRef S = Saver.save(MB->getMemBufferRef().getBuffer());
425a47ee68dSRui Ueyama   std::vector<StringRef> V = tokenize(S);
42631aa1f83SRui Ueyama   Tokens.insert(Tokens.begin() + Pos, V.begin(), V.end());
42731aa1f83SRui Ueyama }
42831aa1f83SRui Ueyama 
429717677afSRui Ueyama void ScriptParser::readOutput() {
430ee59282bSRui Ueyama   // -o <file> takes predecence over OUTPUT(<file>).
431ee59282bSRui Ueyama   expect("(");
432ee59282bSRui Ueyama   StringRef Tok = next();
433ee59282bSRui Ueyama   if (Config->OutputFile.empty())
434ee59282bSRui Ueyama     Config->OutputFile = Tok;
435ee59282bSRui Ueyama   expect(")");
436ee59282bSRui Ueyama }
437ee59282bSRui Ueyama 
438717677afSRui Ueyama void ScriptParser::readOutputArch() {
4399159ce93SDavide Italiano   // Error checking only for now.
4409159ce93SDavide Italiano   expect("(");
4419159ce93SDavide Italiano   next();
4429159ce93SDavide Italiano   expect(")");
4439159ce93SDavide Italiano }
4449159ce93SDavide Italiano 
445717677afSRui Ueyama void ScriptParser::readOutputFormat() {
446f7c5fbb1SRui Ueyama   // Error checking only for now.
447f7c5fbb1SRui Ueyama   expect("(");
448f7c5fbb1SRui Ueyama   next();
4496836c618SDavide Italiano   StringRef Tok = next();
4506836c618SDavide Italiano   if (Tok == ")")
4516836c618SDavide Italiano    return;
452025d59b1SRui Ueyama   if (Tok != ",") {
4535761042dSGeorge Rimar     setError("unexpected token: " + Tok);
454025d59b1SRui Ueyama     return;
455025d59b1SRui Ueyama   }
4566836c618SDavide Italiano   next();
4576836c618SDavide Italiano   expect(",");
4586836c618SDavide Italiano   next();
459f7c5fbb1SRui Ueyama   expect(")");
460f7c5fbb1SRui Ueyama }
461f7c5fbb1SRui Ueyama 
462717677afSRui Ueyama void ScriptParser::readSearchDir() {
46368a39a65SDavide Italiano   expect("(");
46406501920SRafael Espindola   Config->SearchPaths.push_back(next());
46568a39a65SDavide Italiano   expect(")");
46668a39a65SDavide Italiano }
46768a39a65SDavide Italiano 
468717677afSRui Ueyama void ScriptParser::readSections() {
46907320e40SRui Ueyama   Opt.DoLayout = true;
4708e3b38abSDenis Protivensky   expect("{");
471652852c5SGeorge Rimar   while (!Error && !skip("}")) {
472652852c5SGeorge Rimar     StringRef Tok = peek();
473652852c5SGeorge Rimar     if (Tok == ".")
474652852c5SGeorge Rimar       readLocationCounterValue();
475652852c5SGeorge Rimar     else
4768e3b38abSDenis Protivensky       readOutputSectionDescription();
4778e3b38abSDenis Protivensky   }
478652852c5SGeorge Rimar }
4798e3b38abSDenis Protivensky 
480481c2ce6SGeorge Rimar void ScriptParser::readSectionPatterns(StringRef OutSec, bool Keep) {
481481c2ce6SGeorge Rimar   expect("(");
482481c2ce6SGeorge Rimar   while (!Error && !skip(")"))
48307320e40SRui Ueyama     Opt.Sections.emplace_back(OutSec, next(), Keep);
484481c2ce6SGeorge Rimar }
485481c2ce6SGeorge Rimar 
486652852c5SGeorge Rimar void ScriptParser::readLocationCounterValue() {
487652852c5SGeorge Rimar   expect(".");
488652852c5SGeorge Rimar   expect("=");
48907320e40SRui Ueyama   Opt.Commands.push_back({ExprKind, {}, ""});
49007320e40SRui Ueyama   SectionsCommand &Cmd = Opt.Commands.back();
491652852c5SGeorge Rimar   while (!Error) {
492652852c5SGeorge Rimar     StringRef Tok = next();
493652852c5SGeorge Rimar     if (Tok == ";")
494652852c5SGeorge Rimar       break;
4959e957a0aSRui Ueyama     Cmd.Expr.push_back(Tok);
496652852c5SGeorge Rimar   }
4979e957a0aSRui Ueyama   if (Cmd.Expr.empty())
498652852c5SGeorge Rimar     error("error in location counter expression");
499652852c5SGeorge Rimar }
500652852c5SGeorge Rimar 
501717677afSRui Ueyama void ScriptParser::readOutputSectionDescription() {
5023e808976SRui Ueyama   StringRef OutSec = next();
50307320e40SRui Ueyama   Opt.SectionOrder.push_back(OutSec);
50407320e40SRui Ueyama   Opt.Commands.push_back({SectionKind, {}, OutSec});
5058e3b38abSDenis Protivensky   expect(":");
5068e3b38abSDenis Protivensky   expect("{");
507025d59b1SRui Ueyama   while (!Error && !skip("}")) {
508481c2ce6SGeorge Rimar     StringRef Tok = next();
509481c2ce6SGeorge Rimar     if (Tok == "*") {
5103e808976SRui Ueyama       readSectionPatterns(OutSec, false);
511481c2ce6SGeorge Rimar     } else if (Tok == "KEEP") {
5128e3b38abSDenis Protivensky       expect("(");
513481c2ce6SGeorge Rimar       next(); // Skip *
5143e808976SRui Ueyama       readSectionPatterns(OutSec, true);
515481c2ce6SGeorge Rimar       expect(")");
516481c2ce6SGeorge Rimar     } else {
517777f9630SGeorge Rimar       setError("unknown command " + Tok);
518481c2ce6SGeorge Rimar     }
5198e3b38abSDenis Protivensky   }
520e2ee72b5SGeorge Rimar   StringRef Tok = peek();
521e2ee72b5SGeorge Rimar   if (Tok.startswith("=")) {
522e2ee72b5SGeorge Rimar     if (!Tok.startswith("=0x")) {
5233ed2f069SRui Ueyama       setError("filler should be a hexadecimal value");
524e2ee72b5SGeorge Rimar       return;
525e2ee72b5SGeorge Rimar     }
5263e808976SRui Ueyama     Tok = Tok.substr(3);
52707320e40SRui Ueyama     Opt.Filler[OutSec] = parseHex(Tok);
528e2ee72b5SGeorge Rimar     next();
529e2ee72b5SGeorge Rimar   }
5308e3b38abSDenis Protivensky }
5318e3b38abSDenis Protivensky 
53216b0cc9eSSimon Atanasyan static bool isUnderSysroot(StringRef Path) {
53316b0cc9eSSimon Atanasyan   if (Config->Sysroot == "")
53416b0cc9eSSimon Atanasyan     return false;
53516b0cc9eSSimon Atanasyan   for (; !Path.empty(); Path = sys::path::parent_path(Path))
53616b0cc9eSSimon Atanasyan     if (sys::fs::equivalent(Config->Sysroot, Path))
53716b0cc9eSSimon Atanasyan       return true;
53816b0cc9eSSimon Atanasyan   return false;
53916b0cc9eSSimon Atanasyan }
54016b0cc9eSSimon Atanasyan 
54107320e40SRui Ueyama // Entry point.
54207320e40SRui Ueyama void elf::readLinkerScript(MemoryBufferRef MB) {
54316b0cc9eSSimon Atanasyan   StringRef Path = MB.getBufferIdentifier();
54407320e40SRui Ueyama   ScriptParser(MB.getBuffer(), isUnderSysroot(Path)).run();
545f7c5fbb1SRui Ueyama }
5461ebc8ed7SRui Ueyama 
54707320e40SRui Ueyama template class elf::LinkerScript<ELF32LE>;
54807320e40SRui Ueyama template class elf::LinkerScript<ELF32BE>;
54907320e40SRui Ueyama template class elf::LinkerScript<ELF64LE>;
55007320e40SRui Ueyama template class elf::LinkerScript<ELF64BE>;
551