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 
36e0df00b9SRafael Espindola LinkerScript *elf::Script;
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 
67960504b9SRui Ueyama static uint64_t parseExpr(uint64_t Lhs, int MinPrec,
68960504b9SRui Ueyama                           ArrayRef<StringRef> &Tokens, uint64_t Dot);
69960504b9SRui Ueyama 
70960504b9SRui Ueyama // This is a part of the operator-precedence parser to evaluate
71960504b9SRui Ueyama // arithmetic expressions in SECTIONS command. This function evaluates an
72960504b9SRui Ueyama // integer literal, a parenthesized expression or the special variable ".".
73960504b9SRui Ueyama static uint64_t parsePrimary(ArrayRef<StringRef> &Tokens, uint64_t Dot) {
74960504b9SRui Ueyama   StringRef Tok = next(Tokens);
75960504b9SRui Ueyama   if (Tok == ".")
76960504b9SRui Ueyama     return Dot;
77960504b9SRui Ueyama   if (Tok == "(") {
78960504b9SRui Ueyama     uint64_t V = parsePrimary(Tokens, Dot);
79960504b9SRui Ueyama     V = parseExpr(V, 0, Tokens, Dot);
80960504b9SRui Ueyama     if (Tokens.empty()) {
81960504b9SRui Ueyama       error(") expected");
82960504b9SRui Ueyama     } else {
83960504b9SRui Ueyama       Tok = next(Tokens);
84960504b9SRui Ueyama       if (Tok != ")")
85960504b9SRui Ueyama         error(") expected, but got " + Tok);
86960504b9SRui Ueyama     }
87960504b9SRui Ueyama     return V;
88960504b9SRui Ueyama   }
89960504b9SRui Ueyama   return getInteger(Tok);
90960504b9SRui Ueyama }
91960504b9SRui Ueyama 
92960504b9SRui Ueyama static uint64_t apply(StringRef Op, uint64_t L, uint64_t 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     return L * R;
99960504b9SRui Ueyama   if (Op == "/") {
100960504b9SRui Ueyama     if (R == 0) {
101960504b9SRui Ueyama       error("division by zero");
102960504b9SRui Ueyama       return 0;
103960504b9SRui Ueyama     }
104960504b9SRui Ueyama     return L / R;
105960504b9SRui Ueyama   }
106960504b9SRui Ueyama   if (Op == "&")
107960504b9SRui Ueyama     return L & R;
1087a81d674SRui Ueyama   llvm_unreachable("invalid operator");
109652852c5SGeorge Rimar   return 0;
110652852c5SGeorge Rimar }
111652852c5SGeorge Rimar 
112960504b9SRui Ueyama // This is an operator-precedence parser to evaluate
113960504b9SRui Ueyama // arithmetic expressions in SECTIONS command.
114960504b9SRui Ueyama static uint64_t parseExpr(uint64_t Lhs, int MinPrec,
115960504b9SRui Ueyama                           ArrayRef<StringRef> &Tokens, uint64_t Dot) {
116960504b9SRui Ueyama   while (!Tokens.empty()) {
117960504b9SRui Ueyama     // Read an operator and an expression.
118960504b9SRui Ueyama     StringRef Op1 = Tokens.front();
119960504b9SRui Ueyama     if (precedence(Op1) < MinPrec)
120960504b9SRui Ueyama       return Lhs;
121960504b9SRui Ueyama     next(Tokens);
122960504b9SRui Ueyama     uint64_t Rhs = parsePrimary(Tokens, Dot);
123960504b9SRui Ueyama 
124960504b9SRui Ueyama     // Evaluate the remaining part of the expression first if the
125960504b9SRui Ueyama     // next operator has greater precedence than the previous one.
126960504b9SRui Ueyama     // For example, if we have read "+" and "3", and if the next
127960504b9SRui Ueyama     // operator is "*", then we'll evaluate 3 * ... part first.
128960504b9SRui Ueyama     while (!Tokens.empty()) {
129960504b9SRui Ueyama       StringRef Op2 = Tokens.front();
130960504b9SRui Ueyama       if (precedence(Op2) <= precedence(Op1))
131960504b9SRui Ueyama         break;
132960504b9SRui Ueyama       Rhs = parseExpr(Rhs, precedence(Op2), Tokens, Dot);
133652852c5SGeorge Rimar     }
134960504b9SRui Ueyama 
135960504b9SRui Ueyama     Lhs = apply(Op1, Lhs, Rhs);
136960504b9SRui Ueyama   }
137960504b9SRui Ueyama   return Lhs;
138960504b9SRui Ueyama }
139960504b9SRui Ueyama 
140960504b9SRui Ueyama // Evaluates the expression given by list of tokens.
141*0536ec02SRui Ueyama static uint64_t evaluate(ArrayRef<StringRef> Tokens, uint64_t Dot) {
142960504b9SRui Ueyama   uint64_t V = parsePrimary(Tokens, Dot);
143960504b9SRui Ueyama   V = parseExpr(V, 0, Tokens, Dot);
144960504b9SRui Ueyama   if (!Tokens.empty())
145960504b9SRui Ueyama     error("stray token: " + Tokens[0]);
146960504b9SRui Ueyama   return V;
147652852c5SGeorge Rimar }
148652852c5SGeorge Rimar 
1491ebc8ed7SRui Ueyama template <class ELFT>
150481c2ce6SGeorge Rimar SectionRule *LinkerScript::find(InputSectionBase<ELFT> *S) {
1511ebc8ed7SRui Ueyama   for (SectionRule &R : Sections)
1521ebc8ed7SRui Ueyama     if (R.match(S))
153481c2ce6SGeorge Rimar       return &R;
154481c2ce6SGeorge Rimar   return nullptr;
155481c2ce6SGeorge Rimar }
156481c2ce6SGeorge Rimar 
157481c2ce6SGeorge Rimar template <class ELFT>
158481c2ce6SGeorge Rimar StringRef LinkerScript::getOutputSection(InputSectionBase<ELFT> *S) {
159481c2ce6SGeorge Rimar   SectionRule *R = find(S);
160481c2ce6SGeorge Rimar   return R ? R->Dest : "";
161717677afSRui Ueyama }
162717677afSRui Ueyama 
1631ebc8ed7SRui Ueyama template <class ELFT>
1641ebc8ed7SRui Ueyama bool LinkerScript::isDiscarded(InputSectionBase<ELFT> *S) {
1651ebc8ed7SRui Ueyama   return getOutputSection(S) == "/DISCARD/";
166717677afSRui Ueyama }
167717677afSRui Ueyama 
168481c2ce6SGeorge Rimar template <class ELFT> bool LinkerScript::shouldKeep(InputSectionBase<ELFT> *S) {
169481c2ce6SGeorge Rimar   SectionRule *R = find(S);
170481c2ce6SGeorge Rimar   return R && R->Keep;
171481c2ce6SGeorge Rimar }
172481c2ce6SGeorge Rimar 
173652852c5SGeorge Rimar template <class ELFT>
1747c18c28cSRui Ueyama static OutputSectionBase<ELFT> *
1757c18c28cSRui Ueyama findSection(std::vector<OutputSectionBase<ELFT> *> &V, StringRef Name) {
1767c18c28cSRui Ueyama   for (OutputSectionBase<ELFT> *Sec : V)
1777c18c28cSRui Ueyama     if (Sec->getName() == Name)
1787c18c28cSRui Ueyama       return Sec;
1797c18c28cSRui Ueyama   return nullptr;
1807c18c28cSRui Ueyama }
1817c18c28cSRui Ueyama 
1827c18c28cSRui Ueyama template <class ELFT>
1837c18c28cSRui Ueyama void LinkerScript::assignAddresses(
1847c18c28cSRui Ueyama     std::vector<OutputSectionBase<ELFT> *> &Sections) {
1857c18c28cSRui Ueyama   typedef typename ELFT::uint uintX_t;
1867c18c28cSRui Ueyama 
187652852c5SGeorge Rimar   // Orphan sections are sections present in the input files which
1887c18c28cSRui Ueyama   // are not explicitly placed into the output file by the linker script.
1897c18c28cSRui Ueyama   // We place orphan sections at end of file.
1907c18c28cSRui Ueyama   // Other linkers places them using some heuristics as described in
191652852c5SGeorge Rimar   // https://sourceware.org/binutils/docs/ld/Orphan-Sections.html#Orphan-Sections.
1927c18c28cSRui Ueyama   for (OutputSectionBase<ELFT> *Sec : Sections) {
193652852c5SGeorge Rimar     StringRef Name = Sec->getName();
194652852c5SGeorge Rimar     auto I = std::find(SectionOrder.begin(), SectionOrder.end(), Name);
195652852c5SGeorge Rimar     if (I == SectionOrder.end())
1969e957a0aSRui Ueyama       Commands.push_back({SectionKind, {}, Name});
197652852c5SGeorge Rimar   }
198652852c5SGeorge Rimar 
1997c18c28cSRui Ueyama   // Assign addresses as instructed by linker script SECTIONS sub-commands.
200652852c5SGeorge Rimar   uintX_t ThreadBssOffset = 0;
201652852c5SGeorge Rimar   uintX_t VA =
202652852c5SGeorge Rimar       Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize();
203652852c5SGeorge Rimar 
2049e957a0aSRui Ueyama   for (SectionsCommand &Cmd : Commands) {
2059e957a0aSRui Ueyama     if (Cmd.Kind == ExprKind) {
2069e957a0aSRui Ueyama       VA = evaluate(Cmd.Expr, VA);
207652852c5SGeorge Rimar       continue;
208652852c5SGeorge Rimar     }
209652852c5SGeorge Rimar 
2109e957a0aSRui Ueyama     OutputSectionBase<ELFT> *Sec = findSection(Sections, Cmd.SectionName);
2117c18c28cSRui Ueyama     if (!Sec)
212652852c5SGeorge Rimar       continue;
213652852c5SGeorge Rimar 
214652852c5SGeorge Rimar     if ((Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS) {
215652852c5SGeorge Rimar       uintX_t TVA = VA + ThreadBssOffset;
2167c18c28cSRui Ueyama       TVA = alignTo(TVA, Sec->getAlign());
217652852c5SGeorge Rimar       Sec->setVA(TVA);
218652852c5SGeorge Rimar       ThreadBssOffset = TVA - VA + Sec->getSize();
219652852c5SGeorge Rimar       continue;
220652852c5SGeorge Rimar     }
221652852c5SGeorge Rimar 
222652852c5SGeorge Rimar     if (Sec->getFlags() & SHF_ALLOC) {
2237c18c28cSRui Ueyama       VA = alignTo(VA, Sec->getAlign());
224652852c5SGeorge Rimar       Sec->setVA(VA);
225652852c5SGeorge Rimar       VA += Sec->getSize();
226652852c5SGeorge Rimar       continue;
227652852c5SGeorge Rimar     }
228652852c5SGeorge Rimar   }
229652852c5SGeorge Rimar }
230652852c5SGeorge Rimar 
231e2ee72b5SGeorge Rimar ArrayRef<uint8_t> LinkerScript::getFiller(StringRef Name) {
2323e808976SRui Ueyama   auto I = Filler.find(Name);
2333e808976SRui Ueyama   if (I == Filler.end())
234e2ee72b5SGeorge Rimar     return {};
2353e808976SRui Ueyama   return I->second;
236e2ee72b5SGeorge Rimar }
237e2ee72b5SGeorge Rimar 
238e9c58065SRui Ueyama // A compartor to sort output sections. Returns -1 or 1 if both
239e9c58065SRui Ueyama // A and B are mentioned in linker scripts. Otherwise, returns 0
240e9c58065SRui Ueyama // to use the default rule which is implemented in Writer.cpp.
241717677afSRui Ueyama int LinkerScript::compareSections(StringRef A, StringRef B) {
2423e808976SRui Ueyama   auto E = SectionOrder.end();
2433e808976SRui Ueyama   auto I = std::find(SectionOrder.begin(), E, A);
2443e808976SRui Ueyama   auto J = std::find(SectionOrder.begin(), E, B);
2453e808976SRui Ueyama   if (I == E || J == E)
246717677afSRui Ueyama     return 0;
247717677afSRui Ueyama   return I < J ? -1 : 1;
248717677afSRui Ueyama }
249717677afSRui Ueyama 
250cb2aeb66SGeorge Rimar // Returns true if S matches T. S can contain glob meta-characters.
251cb2aeb66SGeorge Rimar // The asterisk ('*') matches zero or more characacters, and the question
252cb2aeb66SGeorge Rimar // mark ('?') matches one character.
2531ebc8ed7SRui Ueyama static bool matchStr(StringRef S, StringRef T) {
2541ebc8ed7SRui Ueyama   for (;;) {
2551ebc8ed7SRui Ueyama     if (S.empty())
2561ebc8ed7SRui Ueyama       return T.empty();
2571ebc8ed7SRui Ueyama     if (S[0] == '*') {
2581ebc8ed7SRui Ueyama       S = S.substr(1);
2591ebc8ed7SRui Ueyama       if (S.empty())
2601ebc8ed7SRui Ueyama         // Fast path. If a pattern is '*', it matches anything.
2611ebc8ed7SRui Ueyama         return true;
2621ebc8ed7SRui Ueyama       for (size_t I = 0, E = T.size(); I < E; ++I)
2631ebc8ed7SRui Ueyama         if (matchStr(S, T.substr(I)))
2641ebc8ed7SRui Ueyama           return true;
2651ebc8ed7SRui Ueyama       return false;
2661ebc8ed7SRui Ueyama     }
267cb2aeb66SGeorge Rimar     if (T.empty() || (S[0] != T[0] && S[0] != '?'))
2681ebc8ed7SRui Ueyama       return false;
2691ebc8ed7SRui Ueyama     S = S.substr(1);
2701ebc8ed7SRui Ueyama     T = T.substr(1);
2711ebc8ed7SRui Ueyama   }
2721ebc8ed7SRui Ueyama }
2731ebc8ed7SRui Ueyama 
2741ebc8ed7SRui Ueyama template <class ELFT> bool SectionRule::match(InputSectionBase<ELFT> *S) {
2751ebc8ed7SRui Ueyama   return matchStr(SectionPattern, S->getSectionName());
2761ebc8ed7SRui Ueyama }
2771ebc8ed7SRui Ueyama 
278e77b5bf6SAdhemerval Zanella class elf::ScriptParser final : public elf::ScriptParserBase {
279c3794e58SGeorge Rimar   typedef void (ScriptParser::*Handler)();
280c3794e58SGeorge Rimar 
281f7c5fbb1SRui Ueyama public:
282717677afSRui Ueyama   ScriptParser(BumpPtrAllocator *A, StringRef S, bool B)
283e77b5bf6SAdhemerval Zanella       : ScriptParserBase(S), Saver(*A), IsUnderSysroot(B) {}
284f23b2320SGeorge Rimar 
285e77b5bf6SAdhemerval Zanella   void run() override;
286f7c5fbb1SRui Ueyama 
287f7c5fbb1SRui Ueyama private:
28852a1509eSRui Ueyama   void addFile(StringRef Path);
28952a1509eSRui Ueyama 
290f7c5fbb1SRui Ueyama   void readAsNeeded();
29190c5099eSDenis Protivensky   void readEntry();
29283f406cfSGeorge Rimar   void readExtern();
293f7c5fbb1SRui Ueyama   void readGroup();
29431aa1f83SRui Ueyama   void readInclude();
295c3794e58SGeorge Rimar   void readNothing() {}
296ee59282bSRui Ueyama   void readOutput();
2979159ce93SDavide Italiano   void readOutputArch();
298f7c5fbb1SRui Ueyama   void readOutputFormat();
29968a39a65SDavide Italiano   void readSearchDir();
3008e3b38abSDenis Protivensky   void readSections();
3018e3b38abSDenis Protivensky 
302652852c5SGeorge Rimar   void readLocationCounterValue();
3038e3b38abSDenis Protivensky   void readOutputSectionDescription();
304481c2ce6SGeorge Rimar   void readSectionPatterns(StringRef OutSec, bool Keep);
305f7c5fbb1SRui Ueyama 
306a47ee68dSRui Ueyama   StringSaver Saver;
307c3794e58SGeorge Rimar   const static StringMap<Handler> Cmd;
30816b0cc9eSSimon Atanasyan   bool IsUnderSysroot;
309f7c5fbb1SRui Ueyama };
310f7c5fbb1SRui Ueyama 
311e0df00b9SRafael Espindola const StringMap<elf::ScriptParser::Handler> elf::ScriptParser::Cmd = {
312c3794e58SGeorge Rimar     {"ENTRY", &ScriptParser::readEntry},
313c3794e58SGeorge Rimar     {"EXTERN", &ScriptParser::readExtern},
314c3794e58SGeorge Rimar     {"GROUP", &ScriptParser::readGroup},
315c3794e58SGeorge Rimar     {"INCLUDE", &ScriptParser::readInclude},
316c3794e58SGeorge Rimar     {"INPUT", &ScriptParser::readGroup},
317c3794e58SGeorge Rimar     {"OUTPUT", &ScriptParser::readOutput},
318c3794e58SGeorge Rimar     {"OUTPUT_ARCH", &ScriptParser::readOutputArch},
319c3794e58SGeorge Rimar     {"OUTPUT_FORMAT", &ScriptParser::readOutputFormat},
320c3794e58SGeorge Rimar     {"SEARCH_DIR", &ScriptParser::readSearchDir},
321c3794e58SGeorge Rimar     {"SECTIONS", &ScriptParser::readSections},
322c3794e58SGeorge Rimar     {";", &ScriptParser::readNothing}};
323c3794e58SGeorge Rimar 
324717677afSRui Ueyama void ScriptParser::run() {
325f7c5fbb1SRui Ueyama   while (!atEOF()) {
326f7c5fbb1SRui Ueyama     StringRef Tok = next();
327c3794e58SGeorge Rimar     if (Handler Fn = Cmd.lookup(Tok))
328c3794e58SGeorge Rimar       (this->*Fn)();
329c3794e58SGeorge Rimar     else
3305761042dSGeorge Rimar       setError("unknown directive: " + Tok);
331f7c5fbb1SRui Ueyama   }
332f7c5fbb1SRui Ueyama }
333f7c5fbb1SRui Ueyama 
334717677afSRui Ueyama void ScriptParser::addFile(StringRef S) {
33516b0cc9eSSimon Atanasyan   if (IsUnderSysroot && S.startswith("/")) {
33616b0cc9eSSimon Atanasyan     SmallString<128> Path;
33716b0cc9eSSimon Atanasyan     (Config->Sysroot + S).toStringRef(Path);
33816b0cc9eSSimon Atanasyan     if (sys::fs::exists(Path)) {
33916b0cc9eSSimon Atanasyan       Driver->addFile(Saver.save(Path.str()));
34016b0cc9eSSimon Atanasyan       return;
34116b0cc9eSSimon Atanasyan     }
34216b0cc9eSSimon Atanasyan   }
34316b0cc9eSSimon Atanasyan 
344f03f3cc1SRui Ueyama   if (sys::path::is_absolute(S)) {
34552a1509eSRui Ueyama     Driver->addFile(S);
34652a1509eSRui Ueyama   } else if (S.startswith("=")) {
34752a1509eSRui Ueyama     if (Config->Sysroot.empty())
34852a1509eSRui Ueyama       Driver->addFile(S.substr(1));
34952a1509eSRui Ueyama     else
35052a1509eSRui Ueyama       Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1)));
35152a1509eSRui Ueyama   } else if (S.startswith("-l")) {
35221eecb4fSRui Ueyama     Driver->addLibrary(S.substr(2));
353a1b8fc3bSSimon Atanasyan   } else if (sys::fs::exists(S)) {
354a1b8fc3bSSimon Atanasyan     Driver->addFile(S);
35552a1509eSRui Ueyama   } else {
35652a1509eSRui Ueyama     std::string Path = findFromSearchPaths(S);
35752a1509eSRui Ueyama     if (Path.empty())
358777f9630SGeorge Rimar       setError("unable to find " + S);
359025d59b1SRui Ueyama     else
36052a1509eSRui Ueyama       Driver->addFile(Saver.save(Path));
36152a1509eSRui Ueyama   }
36252a1509eSRui Ueyama }
36352a1509eSRui Ueyama 
364717677afSRui Ueyama void ScriptParser::readAsNeeded() {
365f7c5fbb1SRui Ueyama   expect("(");
36635da9b6eSRui Ueyama   bool Orig = Config->AsNeeded;
36735da9b6eSRui Ueyama   Config->AsNeeded = true;
368025d59b1SRui Ueyama   while (!Error) {
369f7c5fbb1SRui Ueyama     StringRef Tok = next();
370f7c5fbb1SRui Ueyama     if (Tok == ")")
37135da9b6eSRui Ueyama       break;
37252a1509eSRui Ueyama     addFile(Tok);
373f7c5fbb1SRui Ueyama   }
37435da9b6eSRui Ueyama   Config->AsNeeded = Orig;
375f7c5fbb1SRui Ueyama }
376f7c5fbb1SRui Ueyama 
377717677afSRui Ueyama void ScriptParser::readEntry() {
37890c5099eSDenis Protivensky   // -e <symbol> takes predecence over ENTRY(<symbol>).
37990c5099eSDenis Protivensky   expect("(");
38090c5099eSDenis Protivensky   StringRef Tok = next();
38190c5099eSDenis Protivensky   if (Config->Entry.empty())
38290c5099eSDenis Protivensky     Config->Entry = Tok;
38390c5099eSDenis Protivensky   expect(")");
38490c5099eSDenis Protivensky }
38590c5099eSDenis Protivensky 
386717677afSRui Ueyama void ScriptParser::readExtern() {
38783f406cfSGeorge Rimar   expect("(");
388025d59b1SRui Ueyama   while (!Error) {
38983f406cfSGeorge Rimar     StringRef Tok = next();
39083f406cfSGeorge Rimar     if (Tok == ")")
39183f406cfSGeorge Rimar       return;
39283f406cfSGeorge Rimar     Config->Undefined.push_back(Tok);
39383f406cfSGeorge Rimar   }
39483f406cfSGeorge Rimar }
39583f406cfSGeorge Rimar 
396717677afSRui Ueyama void ScriptParser::readGroup() {
397f7c5fbb1SRui Ueyama   expect("(");
398025d59b1SRui Ueyama   while (!Error) {
399f7c5fbb1SRui Ueyama     StringRef Tok = next();
400f7c5fbb1SRui Ueyama     if (Tok == ")")
401f7c5fbb1SRui Ueyama       return;
402f7c5fbb1SRui Ueyama     if (Tok == "AS_NEEDED") {
403f7c5fbb1SRui Ueyama       readAsNeeded();
404f7c5fbb1SRui Ueyama       continue;
405f7c5fbb1SRui Ueyama     }
40652a1509eSRui Ueyama     addFile(Tok);
407f7c5fbb1SRui Ueyama   }
408f7c5fbb1SRui Ueyama }
409f7c5fbb1SRui Ueyama 
410717677afSRui Ueyama void ScriptParser::readInclude() {
41131aa1f83SRui Ueyama   StringRef Tok = next();
41231aa1f83SRui Ueyama   auto MBOrErr = MemoryBuffer::getFile(Tok);
413025d59b1SRui Ueyama   if (!MBOrErr) {
4145761042dSGeorge Rimar     setError("cannot open " + Tok);
415025d59b1SRui Ueyama     return;
416025d59b1SRui Ueyama   }
41731aa1f83SRui Ueyama   std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
418a47ee68dSRui Ueyama   StringRef S = Saver.save(MB->getMemBufferRef().getBuffer());
419a47ee68dSRui Ueyama   std::vector<StringRef> V = tokenize(S);
42031aa1f83SRui Ueyama   Tokens.insert(Tokens.begin() + Pos, V.begin(), V.end());
42131aa1f83SRui Ueyama }
42231aa1f83SRui Ueyama 
423717677afSRui Ueyama void ScriptParser::readOutput() {
424ee59282bSRui Ueyama   // -o <file> takes predecence over OUTPUT(<file>).
425ee59282bSRui Ueyama   expect("(");
426ee59282bSRui Ueyama   StringRef Tok = next();
427ee59282bSRui Ueyama   if (Config->OutputFile.empty())
428ee59282bSRui Ueyama     Config->OutputFile = Tok;
429ee59282bSRui Ueyama   expect(")");
430ee59282bSRui Ueyama }
431ee59282bSRui Ueyama 
432717677afSRui Ueyama void ScriptParser::readOutputArch() {
4339159ce93SDavide Italiano   // Error checking only for now.
4349159ce93SDavide Italiano   expect("(");
4359159ce93SDavide Italiano   next();
4369159ce93SDavide Italiano   expect(")");
4379159ce93SDavide Italiano }
4389159ce93SDavide Italiano 
439717677afSRui Ueyama void ScriptParser::readOutputFormat() {
440f7c5fbb1SRui Ueyama   // Error checking only for now.
441f7c5fbb1SRui Ueyama   expect("(");
442f7c5fbb1SRui Ueyama   next();
4436836c618SDavide Italiano   StringRef Tok = next();
4446836c618SDavide Italiano   if (Tok == ")")
4456836c618SDavide Italiano    return;
446025d59b1SRui Ueyama   if (Tok != ",") {
4475761042dSGeorge Rimar     setError("unexpected token: " + Tok);
448025d59b1SRui Ueyama     return;
449025d59b1SRui Ueyama   }
4506836c618SDavide Italiano   next();
4516836c618SDavide Italiano   expect(",");
4526836c618SDavide Italiano   next();
453f7c5fbb1SRui Ueyama   expect(")");
454f7c5fbb1SRui Ueyama }
455f7c5fbb1SRui Ueyama 
456717677afSRui Ueyama void ScriptParser::readSearchDir() {
45768a39a65SDavide Italiano   expect("(");
45806501920SRafael Espindola   Config->SearchPaths.push_back(next());
45968a39a65SDavide Italiano   expect(")");
46068a39a65SDavide Italiano }
46168a39a65SDavide Italiano 
462717677afSRui Ueyama void ScriptParser::readSections() {
463652852c5SGeorge Rimar   Script->DoLayout = true;
4648e3b38abSDenis Protivensky   expect("{");
465652852c5SGeorge Rimar   while (!Error && !skip("}")) {
466652852c5SGeorge Rimar     StringRef Tok = peek();
467652852c5SGeorge Rimar     if (Tok == ".")
468652852c5SGeorge Rimar       readLocationCounterValue();
469652852c5SGeorge Rimar     else
4708e3b38abSDenis Protivensky       readOutputSectionDescription();
4718e3b38abSDenis Protivensky   }
472652852c5SGeorge Rimar }
4738e3b38abSDenis Protivensky 
474481c2ce6SGeorge Rimar void ScriptParser::readSectionPatterns(StringRef OutSec, bool Keep) {
475481c2ce6SGeorge Rimar   expect("(");
476481c2ce6SGeorge Rimar   while (!Error && !skip(")"))
477481c2ce6SGeorge Rimar     Script->Sections.emplace_back(OutSec, next(), Keep);
478481c2ce6SGeorge Rimar }
479481c2ce6SGeorge Rimar 
480652852c5SGeorge Rimar void ScriptParser::readLocationCounterValue() {
481652852c5SGeorge Rimar   expect(".");
482652852c5SGeorge Rimar   expect("=");
4839e957a0aSRui Ueyama   Script->Commands.push_back({ExprKind, {}, ""});
4849e957a0aSRui Ueyama   SectionsCommand &Cmd = Script->Commands.back();
485652852c5SGeorge Rimar   while (!Error) {
486652852c5SGeorge Rimar     StringRef Tok = next();
487652852c5SGeorge Rimar     if (Tok == ";")
488652852c5SGeorge Rimar       break;
4899e957a0aSRui Ueyama     Cmd.Expr.push_back(Tok);
490652852c5SGeorge Rimar   }
4919e957a0aSRui Ueyama   if (Cmd.Expr.empty())
492652852c5SGeorge Rimar     error("error in location counter expression");
493652852c5SGeorge Rimar }
494652852c5SGeorge Rimar 
495717677afSRui Ueyama void ScriptParser::readOutputSectionDescription() {
4963e808976SRui Ueyama   StringRef OutSec = next();
4973e808976SRui Ueyama   Script->SectionOrder.push_back(OutSec);
4989e957a0aSRui Ueyama   Script->Commands.push_back({SectionKind, {}, OutSec});
4998e3b38abSDenis Protivensky   expect(":");
5008e3b38abSDenis Protivensky   expect("{");
501025d59b1SRui Ueyama   while (!Error && !skip("}")) {
502481c2ce6SGeorge Rimar     StringRef Tok = next();
503481c2ce6SGeorge Rimar     if (Tok == "*") {
5043e808976SRui Ueyama       readSectionPatterns(OutSec, false);
505481c2ce6SGeorge Rimar     } else if (Tok == "KEEP") {
5068e3b38abSDenis Protivensky       expect("(");
507481c2ce6SGeorge Rimar       next(); // Skip *
5083e808976SRui Ueyama       readSectionPatterns(OutSec, true);
509481c2ce6SGeorge Rimar       expect(")");
510481c2ce6SGeorge Rimar     } else {
511777f9630SGeorge Rimar       setError("unknown command " + Tok);
512481c2ce6SGeorge Rimar     }
5138e3b38abSDenis Protivensky   }
514e2ee72b5SGeorge Rimar   StringRef Tok = peek();
515e2ee72b5SGeorge Rimar   if (Tok.startswith("=")) {
516e2ee72b5SGeorge Rimar     if (!Tok.startswith("=0x")) {
5173ed2f069SRui Ueyama       setError("filler should be a hexadecimal value");
518e2ee72b5SGeorge Rimar       return;
519e2ee72b5SGeorge Rimar     }
5203e808976SRui Ueyama     Tok = Tok.substr(3);
5213e808976SRui Ueyama     Script->Filler[OutSec] = parseHex(Tok);
522e2ee72b5SGeorge Rimar     next();
523e2ee72b5SGeorge Rimar   }
5248e3b38abSDenis Protivensky }
5258e3b38abSDenis Protivensky 
52616b0cc9eSSimon Atanasyan static bool isUnderSysroot(StringRef Path) {
52716b0cc9eSSimon Atanasyan   if (Config->Sysroot == "")
52816b0cc9eSSimon Atanasyan     return false;
52916b0cc9eSSimon Atanasyan   for (; !Path.empty(); Path = sys::path::parent_path(Path))
53016b0cc9eSSimon Atanasyan     if (sys::fs::equivalent(Config->Sysroot, Path))
53116b0cc9eSSimon Atanasyan       return true;
53216b0cc9eSSimon Atanasyan   return false;
53316b0cc9eSSimon Atanasyan }
53416b0cc9eSSimon Atanasyan 
535f7c5fbb1SRui Ueyama // Entry point. The other functions or classes are private to this file.
536f9de0d69SRui Ueyama void LinkerScript::read(MemoryBufferRef MB) {
53716b0cc9eSSimon Atanasyan   StringRef Path = MB.getBufferIdentifier();
538f9de0d69SRui Ueyama   ScriptParser(&Alloc, MB.getBuffer(), isUnderSysroot(Path)).run();
539f7c5fbb1SRui Ueyama }
5401ebc8ed7SRui Ueyama 
5411ebc8ed7SRui Ueyama template StringRef LinkerScript::getOutputSection(InputSectionBase<ELF32LE> *);
5421ebc8ed7SRui Ueyama template StringRef LinkerScript::getOutputSection(InputSectionBase<ELF32BE> *);
5431ebc8ed7SRui Ueyama template StringRef LinkerScript::getOutputSection(InputSectionBase<ELF64LE> *);
5441ebc8ed7SRui Ueyama template StringRef LinkerScript::getOutputSection(InputSectionBase<ELF64BE> *);
5451ebc8ed7SRui Ueyama 
5461ebc8ed7SRui Ueyama template bool LinkerScript::isDiscarded(InputSectionBase<ELF32LE> *);
5471ebc8ed7SRui Ueyama template bool LinkerScript::isDiscarded(InputSectionBase<ELF32BE> *);
5481ebc8ed7SRui Ueyama template bool LinkerScript::isDiscarded(InputSectionBase<ELF64LE> *);
5491ebc8ed7SRui Ueyama template bool LinkerScript::isDiscarded(InputSectionBase<ELF64BE> *);
5501ebc8ed7SRui Ueyama 
551481c2ce6SGeorge Rimar template bool LinkerScript::shouldKeep(InputSectionBase<ELF32LE> *);
552481c2ce6SGeorge Rimar template bool LinkerScript::shouldKeep(InputSectionBase<ELF32BE> *);
553481c2ce6SGeorge Rimar template bool LinkerScript::shouldKeep(InputSectionBase<ELF64LE> *);
554481c2ce6SGeorge Rimar template bool LinkerScript::shouldKeep(InputSectionBase<ELF64BE> *);
555652852c5SGeorge Rimar 
556652852c5SGeorge Rimar template void
557652852c5SGeorge Rimar LinkerScript::assignAddresses(std::vector<OutputSectionBase<ELF32LE> *> &);
558652852c5SGeorge Rimar template void
559652852c5SGeorge Rimar LinkerScript::assignAddresses(std::vector<OutputSectionBase<ELF32BE> *> &);
560652852c5SGeorge Rimar template void
561652852c5SGeorge Rimar LinkerScript::assignAddresses(std::vector<OutputSectionBase<ELF64LE> *> &);
562652852c5SGeorge Rimar template void
563652852c5SGeorge Rimar LinkerScript::assignAddresses(std::vector<OutputSectionBase<ELF64BE> *> &);
564