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.
11629e0aa5SRui Ueyama // It parses a linker script and write the result to Config or ScriptConfig
12629e0aa5SRui Ueyama // objects.
13629e0aa5SRui Ueyama //
14629e0aa5SRui Ueyama // If SECTIONS command is used, a ScriptConfig contains an AST
15629e0aa5SRui Ueyama // of the command which will later be consumed by createSections() and
16629e0aa5SRui Ueyama // assignAddresses().
17f7c5fbb1SRui Ueyama //
18f7c5fbb1SRui Ueyama //===----------------------------------------------------------------------===//
19f7c5fbb1SRui Ueyama 
20717677afSRui Ueyama #include "LinkerScript.h"
21f7c5fbb1SRui Ueyama #include "Config.h"
22f7c5fbb1SRui Ueyama #include "Driver.h"
231ebc8ed7SRui Ueyama #include "InputSection.h"
24652852c5SGeorge Rimar #include "OutputSections.h"
25e77b5bf6SAdhemerval Zanella #include "ScriptParser.h"
2693c9af42SRui Ueyama #include "Strings.h"
27eda81a1bSEugene Leviant #include "Symbols.h"
28f7c5fbb1SRui Ueyama #include "SymbolTable.h"
29467c4d55SEugene Leviant #include "Target.h"
30bbe38602SEugene Leviant #include "Writer.h"
31960504b9SRui Ueyama #include "llvm/ADT/StringSwitch.h"
32652852c5SGeorge Rimar #include "llvm/Support/ELF.h"
33f7c5fbb1SRui Ueyama #include "llvm/Support/FileSystem.h"
34f7c5fbb1SRui Ueyama #include "llvm/Support/MemoryBuffer.h"
35f03f3cc1SRui Ueyama #include "llvm/Support/Path.h"
36a47ee68dSRui Ueyama #include "llvm/Support/StringSaver.h"
37f7c5fbb1SRui Ueyama 
38f7c5fbb1SRui Ueyama using namespace llvm;
39652852c5SGeorge Rimar using namespace llvm::ELF;
401ebc8ed7SRui Ueyama using namespace llvm::object;
41f7c5fbb1SRui Ueyama using namespace lld;
42e0df00b9SRafael Espindola using namespace lld::elf;
43f7c5fbb1SRui Ueyama 
4407320e40SRui Ueyama ScriptConfiguration *elf::ScriptConfig;
45717677afSRui Ueyama 
46076fe157SGeorge Rimar bool SymbolAssignment::classof(const BaseCommand *C) {
47076fe157SGeorge Rimar   return C->Kind == AssignmentKind;
48076fe157SGeorge Rimar }
49076fe157SGeorge Rimar 
50076fe157SGeorge Rimar bool OutputSectionCommand::classof(const BaseCommand *C) {
51076fe157SGeorge Rimar   return C->Kind == OutputSectionKind;
52076fe157SGeorge Rimar }
53076fe157SGeorge Rimar 
54eea3114fSGeorge Rimar bool InputSectionDescription::classof(const BaseCommand *C) {
55eea3114fSGeorge Rimar   return C->Kind == InputSectionKind;
56eea3114fSGeorge Rimar }
57eea3114fSGeorge Rimar 
589c1112d0SRui Ueyama // This is an operator-precedence parser to parse and evaluate
599c1112d0SRui Ueyama // a linker script expression. For each linker script arithmetic
609c1112d0SRui Ueyama // expression (e.g. ". = . + 0x1000"), a new instance of ExprParser
619c1112d0SRui Ueyama // is created and ran.
629c1112d0SRui Ueyama namespace {
639c1112d0SRui Ueyama class ExprParser : public ScriptParserBase {
649c1112d0SRui Ueyama public:
659c1112d0SRui Ueyama   ExprParser(std::vector<StringRef> &Tokens, uint64_t Dot)
669c1112d0SRui Ueyama       : ScriptParserBase(Tokens), Dot(Dot) {}
679c1112d0SRui Ueyama 
689c1112d0SRui Ueyama   uint64_t run();
699c1112d0SRui Ueyama 
709c1112d0SRui Ueyama private:
719c1112d0SRui Ueyama   uint64_t parsePrimary();
729c1112d0SRui Ueyama   uint64_t parseTernary(uint64_t Cond);
739c1112d0SRui Ueyama   uint64_t apply(StringRef Op, uint64_t L, uint64_t R);
749c1112d0SRui Ueyama   uint64_t parseExpr1(uint64_t Lhs, int MinPrec);
759c1112d0SRui Ueyama   uint64_t parseExpr();
769c1112d0SRui Ueyama 
779c1112d0SRui Ueyama   uint64_t Dot;
789c1112d0SRui Ueyama };
799c1112d0SRui Ueyama }
809c1112d0SRui Ueyama 
81960504b9SRui Ueyama static int precedence(StringRef Op) {
82960504b9SRui Ueyama   return StringSwitch<int>(Op)
83960504b9SRui Ueyama       .Case("*", 4)
84ab939066SGeorge Rimar       .Case("/", 4)
85ab939066SGeorge Rimar       .Case("+", 3)
86ab939066SGeorge Rimar       .Case("-", 3)
87ab939066SGeorge Rimar       .Case("<", 2)
88ab939066SGeorge Rimar       .Case(">", 2)
89ab939066SGeorge Rimar       .Case(">=", 2)
90ab939066SGeorge Rimar       .Case("<=", 2)
91ab939066SGeorge Rimar       .Case("==", 2)
92ab939066SGeorge Rimar       .Case("!=", 2)
93960504b9SRui Ueyama       .Case("&", 1)
94960504b9SRui Ueyama       .Default(-1);
95960504b9SRui Ueyama }
96960504b9SRui Ueyama 
979c1112d0SRui Ueyama static uint64_t evalExpr(std::vector<StringRef> &Tokens, uint64_t Dot) {
989c1112d0SRui Ueyama   return ExprParser(Tokens, Dot).run();
99960504b9SRui Ueyama }
100960504b9SRui Ueyama 
1019c1112d0SRui Ueyama uint64_t ExprParser::run() {
1029c1112d0SRui Ueyama   uint64_t V = parseExpr();
1039c1112d0SRui Ueyama   if (!atEOF() && !Error)
1049c1112d0SRui Ueyama     setError("stray token: " + peek());
1059c1112d0SRui Ueyama   return V;
1066011811bSRui Ueyama }
1076011811bSRui Ueyama 
10892e93fb4SGeorge Rimar uint64_t static getConstantValue(StringRef C) {
10992e93fb4SGeorge Rimar   if (C == "COMMONPAGESIZE" || C == "MAXPAGESIZE")
11092e93fb4SGeorge Rimar     return Target->PageSize;
11192e93fb4SGeorge Rimar   error("unknown constant: " + C);
11292e93fb4SGeorge Rimar   return 0;
11392e93fb4SGeorge Rimar }
11492e93fb4SGeorge Rimar 
115960504b9SRui Ueyama // This is a part of the operator-precedence parser to evaluate
116960504b9SRui Ueyama // arithmetic expressions in SECTIONS command. This function evaluates an
117e29a975dSRui Ueyama // integer literal, a parenthesized expression, the ALIGN function,
118e29a975dSRui Ueyama // or the special variable ".".
1199c1112d0SRui Ueyama uint64_t ExprParser::parsePrimary() {
1209c1112d0SRui Ueyama   StringRef Tok = next();
121960504b9SRui Ueyama   if (Tok == ".")
122960504b9SRui Ueyama     return Dot;
123960504b9SRui Ueyama   if (Tok == "(") {
1249c1112d0SRui Ueyama     uint64_t V = parseExpr();
1259c1112d0SRui Ueyama     expect(")");
126960504b9SRui Ueyama     return V;
127960504b9SRui Ueyama   }
128dffc1410SGeorge Rimar   if (Tok == "ALIGN") {
1299c1112d0SRui Ueyama     expect("(");
1309c1112d0SRui Ueyama     uint64_t V = parseExpr();
1319c1112d0SRui Ueyama     expect(")");
132dffc1410SGeorge Rimar     return alignTo(Dot, V);
133dffc1410SGeorge Rimar   }
13492e93fb4SGeorge Rimar   if (Tok == "CONSTANT") {
13592e93fb4SGeorge Rimar     expect("(");
13692e93fb4SGeorge Rimar     uint64_t V = getConstantValue(next());
13792e93fb4SGeorge Rimar     expect(")");
13892e93fb4SGeorge Rimar     return V;
13992e93fb4SGeorge Rimar   }
14092e93fb4SGeorge Rimar   // Documentations says there are two ways to compute
14192e93fb4SGeorge Rimar   // the value of DATA_SEGMENT_ALIGN command, depending on whether the second
14292e93fb4SGeorge Rimar   // uses fewer COMMONPAGESIZE sized pages for the data segment(area between the
14392e93fb4SGeorge Rimar   // result of this expression and `DATA_SEGMENT_END') than the first or not.
14492e93fb4SGeorge Rimar   // That is possible optimization, that we do not support, so we compute that
14592e93fb4SGeorge Rimar   // function always as (ALIGN(MAXPAGESIZE) + (. & (MAXPAGESIZE - 1))) now.
14692e93fb4SGeorge Rimar   if (Tok == "DATA_SEGMENT_ALIGN") {
14792e93fb4SGeorge Rimar     expect("(");
14892e93fb4SGeorge Rimar     uint64_t L = parseExpr();
14992e93fb4SGeorge Rimar     expect(",");
15092e93fb4SGeorge Rimar     parseExpr();
15192e93fb4SGeorge Rimar     expect(")");
15292e93fb4SGeorge Rimar     return alignTo(Dot, L) + (Dot & (L - 1));
15392e93fb4SGeorge Rimar   }
15492e93fb4SGeorge Rimar   // Since we do not support the optimization from comment above,
15592e93fb4SGeorge Rimar   // we can just ignore that command.
15692e93fb4SGeorge Rimar   if (Tok == "DATA_SEGMENT_END") {
15792e93fb4SGeorge Rimar     expect("(");
15892e93fb4SGeorge Rimar     expect(".");
15992e93fb4SGeorge Rimar     expect(")");
16092e93fb4SGeorge Rimar     return Dot;
16192e93fb4SGeorge Rimar   }
1625fa60985SRui Ueyama   uint64_t V = 0;
1635fa60985SRui Ueyama   if (Tok.getAsInteger(0, V))
1649c1112d0SRui Ueyama     setError("malformed number: " + Tok);
1655fa60985SRui Ueyama   return V;
166960504b9SRui Ueyama }
167960504b9SRui Ueyama 
1689c1112d0SRui Ueyama uint64_t ExprParser::parseTernary(uint64_t Cond) {
1699c1112d0SRui Ueyama   next();
1709c1112d0SRui Ueyama   uint64_t V = parseExpr();
1719c1112d0SRui Ueyama   expect(":");
1729c1112d0SRui Ueyama   uint64_t W = parseExpr();
173fba45c41SGeorge Rimar   return Cond ? V : W;
174fba45c41SGeorge Rimar }
175fba45c41SGeorge Rimar 
1769c1112d0SRui Ueyama uint64_t ExprParser::apply(StringRef Op, uint64_t L, uint64_t R) {
177960504b9SRui Ueyama   if (Op == "*")
178960504b9SRui Ueyama     return L * R;
179960504b9SRui Ueyama   if (Op == "/") {
180960504b9SRui Ueyama     if (R == 0) {
181960504b9SRui Ueyama       error("division by zero");
182960504b9SRui Ueyama       return 0;
183960504b9SRui Ueyama     }
184960504b9SRui Ueyama     return L / R;
185960504b9SRui Ueyama   }
186ab939066SGeorge Rimar   if (Op == "+")
187ab939066SGeorge Rimar     return L + R;
188ab939066SGeorge Rimar   if (Op == "-")
189ab939066SGeorge Rimar     return L - R;
190ab939066SGeorge Rimar   if (Op == "<")
191ab939066SGeorge Rimar     return L < R;
192ab939066SGeorge Rimar   if (Op == ">")
193ab939066SGeorge Rimar     return L > R;
194ab939066SGeorge Rimar   if (Op == ">=")
195ab939066SGeorge Rimar     return L >= R;
196ab939066SGeorge Rimar   if (Op == "<=")
197ab939066SGeorge Rimar     return L <= R;
198ab939066SGeorge Rimar   if (Op == "==")
199ab939066SGeorge Rimar     return L == R;
200ab939066SGeorge Rimar   if (Op == "!=")
201ab939066SGeorge Rimar     return L != R;
202960504b9SRui Ueyama   if (Op == "&")
203960504b9SRui Ueyama     return L & R;
2047a81d674SRui Ueyama   llvm_unreachable("invalid operator");
205652852c5SGeorge Rimar }
206652852c5SGeorge Rimar 
2079c1112d0SRui Ueyama // This is a part of the operator-precedence parser.
2089c1112d0SRui Ueyama // This function assumes that the remaining token stream starts
2099c1112d0SRui Ueyama // with an operator.
2109c1112d0SRui Ueyama uint64_t ExprParser::parseExpr1(uint64_t Lhs, int MinPrec) {
2119c1112d0SRui Ueyama   while (!atEOF()) {
212960504b9SRui Ueyama     // Read an operator and an expression.
2139c1112d0SRui Ueyama     StringRef Op1 = peek();
214fba45c41SGeorge Rimar     if (Op1 == "?")
2159c1112d0SRui Ueyama       return parseTernary(Lhs);
216960504b9SRui Ueyama     if (precedence(Op1) < MinPrec)
217960504b9SRui Ueyama       return Lhs;
2189c1112d0SRui Ueyama     next();
2199c1112d0SRui Ueyama     uint64_t Rhs = parsePrimary();
220960504b9SRui Ueyama 
221960504b9SRui Ueyama     // Evaluate the remaining part of the expression first if the
222960504b9SRui Ueyama     // next operator has greater precedence than the previous one.
223960504b9SRui Ueyama     // For example, if we have read "+" and "3", and if the next
224960504b9SRui Ueyama     // operator is "*", then we'll evaluate 3 * ... part first.
2259c1112d0SRui Ueyama     while (!atEOF()) {
2269c1112d0SRui Ueyama       StringRef Op2 = peek();
227960504b9SRui Ueyama       if (precedence(Op2) <= precedence(Op1))
228960504b9SRui Ueyama         break;
2299c1112d0SRui Ueyama       Rhs = parseExpr1(Rhs, precedence(Op2));
230652852c5SGeorge Rimar     }
231960504b9SRui Ueyama 
232960504b9SRui Ueyama     Lhs = apply(Op1, Lhs, Rhs);
233960504b9SRui Ueyama   }
234960504b9SRui Ueyama   return Lhs;
235960504b9SRui Ueyama }
236960504b9SRui Ueyama 
2379c1112d0SRui Ueyama // Reads and evaluates an arithmetic expression.
2389c1112d0SRui Ueyama uint64_t ExprParser::parseExpr() { return parseExpr1(parsePrimary(), 0); }
239652852c5SGeorge Rimar 
24036a153cdSRui Ueyama template <class ELFT> static bool isDiscarded(InputSectionBase<ELFT> *S) {
241eea3114fSGeorge Rimar   return !S || !S->Live;
242717677afSRui Ueyama }
243717677afSRui Ueyama 
24407320e40SRui Ueyama template <class ELFT>
24507320e40SRui Ueyama bool LinkerScript<ELFT>::shouldKeep(InputSectionBase<ELFT> *S) {
2468ec77e64SRui Ueyama   for (StringRef Pat : Opt.KeptSections)
247722830a5SRui Ueyama     if (globMatch(Pat, S->getSectionName()))
2488ec77e64SRui Ueyama       return true;
2498ec77e64SRui Ueyama   return false;
250481c2ce6SGeorge Rimar }
251481c2ce6SGeorge Rimar 
252eea3114fSGeorge Rimar static bool match(StringRef Pattern, ArrayRef<StringRef> Arr) {
253eea3114fSGeorge Rimar   for (StringRef S : Arr)
254eea3114fSGeorge Rimar     if (globMatch(S, Pattern))
255eea3114fSGeorge Rimar       return true;
256eea3114fSGeorge Rimar   return false;
257eea3114fSGeorge Rimar }
258eea3114fSGeorge Rimar 
259652852c5SGeorge Rimar template <class ELFT>
260a7f7884dSRui Ueyama std::vector<OutputSectionBase<ELFT> *>
261e63d81bdSEugene Leviant LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
262eea3114fSGeorge Rimar   typedef const std::unique_ptr<ObjectFile<ELFT>> ObjectFile;
263a7f7884dSRui Ueyama   std::vector<OutputSectionBase<ELFT> *> Result;
264*8a9bb7baSRui Ueyama   DenseSet<OutputSectionBase<ELFT> *> Removed;
265a7f7884dSRui Ueyama 
266e63d81bdSEugene Leviant   // Add input section to output section. If there is no output section yet,
267e63d81bdSEugene Leviant   // then create it and add to output section list.
268*8a9bb7baSRui Ueyama   auto AddInputSec = [&](InputSectionBase<ELFT> *C, StringRef Name,
269*8a9bb7baSRui Ueyama                          ConstraintKind Constraint) {
270e63d81bdSEugene Leviant     OutputSectionBase<ELFT> *Sec;
271e63d81bdSEugene Leviant     bool IsNew;
272e63d81bdSEugene Leviant     std::tie(Sec, IsNew) = Factory.create(C, Name);
273e63d81bdSEugene Leviant     if (IsNew)
274a7f7884dSRui Ueyama       Result.push_back(Sec);
275*8a9bb7baSRui Ueyama     if ((!(C->getSectionHdr()->sh_flags & SHF_WRITE)) &&
276*8a9bb7baSRui Ueyama         Constraint == ReadWrite) {
277*8a9bb7baSRui Ueyama       Removed.insert(Sec);
278*8a9bb7baSRui Ueyama       return;
279*8a9bb7baSRui Ueyama     }
280*8a9bb7baSRui Ueyama     if ((C->getSectionHdr()->sh_flags & SHF_WRITE) && Constraint == ReadOnly) {
281*8a9bb7baSRui Ueyama       Removed.insert(Sec);
282*8a9bb7baSRui Ueyama       return;
283*8a9bb7baSRui Ueyama     }
284e63d81bdSEugene Leviant     Sec->addSection(C);
285e63d81bdSEugene Leviant   };
286e63d81bdSEugene Leviant 
287e63d81bdSEugene Leviant   // Select input sections matching rule and add them to corresponding
288e63d81bdSEugene Leviant   // output section. Section rules are processed in order they're listed
289e63d81bdSEugene Leviant   // in script, so correct input section order is maintained by design.
290eea3114fSGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
291eea3114fSGeorge Rimar     auto *OutCmd = dyn_cast<OutputSectionCommand>(Base.get());
292eea3114fSGeorge Rimar     if (!OutCmd)
293eea3114fSGeorge Rimar       continue;
294eea3114fSGeorge Rimar 
295eea3114fSGeorge Rimar     for (const std::unique_ptr<BaseCommand> &Cmd : OutCmd->Commands) {
296eea3114fSGeorge Rimar       auto *InCmd = dyn_cast<InputSectionDescription>(Cmd.get());
297eea3114fSGeorge Rimar       if (!InCmd)
298eea3114fSGeorge Rimar         continue;
299eea3114fSGeorge Rimar 
300eea3114fSGeorge Rimar       for (ObjectFile &F : Symtab<ELFT>::X->getObjectFiles()) {
301eea3114fSGeorge Rimar         for (InputSectionBase<ELFT> *S : F->getSections()) {
302eea3114fSGeorge Rimar           if (isDiscarded(S) || S->OutSec)
303eea3114fSGeorge Rimar             continue;
304eea3114fSGeorge Rimar 
305eea3114fSGeorge Rimar           if (match(S->getSectionName(), InCmd->Patterns)) {
306eea3114fSGeorge Rimar             if (OutCmd->Name == "/DISCARD/")
307eea3114fSGeorge Rimar               S->Live = false;
308eea3114fSGeorge Rimar             else
309*8a9bb7baSRui Ueyama               AddInputSec(S, OutCmd->Name, OutCmd->Constraint);
310eea3114fSGeorge Rimar           }
311eea3114fSGeorge Rimar         }
312eea3114fSGeorge Rimar       }
313eea3114fSGeorge Rimar     }
314eea3114fSGeorge Rimar   }
315e63d81bdSEugene Leviant 
316e63d81bdSEugene Leviant   // Add all other input sections, which are not listed in script.
317eea3114fSGeorge Rimar   for (ObjectFile &F : Symtab<ELFT>::X->getObjectFiles())
3183c944ec8SReid Kleckner     for (InputSectionBase<ELFT> *S : F->getSections()) {
319e63d81bdSEugene Leviant       if (!isDiscarded(S)) {
320e63d81bdSEugene Leviant         if (!S->OutSec)
321*8a9bb7baSRui Ueyama           AddInputSec(S, getOutputSectionName(S), NoConstraint);
322e63d81bdSEugene Leviant       } else
323e63d81bdSEugene Leviant         reportDiscarded(S, F);
3243c944ec8SReid Kleckner     }
325e63d81bdSEugene Leviant 
326*8a9bb7baSRui Ueyama   // Remove from the output all the sections which did not met the constraints.
327*8a9bb7baSRui Ueyama   Result.erase(std::remove_if(Result.begin(), Result.end(),
328*8a9bb7baSRui Ueyama                               [&](OutputSectionBase<ELFT> *Sec) {
329*8a9bb7baSRui Ueyama                                 return Removed.count(Sec);
330*8a9bb7baSRui Ueyama                               }),
331*8a9bb7baSRui Ueyama                Result.end());
332*8a9bb7baSRui Ueyama   return Result;
333e63d81bdSEugene Leviant }
334e63d81bdSEugene Leviant 
335e63d81bdSEugene Leviant template <class ELFT>
33610e576e1SGeorge Rimar void LinkerScript<ELFT>::dispatchAssignment(SymbolAssignment *Cmd) {
33710e576e1SGeorge Rimar   uint64_t Val = evalExpr(Cmd->Expr, Dot);
33810e576e1SGeorge Rimar   if (Cmd->Name == ".") {
33910e576e1SGeorge Rimar     Dot = Val;
340a31c91b1SEugene Leviant   } else if (!Cmd->Ignore) {
34110e576e1SGeorge Rimar     auto *D = cast<DefinedRegular<ELFT>>(Symtab<ELFT>::X->find(Cmd->Name));
34210e576e1SGeorge Rimar     D->Value = Val;
34310e576e1SGeorge Rimar   }
34410e576e1SGeorge Rimar }
34510e576e1SGeorge Rimar 
34610e576e1SGeorge Rimar template <class ELFT>
34707320e40SRui Ueyama void LinkerScript<ELFT>::assignAddresses(
348dbbd8b15SGeorge Rimar     ArrayRef<OutputSectionBase<ELFT> *> Sections) {
349652852c5SGeorge Rimar   // Orphan sections are sections present in the input files which
3507c18c28cSRui Ueyama   // are not explicitly placed into the output file by the linker script.
3517c18c28cSRui Ueyama   // We place orphan sections at end of file.
3527c18c28cSRui Ueyama   // Other linkers places them using some heuristics as described in
353652852c5SGeorge Rimar   // https://sourceware.org/binutils/docs/ld/Orphan-Sections.html#Orphan-Sections.
3547c18c28cSRui Ueyama   for (OutputSectionBase<ELFT> *Sec : Sections) {
355652852c5SGeorge Rimar     StringRef Name = Sec->getName();
356c3e2a4b0SRui Ueyama     if (getSectionIndex(Name) == INT_MAX)
357076fe157SGeorge Rimar       Opt.Commands.push_back(llvm::make_unique<OutputSectionCommand>(Name));
358652852c5SGeorge Rimar   }
359652852c5SGeorge Rimar 
3607c18c28cSRui Ueyama   // Assign addresses as instructed by linker script SECTIONS sub-commands.
361c998a8c0SRui Ueyama   Dot = Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize();
362467c4d55SEugene Leviant   uintX_t MinVA = std::numeric_limits<uintX_t>::max();
363652852c5SGeorge Rimar   uintX_t ThreadBssOffset = 0;
364652852c5SGeorge Rimar 
365076fe157SGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
366076fe157SGeorge Rimar     if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get())) {
36710e576e1SGeorge Rimar       dispatchAssignment(Cmd);
36805ef4cffSRui Ueyama       continue;
369652852c5SGeorge Rimar     }
370652852c5SGeorge Rimar 
371fb8978fcSDima Stepanov     // Find all the sections with required name. There can be more than
3726ad330acSGeorge Rimar     // one section with such name, if the alignment, flags or type
373fb8978fcSDima Stepanov     // attribute differs.
374076fe157SGeorge Rimar     auto *Cmd = cast<OutputSectionCommand>(Base.get());
375fb8978fcSDima Stepanov     for (OutputSectionBase<ELFT> *Sec : Sections) {
376076fe157SGeorge Rimar       if (Sec->getName() != Cmd->Name)
377652852c5SGeorge Rimar         continue;
378652852c5SGeorge Rimar 
379652852c5SGeorge Rimar       if ((Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS) {
380c998a8c0SRui Ueyama         uintX_t TVA = Dot + ThreadBssOffset;
381424b4081SRui Ueyama         TVA = alignTo(TVA, Sec->getAlignment());
382652852c5SGeorge Rimar         Sec->setVA(TVA);
383c998a8c0SRui Ueyama         ThreadBssOffset = TVA - Dot + Sec->getSize();
384652852c5SGeorge Rimar         continue;
385652852c5SGeorge Rimar       }
386652852c5SGeorge Rimar 
387652852c5SGeorge Rimar       if (Sec->getFlags() & SHF_ALLOC) {
388424b4081SRui Ueyama         Dot = alignTo(Dot, Sec->getAlignment());
389c998a8c0SRui Ueyama         Sec->setVA(Dot);
390467c4d55SEugene Leviant         MinVA = std::min(MinVA, Dot);
391c998a8c0SRui Ueyama         Dot += Sec->getSize();
392652852c5SGeorge Rimar         continue;
393652852c5SGeorge Rimar       }
394652852c5SGeorge Rimar     }
395652852c5SGeorge Rimar   }
396467c4d55SEugene Leviant 
39764c32d6fSRafael Espindola   // ELF and Program headers need to be right before the first section in
398b91e7118SGeorge Rimar   // memory. Set their addresses accordingly.
399467c4d55SEugene Leviant   MinVA = alignDown(MinVA - Out<ELFT>::ElfHeader->getSize() -
400467c4d55SEugene Leviant                         Out<ELFT>::ProgramHeaders->getSize(),
401467c4d55SEugene Leviant                     Target->PageSize);
402467c4d55SEugene Leviant   Out<ELFT>::ElfHeader->setVA(MinVA);
403467c4d55SEugene Leviant   Out<ELFT>::ProgramHeaders->setVA(Out<ELFT>::ElfHeader->getSize() + MinVA);
404fb8978fcSDima Stepanov }
405652852c5SGeorge Rimar 
40607320e40SRui Ueyama template <class ELFT>
40774df5c7eSRafael Espindola std::vector<PhdrEntry<ELFT>>
408bbe38602SEugene Leviant LinkerScript<ELFT>::createPhdrs(ArrayRef<OutputSectionBase<ELFT> *> Sections) {
409bbe38602SEugene Leviant   int TlsNum = -1;
410bbe38602SEugene Leviant   int NoteNum = -1;
411bbe38602SEugene Leviant   int RelroNum = -1;
412adca245fSRui Ueyama   PhdrEntry<ELFT> *Load = nullptr;
413bbe38602SEugene Leviant   uintX_t Flags = PF_R;
414adca245fSRui Ueyama   std::vector<PhdrEntry<ELFT>> Phdrs;
415bbe38602SEugene Leviant 
416bbe38602SEugene Leviant   for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) {
417865bf863SEugene Leviant     Phdrs.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags);
418adca245fSRui Ueyama     PhdrEntry<ELFT> &Phdr = Phdrs.back();
419bbe38602SEugene Leviant 
420bbe38602SEugene Leviant     if (Cmd.HasFilehdr)
421adca245fSRui Ueyama       Phdr.add(Out<ELFT>::ElfHeader);
422bbe38602SEugene Leviant     if (Cmd.HasPhdrs)
423adca245fSRui Ueyama       Phdr.add(Out<ELFT>::ProgramHeaders);
424bbe38602SEugene Leviant 
425bbe38602SEugene Leviant     switch (Cmd.Type) {
426bbe38602SEugene Leviant     case PT_INTERP:
427fd03cfd2SRui Ueyama       if (Out<ELFT>::Interp)
428adca245fSRui Ueyama         Phdr.add(Out<ELFT>::Interp);
429bbe38602SEugene Leviant       break;
430bbe38602SEugene Leviant     case PT_DYNAMIC:
431bbe38602SEugene Leviant       if (isOutputDynamic<ELFT>()) {
432adca245fSRui Ueyama         Phdr.H.p_flags = toPhdrFlags(Out<ELFT>::Dynamic->getFlags());
433adca245fSRui Ueyama         Phdr.add(Out<ELFT>::Dynamic);
434bbe38602SEugene Leviant       }
435bbe38602SEugene Leviant       break;
436bbe38602SEugene Leviant     case PT_TLS:
437bbe38602SEugene Leviant       TlsNum = Phdrs.size() - 1;
438bbe38602SEugene Leviant       break;
439bbe38602SEugene Leviant     case PT_NOTE:
440bbe38602SEugene Leviant       NoteNum = Phdrs.size() - 1;
441bbe38602SEugene Leviant       break;
442bbe38602SEugene Leviant     case PT_GNU_RELRO:
443bbe38602SEugene Leviant       RelroNum = Phdrs.size() - 1;
444bbe38602SEugene Leviant       break;
445bbe38602SEugene Leviant     case PT_GNU_EH_FRAME:
446bbe38602SEugene Leviant       if (!Out<ELFT>::EhFrame->empty() && Out<ELFT>::EhFrameHdr) {
447adca245fSRui Ueyama         Phdr.H.p_flags = toPhdrFlags(Out<ELFT>::EhFrameHdr->getFlags());
448adca245fSRui Ueyama         Phdr.add(Out<ELFT>::EhFrameHdr);
449bbe38602SEugene Leviant       }
450bbe38602SEugene Leviant       break;
451bbe38602SEugene Leviant     }
452bbe38602SEugene Leviant   }
453bbe38602SEugene Leviant 
454bbe38602SEugene Leviant   for (OutputSectionBase<ELFT> *Sec : Sections) {
455bbe38602SEugene Leviant     if (!(Sec->getFlags() & SHF_ALLOC))
456bbe38602SEugene Leviant       break;
457bbe38602SEugene Leviant 
458bbe38602SEugene Leviant     if (TlsNum != -1 && (Sec->getFlags() & SHF_TLS))
45918f084ffSRui Ueyama       Phdrs[TlsNum].add(Sec);
460bbe38602SEugene Leviant 
461bbe38602SEugene Leviant     if (!needsPtLoad<ELFT>(Sec))
462bbe38602SEugene Leviant       continue;
463bbe38602SEugene Leviant 
464bbe38602SEugene Leviant     const std::vector<size_t> &PhdrIds =
465bbe38602SEugene Leviant         getPhdrIndicesForSection(Sec->getName());
466bbe38602SEugene Leviant     if (!PhdrIds.empty()) {
467bbe38602SEugene Leviant       // Assign headers specified by linker script
468bbe38602SEugene Leviant       for (size_t Id : PhdrIds) {
46918f084ffSRui Ueyama         Phdrs[Id].add(Sec);
470865bf863SEugene Leviant         if (Opt.PhdrsCommands[Id].Flags == UINT_MAX)
471865bf863SEugene Leviant           Phdrs[Id].H.p_flags |= toPhdrFlags(Sec->getFlags());
472bbe38602SEugene Leviant       }
473bbe38602SEugene Leviant     } else {
474bbe38602SEugene Leviant       // If we have no load segment or flags've changed then we want new load
475bbe38602SEugene Leviant       // segment.
476bbe38602SEugene Leviant       uintX_t NewFlags = toPhdrFlags(Sec->getFlags());
477bbe38602SEugene Leviant       if (Load == nullptr || Flags != NewFlags) {
478bbe38602SEugene Leviant         Load = &*Phdrs.emplace(Phdrs.end(), PT_LOAD, NewFlags);
479bbe38602SEugene Leviant         Flags = NewFlags;
480bbe38602SEugene Leviant       }
48118f084ffSRui Ueyama       Load->add(Sec);
482bbe38602SEugene Leviant     }
483bbe38602SEugene Leviant 
484bbe38602SEugene Leviant     if (RelroNum != -1 && isRelroSection(Sec))
48518f084ffSRui Ueyama       Phdrs[RelroNum].add(Sec);
486bbe38602SEugene Leviant     if (NoteNum != -1 && Sec->getType() == SHT_NOTE)
48718f084ffSRui Ueyama       Phdrs[NoteNum].add(Sec);
488bbe38602SEugene Leviant   }
489bbe38602SEugene Leviant   return Phdrs;
490bbe38602SEugene Leviant }
491bbe38602SEugene Leviant 
492bbe38602SEugene Leviant template <class ELFT>
49307320e40SRui Ueyama ArrayRef<uint8_t> LinkerScript<ELFT>::getFiller(StringRef Name) {
494f6c3ccefSGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands)
495f6c3ccefSGeorge Rimar     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()))
496f6c3ccefSGeorge Rimar       if (Cmd->Name == Name)
497f6c3ccefSGeorge Rimar         return Cmd->Filler;
498e2ee72b5SGeorge Rimar   return {};
499e2ee72b5SGeorge Rimar }
500e2ee72b5SGeorge Rimar 
501c3e2a4b0SRui Ueyama // Returns the index of the given section name in linker script
502c3e2a4b0SRui Ueyama // SECTIONS commands. Sections are laid out as the same order as they
503c3e2a4b0SRui Ueyama // were in the script. If a given name did not appear in the script,
504c3e2a4b0SRui Ueyama // it returns INT_MAX, so that it will be laid out at end of file.
505076fe157SGeorge Rimar template <class ELFT> int LinkerScript<ELFT>::getSectionIndex(StringRef Name) {
50671b26e94SGeorge Rimar   auto Begin = Opt.Commands.begin();
50771b26e94SGeorge Rimar   auto End = Opt.Commands.end();
508076fe157SGeorge Rimar   auto I =
509076fe157SGeorge Rimar       std::find_if(Begin, End, [&](const std::unique_ptr<BaseCommand> &Base) {
510076fe157SGeorge Rimar         if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()))
511076fe157SGeorge Rimar           if (Cmd->Name == Name)
512076fe157SGeorge Rimar             return true;
513076fe157SGeorge Rimar         return false;
51471b26e94SGeorge Rimar       });
515c3e2a4b0SRui Ueyama   return I == End ? INT_MAX : (I - Begin);
51671b26e94SGeorge Rimar }
51771b26e94SGeorge Rimar 
51871b26e94SGeorge Rimar // A compartor to sort output sections. Returns -1 or 1 if
51971b26e94SGeorge Rimar // A or B are mentioned in linker script. Otherwise, returns 0.
52007320e40SRui Ueyama template <class ELFT>
52107320e40SRui Ueyama int LinkerScript<ELFT>::compareSections(StringRef A, StringRef B) {
522c3e2a4b0SRui Ueyama   int I = getSectionIndex(A);
523c3e2a4b0SRui Ueyama   int J = getSectionIndex(B);
524c3e2a4b0SRui Ueyama   if (I == INT_MAX && J == INT_MAX)
525717677afSRui Ueyama     return 0;
526717677afSRui Ueyama   return I < J ? -1 : 1;
527717677afSRui Ueyama }
528717677afSRui Ueyama 
529076fe157SGeorge Rimar template <class ELFT> void LinkerScript<ELFT>::addScriptedSymbols() {
530a31c91b1SEugene Leviant   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
531a31c91b1SEugene Leviant     auto *Cmd = dyn_cast<SymbolAssignment>(Base.get());
532a31c91b1SEugene Leviant     if (!Cmd || Cmd->Name == ".")
533a31c91b1SEugene Leviant       continue;
534a31c91b1SEugene Leviant 
5358ab4108dSDavide Italiano     SymbolBody *B = Symtab<ELFT>::X->find(Cmd->Name);
5368ab4108dSDavide Italiano     if (!B || B->isUndefined())
537a31c91b1SEugene Leviant       Symtab<ELFT>::X->addAbsolute(Cmd->Name,
538a31c91b1SEugene Leviant                                    Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT);
539a31c91b1SEugene Leviant     else
540a31c91b1SEugene Leviant       // Symbol already exists in symbol table. If it is provided
541a31c91b1SEugene Leviant       // then we can't override its value.
542a31c91b1SEugene Leviant       Cmd->Ignore = Cmd->Provide;
543a31c91b1SEugene Leviant   }
544eda81a1bSEugene Leviant }
545eda81a1bSEugene Leviant 
546bbe38602SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::hasPhdrsCommands() {
547bbe38602SEugene Leviant   return !Opt.PhdrsCommands.empty();
548bbe38602SEugene Leviant }
549bbe38602SEugene Leviant 
550bbe38602SEugene Leviant // Returns indices of ELF headers containing specific section, identified
551bbe38602SEugene Leviant // by Name. Each index is a zero based number of ELF header listed within
552bbe38602SEugene Leviant // PHDRS {} script block.
553bbe38602SEugene Leviant template <class ELFT>
554bbe38602SEugene Leviant std::vector<size_t>
555bbe38602SEugene Leviant LinkerScript<ELFT>::getPhdrIndicesForSection(StringRef Name) {
556076fe157SGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
557076fe157SGeorge Rimar     auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get());
558076fe157SGeorge Rimar     if (!Cmd || Cmd->Name != Name)
55931d842f5SGeorge Rimar       continue;
56031d842f5SGeorge Rimar 
561bbe38602SEugene Leviant     std::vector<size_t> Indices;
562076fe157SGeorge Rimar     for (StringRef PhdrName : Cmd->Phdrs) {
56331d842f5SGeorge Rimar       auto ItPhdr =
56431d842f5SGeorge Rimar           std::find_if(Opt.PhdrsCommands.rbegin(), Opt.PhdrsCommands.rend(),
565076fe157SGeorge Rimar                        [&](PhdrsCommand &P) { return P.Name == PhdrName; });
566bbe38602SEugene Leviant       if (ItPhdr == Opt.PhdrsCommands.rend())
567bbe38602SEugene Leviant         error("section header '" + PhdrName + "' is not listed in PHDRS");
568bbe38602SEugene Leviant       else
569bbe38602SEugene Leviant         Indices.push_back(std::distance(ItPhdr, Opt.PhdrsCommands.rend()) - 1);
570bbe38602SEugene Leviant     }
571bbe38602SEugene Leviant     return Indices;
572bbe38602SEugene Leviant   }
57331d842f5SGeorge Rimar   return {};
57431d842f5SGeorge Rimar }
575bbe38602SEugene Leviant 
57607320e40SRui Ueyama class elf::ScriptParser : public ScriptParserBase {
577c3794e58SGeorge Rimar   typedef void (ScriptParser::*Handler)();
578c3794e58SGeorge Rimar 
579f7c5fbb1SRui Ueyama public:
58007320e40SRui Ueyama   ScriptParser(StringRef S, bool B) : ScriptParserBase(S), IsUnderSysroot(B) {}
581f23b2320SGeorge Rimar 
5824a46539cSRui Ueyama   void run();
583f7c5fbb1SRui Ueyama 
584f7c5fbb1SRui Ueyama private:
58552a1509eSRui Ueyama   void addFile(StringRef Path);
58652a1509eSRui Ueyama 
587f7c5fbb1SRui Ueyama   void readAsNeeded();
58890c5099eSDenis Protivensky   void readEntry();
58983f406cfSGeorge Rimar   void readExtern();
590f7c5fbb1SRui Ueyama   void readGroup();
59131aa1f83SRui Ueyama   void readInclude();
592c3794e58SGeorge Rimar   void readNothing() {}
593ee59282bSRui Ueyama   void readOutput();
5949159ce93SDavide Italiano   void readOutputArch();
595f7c5fbb1SRui Ueyama   void readOutputFormat();
596bbe38602SEugene Leviant   void readPhdrs();
59768a39a65SDavide Italiano   void readSearchDir();
5988e3b38abSDenis Protivensky   void readSections();
5998e3b38abSDenis Protivensky 
600652852c5SGeorge Rimar   void readLocationCounterValue();
601eda81a1bSEugene Leviant   void readOutputSectionDescription(StringRef OutSec);
602bbe38602SEugene Leviant   std::vector<StringRef> readOutputSectionPhdrs();
603bbe38602SEugene Leviant   unsigned readPhdrType();
604a31c91b1SEugene Leviant   void readProvide(bool Hidden);
605a31c91b1SEugene Leviant   SymbolAssignment *readSymbolAssignment(StringRef Name);
606eda81a1bSEugene Leviant   std::vector<StringRef> readSectionsCommandExpr();
607f7c5fbb1SRui Ueyama 
608c3794e58SGeorge Rimar   const static StringMap<Handler> Cmd;
60907320e40SRui Ueyama   ScriptConfiguration &Opt = *ScriptConfig;
61007320e40SRui Ueyama   StringSaver Saver = {ScriptConfig->Alloc};
61116b0cc9eSSimon Atanasyan   bool IsUnderSysroot;
612f7c5fbb1SRui Ueyama };
613f7c5fbb1SRui Ueyama 
614e0df00b9SRafael Espindola const StringMap<elf::ScriptParser::Handler> elf::ScriptParser::Cmd = {
615c3794e58SGeorge Rimar     {"ENTRY", &ScriptParser::readEntry},
616c3794e58SGeorge Rimar     {"EXTERN", &ScriptParser::readExtern},
617c3794e58SGeorge Rimar     {"GROUP", &ScriptParser::readGroup},
618c3794e58SGeorge Rimar     {"INCLUDE", &ScriptParser::readInclude},
619c3794e58SGeorge Rimar     {"INPUT", &ScriptParser::readGroup},
620c3794e58SGeorge Rimar     {"OUTPUT", &ScriptParser::readOutput},
621c3794e58SGeorge Rimar     {"OUTPUT_ARCH", &ScriptParser::readOutputArch},
622c3794e58SGeorge Rimar     {"OUTPUT_FORMAT", &ScriptParser::readOutputFormat},
623bbe38602SEugene Leviant     {"PHDRS", &ScriptParser::readPhdrs},
624c3794e58SGeorge Rimar     {"SEARCH_DIR", &ScriptParser::readSearchDir},
625c3794e58SGeorge Rimar     {"SECTIONS", &ScriptParser::readSections},
626c3794e58SGeorge Rimar     {";", &ScriptParser::readNothing}};
627c3794e58SGeorge Rimar 
628717677afSRui Ueyama void ScriptParser::run() {
629f7c5fbb1SRui Ueyama   while (!atEOF()) {
630f7c5fbb1SRui Ueyama     StringRef Tok = next();
631c3794e58SGeorge Rimar     if (Handler Fn = Cmd.lookup(Tok))
632c3794e58SGeorge Rimar       (this->*Fn)();
633c3794e58SGeorge Rimar     else
6345761042dSGeorge Rimar       setError("unknown directive: " + Tok);
635f7c5fbb1SRui Ueyama   }
636f7c5fbb1SRui Ueyama }
637f7c5fbb1SRui Ueyama 
638717677afSRui Ueyama void ScriptParser::addFile(StringRef S) {
63916b0cc9eSSimon Atanasyan   if (IsUnderSysroot && S.startswith("/")) {
64016b0cc9eSSimon Atanasyan     SmallString<128> Path;
64116b0cc9eSSimon Atanasyan     (Config->Sysroot + S).toStringRef(Path);
64216b0cc9eSSimon Atanasyan     if (sys::fs::exists(Path)) {
64316b0cc9eSSimon Atanasyan       Driver->addFile(Saver.save(Path.str()));
64416b0cc9eSSimon Atanasyan       return;
64516b0cc9eSSimon Atanasyan     }
64616b0cc9eSSimon Atanasyan   }
64716b0cc9eSSimon Atanasyan 
648f03f3cc1SRui Ueyama   if (sys::path::is_absolute(S)) {
64952a1509eSRui Ueyama     Driver->addFile(S);
65052a1509eSRui Ueyama   } else if (S.startswith("=")) {
65152a1509eSRui Ueyama     if (Config->Sysroot.empty())
65252a1509eSRui Ueyama       Driver->addFile(S.substr(1));
65352a1509eSRui Ueyama     else
65452a1509eSRui Ueyama       Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1)));
65552a1509eSRui Ueyama   } else if (S.startswith("-l")) {
65621eecb4fSRui Ueyama     Driver->addLibrary(S.substr(2));
657a1b8fc3bSSimon Atanasyan   } else if (sys::fs::exists(S)) {
658a1b8fc3bSSimon Atanasyan     Driver->addFile(S);
65952a1509eSRui Ueyama   } else {
66052a1509eSRui Ueyama     std::string Path = findFromSearchPaths(S);
66152a1509eSRui Ueyama     if (Path.empty())
662777f9630SGeorge Rimar       setError("unable to find " + S);
663025d59b1SRui Ueyama     else
66452a1509eSRui Ueyama       Driver->addFile(Saver.save(Path));
66552a1509eSRui Ueyama   }
66652a1509eSRui Ueyama }
66752a1509eSRui Ueyama 
668717677afSRui Ueyama void ScriptParser::readAsNeeded() {
669f7c5fbb1SRui Ueyama   expect("(");
67035da9b6eSRui Ueyama   bool Orig = Config->AsNeeded;
67135da9b6eSRui Ueyama   Config->AsNeeded = true;
672025d59b1SRui Ueyama   while (!Error) {
673f7c5fbb1SRui Ueyama     StringRef Tok = next();
674f7c5fbb1SRui Ueyama     if (Tok == ")")
67535da9b6eSRui Ueyama       break;
67652a1509eSRui Ueyama     addFile(Tok);
677f7c5fbb1SRui Ueyama   }
67835da9b6eSRui Ueyama   Config->AsNeeded = Orig;
679f7c5fbb1SRui Ueyama }
680f7c5fbb1SRui Ueyama 
681717677afSRui Ueyama void ScriptParser::readEntry() {
68290c5099eSDenis Protivensky   // -e <symbol> takes predecence over ENTRY(<symbol>).
68390c5099eSDenis Protivensky   expect("(");
68490c5099eSDenis Protivensky   StringRef Tok = next();
68590c5099eSDenis Protivensky   if (Config->Entry.empty())
68690c5099eSDenis Protivensky     Config->Entry = Tok;
68790c5099eSDenis Protivensky   expect(")");
68890c5099eSDenis Protivensky }
68990c5099eSDenis Protivensky 
690717677afSRui Ueyama void ScriptParser::readExtern() {
69183f406cfSGeorge Rimar   expect("(");
692025d59b1SRui Ueyama   while (!Error) {
69383f406cfSGeorge Rimar     StringRef Tok = next();
69483f406cfSGeorge Rimar     if (Tok == ")")
69583f406cfSGeorge Rimar       return;
69683f406cfSGeorge Rimar     Config->Undefined.push_back(Tok);
69783f406cfSGeorge Rimar   }
69883f406cfSGeorge Rimar }
69983f406cfSGeorge Rimar 
700717677afSRui Ueyama void ScriptParser::readGroup() {
701f7c5fbb1SRui Ueyama   expect("(");
702025d59b1SRui Ueyama   while (!Error) {
703f7c5fbb1SRui Ueyama     StringRef Tok = next();
704f7c5fbb1SRui Ueyama     if (Tok == ")")
705f7c5fbb1SRui Ueyama       return;
706f7c5fbb1SRui Ueyama     if (Tok == "AS_NEEDED") {
707f7c5fbb1SRui Ueyama       readAsNeeded();
708f7c5fbb1SRui Ueyama       continue;
709f7c5fbb1SRui Ueyama     }
71052a1509eSRui Ueyama     addFile(Tok);
711f7c5fbb1SRui Ueyama   }
712f7c5fbb1SRui Ueyama }
713f7c5fbb1SRui Ueyama 
714717677afSRui Ueyama void ScriptParser::readInclude() {
71531aa1f83SRui Ueyama   StringRef Tok = next();
71631aa1f83SRui Ueyama   auto MBOrErr = MemoryBuffer::getFile(Tok);
717025d59b1SRui Ueyama   if (!MBOrErr) {
7185761042dSGeorge Rimar     setError("cannot open " + Tok);
719025d59b1SRui Ueyama     return;
720025d59b1SRui Ueyama   }
72131aa1f83SRui Ueyama   std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
722a47ee68dSRui Ueyama   StringRef S = Saver.save(MB->getMemBufferRef().getBuffer());
723a47ee68dSRui Ueyama   std::vector<StringRef> V = tokenize(S);
72431aa1f83SRui Ueyama   Tokens.insert(Tokens.begin() + Pos, V.begin(), V.end());
72531aa1f83SRui Ueyama }
72631aa1f83SRui Ueyama 
727717677afSRui Ueyama void ScriptParser::readOutput() {
728ee59282bSRui Ueyama   // -o <file> takes predecence over OUTPUT(<file>).
729ee59282bSRui Ueyama   expect("(");
730ee59282bSRui Ueyama   StringRef Tok = next();
731ee59282bSRui Ueyama   if (Config->OutputFile.empty())
732ee59282bSRui Ueyama     Config->OutputFile = Tok;
733ee59282bSRui Ueyama   expect(")");
734ee59282bSRui Ueyama }
735ee59282bSRui Ueyama 
736717677afSRui Ueyama void ScriptParser::readOutputArch() {
7379159ce93SDavide Italiano   // Error checking only for now.
7389159ce93SDavide Italiano   expect("(");
7399159ce93SDavide Italiano   next();
7409159ce93SDavide Italiano   expect(")");
7419159ce93SDavide Italiano }
7429159ce93SDavide Italiano 
743717677afSRui Ueyama void ScriptParser::readOutputFormat() {
744f7c5fbb1SRui Ueyama   // Error checking only for now.
745f7c5fbb1SRui Ueyama   expect("(");
746f7c5fbb1SRui Ueyama   next();
7476836c618SDavide Italiano   StringRef Tok = next();
7486836c618SDavide Italiano   if (Tok == ")")
7496836c618SDavide Italiano    return;
750025d59b1SRui Ueyama   if (Tok != ",") {
7515761042dSGeorge Rimar     setError("unexpected token: " + Tok);
752025d59b1SRui Ueyama     return;
753025d59b1SRui Ueyama   }
7546836c618SDavide Italiano   next();
7556836c618SDavide Italiano   expect(",");
7566836c618SDavide Italiano   next();
757f7c5fbb1SRui Ueyama   expect(")");
758f7c5fbb1SRui Ueyama }
759f7c5fbb1SRui Ueyama 
760bbe38602SEugene Leviant void ScriptParser::readPhdrs() {
761bbe38602SEugene Leviant   expect("{");
762bbe38602SEugene Leviant   while (!Error && !skip("}")) {
763bbe38602SEugene Leviant     StringRef Tok = next();
764865bf863SEugene Leviant     Opt.PhdrsCommands.push_back({Tok, PT_NULL, false, false, UINT_MAX});
765bbe38602SEugene Leviant     PhdrsCommand &PhdrCmd = Opt.PhdrsCommands.back();
766bbe38602SEugene Leviant 
767bbe38602SEugene Leviant     PhdrCmd.Type = readPhdrType();
768bbe38602SEugene Leviant     do {
769bbe38602SEugene Leviant       Tok = next();
770bbe38602SEugene Leviant       if (Tok == ";")
771bbe38602SEugene Leviant         break;
772bbe38602SEugene Leviant       if (Tok == "FILEHDR")
773bbe38602SEugene Leviant         PhdrCmd.HasFilehdr = true;
774bbe38602SEugene Leviant       else if (Tok == "PHDRS")
775bbe38602SEugene Leviant         PhdrCmd.HasPhdrs = true;
776865bf863SEugene Leviant       else if (Tok == "FLAGS") {
777865bf863SEugene Leviant         expect("(");
778865bf863SEugene Leviant         next().getAsInteger(0, PhdrCmd.Flags);
779865bf863SEugene Leviant         expect(")");
780865bf863SEugene Leviant       } else
781bbe38602SEugene Leviant         setError("unexpected header attribute: " + Tok);
782bbe38602SEugene Leviant     } while (!Error);
783bbe38602SEugene Leviant   }
784bbe38602SEugene Leviant }
785bbe38602SEugene Leviant 
786717677afSRui Ueyama void ScriptParser::readSearchDir() {
78768a39a65SDavide Italiano   expect("(");
78806501920SRafael Espindola   Config->SearchPaths.push_back(next());
78968a39a65SDavide Italiano   expect(")");
79068a39a65SDavide Italiano }
79168a39a65SDavide Italiano 
792717677afSRui Ueyama void ScriptParser::readSections() {
79307320e40SRui Ueyama   Opt.DoLayout = true;
7948e3b38abSDenis Protivensky   expect("{");
795652852c5SGeorge Rimar   while (!Error && !skip("}")) {
796652852c5SGeorge Rimar     StringRef Tok = peek();
797eda81a1bSEugene Leviant     if (Tok == ".") {
798652852c5SGeorge Rimar       readLocationCounterValue();
799eda81a1bSEugene Leviant       continue;
800eda81a1bSEugene Leviant     }
801eda81a1bSEugene Leviant     next();
802a31c91b1SEugene Leviant     if (Tok == "PROVIDE")
803a31c91b1SEugene Leviant       readProvide(false);
804a31c91b1SEugene Leviant     else if (Tok == "PROVIDE_HIDDEN")
805a31c91b1SEugene Leviant       readProvide(true);
806a31c91b1SEugene Leviant     else if (peek() == "=")
807eda81a1bSEugene Leviant       readSymbolAssignment(Tok);
808652852c5SGeorge Rimar     else
809eda81a1bSEugene Leviant       readOutputSectionDescription(Tok);
8108e3b38abSDenis Protivensky   }
811652852c5SGeorge Rimar }
8128e3b38abSDenis Protivensky 
813652852c5SGeorge Rimar void ScriptParser::readLocationCounterValue() {
814652852c5SGeorge Rimar   expect(".");
815652852c5SGeorge Rimar   expect("=");
816eda81a1bSEugene Leviant   std::vector<StringRef> Expr = readSectionsCommandExpr();
817eda81a1bSEugene Leviant   if (Expr.empty())
818652852c5SGeorge Rimar     error("error in location counter expression");
819eda81a1bSEugene Leviant   else
820076fe157SGeorge Rimar     Opt.Commands.push_back(llvm::make_unique<SymbolAssignment>(".", Expr));
821652852c5SGeorge Rimar }
822652852c5SGeorge Rimar 
823eda81a1bSEugene Leviant void ScriptParser::readOutputSectionDescription(StringRef OutSec) {
824076fe157SGeorge Rimar   OutputSectionCommand *Cmd = new OutputSectionCommand(OutSec);
825076fe157SGeorge Rimar   Opt.Commands.emplace_back(Cmd);
8268e3b38abSDenis Protivensky   expect(":");
827246f681eSDavide Italiano 
828246f681eSDavide Italiano   // Parse constraints.
829246f681eSDavide Italiano   if (skip("ONLY_IF_RO"))
830246f681eSDavide Italiano     Cmd->Constraint = ReadOnly;
831246f681eSDavide Italiano   if (skip("ONLY_IF_RW"))
832246f681eSDavide Italiano     Cmd->Constraint = ReadWrite;
8338e3b38abSDenis Protivensky   expect("{");
8348ec77e64SRui Ueyama 
835025d59b1SRui Ueyama   while (!Error && !skip("}")) {
836481c2ce6SGeorge Rimar     StringRef Tok = next();
837481c2ce6SGeorge Rimar     if (Tok == "*") {
838eea3114fSGeorge Rimar       auto *InCmd = new InputSectionDescription();
839eea3114fSGeorge Rimar       Cmd->Commands.emplace_back(InCmd);
8408ec77e64SRui Ueyama       expect("(");
8418ec77e64SRui Ueyama       while (!Error && !skip(")"))
842eea3114fSGeorge Rimar         InCmd->Patterns.push_back(next());
843481c2ce6SGeorge Rimar     } else if (Tok == "KEEP") {
8448e3b38abSDenis Protivensky       expect("(");
8458ec77e64SRui Ueyama       expect("*");
8468ec77e64SRui Ueyama       expect("(");
847eea3114fSGeorge Rimar       auto *InCmd = new InputSectionDescription();
848eea3114fSGeorge Rimar       Cmd->Commands.emplace_back(InCmd);
8498ec77e64SRui Ueyama       while (!Error && !skip(")")) {
850eea3114fSGeorge Rimar         Opt.KeptSections.push_back(peek());
851eea3114fSGeorge Rimar         InCmd->Patterns.push_back(next());
8528ec77e64SRui Ueyama       }
853481c2ce6SGeorge Rimar       expect(")");
854481c2ce6SGeorge Rimar     } else {
855777f9630SGeorge Rimar       setError("unknown command " + Tok);
856481c2ce6SGeorge Rimar     }
8578e3b38abSDenis Protivensky   }
858076fe157SGeorge Rimar   Cmd->Phdrs = readOutputSectionPhdrs();
8598ec77e64SRui Ueyama 
860e2ee72b5SGeorge Rimar   StringRef Tok = peek();
861e2ee72b5SGeorge Rimar   if (Tok.startswith("=")) {
862e2ee72b5SGeorge Rimar     if (!Tok.startswith("=0x")) {
8633ed2f069SRui Ueyama       setError("filler should be a hexadecimal value");
864e2ee72b5SGeorge Rimar       return;
865e2ee72b5SGeorge Rimar     }
8663e808976SRui Ueyama     Tok = Tok.substr(3);
867f6c3ccefSGeorge Rimar     Cmd->Filler = parseHex(Tok);
868e2ee72b5SGeorge Rimar     next();
869e2ee72b5SGeorge Rimar   }
8708e3b38abSDenis Protivensky }
8718e3b38abSDenis Protivensky 
872a31c91b1SEugene Leviant void ScriptParser::readProvide(bool Hidden) {
873a31c91b1SEugene Leviant   expect("(");
874a31c91b1SEugene Leviant   if (SymbolAssignment *Assignment = readSymbolAssignment(next())) {
875a31c91b1SEugene Leviant     Assignment->Provide = true;
876a31c91b1SEugene Leviant     Assignment->Hidden = Hidden;
877a31c91b1SEugene Leviant   }
878a31c91b1SEugene Leviant   expect(")");
879a31c91b1SEugene Leviant   expect(";");
880eda81a1bSEugene Leviant }
881eda81a1bSEugene Leviant 
882a31c91b1SEugene Leviant SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef Name) {
883a31c91b1SEugene Leviant   expect("=");
884a31c91b1SEugene Leviant   std::vector<StringRef> Expr = readSectionsCommandExpr();
885a31c91b1SEugene Leviant   if (Expr.empty()) {
886a31c91b1SEugene Leviant     error("error in symbol assignment expression");
887a31c91b1SEugene Leviant   } else {
888a31c91b1SEugene Leviant     Opt.Commands.push_back(llvm::make_unique<SymbolAssignment>(Name, Expr));
889a31c91b1SEugene Leviant     return static_cast<SymbolAssignment *>(Opt.Commands.back().get());
890a31c91b1SEugene Leviant   }
891a31c91b1SEugene Leviant   return nullptr;
892a31c91b1SEugene Leviant }
893a31c91b1SEugene Leviant 
894a31c91b1SEugene Leviant // This function reads balanced expression until semicolon is seen.
895eda81a1bSEugene Leviant std::vector<StringRef> ScriptParser::readSectionsCommandExpr() {
896a31c91b1SEugene Leviant   int Braces = 0;
897eda81a1bSEugene Leviant   std::vector<StringRef> Expr;
898eda81a1bSEugene Leviant   while (!Error) {
899a31c91b1SEugene Leviant     StringRef Tok = peek();
900a31c91b1SEugene Leviant 
901a31c91b1SEugene Leviant     if (Tok == "(")
902a31c91b1SEugene Leviant       Braces++;
903a31c91b1SEugene Leviant     else if (Tok == ")")
904a31c91b1SEugene Leviant       if (--Braces < 0)
905a31c91b1SEugene Leviant         break;
906a31c91b1SEugene Leviant 
907a31c91b1SEugene Leviant     next();
908eda81a1bSEugene Leviant     if (Tok == ";")
909eda81a1bSEugene Leviant       break;
910eda81a1bSEugene Leviant     Expr.push_back(Tok);
911eda81a1bSEugene Leviant   }
912eda81a1bSEugene Leviant   return Expr;
913eda81a1bSEugene Leviant }
914eda81a1bSEugene Leviant 
915bbe38602SEugene Leviant std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() {
916bbe38602SEugene Leviant   std::vector<StringRef> Phdrs;
917bbe38602SEugene Leviant   while (!Error && peek().startswith(":")) {
918bbe38602SEugene Leviant     StringRef Tok = next();
919bbe38602SEugene Leviant     Tok = (Tok.size() == 1) ? next() : Tok.substr(1);
920bbe38602SEugene Leviant     if (Tok.empty()) {
921bbe38602SEugene Leviant       setError("section header name is empty");
922bbe38602SEugene Leviant       break;
923bbe38602SEugene Leviant     }
924bbe38602SEugene Leviant     Phdrs.push_back(Tok);
925bbe38602SEugene Leviant   }
926bbe38602SEugene Leviant   return Phdrs;
927bbe38602SEugene Leviant }
928bbe38602SEugene Leviant 
929bbe38602SEugene Leviant unsigned ScriptParser::readPhdrType() {
930bbe38602SEugene Leviant   StringRef Tok = next();
931b0f6c590SRui Ueyama   unsigned Ret = StringSwitch<unsigned>(Tok)
932b0f6c590SRui Ueyama       .Case("PT_NULL", PT_NULL)
933b0f6c590SRui Ueyama       .Case("PT_LOAD", PT_LOAD)
934b0f6c590SRui Ueyama       .Case("PT_DYNAMIC", PT_DYNAMIC)
935b0f6c590SRui Ueyama       .Case("PT_INTERP", PT_INTERP)
936b0f6c590SRui Ueyama       .Case("PT_NOTE", PT_NOTE)
937b0f6c590SRui Ueyama       .Case("PT_SHLIB", PT_SHLIB)
938b0f6c590SRui Ueyama       .Case("PT_PHDR", PT_PHDR)
939b0f6c590SRui Ueyama       .Case("PT_TLS", PT_TLS)
940b0f6c590SRui Ueyama       .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME)
941b0f6c590SRui Ueyama       .Case("PT_GNU_STACK", PT_GNU_STACK)
942b0f6c590SRui Ueyama       .Case("PT_GNU_RELRO", PT_GNU_RELRO)
943b0f6c590SRui Ueyama       .Default(-1);
944bbe38602SEugene Leviant 
945b0f6c590SRui Ueyama   if (Ret == (unsigned)-1) {
946b0f6c590SRui Ueyama     setError("invalid program header type: " + Tok);
947b0f6c590SRui Ueyama     return PT_NULL;
948b0f6c590SRui Ueyama   }
949b0f6c590SRui Ueyama   return Ret;
950bbe38602SEugene Leviant }
951bbe38602SEugene Leviant 
95216b0cc9eSSimon Atanasyan static bool isUnderSysroot(StringRef Path) {
95316b0cc9eSSimon Atanasyan   if (Config->Sysroot == "")
95416b0cc9eSSimon Atanasyan     return false;
95516b0cc9eSSimon Atanasyan   for (; !Path.empty(); Path = sys::path::parent_path(Path))
95616b0cc9eSSimon Atanasyan     if (sys::fs::equivalent(Config->Sysroot, Path))
95716b0cc9eSSimon Atanasyan       return true;
95816b0cc9eSSimon Atanasyan   return false;
95916b0cc9eSSimon Atanasyan }
96016b0cc9eSSimon Atanasyan 
96107320e40SRui Ueyama // Entry point.
96207320e40SRui Ueyama void elf::readLinkerScript(MemoryBufferRef MB) {
96316b0cc9eSSimon Atanasyan   StringRef Path = MB.getBufferIdentifier();
96407320e40SRui Ueyama   ScriptParser(MB.getBuffer(), isUnderSysroot(Path)).run();
965f7c5fbb1SRui Ueyama }
9661ebc8ed7SRui Ueyama 
96707320e40SRui Ueyama template class elf::LinkerScript<ELF32LE>;
96807320e40SRui Ueyama template class elf::LinkerScript<ELF32BE>;
96907320e40SRui Ueyama template class elf::LinkerScript<ELF64LE>;
97007320e40SRui Ueyama template class elf::LinkerScript<ELF64BE>;
971