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"
2293c9af42SRui Ueyama #include "Strings.h"
23eda81a1bSEugene Leviant #include "Symbols.h"
24f7c5fbb1SRui Ueyama #include "SymbolTable.h"
25467c4d55SEugene Leviant #include "Target.h"
26bbe38602SEugene Leviant #include "Writer.h"
27960504b9SRui Ueyama #include "llvm/ADT/StringSwitch.h"
28652852c5SGeorge Rimar #include "llvm/Support/ELF.h"
29f7c5fbb1SRui Ueyama #include "llvm/Support/FileSystem.h"
30f7c5fbb1SRui Ueyama #include "llvm/Support/MemoryBuffer.h"
31f03f3cc1SRui Ueyama #include "llvm/Support/Path.h"
32a47ee68dSRui Ueyama #include "llvm/Support/StringSaver.h"
33f7c5fbb1SRui Ueyama 
34f7c5fbb1SRui Ueyama using namespace llvm;
35652852c5SGeorge Rimar using namespace llvm::ELF;
361ebc8ed7SRui Ueyama using namespace llvm::object;
37f7c5fbb1SRui Ueyama using namespace lld;
38e0df00b9SRafael Espindola using namespace lld::elf;
39f7c5fbb1SRui Ueyama 
4007320e40SRui Ueyama ScriptConfiguration *elf::ScriptConfig;
41717677afSRui Ueyama 
42076fe157SGeorge Rimar bool SymbolAssignment::classof(const BaseCommand *C) {
43076fe157SGeorge Rimar   return C->Kind == AssignmentKind;
44076fe157SGeorge Rimar }
45076fe157SGeorge Rimar 
46076fe157SGeorge Rimar bool OutputSectionCommand::classof(const BaseCommand *C) {
47076fe157SGeorge Rimar   return C->Kind == OutputSectionKind;
48076fe157SGeorge Rimar }
49076fe157SGeorge Rimar 
509c1112d0SRui Ueyama // This is an operator-precedence parser to parse and evaluate
519c1112d0SRui Ueyama // a linker script expression. For each linker script arithmetic
529c1112d0SRui Ueyama // expression (e.g. ". = . + 0x1000"), a new instance of ExprParser
539c1112d0SRui Ueyama // is created and ran.
549c1112d0SRui Ueyama namespace {
559c1112d0SRui Ueyama class ExprParser : public ScriptParserBase {
569c1112d0SRui Ueyama public:
579c1112d0SRui Ueyama   ExprParser(std::vector<StringRef> &Tokens, uint64_t Dot)
589c1112d0SRui Ueyama       : ScriptParserBase(Tokens), Dot(Dot) {}
599c1112d0SRui Ueyama 
609c1112d0SRui Ueyama   uint64_t run();
619c1112d0SRui Ueyama 
629c1112d0SRui Ueyama private:
639c1112d0SRui Ueyama   uint64_t parsePrimary();
649c1112d0SRui Ueyama   uint64_t parseTernary(uint64_t Cond);
659c1112d0SRui Ueyama   uint64_t apply(StringRef Op, uint64_t L, uint64_t R);
669c1112d0SRui Ueyama   uint64_t parseExpr1(uint64_t Lhs, int MinPrec);
679c1112d0SRui Ueyama   uint64_t parseExpr();
689c1112d0SRui Ueyama 
699c1112d0SRui Ueyama   uint64_t Dot;
709c1112d0SRui Ueyama };
719c1112d0SRui Ueyama }
729c1112d0SRui Ueyama 
73960504b9SRui Ueyama static int precedence(StringRef Op) {
74960504b9SRui Ueyama   return StringSwitch<int>(Op)
75960504b9SRui Ueyama       .Case("*", 4)
76ab939066SGeorge Rimar       .Case("/", 4)
77ab939066SGeorge Rimar       .Case("+", 3)
78ab939066SGeorge Rimar       .Case("-", 3)
79ab939066SGeorge Rimar       .Case("<", 2)
80ab939066SGeorge Rimar       .Case(">", 2)
81ab939066SGeorge Rimar       .Case(">=", 2)
82ab939066SGeorge Rimar       .Case("<=", 2)
83ab939066SGeorge Rimar       .Case("==", 2)
84ab939066SGeorge Rimar       .Case("!=", 2)
85960504b9SRui Ueyama       .Case("&", 1)
86960504b9SRui Ueyama       .Default(-1);
87960504b9SRui Ueyama }
88960504b9SRui Ueyama 
899c1112d0SRui Ueyama static uint64_t evalExpr(std::vector<StringRef> &Tokens, uint64_t Dot) {
909c1112d0SRui Ueyama   return ExprParser(Tokens, Dot).run();
91960504b9SRui Ueyama }
92960504b9SRui Ueyama 
939c1112d0SRui Ueyama uint64_t ExprParser::run() {
949c1112d0SRui Ueyama   uint64_t V = parseExpr();
959c1112d0SRui Ueyama   if (!atEOF() && !Error)
969c1112d0SRui Ueyama     setError("stray token: " + peek());
979c1112d0SRui Ueyama   return V;
986011811bSRui Ueyama }
996011811bSRui Ueyama 
100960504b9SRui Ueyama // This is a part of the operator-precedence parser to evaluate
101960504b9SRui Ueyama // arithmetic expressions in SECTIONS command. This function evaluates an
102e29a975dSRui Ueyama // integer literal, a parenthesized expression, the ALIGN function,
103e29a975dSRui Ueyama // or the special variable ".".
1049c1112d0SRui Ueyama uint64_t ExprParser::parsePrimary() {
1059c1112d0SRui Ueyama   StringRef Tok = next();
106960504b9SRui Ueyama   if (Tok == ".")
107960504b9SRui Ueyama     return Dot;
108960504b9SRui Ueyama   if (Tok == "(") {
1099c1112d0SRui Ueyama     uint64_t V = parseExpr();
1109c1112d0SRui Ueyama     expect(")");
111960504b9SRui Ueyama     return V;
112960504b9SRui Ueyama   }
113dffc1410SGeorge Rimar   if (Tok == "ALIGN") {
1149c1112d0SRui Ueyama     expect("(");
1159c1112d0SRui Ueyama     uint64_t V = parseExpr();
1169c1112d0SRui Ueyama     expect(")");
117dffc1410SGeorge Rimar     return alignTo(Dot, V);
118dffc1410SGeorge Rimar   }
1195fa60985SRui Ueyama   uint64_t V = 0;
1205fa60985SRui Ueyama   if (Tok.getAsInteger(0, V))
1219c1112d0SRui Ueyama     setError("malformed number: " + Tok);
1225fa60985SRui Ueyama   return V;
123960504b9SRui Ueyama }
124960504b9SRui Ueyama 
1259c1112d0SRui Ueyama uint64_t ExprParser::parseTernary(uint64_t Cond) {
1269c1112d0SRui Ueyama   next();
1279c1112d0SRui Ueyama   uint64_t V = parseExpr();
1289c1112d0SRui Ueyama   expect(":");
1299c1112d0SRui Ueyama   uint64_t W = parseExpr();
130fba45c41SGeorge Rimar   return Cond ? V : W;
131fba45c41SGeorge Rimar }
132fba45c41SGeorge Rimar 
1339c1112d0SRui Ueyama uint64_t ExprParser::apply(StringRef Op, uint64_t L, uint64_t R) {
134960504b9SRui Ueyama   if (Op == "*")
135960504b9SRui Ueyama     return L * R;
136960504b9SRui Ueyama   if (Op == "/") {
137960504b9SRui Ueyama     if (R == 0) {
138960504b9SRui Ueyama       error("division by zero");
139960504b9SRui Ueyama       return 0;
140960504b9SRui Ueyama     }
141960504b9SRui Ueyama     return L / R;
142960504b9SRui Ueyama   }
143ab939066SGeorge Rimar   if (Op == "+")
144ab939066SGeorge Rimar     return L + R;
145ab939066SGeorge Rimar   if (Op == "-")
146ab939066SGeorge Rimar     return L - R;
147ab939066SGeorge Rimar   if (Op == "<")
148ab939066SGeorge Rimar     return L < R;
149ab939066SGeorge Rimar   if (Op == ">")
150ab939066SGeorge Rimar     return L > R;
151ab939066SGeorge Rimar   if (Op == ">=")
152ab939066SGeorge Rimar     return L >= R;
153ab939066SGeorge Rimar   if (Op == "<=")
154ab939066SGeorge Rimar     return L <= R;
155ab939066SGeorge Rimar   if (Op == "==")
156ab939066SGeorge Rimar     return L == R;
157ab939066SGeorge Rimar   if (Op == "!=")
158ab939066SGeorge Rimar     return L != R;
159960504b9SRui Ueyama   if (Op == "&")
160960504b9SRui Ueyama     return L & R;
1617a81d674SRui Ueyama   llvm_unreachable("invalid operator");
162652852c5SGeorge Rimar }
163652852c5SGeorge Rimar 
1649c1112d0SRui Ueyama // This is a part of the operator-precedence parser.
1659c1112d0SRui Ueyama // This function assumes that the remaining token stream starts
1669c1112d0SRui Ueyama // with an operator.
1679c1112d0SRui Ueyama uint64_t ExprParser::parseExpr1(uint64_t Lhs, int MinPrec) {
1689c1112d0SRui Ueyama   while (!atEOF()) {
169960504b9SRui Ueyama     // Read an operator and an expression.
1709c1112d0SRui Ueyama     StringRef Op1 = peek();
171fba45c41SGeorge Rimar     if (Op1 == "?")
1729c1112d0SRui Ueyama       return parseTernary(Lhs);
173960504b9SRui Ueyama     if (precedence(Op1) < MinPrec)
174960504b9SRui Ueyama       return Lhs;
1759c1112d0SRui Ueyama     next();
1769c1112d0SRui Ueyama     uint64_t Rhs = parsePrimary();
177960504b9SRui Ueyama 
178960504b9SRui Ueyama     // Evaluate the remaining part of the expression first if the
179960504b9SRui Ueyama     // next operator has greater precedence than the previous one.
180960504b9SRui Ueyama     // For example, if we have read "+" and "3", and if the next
181960504b9SRui Ueyama     // operator is "*", then we'll evaluate 3 * ... part first.
1829c1112d0SRui Ueyama     while (!atEOF()) {
1839c1112d0SRui Ueyama       StringRef Op2 = peek();
184960504b9SRui Ueyama       if (precedence(Op2) <= precedence(Op1))
185960504b9SRui Ueyama         break;
1869c1112d0SRui Ueyama       Rhs = parseExpr1(Rhs, precedence(Op2));
187652852c5SGeorge Rimar     }
188960504b9SRui Ueyama 
189960504b9SRui Ueyama     Lhs = apply(Op1, Lhs, Rhs);
190960504b9SRui Ueyama   }
191960504b9SRui Ueyama   return Lhs;
192960504b9SRui Ueyama }
193960504b9SRui Ueyama 
1949c1112d0SRui Ueyama // Reads and evaluates an arithmetic expression.
1959c1112d0SRui Ueyama uint64_t ExprParser::parseExpr() { return parseExpr1(parsePrimary(), 0); }
196652852c5SGeorge Rimar 
1971ebc8ed7SRui Ueyama template <class ELFT>
1988ec77e64SRui Ueyama StringRef LinkerScript<ELFT>::getOutputSection(InputSectionBase<ELFT> *S) {
19907320e40SRui Ueyama   for (SectionRule &R : Opt.Sections)
200722830a5SRui Ueyama     if (globMatch(R.SectionPattern, S->getSectionName()))
2018ec77e64SRui Ueyama       return R.Dest;
2028ec77e64SRui Ueyama   return "";
203717677afSRui Ueyama }
204717677afSRui Ueyama 
2051ebc8ed7SRui Ueyama template <class ELFT>
20607320e40SRui Ueyama bool LinkerScript<ELFT>::isDiscarded(InputSectionBase<ELFT> *S) {
207e63d81bdSEugene Leviant   return !S || !S->Live || getOutputSection(S) == "/DISCARD/";
208717677afSRui Ueyama }
209717677afSRui Ueyama 
21007320e40SRui Ueyama template <class ELFT>
21107320e40SRui Ueyama bool LinkerScript<ELFT>::shouldKeep(InputSectionBase<ELFT> *S) {
2128ec77e64SRui Ueyama   for (StringRef Pat : Opt.KeptSections)
213722830a5SRui Ueyama     if (globMatch(Pat, S->getSectionName()))
2148ec77e64SRui Ueyama       return true;
2158ec77e64SRui Ueyama   return false;
216481c2ce6SGeorge Rimar }
217481c2ce6SGeorge Rimar 
218652852c5SGeorge Rimar template <class ELFT>
219a7f7884dSRui Ueyama std::vector<OutputSectionBase<ELFT> *>
220e63d81bdSEugene Leviant LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
221a7f7884dSRui Ueyama   std::vector<OutputSectionBase<ELFT> *> Result;
222a7f7884dSRui Ueyama 
223e63d81bdSEugene Leviant   // Add input section to output section. If there is no output section yet,
224e63d81bdSEugene Leviant   // then create it and add to output section list.
225e63d81bdSEugene Leviant   auto AddInputSec = [&](InputSectionBase<ELFT> *C, StringRef Name) {
226e63d81bdSEugene Leviant     OutputSectionBase<ELFT> *Sec;
227e63d81bdSEugene Leviant     bool IsNew;
228e63d81bdSEugene Leviant     std::tie(Sec, IsNew) = Factory.create(C, Name);
229e63d81bdSEugene Leviant     if (IsNew)
230a7f7884dSRui Ueyama       Result.push_back(Sec);
231e63d81bdSEugene Leviant     Sec->addSection(C);
232e63d81bdSEugene Leviant   };
233e63d81bdSEugene Leviant 
234e63d81bdSEugene Leviant   // Select input sections matching rule and add them to corresponding
235e63d81bdSEugene Leviant   // output section. Section rules are processed in order they're listed
236e63d81bdSEugene Leviant   // in script, so correct input section order is maintained by design.
237e63d81bdSEugene Leviant   for (SectionRule &R : Opt.Sections)
238e63d81bdSEugene Leviant     for (const std::unique_ptr<ObjectFile<ELFT>> &F :
239e63d81bdSEugene Leviant          Symtab<ELFT>::X->getObjectFiles())
240e63d81bdSEugene Leviant       for (InputSectionBase<ELFT> *S : F->getSections())
241e63d81bdSEugene Leviant         if (!isDiscarded(S) && !S->OutSec &&
242e63d81bdSEugene Leviant             globMatch(R.SectionPattern, S->getSectionName()))
243e63d81bdSEugene Leviant           // Add single input section to output section.
244e63d81bdSEugene Leviant           AddInputSec(S, R.Dest);
245e63d81bdSEugene Leviant 
246e63d81bdSEugene Leviant   // Add all other input sections, which are not listed in script.
247e63d81bdSEugene Leviant   for (const std::unique_ptr<ObjectFile<ELFT>> &F :
248e63d81bdSEugene Leviant        Symtab<ELFT>::X->getObjectFiles())
249e63d81bdSEugene Leviant     for (InputSectionBase<ELFT> *S : F->getSections())
250e63d81bdSEugene Leviant       if (!isDiscarded(S)) {
251e63d81bdSEugene Leviant         if (!S->OutSec)
252e63d81bdSEugene Leviant           AddInputSec(S, getOutputSectionName(S));
253e63d81bdSEugene Leviant       } else
254e63d81bdSEugene Leviant         reportDiscarded(S, F);
255e63d81bdSEugene Leviant 
256e63d81bdSEugene Leviant   return Result;
257e63d81bdSEugene Leviant }
258e63d81bdSEugene Leviant 
259e63d81bdSEugene Leviant template <class ELFT>
26007320e40SRui Ueyama void LinkerScript<ELFT>::assignAddresses(
261dbbd8b15SGeorge Rimar     ArrayRef<OutputSectionBase<ELFT> *> Sections) {
262652852c5SGeorge Rimar   // Orphan sections are sections present in the input files which
2637c18c28cSRui Ueyama   // are not explicitly placed into the output file by the linker script.
2647c18c28cSRui Ueyama   // We place orphan sections at end of file.
2657c18c28cSRui Ueyama   // Other linkers places them using some heuristics as described in
266652852c5SGeorge Rimar   // https://sourceware.org/binutils/docs/ld/Orphan-Sections.html#Orphan-Sections.
2677c18c28cSRui Ueyama   for (OutputSectionBase<ELFT> *Sec : Sections) {
268652852c5SGeorge Rimar     StringRef Name = Sec->getName();
269c3e2a4b0SRui Ueyama     if (getSectionIndex(Name) == INT_MAX)
270076fe157SGeorge Rimar       Opt.Commands.push_back(llvm::make_unique<OutputSectionCommand>(Name));
271652852c5SGeorge Rimar   }
272652852c5SGeorge Rimar 
2737c18c28cSRui Ueyama   // Assign addresses as instructed by linker script SECTIONS sub-commands.
274c998a8c0SRui Ueyama   Dot = Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize();
275467c4d55SEugene Leviant   uintX_t MinVA = std::numeric_limits<uintX_t>::max();
276652852c5SGeorge Rimar   uintX_t ThreadBssOffset = 0;
277652852c5SGeorge Rimar 
278076fe157SGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
279076fe157SGeorge Rimar     if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get())) {
280076fe157SGeorge Rimar       uint64_t Val = evalExpr(Cmd->Expr, Dot);
281076fe157SGeorge Rimar       if (Cmd->Name == ".") {
28205ef4cffSRui Ueyama 
28305ef4cffSRui Ueyama         Dot = Val;
28405ef4cffSRui Ueyama       } else {
285076fe157SGeorge Rimar         auto *D = cast<DefinedRegular<ELFT>>(Symtab<ELFT>::X->find(Cmd->Name));
28605ef4cffSRui Ueyama         D->Value = Val;
287eda81a1bSEugene Leviant       }
28805ef4cffSRui Ueyama       continue;
289652852c5SGeorge Rimar     }
290652852c5SGeorge Rimar 
291fb8978fcSDima Stepanov     // Find all the sections with required name. There can be more than
2926ad330acSGeorge Rimar     // one section with such name, if the alignment, flags or type
293fb8978fcSDima Stepanov     // attribute differs.
294076fe157SGeorge Rimar     auto *Cmd = cast<OutputSectionCommand>(Base.get());
295fb8978fcSDima Stepanov     for (OutputSectionBase<ELFT> *Sec : Sections) {
296076fe157SGeorge Rimar       if (Sec->getName() != Cmd->Name)
297652852c5SGeorge Rimar         continue;
298652852c5SGeorge Rimar 
299652852c5SGeorge Rimar       if ((Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS) {
300c998a8c0SRui Ueyama         uintX_t TVA = Dot + ThreadBssOffset;
301424b4081SRui Ueyama         TVA = alignTo(TVA, Sec->getAlignment());
302652852c5SGeorge Rimar         Sec->setVA(TVA);
303c998a8c0SRui Ueyama         ThreadBssOffset = TVA - Dot + Sec->getSize();
304652852c5SGeorge Rimar         continue;
305652852c5SGeorge Rimar       }
306652852c5SGeorge Rimar 
307652852c5SGeorge Rimar       if (Sec->getFlags() & SHF_ALLOC) {
308424b4081SRui Ueyama         Dot = alignTo(Dot, Sec->getAlignment());
309c998a8c0SRui Ueyama         Sec->setVA(Dot);
310467c4d55SEugene Leviant         MinVA = std::min(MinVA, Dot);
311c998a8c0SRui Ueyama         Dot += Sec->getSize();
312652852c5SGeorge Rimar         continue;
313652852c5SGeorge Rimar       }
314652852c5SGeorge Rimar     }
315652852c5SGeorge Rimar   }
316467c4d55SEugene Leviant 
31764c32d6fSRafael Espindola   // ELF and Program headers need to be right before the first section in
318b91e7118SGeorge Rimar   // memory. Set their addresses accordingly.
319467c4d55SEugene Leviant   MinVA = alignDown(MinVA - Out<ELFT>::ElfHeader->getSize() -
320467c4d55SEugene Leviant                         Out<ELFT>::ProgramHeaders->getSize(),
321467c4d55SEugene Leviant                     Target->PageSize);
322467c4d55SEugene Leviant   Out<ELFT>::ElfHeader->setVA(MinVA);
323467c4d55SEugene Leviant   Out<ELFT>::ProgramHeaders->setVA(Out<ELFT>::ElfHeader->getSize() + MinVA);
324fb8978fcSDima Stepanov }
325652852c5SGeorge Rimar 
32607320e40SRui Ueyama template <class ELFT>
32774df5c7eSRafael Espindola std::vector<PhdrEntry<ELFT>>
328bbe38602SEugene Leviant LinkerScript<ELFT>::createPhdrs(ArrayRef<OutputSectionBase<ELFT> *> Sections) {
329bbe38602SEugene Leviant   int TlsNum = -1;
330bbe38602SEugene Leviant   int NoteNum = -1;
331bbe38602SEugene Leviant   int RelroNum = -1;
332bbe38602SEugene Leviant   Phdr *Load = nullptr;
333bbe38602SEugene Leviant   uintX_t Flags = PF_R;
334bbe38602SEugene Leviant   std::vector<Phdr> Phdrs;
335bbe38602SEugene Leviant 
336bbe38602SEugene Leviant   for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) {
337865bf863SEugene Leviant     Phdrs.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags);
338bbe38602SEugene Leviant     Phdr &Added = Phdrs.back();
339bbe38602SEugene Leviant 
340bbe38602SEugene Leviant     if (Cmd.HasFilehdr)
34118f084ffSRui Ueyama       Added.add(Out<ELFT>::ElfHeader);
342bbe38602SEugene Leviant     if (Cmd.HasPhdrs)
34318f084ffSRui Ueyama       Added.add(Out<ELFT>::ProgramHeaders);
344bbe38602SEugene Leviant 
345bbe38602SEugene Leviant     switch (Cmd.Type) {
346bbe38602SEugene Leviant     case PT_INTERP:
347*fd03cfd2SRui Ueyama       if (Out<ELFT>::Interp)
34818f084ffSRui Ueyama         Added.add(Out<ELFT>::Interp);
349bbe38602SEugene Leviant       break;
350bbe38602SEugene Leviant     case PT_DYNAMIC:
351bbe38602SEugene Leviant       if (isOutputDynamic<ELFT>()) {
352bbe38602SEugene Leviant         Added.H.p_flags = toPhdrFlags(Out<ELFT>::Dynamic->getFlags());
35318f084ffSRui Ueyama         Added.add(Out<ELFT>::Dynamic);
354bbe38602SEugene Leviant       }
355bbe38602SEugene Leviant       break;
356bbe38602SEugene Leviant     case PT_TLS:
357bbe38602SEugene Leviant       TlsNum = Phdrs.size() - 1;
358bbe38602SEugene Leviant       break;
359bbe38602SEugene Leviant     case PT_NOTE:
360bbe38602SEugene Leviant       NoteNum = Phdrs.size() - 1;
361bbe38602SEugene Leviant       break;
362bbe38602SEugene Leviant     case PT_GNU_RELRO:
363bbe38602SEugene Leviant       RelroNum = Phdrs.size() - 1;
364bbe38602SEugene Leviant       break;
365bbe38602SEugene Leviant     case PT_GNU_EH_FRAME:
366bbe38602SEugene Leviant       if (!Out<ELFT>::EhFrame->empty() && Out<ELFT>::EhFrameHdr) {
367bbe38602SEugene Leviant         Added.H.p_flags = toPhdrFlags(Out<ELFT>::EhFrameHdr->getFlags());
36818f084ffSRui Ueyama         Added.add(Out<ELFT>::EhFrameHdr);
369bbe38602SEugene Leviant       }
370bbe38602SEugene Leviant       break;
371bbe38602SEugene Leviant     }
372bbe38602SEugene Leviant   }
373bbe38602SEugene Leviant 
374bbe38602SEugene Leviant   for (OutputSectionBase<ELFT> *Sec : Sections) {
375bbe38602SEugene Leviant     if (!(Sec->getFlags() & SHF_ALLOC))
376bbe38602SEugene Leviant       break;
377bbe38602SEugene Leviant 
378bbe38602SEugene Leviant     if (TlsNum != -1 && (Sec->getFlags() & SHF_TLS))
37918f084ffSRui Ueyama       Phdrs[TlsNum].add(Sec);
380bbe38602SEugene Leviant 
381bbe38602SEugene Leviant     if (!needsPtLoad<ELFT>(Sec))
382bbe38602SEugene Leviant       continue;
383bbe38602SEugene Leviant 
384bbe38602SEugene Leviant     const std::vector<size_t> &PhdrIds =
385bbe38602SEugene Leviant         getPhdrIndicesForSection(Sec->getName());
386bbe38602SEugene Leviant     if (!PhdrIds.empty()) {
387bbe38602SEugene Leviant       // Assign headers specified by linker script
388bbe38602SEugene Leviant       for (size_t Id : PhdrIds) {
38918f084ffSRui Ueyama         Phdrs[Id].add(Sec);
390865bf863SEugene Leviant         if (Opt.PhdrsCommands[Id].Flags == UINT_MAX)
391865bf863SEugene Leviant           Phdrs[Id].H.p_flags |= toPhdrFlags(Sec->getFlags());
392bbe38602SEugene Leviant         Phdrs[Id].H.p_flags |= toPhdrFlags(Sec->getFlags());
393bbe38602SEugene Leviant       }
394bbe38602SEugene Leviant     } else {
395bbe38602SEugene Leviant       // If we have no load segment or flags've changed then we want new load
396bbe38602SEugene Leviant       // segment.
397bbe38602SEugene Leviant       uintX_t NewFlags = toPhdrFlags(Sec->getFlags());
398bbe38602SEugene Leviant       if (Load == nullptr || Flags != NewFlags) {
399bbe38602SEugene Leviant         Load = &*Phdrs.emplace(Phdrs.end(), PT_LOAD, NewFlags);
400bbe38602SEugene Leviant         Flags = NewFlags;
401bbe38602SEugene Leviant       }
40218f084ffSRui Ueyama       Load->add(Sec);
403bbe38602SEugene Leviant     }
404bbe38602SEugene Leviant 
405bbe38602SEugene Leviant     if (RelroNum != -1 && isRelroSection(Sec))
40618f084ffSRui Ueyama       Phdrs[RelroNum].add(Sec);
407bbe38602SEugene Leviant     if (NoteNum != -1 && Sec->getType() == SHT_NOTE)
40818f084ffSRui Ueyama       Phdrs[NoteNum].add(Sec);
409bbe38602SEugene Leviant   }
410bbe38602SEugene Leviant   return Phdrs;
411bbe38602SEugene Leviant }
412bbe38602SEugene Leviant 
413bbe38602SEugene Leviant template <class ELFT>
41407320e40SRui Ueyama ArrayRef<uint8_t> LinkerScript<ELFT>::getFiller(StringRef Name) {
415f6c3ccefSGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands)
416f6c3ccefSGeorge Rimar     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()))
417f6c3ccefSGeorge Rimar       if (Cmd->Name == Name)
418f6c3ccefSGeorge Rimar         return Cmd->Filler;
419e2ee72b5SGeorge Rimar   return {};
420e2ee72b5SGeorge Rimar }
421e2ee72b5SGeorge Rimar 
422c3e2a4b0SRui Ueyama // Returns the index of the given section name in linker script
423c3e2a4b0SRui Ueyama // SECTIONS commands. Sections are laid out as the same order as they
424c3e2a4b0SRui Ueyama // were in the script. If a given name did not appear in the script,
425c3e2a4b0SRui Ueyama // it returns INT_MAX, so that it will be laid out at end of file.
426076fe157SGeorge Rimar template <class ELFT> int LinkerScript<ELFT>::getSectionIndex(StringRef Name) {
42771b26e94SGeorge Rimar   auto Begin = Opt.Commands.begin();
42871b26e94SGeorge Rimar   auto End = Opt.Commands.end();
429076fe157SGeorge Rimar   auto I =
430076fe157SGeorge Rimar       std::find_if(Begin, End, [&](const std::unique_ptr<BaseCommand> &Base) {
431076fe157SGeorge Rimar         if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get()))
432076fe157SGeorge Rimar           if (Cmd->Name == Name)
433076fe157SGeorge Rimar             return true;
434076fe157SGeorge Rimar         return false;
43571b26e94SGeorge Rimar       });
436c3e2a4b0SRui Ueyama   return I == End ? INT_MAX : (I - Begin);
43771b26e94SGeorge Rimar }
43871b26e94SGeorge Rimar 
43971b26e94SGeorge Rimar // A compartor to sort output sections. Returns -1 or 1 if
44071b26e94SGeorge Rimar // A or B are mentioned in linker script. Otherwise, returns 0.
44107320e40SRui Ueyama template <class ELFT>
44207320e40SRui Ueyama int LinkerScript<ELFT>::compareSections(StringRef A, StringRef B) {
443c3e2a4b0SRui Ueyama   int I = getSectionIndex(A);
444c3e2a4b0SRui Ueyama   int J = getSectionIndex(B);
445c3e2a4b0SRui Ueyama   if (I == INT_MAX && J == INT_MAX)
446717677afSRui Ueyama     return 0;
447717677afSRui Ueyama   return I < J ? -1 : 1;
448717677afSRui Ueyama }
449717677afSRui Ueyama 
450076fe157SGeorge Rimar template <class ELFT> void LinkerScript<ELFT>::addScriptedSymbols() {
451076fe157SGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands)
452076fe157SGeorge Rimar     if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get()))
453076fe157SGeorge Rimar       if (Cmd->Name != "." && Symtab<ELFT>::X->find(Cmd->Name) == nullptr)
454076fe157SGeorge Rimar         Symtab<ELFT>::X->addAbsolute(Cmd->Name, STV_DEFAULT);
455eda81a1bSEugene Leviant }
456eda81a1bSEugene Leviant 
457bbe38602SEugene Leviant template <class ELFT> bool LinkerScript<ELFT>::hasPhdrsCommands() {
458bbe38602SEugene Leviant   return !Opt.PhdrsCommands.empty();
459bbe38602SEugene Leviant }
460bbe38602SEugene Leviant 
461bbe38602SEugene Leviant // Returns indices of ELF headers containing specific section, identified
462bbe38602SEugene Leviant // by Name. Each index is a zero based number of ELF header listed within
463bbe38602SEugene Leviant // PHDRS {} script block.
464bbe38602SEugene Leviant template <class ELFT>
465bbe38602SEugene Leviant std::vector<size_t>
466bbe38602SEugene Leviant LinkerScript<ELFT>::getPhdrIndicesForSection(StringRef Name) {
467076fe157SGeorge Rimar   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
468076fe157SGeorge Rimar     auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get());
469076fe157SGeorge Rimar     if (!Cmd || Cmd->Name != Name)
47031d842f5SGeorge Rimar       continue;
47131d842f5SGeorge Rimar 
472bbe38602SEugene Leviant     std::vector<size_t> Indices;
473076fe157SGeorge Rimar     for (StringRef PhdrName : Cmd->Phdrs) {
47431d842f5SGeorge Rimar       auto ItPhdr =
47531d842f5SGeorge Rimar           std::find_if(Opt.PhdrsCommands.rbegin(), Opt.PhdrsCommands.rend(),
476076fe157SGeorge Rimar                        [&](PhdrsCommand &P) { return P.Name == PhdrName; });
477bbe38602SEugene Leviant       if (ItPhdr == Opt.PhdrsCommands.rend())
478bbe38602SEugene Leviant         error("section header '" + PhdrName + "' is not listed in PHDRS");
479bbe38602SEugene Leviant       else
480bbe38602SEugene Leviant         Indices.push_back(std::distance(ItPhdr, Opt.PhdrsCommands.rend()) - 1);
481bbe38602SEugene Leviant     }
482bbe38602SEugene Leviant     return Indices;
483bbe38602SEugene Leviant   }
48431d842f5SGeorge Rimar   return {};
48531d842f5SGeorge Rimar }
486bbe38602SEugene Leviant 
48707320e40SRui Ueyama class elf::ScriptParser : public ScriptParserBase {
488c3794e58SGeorge Rimar   typedef void (ScriptParser::*Handler)();
489c3794e58SGeorge Rimar 
490f7c5fbb1SRui Ueyama public:
49107320e40SRui Ueyama   ScriptParser(StringRef S, bool B) : ScriptParserBase(S), IsUnderSysroot(B) {}
492f23b2320SGeorge Rimar 
4934a46539cSRui Ueyama   void run();
494f7c5fbb1SRui Ueyama 
495f7c5fbb1SRui Ueyama private:
49652a1509eSRui Ueyama   void addFile(StringRef Path);
49752a1509eSRui Ueyama 
498f7c5fbb1SRui Ueyama   void readAsNeeded();
49990c5099eSDenis Protivensky   void readEntry();
50083f406cfSGeorge Rimar   void readExtern();
501f7c5fbb1SRui Ueyama   void readGroup();
50231aa1f83SRui Ueyama   void readInclude();
503c3794e58SGeorge Rimar   void readNothing() {}
504ee59282bSRui Ueyama   void readOutput();
5059159ce93SDavide Italiano   void readOutputArch();
506f7c5fbb1SRui Ueyama   void readOutputFormat();
507bbe38602SEugene Leviant   void readPhdrs();
50868a39a65SDavide Italiano   void readSearchDir();
5098e3b38abSDenis Protivensky   void readSections();
5108e3b38abSDenis Protivensky 
511652852c5SGeorge Rimar   void readLocationCounterValue();
512eda81a1bSEugene Leviant   void readOutputSectionDescription(StringRef OutSec);
513bbe38602SEugene Leviant   std::vector<StringRef> readOutputSectionPhdrs();
514bbe38602SEugene Leviant   unsigned readPhdrType();
515eda81a1bSEugene Leviant   void readSymbolAssignment(StringRef Name);
516eda81a1bSEugene Leviant   std::vector<StringRef> readSectionsCommandExpr();
517f7c5fbb1SRui Ueyama 
518c3794e58SGeorge Rimar   const static StringMap<Handler> Cmd;
51907320e40SRui Ueyama   ScriptConfiguration &Opt = *ScriptConfig;
52007320e40SRui Ueyama   StringSaver Saver = {ScriptConfig->Alloc};
52116b0cc9eSSimon Atanasyan   bool IsUnderSysroot;
522f7c5fbb1SRui Ueyama };
523f7c5fbb1SRui Ueyama 
524e0df00b9SRafael Espindola const StringMap<elf::ScriptParser::Handler> elf::ScriptParser::Cmd = {
525c3794e58SGeorge Rimar     {"ENTRY", &ScriptParser::readEntry},
526c3794e58SGeorge Rimar     {"EXTERN", &ScriptParser::readExtern},
527c3794e58SGeorge Rimar     {"GROUP", &ScriptParser::readGroup},
528c3794e58SGeorge Rimar     {"INCLUDE", &ScriptParser::readInclude},
529c3794e58SGeorge Rimar     {"INPUT", &ScriptParser::readGroup},
530c3794e58SGeorge Rimar     {"OUTPUT", &ScriptParser::readOutput},
531c3794e58SGeorge Rimar     {"OUTPUT_ARCH", &ScriptParser::readOutputArch},
532c3794e58SGeorge Rimar     {"OUTPUT_FORMAT", &ScriptParser::readOutputFormat},
533bbe38602SEugene Leviant     {"PHDRS", &ScriptParser::readPhdrs},
534c3794e58SGeorge Rimar     {"SEARCH_DIR", &ScriptParser::readSearchDir},
535c3794e58SGeorge Rimar     {"SECTIONS", &ScriptParser::readSections},
536c3794e58SGeorge Rimar     {";", &ScriptParser::readNothing}};
537c3794e58SGeorge Rimar 
538717677afSRui Ueyama void ScriptParser::run() {
539f7c5fbb1SRui Ueyama   while (!atEOF()) {
540f7c5fbb1SRui Ueyama     StringRef Tok = next();
541c3794e58SGeorge Rimar     if (Handler Fn = Cmd.lookup(Tok))
542c3794e58SGeorge Rimar       (this->*Fn)();
543c3794e58SGeorge Rimar     else
5445761042dSGeorge Rimar       setError("unknown directive: " + Tok);
545f7c5fbb1SRui Ueyama   }
546f7c5fbb1SRui Ueyama }
547f7c5fbb1SRui Ueyama 
548717677afSRui Ueyama void ScriptParser::addFile(StringRef S) {
54916b0cc9eSSimon Atanasyan   if (IsUnderSysroot && S.startswith("/")) {
55016b0cc9eSSimon Atanasyan     SmallString<128> Path;
55116b0cc9eSSimon Atanasyan     (Config->Sysroot + S).toStringRef(Path);
55216b0cc9eSSimon Atanasyan     if (sys::fs::exists(Path)) {
55316b0cc9eSSimon Atanasyan       Driver->addFile(Saver.save(Path.str()));
55416b0cc9eSSimon Atanasyan       return;
55516b0cc9eSSimon Atanasyan     }
55616b0cc9eSSimon Atanasyan   }
55716b0cc9eSSimon Atanasyan 
558f03f3cc1SRui Ueyama   if (sys::path::is_absolute(S)) {
55952a1509eSRui Ueyama     Driver->addFile(S);
56052a1509eSRui Ueyama   } else if (S.startswith("=")) {
56152a1509eSRui Ueyama     if (Config->Sysroot.empty())
56252a1509eSRui Ueyama       Driver->addFile(S.substr(1));
56352a1509eSRui Ueyama     else
56452a1509eSRui Ueyama       Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1)));
56552a1509eSRui Ueyama   } else if (S.startswith("-l")) {
56621eecb4fSRui Ueyama     Driver->addLibrary(S.substr(2));
567a1b8fc3bSSimon Atanasyan   } else if (sys::fs::exists(S)) {
568a1b8fc3bSSimon Atanasyan     Driver->addFile(S);
56952a1509eSRui Ueyama   } else {
57052a1509eSRui Ueyama     std::string Path = findFromSearchPaths(S);
57152a1509eSRui Ueyama     if (Path.empty())
572777f9630SGeorge Rimar       setError("unable to find " + S);
573025d59b1SRui Ueyama     else
57452a1509eSRui Ueyama       Driver->addFile(Saver.save(Path));
57552a1509eSRui Ueyama   }
57652a1509eSRui Ueyama }
57752a1509eSRui Ueyama 
578717677afSRui Ueyama void ScriptParser::readAsNeeded() {
579f7c5fbb1SRui Ueyama   expect("(");
58035da9b6eSRui Ueyama   bool Orig = Config->AsNeeded;
58135da9b6eSRui Ueyama   Config->AsNeeded = true;
582025d59b1SRui Ueyama   while (!Error) {
583f7c5fbb1SRui Ueyama     StringRef Tok = next();
584f7c5fbb1SRui Ueyama     if (Tok == ")")
58535da9b6eSRui Ueyama       break;
58652a1509eSRui Ueyama     addFile(Tok);
587f7c5fbb1SRui Ueyama   }
58835da9b6eSRui Ueyama   Config->AsNeeded = Orig;
589f7c5fbb1SRui Ueyama }
590f7c5fbb1SRui Ueyama 
591717677afSRui Ueyama void ScriptParser::readEntry() {
59290c5099eSDenis Protivensky   // -e <symbol> takes predecence over ENTRY(<symbol>).
59390c5099eSDenis Protivensky   expect("(");
59490c5099eSDenis Protivensky   StringRef Tok = next();
59590c5099eSDenis Protivensky   if (Config->Entry.empty())
59690c5099eSDenis Protivensky     Config->Entry = Tok;
59790c5099eSDenis Protivensky   expect(")");
59890c5099eSDenis Protivensky }
59990c5099eSDenis Protivensky 
600717677afSRui Ueyama void ScriptParser::readExtern() {
60183f406cfSGeorge Rimar   expect("(");
602025d59b1SRui Ueyama   while (!Error) {
60383f406cfSGeorge Rimar     StringRef Tok = next();
60483f406cfSGeorge Rimar     if (Tok == ")")
60583f406cfSGeorge Rimar       return;
60683f406cfSGeorge Rimar     Config->Undefined.push_back(Tok);
60783f406cfSGeorge Rimar   }
60883f406cfSGeorge Rimar }
60983f406cfSGeorge Rimar 
610717677afSRui Ueyama void ScriptParser::readGroup() {
611f7c5fbb1SRui Ueyama   expect("(");
612025d59b1SRui Ueyama   while (!Error) {
613f7c5fbb1SRui Ueyama     StringRef Tok = next();
614f7c5fbb1SRui Ueyama     if (Tok == ")")
615f7c5fbb1SRui Ueyama       return;
616f7c5fbb1SRui Ueyama     if (Tok == "AS_NEEDED") {
617f7c5fbb1SRui Ueyama       readAsNeeded();
618f7c5fbb1SRui Ueyama       continue;
619f7c5fbb1SRui Ueyama     }
62052a1509eSRui Ueyama     addFile(Tok);
621f7c5fbb1SRui Ueyama   }
622f7c5fbb1SRui Ueyama }
623f7c5fbb1SRui Ueyama 
624717677afSRui Ueyama void ScriptParser::readInclude() {
62531aa1f83SRui Ueyama   StringRef Tok = next();
62631aa1f83SRui Ueyama   auto MBOrErr = MemoryBuffer::getFile(Tok);
627025d59b1SRui Ueyama   if (!MBOrErr) {
6285761042dSGeorge Rimar     setError("cannot open " + Tok);
629025d59b1SRui Ueyama     return;
630025d59b1SRui Ueyama   }
63131aa1f83SRui Ueyama   std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
632a47ee68dSRui Ueyama   StringRef S = Saver.save(MB->getMemBufferRef().getBuffer());
633a47ee68dSRui Ueyama   std::vector<StringRef> V = tokenize(S);
63431aa1f83SRui Ueyama   Tokens.insert(Tokens.begin() + Pos, V.begin(), V.end());
63531aa1f83SRui Ueyama }
63631aa1f83SRui Ueyama 
637717677afSRui Ueyama void ScriptParser::readOutput() {
638ee59282bSRui Ueyama   // -o <file> takes predecence over OUTPUT(<file>).
639ee59282bSRui Ueyama   expect("(");
640ee59282bSRui Ueyama   StringRef Tok = next();
641ee59282bSRui Ueyama   if (Config->OutputFile.empty())
642ee59282bSRui Ueyama     Config->OutputFile = Tok;
643ee59282bSRui Ueyama   expect(")");
644ee59282bSRui Ueyama }
645ee59282bSRui Ueyama 
646717677afSRui Ueyama void ScriptParser::readOutputArch() {
6479159ce93SDavide Italiano   // Error checking only for now.
6489159ce93SDavide Italiano   expect("(");
6499159ce93SDavide Italiano   next();
6509159ce93SDavide Italiano   expect(")");
6519159ce93SDavide Italiano }
6529159ce93SDavide Italiano 
653717677afSRui Ueyama void ScriptParser::readOutputFormat() {
654f7c5fbb1SRui Ueyama   // Error checking only for now.
655f7c5fbb1SRui Ueyama   expect("(");
656f7c5fbb1SRui Ueyama   next();
6576836c618SDavide Italiano   StringRef Tok = next();
6586836c618SDavide Italiano   if (Tok == ")")
6596836c618SDavide Italiano    return;
660025d59b1SRui Ueyama   if (Tok != ",") {
6615761042dSGeorge Rimar     setError("unexpected token: " + Tok);
662025d59b1SRui Ueyama     return;
663025d59b1SRui Ueyama   }
6646836c618SDavide Italiano   next();
6656836c618SDavide Italiano   expect(",");
6666836c618SDavide Italiano   next();
667f7c5fbb1SRui Ueyama   expect(")");
668f7c5fbb1SRui Ueyama }
669f7c5fbb1SRui Ueyama 
670bbe38602SEugene Leviant void ScriptParser::readPhdrs() {
671bbe38602SEugene Leviant   expect("{");
672bbe38602SEugene Leviant   while (!Error && !skip("}")) {
673bbe38602SEugene Leviant     StringRef Tok = next();
674865bf863SEugene Leviant     Opt.PhdrsCommands.push_back({Tok, PT_NULL, false, false, UINT_MAX});
675bbe38602SEugene Leviant     PhdrsCommand &PhdrCmd = Opt.PhdrsCommands.back();
676bbe38602SEugene Leviant 
677bbe38602SEugene Leviant     PhdrCmd.Type = readPhdrType();
678bbe38602SEugene Leviant     do {
679bbe38602SEugene Leviant       Tok = next();
680bbe38602SEugene Leviant       if (Tok == ";")
681bbe38602SEugene Leviant         break;
682bbe38602SEugene Leviant       if (Tok == "FILEHDR")
683bbe38602SEugene Leviant         PhdrCmd.HasFilehdr = true;
684bbe38602SEugene Leviant       else if (Tok == "PHDRS")
685bbe38602SEugene Leviant         PhdrCmd.HasPhdrs = true;
686865bf863SEugene Leviant       else if (Tok == "FLAGS") {
687865bf863SEugene Leviant         expect("(");
688865bf863SEugene Leviant         next().getAsInteger(0, PhdrCmd.Flags);
689865bf863SEugene Leviant         expect(")");
690865bf863SEugene Leviant       } else
691bbe38602SEugene Leviant         setError("unexpected header attribute: " + Tok);
692bbe38602SEugene Leviant     } while (!Error);
693bbe38602SEugene Leviant   }
694bbe38602SEugene Leviant }
695bbe38602SEugene Leviant 
696717677afSRui Ueyama void ScriptParser::readSearchDir() {
69768a39a65SDavide Italiano   expect("(");
69806501920SRafael Espindola   Config->SearchPaths.push_back(next());
69968a39a65SDavide Italiano   expect(")");
70068a39a65SDavide Italiano }
70168a39a65SDavide Italiano 
702717677afSRui Ueyama void ScriptParser::readSections() {
70307320e40SRui Ueyama   Opt.DoLayout = true;
7048e3b38abSDenis Protivensky   expect("{");
705652852c5SGeorge Rimar   while (!Error && !skip("}")) {
706652852c5SGeorge Rimar     StringRef Tok = peek();
707eda81a1bSEugene Leviant     if (Tok == ".") {
708652852c5SGeorge Rimar       readLocationCounterValue();
709eda81a1bSEugene Leviant       continue;
710eda81a1bSEugene Leviant     }
711eda81a1bSEugene Leviant     next();
712eda81a1bSEugene Leviant     if (peek() == "=")
713eda81a1bSEugene Leviant       readSymbolAssignment(Tok);
714652852c5SGeorge Rimar     else
715eda81a1bSEugene Leviant       readOutputSectionDescription(Tok);
7168e3b38abSDenis Protivensky   }
717652852c5SGeorge Rimar }
7188e3b38abSDenis Protivensky 
719652852c5SGeorge Rimar void ScriptParser::readLocationCounterValue() {
720652852c5SGeorge Rimar   expect(".");
721652852c5SGeorge Rimar   expect("=");
722eda81a1bSEugene Leviant   std::vector<StringRef> Expr = readSectionsCommandExpr();
723eda81a1bSEugene Leviant   if (Expr.empty())
724652852c5SGeorge Rimar     error("error in location counter expression");
725eda81a1bSEugene Leviant   else
726076fe157SGeorge Rimar     Opt.Commands.push_back(llvm::make_unique<SymbolAssignment>(".", Expr));
727652852c5SGeorge Rimar }
728652852c5SGeorge Rimar 
729eda81a1bSEugene Leviant void ScriptParser::readOutputSectionDescription(StringRef OutSec) {
730076fe157SGeorge Rimar   OutputSectionCommand *Cmd = new OutputSectionCommand(OutSec);
731076fe157SGeorge Rimar   Opt.Commands.emplace_back(Cmd);
7328e3b38abSDenis Protivensky   expect(":");
7338e3b38abSDenis Protivensky   expect("{");
7348ec77e64SRui Ueyama 
735025d59b1SRui Ueyama   while (!Error && !skip("}")) {
736481c2ce6SGeorge Rimar     StringRef Tok = next();
737481c2ce6SGeorge Rimar     if (Tok == "*") {
7388ec77e64SRui Ueyama       expect("(");
7398ec77e64SRui Ueyama       while (!Error && !skip(")"))
7408ec77e64SRui Ueyama         Opt.Sections.emplace_back(OutSec, next());
741481c2ce6SGeorge Rimar     } else if (Tok == "KEEP") {
7428e3b38abSDenis Protivensky       expect("(");
7438ec77e64SRui Ueyama       expect("*");
7448ec77e64SRui Ueyama       expect("(");
7458ec77e64SRui Ueyama       while (!Error && !skip(")")) {
7468ec77e64SRui Ueyama         StringRef Sec = next();
7478ec77e64SRui Ueyama         Opt.Sections.emplace_back(OutSec, Sec);
7488ec77e64SRui Ueyama         Opt.KeptSections.push_back(Sec);
7498ec77e64SRui Ueyama       }
750481c2ce6SGeorge Rimar       expect(")");
751481c2ce6SGeorge Rimar     } else {
752777f9630SGeorge Rimar       setError("unknown command " + Tok);
753481c2ce6SGeorge Rimar     }
7548e3b38abSDenis Protivensky   }
755076fe157SGeorge Rimar   Cmd->Phdrs = readOutputSectionPhdrs();
7568ec77e64SRui Ueyama 
757e2ee72b5SGeorge Rimar   StringRef Tok = peek();
758e2ee72b5SGeorge Rimar   if (Tok.startswith("=")) {
759e2ee72b5SGeorge Rimar     if (!Tok.startswith("=0x")) {
7603ed2f069SRui Ueyama       setError("filler should be a hexadecimal value");
761e2ee72b5SGeorge Rimar       return;
762e2ee72b5SGeorge Rimar     }
7633e808976SRui Ueyama     Tok = Tok.substr(3);
764f6c3ccefSGeorge Rimar     Cmd->Filler = parseHex(Tok);
765e2ee72b5SGeorge Rimar     next();
766e2ee72b5SGeorge Rimar   }
7678e3b38abSDenis Protivensky }
7688e3b38abSDenis Protivensky 
769eda81a1bSEugene Leviant void ScriptParser::readSymbolAssignment(StringRef Name) {
770eda81a1bSEugene Leviant   expect("=");
771eda81a1bSEugene Leviant   std::vector<StringRef> Expr = readSectionsCommandExpr();
772eda81a1bSEugene Leviant   if (Expr.empty())
773eda81a1bSEugene Leviant     error("error in symbol assignment expression");
774eda81a1bSEugene Leviant   else
775076fe157SGeorge Rimar     Opt.Commands.push_back(llvm::make_unique<SymbolAssignment>(Name, Expr));
776eda81a1bSEugene Leviant }
777eda81a1bSEugene Leviant 
778eda81a1bSEugene Leviant std::vector<StringRef> ScriptParser::readSectionsCommandExpr() {
779eda81a1bSEugene Leviant   std::vector<StringRef> Expr;
780eda81a1bSEugene Leviant   while (!Error) {
781eda81a1bSEugene Leviant     StringRef Tok = next();
782eda81a1bSEugene Leviant     if (Tok == ";")
783eda81a1bSEugene Leviant       break;
784eda81a1bSEugene Leviant     Expr.push_back(Tok);
785eda81a1bSEugene Leviant   }
786eda81a1bSEugene Leviant   return Expr;
787eda81a1bSEugene Leviant }
788eda81a1bSEugene Leviant 
789bbe38602SEugene Leviant std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() {
790bbe38602SEugene Leviant   std::vector<StringRef> Phdrs;
791bbe38602SEugene Leviant   while (!Error && peek().startswith(":")) {
792bbe38602SEugene Leviant     StringRef Tok = next();
793bbe38602SEugene Leviant     Tok = (Tok.size() == 1) ? next() : Tok.substr(1);
794bbe38602SEugene Leviant     if (Tok.empty()) {
795bbe38602SEugene Leviant       setError("section header name is empty");
796bbe38602SEugene Leviant       break;
797bbe38602SEugene Leviant     }
798bbe38602SEugene Leviant     Phdrs.push_back(Tok);
799bbe38602SEugene Leviant   }
800bbe38602SEugene Leviant   return Phdrs;
801bbe38602SEugene Leviant }
802bbe38602SEugene Leviant 
803bbe38602SEugene Leviant unsigned ScriptParser::readPhdrType() {
804bbe38602SEugene Leviant   StringRef Tok = next();
805b0f6c590SRui Ueyama   unsigned Ret = StringSwitch<unsigned>(Tok)
806b0f6c590SRui Ueyama       .Case("PT_NULL", PT_NULL)
807b0f6c590SRui Ueyama       .Case("PT_LOAD", PT_LOAD)
808b0f6c590SRui Ueyama       .Case("PT_DYNAMIC", PT_DYNAMIC)
809b0f6c590SRui Ueyama       .Case("PT_INTERP", PT_INTERP)
810b0f6c590SRui Ueyama       .Case("PT_NOTE", PT_NOTE)
811b0f6c590SRui Ueyama       .Case("PT_SHLIB", PT_SHLIB)
812b0f6c590SRui Ueyama       .Case("PT_PHDR", PT_PHDR)
813b0f6c590SRui Ueyama       .Case("PT_TLS", PT_TLS)
814b0f6c590SRui Ueyama       .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME)
815b0f6c590SRui Ueyama       .Case("PT_GNU_STACK", PT_GNU_STACK)
816b0f6c590SRui Ueyama       .Case("PT_GNU_RELRO", PT_GNU_RELRO)
817b0f6c590SRui Ueyama       .Default(-1);
818bbe38602SEugene Leviant 
819b0f6c590SRui Ueyama   if (Ret == (unsigned)-1) {
820b0f6c590SRui Ueyama     setError("invalid program header type: " + Tok);
821b0f6c590SRui Ueyama     return PT_NULL;
822b0f6c590SRui Ueyama   }
823b0f6c590SRui Ueyama   return Ret;
824bbe38602SEugene Leviant }
825bbe38602SEugene Leviant 
82616b0cc9eSSimon Atanasyan static bool isUnderSysroot(StringRef Path) {
82716b0cc9eSSimon Atanasyan   if (Config->Sysroot == "")
82816b0cc9eSSimon Atanasyan     return false;
82916b0cc9eSSimon Atanasyan   for (; !Path.empty(); Path = sys::path::parent_path(Path))
83016b0cc9eSSimon Atanasyan     if (sys::fs::equivalent(Config->Sysroot, Path))
83116b0cc9eSSimon Atanasyan       return true;
83216b0cc9eSSimon Atanasyan   return false;
83316b0cc9eSSimon Atanasyan }
83416b0cc9eSSimon Atanasyan 
83507320e40SRui Ueyama // Entry point.
83607320e40SRui Ueyama void elf::readLinkerScript(MemoryBufferRef MB) {
83716b0cc9eSSimon Atanasyan   StringRef Path = MB.getBufferIdentifier();
83807320e40SRui Ueyama   ScriptParser(MB.getBuffer(), isUnderSysroot(Path)).run();
839f7c5fbb1SRui Ueyama }
8401ebc8ed7SRui Ueyama 
84107320e40SRui Ueyama template class elf::LinkerScript<ELF32LE>;
84207320e40SRui Ueyama template class elf::LinkerScript<ELF32BE>;
84307320e40SRui Ueyama template class elf::LinkerScript<ELF64LE>;
84407320e40SRui Ueyama template class elf::LinkerScript<ELF64BE>;
845