197c3811cSEd Maste //===- ScriptParser.cpp ---------------------------------------------------===//
297c3811cSEd Maste //
397c3811cSEd Maste //                             The LLVM Linker
497c3811cSEd Maste //
597c3811cSEd Maste // This file is distributed under the University of Illinois Open Source
697c3811cSEd Maste // License. See LICENSE.TXT for details.
797c3811cSEd Maste //
897c3811cSEd Maste //===----------------------------------------------------------------------===//
997c3811cSEd Maste //
1046b69c69SDimitry Andric // This file contains a recursive-descendent parser for linker scripts.
1146b69c69SDimitry Andric // Parsed results are stored to Config and Script global objects.
1297c3811cSEd Maste //
1397c3811cSEd Maste //===----------------------------------------------------------------------===//
1497c3811cSEd Maste 
1597c3811cSEd Maste #include "ScriptParser.h"
1646b69c69SDimitry Andric #include "Config.h"
1746b69c69SDimitry Andric #include "Driver.h"
1846b69c69SDimitry Andric #include "InputSection.h"
1946b69c69SDimitry Andric #include "LinkerScript.h"
2046b69c69SDimitry Andric #include "OutputSections.h"
2146b69c69SDimitry Andric #include "ScriptLexer.h"
2246b69c69SDimitry Andric #include "Symbols.h"
2346b69c69SDimitry Andric #include "Target.h"
2410dc89a5SDimitry Andric #include "lld/Common/Memory.h"
2546b69c69SDimitry Andric #include "llvm/ADT/SmallString.h"
2646b69c69SDimitry Andric #include "llvm/ADT/StringRef.h"
2710dc89a5SDimitry Andric #include "llvm/ADT/StringSet.h"
2846b69c69SDimitry Andric #include "llvm/ADT/StringSwitch.h"
29db17bf38SDimitry Andric #include "llvm/BinaryFormat/ELF.h"
3046b69c69SDimitry Andric #include "llvm/Support/Casting.h"
3146b69c69SDimitry Andric #include "llvm/Support/ErrorHandling.h"
3246b69c69SDimitry Andric #include "llvm/Support/FileSystem.h"
3346b69c69SDimitry Andric #include "llvm/Support/Path.h"
3446b69c69SDimitry Andric #include <cassert>
3546b69c69SDimitry Andric #include <limits>
3646b69c69SDimitry Andric #include <vector>
3797c3811cSEd Maste 
3897c3811cSEd Maste using namespace llvm;
3946b69c69SDimitry Andric using namespace llvm::ELF;
4046b69c69SDimitry Andric using namespace llvm::support::endian;
4197c3811cSEd Maste using namespace lld;
4297c3811cSEd Maste using namespace lld::elf;
4397c3811cSEd Maste 
4446b69c69SDimitry Andric static bool isUnderSysroot(StringRef Path);
451189dbaaSDimitry Andric 
4646b69c69SDimitry Andric namespace {
4746b69c69SDimitry Andric class ScriptParser final : ScriptLexer {
4846b69c69SDimitry Andric public:
ScriptParser(MemoryBufferRef MB)4946b69c69SDimitry Andric   ScriptParser(MemoryBufferRef MB)
5046b69c69SDimitry Andric       : ScriptLexer(MB),
5146b69c69SDimitry Andric         IsUnderSysroot(isUnderSysroot(MB.getBufferIdentifier())) {}
5297c3811cSEd Maste 
5346b69c69SDimitry Andric   void readLinkerScript();
5446b69c69SDimitry Andric   void readVersionScript();
5546b69c69SDimitry Andric   void readDynamicList();
5610dc89a5SDimitry Andric   void readDefsym(StringRef Name);
5797c3811cSEd Maste 
5846b69c69SDimitry Andric private:
5946b69c69SDimitry Andric   void addFile(StringRef Path);
601189dbaaSDimitry Andric 
6146b69c69SDimitry Andric   void readAsNeeded();
6246b69c69SDimitry Andric   void readEntry();
6346b69c69SDimitry Andric   void readExtern();
6446b69c69SDimitry Andric   void readGroup();
6546b69c69SDimitry Andric   void readInclude();
664ba319b5SDimitry Andric   void readInput();
6746b69c69SDimitry Andric   void readMemory();
6846b69c69SDimitry Andric   void readOutput();
6946b69c69SDimitry Andric   void readOutputArch();
7046b69c69SDimitry Andric   void readOutputFormat();
7146b69c69SDimitry Andric   void readPhdrs();
7210dc89a5SDimitry Andric   void readRegionAlias();
7346b69c69SDimitry Andric   void readSearchDir();
7446b69c69SDimitry Andric   void readSections();
75*b5893f02SDimitry Andric   void readTarget();
7646b69c69SDimitry Andric   void readVersion();
7746b69c69SDimitry Andric   void readVersionScriptCommand();
781189dbaaSDimitry Andric 
794ba319b5SDimitry Andric   SymbolAssignment *readSymbolAssignment(StringRef Name);
8010dc89a5SDimitry Andric   ByteCommand *readByteCommand(StringRef Tok);
81*b5893f02SDimitry Andric   std::array<uint8_t, 4> readFill();
82*b5893f02SDimitry Andric   std::array<uint8_t, 4> parseFill(StringRef Tok);
83*b5893f02SDimitry Andric   bool readSectionDirective(OutputSection *Cmd, StringRef Tok1, StringRef Tok2);
8410dc89a5SDimitry Andric   void readSectionAddressType(OutputSection *Cmd);
854ba319b5SDimitry Andric   OutputSection *readOverlaySectionDescription();
8610dc89a5SDimitry Andric   OutputSection *readOutputSectionDescription(StringRef OutSec);
874ba319b5SDimitry Andric   std::vector<BaseCommand *> readOverlay();
8846b69c69SDimitry Andric   std::vector<StringRef> readOutputSectionPhdrs();
8946b69c69SDimitry Andric   InputSectionDescription *readInputSectionDescription(StringRef Tok);
9046b69c69SDimitry Andric   StringMatcher readFilePatterns();
9146b69c69SDimitry Andric   std::vector<SectionPattern> readInputSectionsList();
9246b69c69SDimitry Andric   InputSectionDescription *readInputSectionRules(StringRef FilePattern);
9346b69c69SDimitry Andric   unsigned readPhdrType();
9446b69c69SDimitry Andric   SortSectionPolicy readSortKind();
9546b69c69SDimitry Andric   SymbolAssignment *readProvideHidden(bool Provide, bool Hidden);
964ba319b5SDimitry Andric   SymbolAssignment *readAssignment(StringRef Tok);
9746b69c69SDimitry Andric   void readSort();
984ba319b5SDimitry Andric   Expr readAssert();
9910dc89a5SDimitry Andric   Expr readConstant();
10010dc89a5SDimitry Andric   Expr getPageSize();
1011189dbaaSDimitry Andric 
10246b69c69SDimitry Andric   uint64_t readMemoryAssignment(StringRef, StringRef, StringRef);
10346b69c69SDimitry Andric   std::pair<uint32_t, uint32_t> readMemoryAttributes();
1041189dbaaSDimitry Andric 
1054ba319b5SDimitry Andric   Expr combine(StringRef Op, Expr L, Expr R);
10646b69c69SDimitry Andric   Expr readExpr();
10746b69c69SDimitry Andric   Expr readExpr1(Expr Lhs, int MinPrec);
10846b69c69SDimitry Andric   StringRef readParenLiteral();
10946b69c69SDimitry Andric   Expr readPrimary();
11046b69c69SDimitry Andric   Expr readTernary(Expr Cond);
11146b69c69SDimitry Andric   Expr readParenExpr();
1121189dbaaSDimitry Andric 
11346b69c69SDimitry Andric   // For parsing version script.
11446b69c69SDimitry Andric   std::vector<SymbolVersion> readVersionExtern();
11546b69c69SDimitry Andric   void readAnonymousDeclaration();
11646b69c69SDimitry Andric   void readVersionDeclaration(StringRef VerStr);
11797c3811cSEd Maste 
11846b69c69SDimitry Andric   std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>>
11946b69c69SDimitry Andric   readSymbols();
1201189dbaaSDimitry Andric 
12110dc89a5SDimitry Andric   // True if a script being read is in a subdirectory specified by -sysroot.
12246b69c69SDimitry Andric   bool IsUnderSysroot;
12310dc89a5SDimitry Andric 
12410dc89a5SDimitry Andric   // A set to detect an INCLUDE() cycle.
12510dc89a5SDimitry Andric   StringSet<> Seen;
12646b69c69SDimitry Andric };
12746b69c69SDimitry Andric } // namespace
12897c3811cSEd Maste 
unquote(StringRef S)129b40b48b8SDimitry Andric static StringRef unquote(StringRef S) {
130b40b48b8SDimitry Andric   if (S.startswith("\""))
131b40b48b8SDimitry Andric     return S.substr(1, S.size() - 2);
132b40b48b8SDimitry Andric   return S;
133b40b48b8SDimitry Andric }
134b40b48b8SDimitry Andric 
isUnderSysroot(StringRef Path)13546b69c69SDimitry Andric static bool isUnderSysroot(StringRef Path) {
13646b69c69SDimitry Andric   if (Config->Sysroot == "")
13746b69c69SDimitry Andric     return false;
13846b69c69SDimitry Andric   for (; !Path.empty(); Path = sys::path::parent_path(Path))
13946b69c69SDimitry Andric     if (sys::fs::equivalent(Config->Sysroot, Path))
14097c3811cSEd Maste       return true;
1411189dbaaSDimitry Andric   return false;
1421189dbaaSDimitry Andric }
1431189dbaaSDimitry Andric 
14446b69c69SDimitry Andric // Some operations only support one non absolute value. Move the
14546b69c69SDimitry Andric // absolute one to the right hand side for convenience.
moveAbsRight(ExprValue & A,ExprValue & B)14646b69c69SDimitry Andric static void moveAbsRight(ExprValue &A, ExprValue &B) {
14710dc89a5SDimitry Andric   if (A.Sec == nullptr || (A.ForceAbsolute && !B.isAbsolute()))
14846b69c69SDimitry Andric     std::swap(A, B);
14946b69c69SDimitry Andric   if (!B.isAbsolute())
150db17bf38SDimitry Andric     error(A.Loc + ": at least one side of the expression must be absolute");
15146b69c69SDimitry Andric }
15297c3811cSEd Maste 
add(ExprValue A,ExprValue B)15346b69c69SDimitry Andric static ExprValue add(ExprValue A, ExprValue B) {
15446b69c69SDimitry Andric   moveAbsRight(A, B);
15510dc89a5SDimitry Andric   return {A.Sec, A.ForceAbsolute, A.getSectionOffset() + B.getValue(), A.Loc};
15646b69c69SDimitry Andric }
15746b69c69SDimitry Andric 
sub(ExprValue A,ExprValue B)15846b69c69SDimitry Andric static ExprValue sub(ExprValue A, ExprValue B) {
159fe4fed2eSDimitry Andric   // The distance between two symbols in sections is absolute.
1608ca4c80bSDimitry Andric   if (!A.isAbsolute() && !B.isAbsolute())
1618ca4c80bSDimitry Andric     return A.getValue() - B.getValue();
16210dc89a5SDimitry Andric   return {A.Sec, false, A.getSectionOffset() - B.getValue(), A.Loc};
16346b69c69SDimitry Andric }
16446b69c69SDimitry Andric 
bitAnd(ExprValue A,ExprValue B)16546b69c69SDimitry Andric static ExprValue bitAnd(ExprValue A, ExprValue B) {
16646b69c69SDimitry Andric   moveAbsRight(A, B);
16746b69c69SDimitry Andric   return {A.Sec, A.ForceAbsolute,
168db17bf38SDimitry Andric           (A.getValue() & B.getValue()) - A.getSecAddr(), A.Loc};
16946b69c69SDimitry Andric }
17046b69c69SDimitry Andric 
bitOr(ExprValue A,ExprValue B)17146b69c69SDimitry Andric static ExprValue bitOr(ExprValue A, ExprValue B) {
17246b69c69SDimitry Andric   moveAbsRight(A, B);
17346b69c69SDimitry Andric   return {A.Sec, A.ForceAbsolute,
174db17bf38SDimitry Andric           (A.getValue() | B.getValue()) - A.getSecAddr(), A.Loc};
17546b69c69SDimitry Andric }
17646b69c69SDimitry Andric 
readDynamicList()17746b69c69SDimitry Andric void ScriptParser::readDynamicList() {
17810dc89a5SDimitry Andric   Config->HasDynamicList = true;
17946b69c69SDimitry Andric   expect("{");
18010dc89a5SDimitry Andric   std::vector<SymbolVersion> Locals;
18110dc89a5SDimitry Andric   std::vector<SymbolVersion> Globals;
18210dc89a5SDimitry Andric   std::tie(Locals, Globals) = readSymbols();
18310dc89a5SDimitry Andric   expect(";");
18410dc89a5SDimitry Andric 
18510dc89a5SDimitry Andric   if (!atEOF()) {
18646b69c69SDimitry Andric     setError("EOF expected, but got " + next());
18710dc89a5SDimitry Andric     return;
18810dc89a5SDimitry Andric   }
18910dc89a5SDimitry Andric   if (!Locals.empty()) {
19010dc89a5SDimitry Andric     setError("\"local:\" scope not supported in --dynamic-list");
19110dc89a5SDimitry Andric     return;
19210dc89a5SDimitry Andric   }
19310dc89a5SDimitry Andric 
19410dc89a5SDimitry Andric   for (SymbolVersion V : Globals)
19510dc89a5SDimitry Andric     Config->DynamicList.push_back(V);
19646b69c69SDimitry Andric }
19746b69c69SDimitry Andric 
readVersionScript()19846b69c69SDimitry Andric void ScriptParser::readVersionScript() {
19946b69c69SDimitry Andric   readVersionScriptCommand();
20046b69c69SDimitry Andric   if (!atEOF())
20146b69c69SDimitry Andric     setError("EOF expected, but got " + next());
20246b69c69SDimitry Andric }
20346b69c69SDimitry Andric 
readVersionScriptCommand()20446b69c69SDimitry Andric void ScriptParser::readVersionScriptCommand() {
20546b69c69SDimitry Andric   if (consume("{")) {
20646b69c69SDimitry Andric     readAnonymousDeclaration();
20797c3811cSEd Maste     return;
20846b69c69SDimitry Andric   }
20946b69c69SDimitry Andric 
21010dc89a5SDimitry Andric   while (!atEOF() && !errorCount() && peek() != "}") {
21146b69c69SDimitry Andric     StringRef VerStr = next();
21246b69c69SDimitry Andric     if (VerStr == "{") {
21346b69c69SDimitry Andric       setError("anonymous version definition is used in "
21446b69c69SDimitry Andric                "combination with other version definitions");
21546b69c69SDimitry Andric       return;
21646b69c69SDimitry Andric     }
21746b69c69SDimitry Andric     expect("{");
21846b69c69SDimitry Andric     readVersionDeclaration(VerStr);
21946b69c69SDimitry Andric   }
22046b69c69SDimitry Andric }
22146b69c69SDimitry Andric 
readVersion()22246b69c69SDimitry Andric void ScriptParser::readVersion() {
22346b69c69SDimitry Andric   expect("{");
22446b69c69SDimitry Andric   readVersionScriptCommand();
22546b69c69SDimitry Andric   expect("}");
22646b69c69SDimitry Andric }
22746b69c69SDimitry Andric 
readLinkerScript()22846b69c69SDimitry Andric void ScriptParser::readLinkerScript() {
22946b69c69SDimitry Andric   while (!atEOF()) {
23097c3811cSEd Maste     StringRef Tok = next();
23146b69c69SDimitry Andric     if (Tok == ";")
23246b69c69SDimitry Andric       continue;
23346b69c69SDimitry Andric 
2344ba319b5SDimitry Andric     if (Tok == "ENTRY") {
23546b69c69SDimitry Andric       readEntry();
23646b69c69SDimitry Andric     } else if (Tok == "EXTERN") {
23746b69c69SDimitry Andric       readExtern();
2384ba319b5SDimitry Andric     } else if (Tok == "GROUP") {
23946b69c69SDimitry Andric       readGroup();
24046b69c69SDimitry Andric     } else if (Tok == "INCLUDE") {
24146b69c69SDimitry Andric       readInclude();
2424ba319b5SDimitry Andric     } else if (Tok == "INPUT") {
2434ba319b5SDimitry Andric       readInput();
24446b69c69SDimitry Andric     } else if (Tok == "MEMORY") {
24546b69c69SDimitry Andric       readMemory();
24646b69c69SDimitry Andric     } else if (Tok == "OUTPUT") {
24746b69c69SDimitry Andric       readOutput();
24846b69c69SDimitry Andric     } else if (Tok == "OUTPUT_ARCH") {
24946b69c69SDimitry Andric       readOutputArch();
25046b69c69SDimitry Andric     } else if (Tok == "OUTPUT_FORMAT") {
25146b69c69SDimitry Andric       readOutputFormat();
25246b69c69SDimitry Andric     } else if (Tok == "PHDRS") {
25346b69c69SDimitry Andric       readPhdrs();
25410dc89a5SDimitry Andric     } else if (Tok == "REGION_ALIAS") {
25510dc89a5SDimitry Andric       readRegionAlias();
25646b69c69SDimitry Andric     } else if (Tok == "SEARCH_DIR") {
25746b69c69SDimitry Andric       readSearchDir();
25846b69c69SDimitry Andric     } else if (Tok == "SECTIONS") {
25946b69c69SDimitry Andric       readSections();
260*b5893f02SDimitry Andric     } else if (Tok == "TARGET") {
261*b5893f02SDimitry Andric       readTarget();
26246b69c69SDimitry Andric     } else if (Tok == "VERSION") {
26346b69c69SDimitry Andric       readVersion();
2644ba319b5SDimitry Andric     } else if (SymbolAssignment *Cmd = readAssignment(Tok)) {
26510dc89a5SDimitry Andric       Script->SectionCommands.push_back(Cmd);
26646b69c69SDimitry Andric     } else {
26746b69c69SDimitry Andric       setError("unknown directive: " + Tok);
26846b69c69SDimitry Andric     }
26946b69c69SDimitry Andric   }
27097c3811cSEd Maste }
27197c3811cSEd Maste 
readDefsym(StringRef Name)27210dc89a5SDimitry Andric void ScriptParser::readDefsym(StringRef Name) {
273*b5893f02SDimitry Andric   if (errorCount())
274*b5893f02SDimitry Andric     return;
27510dc89a5SDimitry Andric   Expr E = readExpr();
27610dc89a5SDimitry Andric   if (!atEOF())
27710dc89a5SDimitry Andric     setError("EOF expected, but got " + next());
27810dc89a5SDimitry Andric   SymbolAssignment *Cmd = make<SymbolAssignment>(Name, E, getCurrentLocation());
27910dc89a5SDimitry Andric   Script->SectionCommands.push_back(Cmd);
28010dc89a5SDimitry Andric }
28110dc89a5SDimitry Andric 
addFile(StringRef S)28246b69c69SDimitry Andric void ScriptParser::addFile(StringRef S) {
28346b69c69SDimitry Andric   if (IsUnderSysroot && S.startswith("/")) {
28446b69c69SDimitry Andric     SmallString<128> PathData;
28546b69c69SDimitry Andric     StringRef Path = (Config->Sysroot + S).toStringRef(PathData);
28646b69c69SDimitry Andric     if (sys::fs::exists(Path)) {
28746b69c69SDimitry Andric       Driver->addFile(Saver.save(Path), /*WithLOption=*/false);
28846b69c69SDimitry Andric       return;
28946b69c69SDimitry Andric     }
2901189dbaaSDimitry Andric   }
2911189dbaaSDimitry Andric 
29210dc89a5SDimitry Andric   if (S.startswith("/")) {
29346b69c69SDimitry Andric     Driver->addFile(S, /*WithLOption=*/false);
29446b69c69SDimitry Andric   } else if (S.startswith("=")) {
29546b69c69SDimitry Andric     if (Config->Sysroot.empty())
29646b69c69SDimitry Andric       Driver->addFile(S.substr(1), /*WithLOption=*/false);
29746b69c69SDimitry Andric     else
29846b69c69SDimitry Andric       Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1)),
29946b69c69SDimitry Andric                       /*WithLOption=*/false);
30046b69c69SDimitry Andric   } else if (S.startswith("-l")) {
30146b69c69SDimitry Andric     Driver->addLibrary(S.substr(2));
30246b69c69SDimitry Andric   } else if (sys::fs::exists(S)) {
30346b69c69SDimitry Andric     Driver->addFile(S, /*WithLOption=*/false);
30446b69c69SDimitry Andric   } else {
30546b69c69SDimitry Andric     if (Optional<std::string> Path = findFromSearchPaths(S))
30646b69c69SDimitry Andric       Driver->addFile(Saver.save(*Path), /*WithLOption=*/true);
30746b69c69SDimitry Andric     else
30846b69c69SDimitry Andric       setError("unable to find " + S);
30946b69c69SDimitry Andric   }
31046b69c69SDimitry Andric }
3111189dbaaSDimitry Andric 
readAsNeeded()31246b69c69SDimitry Andric void ScriptParser::readAsNeeded() {
31346b69c69SDimitry Andric   expect("(");
31446b69c69SDimitry Andric   bool Orig = Config->AsNeeded;
31546b69c69SDimitry Andric   Config->AsNeeded = true;
31610dc89a5SDimitry Andric   while (!errorCount() && !consume(")"))
31746b69c69SDimitry Andric     addFile(unquote(next()));
31846b69c69SDimitry Andric   Config->AsNeeded = Orig;
31946b69c69SDimitry Andric }
32046b69c69SDimitry Andric 
readEntry()32146b69c69SDimitry Andric void ScriptParser::readEntry() {
32246b69c69SDimitry Andric   // -e <symbol> takes predecence over ENTRY(<symbol>).
32346b69c69SDimitry Andric   expect("(");
32446b69c69SDimitry Andric   StringRef Tok = next();
32546b69c69SDimitry Andric   if (Config->Entry.empty())
32646b69c69SDimitry Andric     Config->Entry = Tok;
32746b69c69SDimitry Andric   expect(")");
32846b69c69SDimitry Andric }
32946b69c69SDimitry Andric 
readExtern()33046b69c69SDimitry Andric void ScriptParser::readExtern() {
33146b69c69SDimitry Andric   expect("(");
33210dc89a5SDimitry Andric   while (!errorCount() && !consume(")"))
33346b69c69SDimitry Andric     Config->Undefined.push_back(next());
33446b69c69SDimitry Andric }
33546b69c69SDimitry Andric 
readGroup()33646b69c69SDimitry Andric void ScriptParser::readGroup() {
3374ba319b5SDimitry Andric   bool Orig = InputFile::IsInGroup;
3384ba319b5SDimitry Andric   InputFile::IsInGroup = true;
3394ba319b5SDimitry Andric   readInput();
3404ba319b5SDimitry Andric   InputFile::IsInGroup = Orig;
3414ba319b5SDimitry Andric   if (!Orig)
3424ba319b5SDimitry Andric     ++InputFile::NextGroupId;
34346b69c69SDimitry Andric }
34446b69c69SDimitry Andric 
readInclude()34546b69c69SDimitry Andric void ScriptParser::readInclude() {
34646b69c69SDimitry Andric   StringRef Tok = unquote(next());
34746b69c69SDimitry Andric 
34810dc89a5SDimitry Andric   if (!Seen.insert(Tok).second) {
34910dc89a5SDimitry Andric     setError("there is a cycle in linker script INCLUDEs");
35046b69c69SDimitry Andric     return;
35146b69c69SDimitry Andric   }
35210dc89a5SDimitry Andric 
3534ba319b5SDimitry Andric   if (Optional<std::string> Path = searchScript(Tok)) {
35446b69c69SDimitry Andric     if (Optional<MemoryBufferRef> MB = readFile(*Path))
35546b69c69SDimitry Andric       tokenize(*MB);
35646b69c69SDimitry Andric     return;
35746b69c69SDimitry Andric   }
35810dc89a5SDimitry Andric   setError("cannot find linker script " + Tok);
35946b69c69SDimitry Andric }
36046b69c69SDimitry Andric 
readInput()3614ba319b5SDimitry Andric void ScriptParser::readInput() {
3624ba319b5SDimitry Andric   expect("(");
3634ba319b5SDimitry Andric   while (!errorCount() && !consume(")")) {
3644ba319b5SDimitry Andric     if (consume("AS_NEEDED"))
3654ba319b5SDimitry Andric       readAsNeeded();
3664ba319b5SDimitry Andric     else
3674ba319b5SDimitry Andric       addFile(unquote(next()));
3684ba319b5SDimitry Andric   }
3694ba319b5SDimitry Andric }
3704ba319b5SDimitry Andric 
readOutput()37146b69c69SDimitry Andric void ScriptParser::readOutput() {
37246b69c69SDimitry Andric   // -o <file> takes predecence over OUTPUT(<file>).
37346b69c69SDimitry Andric   expect("(");
37446b69c69SDimitry Andric   StringRef Tok = next();
37546b69c69SDimitry Andric   if (Config->OutputFile.empty())
37646b69c69SDimitry Andric     Config->OutputFile = unquote(Tok);
37746b69c69SDimitry Andric   expect(")");
37846b69c69SDimitry Andric }
37946b69c69SDimitry Andric 
readOutputArch()38046b69c69SDimitry Andric void ScriptParser::readOutputArch() {
38146b69c69SDimitry Andric   // OUTPUT_ARCH is ignored for now.
38246b69c69SDimitry Andric   expect("(");
38310dc89a5SDimitry Andric   while (!errorCount() && !consume(")"))
38446b69c69SDimitry Andric     skip();
38546b69c69SDimitry Andric }
38646b69c69SDimitry Andric 
parseBfdName(StringRef S)387*b5893f02SDimitry Andric static std::pair<ELFKind, uint16_t> parseBfdName(StringRef S) {
388*b5893f02SDimitry Andric   return StringSwitch<std::pair<ELFKind, uint16_t>>(S)
389*b5893f02SDimitry Andric       .Case("elf32-i386", {ELF32LEKind, EM_386})
390*b5893f02SDimitry Andric       .Case("elf32-iamcu", {ELF32LEKind, EM_IAMCU})
391*b5893f02SDimitry Andric       .Case("elf32-littlearm", {ELF32LEKind, EM_ARM})
392*b5893f02SDimitry Andric       .Case("elf32-x86-64", {ELF32LEKind, EM_X86_64})
393*b5893f02SDimitry Andric       .Case("elf64-aarch64", {ELF64LEKind, EM_AARCH64})
394*b5893f02SDimitry Andric       .Case("elf64-littleaarch64", {ELF64LEKind, EM_AARCH64})
395*b5893f02SDimitry Andric       .Case("elf32-powerpc", {ELF32BEKind, EM_PPC})
396*b5893f02SDimitry Andric       .Case("elf64-powerpc", {ELF64BEKind, EM_PPC64})
397*b5893f02SDimitry Andric       .Case("elf64-powerpcle", {ELF64LEKind, EM_PPC64})
398*b5893f02SDimitry Andric       .Case("elf64-x86-64", {ELF64LEKind, EM_X86_64})
399*b5893f02SDimitry Andric       .Cases("elf32-tradbigmips", "elf32-bigmips", {ELF32BEKind, EM_MIPS})
400*b5893f02SDimitry Andric       .Case("elf32-ntradbigmips", {ELF32BEKind, EM_MIPS})
401*b5893f02SDimitry Andric       .Case("elf32-tradlittlemips", {ELF32LEKind, EM_MIPS})
402*b5893f02SDimitry Andric       .Case("elf32-ntradlittlemips", {ELF32LEKind, EM_MIPS})
403*b5893f02SDimitry Andric       .Case("elf64-tradbigmips", {ELF64BEKind, EM_MIPS})
404*b5893f02SDimitry Andric       .Case("elf64-tradlittlemips", {ELF64LEKind, EM_MIPS})
405*b5893f02SDimitry Andric       .Default({ELFNoneKind, EM_NONE});
406*b5893f02SDimitry Andric }
407*b5893f02SDimitry Andric 
408*b5893f02SDimitry Andric // Parse OUTPUT_FORMAT(bfdname) or OUTPUT_FORMAT(bfdname, big, little).
409*b5893f02SDimitry Andric // Currently we ignore big and little parameters.
readOutputFormat()41046b69c69SDimitry Andric void ScriptParser::readOutputFormat() {
41146b69c69SDimitry Andric   expect("(");
412*b5893f02SDimitry Andric 
413*b5893f02SDimitry Andric   StringRef Name = unquote(next());
414*b5893f02SDimitry Andric   StringRef S = Name;
415*b5893f02SDimitry Andric   if (S.consume_back("-freebsd"))
416*b5893f02SDimitry Andric     Config->OSABI = ELFOSABI_FREEBSD;
417*b5893f02SDimitry Andric 
418*b5893f02SDimitry Andric   std::tie(Config->EKind, Config->EMachine) = parseBfdName(S);
419*b5893f02SDimitry Andric   if (Config->EMachine == EM_NONE)
420*b5893f02SDimitry Andric     setError("unknown output format name: " + Name);
421*b5893f02SDimitry Andric   if (S == "elf32-ntradlittlemips" || S == "elf32-ntradbigmips")
422*b5893f02SDimitry Andric     Config->MipsN32Abi = true;
423*b5893f02SDimitry Andric 
42446b69c69SDimitry Andric   if (consume(")"))
42546b69c69SDimitry Andric     return;
42646b69c69SDimitry Andric   expect(",");
42746b69c69SDimitry Andric   skip();
42846b69c69SDimitry Andric   expect(",");
42946b69c69SDimitry Andric   skip();
43046b69c69SDimitry Andric   expect(")");
43146b69c69SDimitry Andric }
43246b69c69SDimitry Andric 
readPhdrs()43346b69c69SDimitry Andric void ScriptParser::readPhdrs() {
43446b69c69SDimitry Andric   expect("{");
43546b69c69SDimitry Andric 
43610dc89a5SDimitry Andric   while (!errorCount() && !consume("}")) {
43710dc89a5SDimitry Andric     PhdrsCommand Cmd;
43810dc89a5SDimitry Andric     Cmd.Name = next();
43910dc89a5SDimitry Andric     Cmd.Type = readPhdrType();
44046b69c69SDimitry Andric 
44110dc89a5SDimitry Andric     while (!errorCount() && !consume(";")) {
44246b69c69SDimitry Andric       if (consume("FILEHDR"))
44310dc89a5SDimitry Andric         Cmd.HasFilehdr = true;
44446b69c69SDimitry Andric       else if (consume("PHDRS"))
44510dc89a5SDimitry Andric         Cmd.HasPhdrs = true;
44646b69c69SDimitry Andric       else if (consume("AT"))
44710dc89a5SDimitry Andric         Cmd.LMAExpr = readParenExpr();
44846b69c69SDimitry Andric       else if (consume("FLAGS"))
44910dc89a5SDimitry Andric         Cmd.Flags = readParenExpr()().getValue();
45046b69c69SDimitry Andric       else
45146b69c69SDimitry Andric         setError("unexpected header attribute: " + next());
45246b69c69SDimitry Andric     }
45310dc89a5SDimitry Andric 
45410dc89a5SDimitry Andric     Script->PhdrsCommands.push_back(Cmd);
45546b69c69SDimitry Andric   }
45646b69c69SDimitry Andric }
45746b69c69SDimitry Andric 
readRegionAlias()45810dc89a5SDimitry Andric void ScriptParser::readRegionAlias() {
45910dc89a5SDimitry Andric   expect("(");
46010dc89a5SDimitry Andric   StringRef Alias = unquote(next());
46110dc89a5SDimitry Andric   expect(",");
46210dc89a5SDimitry Andric   StringRef Name = next();
46310dc89a5SDimitry Andric   expect(")");
46410dc89a5SDimitry Andric 
46510dc89a5SDimitry Andric   if (Script->MemoryRegions.count(Alias))
46610dc89a5SDimitry Andric     setError("redefinition of memory region '" + Alias + "'");
46710dc89a5SDimitry Andric   if (!Script->MemoryRegions.count(Name))
46810dc89a5SDimitry Andric     setError("memory region '" + Name + "' is not defined");
46910dc89a5SDimitry Andric   Script->MemoryRegions.insert({Alias, Script->MemoryRegions[Name]});
47010dc89a5SDimitry Andric }
47110dc89a5SDimitry Andric 
readSearchDir()47246b69c69SDimitry Andric void ScriptParser::readSearchDir() {
47346b69c69SDimitry Andric   expect("(");
47446b69c69SDimitry Andric   StringRef Tok = next();
47546b69c69SDimitry Andric   if (!Config->Nostdlib)
47646b69c69SDimitry Andric     Config->SearchPaths.push_back(unquote(Tok));
47746b69c69SDimitry Andric   expect(")");
47846b69c69SDimitry Andric }
47946b69c69SDimitry Andric 
4804ba319b5SDimitry Andric // This reads an overlay description. Overlays are used to describe output
4814ba319b5SDimitry Andric // sections that use the same virtual memory range and normally would trigger
4824ba319b5SDimitry Andric // linker's sections sanity check failures.
4834ba319b5SDimitry Andric // https://sourceware.org/binutils/docs/ld/Overlay-Description.html#Overlay-Description
readOverlay()4844ba319b5SDimitry Andric std::vector<BaseCommand *> ScriptParser::readOverlay() {
4854ba319b5SDimitry Andric   // VA and LMA expressions are optional, though for simplicity of
4864ba319b5SDimitry Andric   // implementation we assume they are not. That is what OVERLAY was designed
4874ba319b5SDimitry Andric   // for first of all: to allow sections with overlapping VAs at different LMAs.
4884ba319b5SDimitry Andric   Expr AddrExpr = readExpr();
4894ba319b5SDimitry Andric   expect(":");
4904ba319b5SDimitry Andric   expect("AT");
4914ba319b5SDimitry Andric   Expr LMAExpr = readParenExpr();
4924ba319b5SDimitry Andric   expect("{");
4934ba319b5SDimitry Andric 
4944ba319b5SDimitry Andric   std::vector<BaseCommand *> V;
4954ba319b5SDimitry Andric   OutputSection *Prev = nullptr;
4964ba319b5SDimitry Andric   while (!errorCount() && !consume("}")) {
4974ba319b5SDimitry Andric     // VA is the same for all sections. The LMAs are consecutive in memory
4984ba319b5SDimitry Andric     // starting from the base load address specified.
4994ba319b5SDimitry Andric     OutputSection *OS = readOverlaySectionDescription();
5004ba319b5SDimitry Andric     OS->AddrExpr = AddrExpr;
5014ba319b5SDimitry Andric     if (Prev)
5024ba319b5SDimitry Andric       OS->LMAExpr = [=] { return Prev->getLMA() + Prev->Size; };
5034ba319b5SDimitry Andric     else
5044ba319b5SDimitry Andric       OS->LMAExpr = LMAExpr;
5054ba319b5SDimitry Andric     V.push_back(OS);
5064ba319b5SDimitry Andric     Prev = OS;
5074ba319b5SDimitry Andric   }
5084ba319b5SDimitry Andric 
5094ba319b5SDimitry Andric   // According to the specification, at the end of the overlay, the location
5104ba319b5SDimitry Andric   // counter should be equal to the overlay base address plus size of the
5114ba319b5SDimitry Andric   // largest section seen in the overlay.
5124ba319b5SDimitry Andric   // Here we want to create the Dot assignment command to achieve that.
5134ba319b5SDimitry Andric   Expr MoveDot = [=] {
5144ba319b5SDimitry Andric     uint64_t Max = 0;
5154ba319b5SDimitry Andric     for (BaseCommand *Cmd : V)
5164ba319b5SDimitry Andric       Max = std::max(Max, cast<OutputSection>(Cmd)->Size);
5174ba319b5SDimitry Andric     return AddrExpr().getValue() + Max;
5184ba319b5SDimitry Andric   };
5194ba319b5SDimitry Andric   V.push_back(make<SymbolAssignment>(".", MoveDot, getCurrentLocation()));
5204ba319b5SDimitry Andric   return V;
5214ba319b5SDimitry Andric }
5224ba319b5SDimitry Andric 
readSections()52346b69c69SDimitry Andric void ScriptParser::readSections() {
52410dc89a5SDimitry Andric   Script->HasSectionsCommand = true;
52546b69c69SDimitry Andric 
52646b69c69SDimitry Andric   // -no-rosegment is used to avoid placing read only non-executable sections in
52746b69c69SDimitry Andric   // their own segment. We do the same if SECTIONS command is present in linker
52846b69c69SDimitry Andric   // script. See comment for computeFlags().
52946b69c69SDimitry Andric   Config->SingleRoRx = true;
53046b69c69SDimitry Andric 
53146b69c69SDimitry Andric   expect("{");
5324ba319b5SDimitry Andric   std::vector<BaseCommand *> V;
53310dc89a5SDimitry Andric   while (!errorCount() && !consume("}")) {
53446b69c69SDimitry Andric     StringRef Tok = next();
5354ba319b5SDimitry Andric     if (Tok == "OVERLAY") {
5364ba319b5SDimitry Andric       for (BaseCommand *Cmd : readOverlay())
5374ba319b5SDimitry Andric         V.push_back(Cmd);
5384ba319b5SDimitry Andric       continue;
5394ba319b5SDimitry Andric     } else if (Tok == "INCLUDE") {
5404ba319b5SDimitry Andric       readInclude();
5414ba319b5SDimitry Andric       continue;
5424ba319b5SDimitry Andric     }
5434ba319b5SDimitry Andric 
5444ba319b5SDimitry Andric     if (BaseCommand *Cmd = readAssignment(Tok))
5454ba319b5SDimitry Andric       V.push_back(Cmd);
54646b69c69SDimitry Andric     else
5474ba319b5SDimitry Andric       V.push_back(readOutputSectionDescription(Tok));
54846b69c69SDimitry Andric   }
5494ba319b5SDimitry Andric 
5504ba319b5SDimitry Andric   if (!atEOF() && consume("INSERT")) {
5514ba319b5SDimitry Andric     std::vector<BaseCommand *> *Dest = nullptr;
5524ba319b5SDimitry Andric     if (consume("AFTER"))
5534ba319b5SDimitry Andric       Dest = &Script->InsertAfterCommands[next()];
5544ba319b5SDimitry Andric     else if (consume("BEFORE"))
5554ba319b5SDimitry Andric       Dest = &Script->InsertBeforeCommands[next()];
5564ba319b5SDimitry Andric     else
5574ba319b5SDimitry Andric       setError("expected AFTER/BEFORE, but got '" + next() + "'");
5584ba319b5SDimitry Andric     if (Dest)
5594ba319b5SDimitry Andric       Dest->insert(Dest->end(), V.begin(), V.end());
5604ba319b5SDimitry Andric     return;
56146b69c69SDimitry Andric   }
5624ba319b5SDimitry Andric 
5634ba319b5SDimitry Andric   Script->SectionCommands.insert(Script->SectionCommands.end(), V.begin(),
5644ba319b5SDimitry Andric                                  V.end());
56546b69c69SDimitry Andric }
56646b69c69SDimitry Andric 
readTarget()567*b5893f02SDimitry Andric void ScriptParser::readTarget() {
568*b5893f02SDimitry Andric   // TARGET(foo) is an alias for "--format foo". Unlike GNU linkers,
569*b5893f02SDimitry Andric   // we accept only a limited set of BFD names (i.e. "elf" or "binary")
570*b5893f02SDimitry Andric   // for --format. We recognize only /^elf/ and "binary" in the linker
571*b5893f02SDimitry Andric   // script as well.
572*b5893f02SDimitry Andric   expect("(");
573*b5893f02SDimitry Andric   StringRef Tok = next();
574*b5893f02SDimitry Andric   expect(")");
575*b5893f02SDimitry Andric 
576*b5893f02SDimitry Andric   if (Tok.startswith("elf"))
577*b5893f02SDimitry Andric     Config->FormatBinary = false;
578*b5893f02SDimitry Andric   else if (Tok == "binary")
579*b5893f02SDimitry Andric     Config->FormatBinary = true;
580*b5893f02SDimitry Andric   else
581*b5893f02SDimitry Andric     setError("unknown target: " + Tok);
582*b5893f02SDimitry Andric }
583*b5893f02SDimitry Andric 
precedence(StringRef Op)58446b69c69SDimitry Andric static int precedence(StringRef Op) {
58546b69c69SDimitry Andric   return StringSwitch<int>(Op)
5864ba319b5SDimitry Andric       .Cases("*", "/", "%", 8)
5874ba319b5SDimitry Andric       .Cases("+", "-", 7)
5884ba319b5SDimitry Andric       .Cases("<<", ">>", 6)
5894ba319b5SDimitry Andric       .Cases("<", "<=", ">", ">=", "==", "!=", 5)
5904ba319b5SDimitry Andric       .Case("&", 4)
5914ba319b5SDimitry Andric       .Case("|", 3)
5924ba319b5SDimitry Andric       .Case("&&", 2)
5934ba319b5SDimitry Andric       .Case("||", 1)
59446b69c69SDimitry Andric       .Default(-1);
59546b69c69SDimitry Andric }
59646b69c69SDimitry Andric 
readFilePatterns()59746b69c69SDimitry Andric StringMatcher ScriptParser::readFilePatterns() {
59846b69c69SDimitry Andric   std::vector<StringRef> V;
59910dc89a5SDimitry Andric   while (!errorCount() && !consume(")"))
60046b69c69SDimitry Andric     V.push_back(next());
60146b69c69SDimitry Andric   return StringMatcher(V);
60246b69c69SDimitry Andric }
60346b69c69SDimitry Andric 
readSortKind()60446b69c69SDimitry Andric SortSectionPolicy ScriptParser::readSortKind() {
60546b69c69SDimitry Andric   if (consume("SORT") || consume("SORT_BY_NAME"))
60646b69c69SDimitry Andric     return SortSectionPolicy::Name;
60746b69c69SDimitry Andric   if (consume("SORT_BY_ALIGNMENT"))
60846b69c69SDimitry Andric     return SortSectionPolicy::Alignment;
60946b69c69SDimitry Andric   if (consume("SORT_BY_INIT_PRIORITY"))
61046b69c69SDimitry Andric     return SortSectionPolicy::Priority;
61146b69c69SDimitry Andric   if (consume("SORT_NONE"))
61246b69c69SDimitry Andric     return SortSectionPolicy::None;
61346b69c69SDimitry Andric   return SortSectionPolicy::Default;
61446b69c69SDimitry Andric }
61546b69c69SDimitry Andric 
61646b69c69SDimitry Andric // Reads SECTIONS command contents in the following form:
61746b69c69SDimitry Andric //
61846b69c69SDimitry Andric // <contents> ::= <elem>*
61946b69c69SDimitry Andric // <elem>     ::= <exclude>? <glob-pattern>
62046b69c69SDimitry Andric // <exclude>  ::= "EXCLUDE_FILE" "(" <glob-pattern>+ ")"
62146b69c69SDimitry Andric //
62246b69c69SDimitry Andric // For example,
62346b69c69SDimitry Andric //
62446b69c69SDimitry Andric // *(.foo EXCLUDE_FILE (a.o) .bar EXCLUDE_FILE (b.o) .baz)
62546b69c69SDimitry Andric //
62646b69c69SDimitry Andric // is parsed as ".foo", ".bar" with "a.o", and ".baz" with "b.o".
62746b69c69SDimitry Andric // The semantics of that is section .foo in any file, section .bar in
62846b69c69SDimitry Andric // any file but a.o, and section .baz in any file but b.o.
readInputSectionsList()62946b69c69SDimitry Andric std::vector<SectionPattern> ScriptParser::readInputSectionsList() {
63046b69c69SDimitry Andric   std::vector<SectionPattern> Ret;
63110dc89a5SDimitry Andric   while (!errorCount() && peek() != ")") {
63246b69c69SDimitry Andric     StringMatcher ExcludeFilePat;
63346b69c69SDimitry Andric     if (consume("EXCLUDE_FILE")) {
63446b69c69SDimitry Andric       expect("(");
63546b69c69SDimitry Andric       ExcludeFilePat = readFilePatterns();
63646b69c69SDimitry Andric     }
63746b69c69SDimitry Andric 
63846b69c69SDimitry Andric     std::vector<StringRef> V;
63910dc89a5SDimitry Andric     while (!errorCount() && peek() != ")" && peek() != "EXCLUDE_FILE")
64046b69c69SDimitry Andric       V.push_back(next());
64146b69c69SDimitry Andric 
64246b69c69SDimitry Andric     if (!V.empty())
64346b69c69SDimitry Andric       Ret.push_back({std::move(ExcludeFilePat), StringMatcher(V)});
64446b69c69SDimitry Andric     else
64546b69c69SDimitry Andric       setError("section pattern is expected");
64646b69c69SDimitry Andric   }
64746b69c69SDimitry Andric   return Ret;
64846b69c69SDimitry Andric }
64946b69c69SDimitry Andric 
65046b69c69SDimitry Andric // Reads contents of "SECTIONS" directive. That directive contains a
65146b69c69SDimitry Andric // list of glob patterns for input sections. The grammar is as follows.
65246b69c69SDimitry Andric //
65346b69c69SDimitry Andric // <patterns> ::= <section-list>
65446b69c69SDimitry Andric //              | <sort> "(" <section-list> ")"
65546b69c69SDimitry Andric //              | <sort> "(" <sort> "(" <section-list> ")" ")"
65646b69c69SDimitry Andric //
65746b69c69SDimitry Andric // <sort>     ::= "SORT" | "SORT_BY_NAME" | "SORT_BY_ALIGNMENT"
65846b69c69SDimitry Andric //              | "SORT_BY_INIT_PRIORITY" | "SORT_NONE"
65946b69c69SDimitry Andric //
66046b69c69SDimitry Andric // <section-list> is parsed by readInputSectionsList().
66146b69c69SDimitry Andric InputSectionDescription *
readInputSectionRules(StringRef FilePattern)66246b69c69SDimitry Andric ScriptParser::readInputSectionRules(StringRef FilePattern) {
66346b69c69SDimitry Andric   auto *Cmd = make<InputSectionDescription>(FilePattern);
66446b69c69SDimitry Andric   expect("(");
66546b69c69SDimitry Andric 
66610dc89a5SDimitry Andric   while (!errorCount() && !consume(")")) {
66746b69c69SDimitry Andric     SortSectionPolicy Outer = readSortKind();
66846b69c69SDimitry Andric     SortSectionPolicy Inner = SortSectionPolicy::Default;
66946b69c69SDimitry Andric     std::vector<SectionPattern> V;
67046b69c69SDimitry Andric     if (Outer != SortSectionPolicy::Default) {
67146b69c69SDimitry Andric       expect("(");
67246b69c69SDimitry Andric       Inner = readSortKind();
67346b69c69SDimitry Andric       if (Inner != SortSectionPolicy::Default) {
67446b69c69SDimitry Andric         expect("(");
67546b69c69SDimitry Andric         V = readInputSectionsList();
67646b69c69SDimitry Andric         expect(")");
67746b69c69SDimitry Andric       } else {
67846b69c69SDimitry Andric         V = readInputSectionsList();
67946b69c69SDimitry Andric       }
68046b69c69SDimitry Andric       expect(")");
68146b69c69SDimitry Andric     } else {
68246b69c69SDimitry Andric       V = readInputSectionsList();
68346b69c69SDimitry Andric     }
68446b69c69SDimitry Andric 
68546b69c69SDimitry Andric     for (SectionPattern &Pat : V) {
68646b69c69SDimitry Andric       Pat.SortInner = Inner;
68746b69c69SDimitry Andric       Pat.SortOuter = Outer;
68846b69c69SDimitry Andric     }
68946b69c69SDimitry Andric 
69046b69c69SDimitry Andric     std::move(V.begin(), V.end(), std::back_inserter(Cmd->SectionPatterns));
69146b69c69SDimitry Andric   }
69246b69c69SDimitry Andric   return Cmd;
69346b69c69SDimitry Andric }
69446b69c69SDimitry Andric 
69546b69c69SDimitry Andric InputSectionDescription *
readInputSectionDescription(StringRef Tok)69646b69c69SDimitry Andric ScriptParser::readInputSectionDescription(StringRef Tok) {
69746b69c69SDimitry Andric   // Input section wildcard can be surrounded by KEEP.
69846b69c69SDimitry Andric   // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep
69946b69c69SDimitry Andric   if (Tok == "KEEP") {
70046b69c69SDimitry Andric     expect("(");
70146b69c69SDimitry Andric     StringRef FilePattern = next();
70246b69c69SDimitry Andric     InputSectionDescription *Cmd = readInputSectionRules(FilePattern);
70346b69c69SDimitry Andric     expect(")");
70410dc89a5SDimitry Andric     Script->KeptSections.push_back(Cmd);
70546b69c69SDimitry Andric     return Cmd;
70646b69c69SDimitry Andric   }
70746b69c69SDimitry Andric   return readInputSectionRules(Tok);
70846b69c69SDimitry Andric }
70946b69c69SDimitry Andric 
readSort()71046b69c69SDimitry Andric void ScriptParser::readSort() {
71146b69c69SDimitry Andric   expect("(");
71246b69c69SDimitry Andric   expect("CONSTRUCTORS");
71346b69c69SDimitry Andric   expect(")");
71446b69c69SDimitry Andric }
71546b69c69SDimitry Andric 
readAssert()7164ba319b5SDimitry Andric Expr ScriptParser::readAssert() {
71746b69c69SDimitry Andric   expect("(");
71846b69c69SDimitry Andric   Expr E = readExpr();
71946b69c69SDimitry Andric   expect(",");
72046b69c69SDimitry Andric   StringRef Msg = unquote(next());
72146b69c69SDimitry Andric   expect(")");
72246b69c69SDimitry Andric 
72346b69c69SDimitry Andric   return [=] {
72446b69c69SDimitry Andric     if (!E().getValue())
72546b69c69SDimitry Andric       error(Msg);
72646b69c69SDimitry Andric     return Script->getDot();
72746b69c69SDimitry Andric   };
72846b69c69SDimitry Andric }
72946b69c69SDimitry Andric 
73046b69c69SDimitry Andric // Reads a FILL(expr) command. We handle the FILL command as an
73146b69c69SDimitry Andric // alias for =fillexp section attribute, which is different from
73246b69c69SDimitry Andric // what GNU linkers do.
73346b69c69SDimitry Andric // https://sourceware.org/binutils/docs/ld/Output-Section-Data.html
readFill()734*b5893f02SDimitry Andric std::array<uint8_t, 4> ScriptParser::readFill() {
73546b69c69SDimitry Andric   expect("(");
736*b5893f02SDimitry Andric   std::array<uint8_t, 4> V = parseFill(next());
73746b69c69SDimitry Andric   expect(")");
73846b69c69SDimitry Andric   return V;
73946b69c69SDimitry Andric }
74046b69c69SDimitry Andric 
741*b5893f02SDimitry Andric // Tries to read the special directive for an output section definition which
742*b5893f02SDimitry Andric // can be one of following: "(NOLOAD)", "(COPY)", "(INFO)" or "(OVERLAY)".
743*b5893f02SDimitry Andric // Tok1 and Tok2 are next 2 tokens peeked. See comment for readSectionAddressType below.
readSectionDirective(OutputSection * Cmd,StringRef Tok1,StringRef Tok2)744*b5893f02SDimitry Andric bool ScriptParser::readSectionDirective(OutputSection *Cmd, StringRef Tok1, StringRef Tok2) {
745*b5893f02SDimitry Andric   if (Tok1 != "(")
746*b5893f02SDimitry Andric     return false;
747*b5893f02SDimitry Andric   if (Tok2 != "NOLOAD" && Tok2 != "COPY" && Tok2 != "INFO" && Tok2 != "OVERLAY")
748*b5893f02SDimitry Andric     return false;
749*b5893f02SDimitry Andric 
750*b5893f02SDimitry Andric   expect("(");
751*b5893f02SDimitry Andric   if (consume("NOLOAD")) {
752*b5893f02SDimitry Andric     Cmd->Noload = true;
753*b5893f02SDimitry Andric   } else {
754*b5893f02SDimitry Andric     skip(); // This is "COPY", "INFO" or "OVERLAY".
755*b5893f02SDimitry Andric     Cmd->NonAlloc = true;
756*b5893f02SDimitry Andric   }
757*b5893f02SDimitry Andric   expect(")");
758*b5893f02SDimitry Andric   return true;
759*b5893f02SDimitry Andric }
760*b5893f02SDimitry Andric 
7614ba319b5SDimitry Andric // Reads an expression and/or the special directive for an output
7624ba319b5SDimitry Andric // section definition. Directive is one of following: "(NOLOAD)",
7634ba319b5SDimitry Andric // "(COPY)", "(INFO)" or "(OVERLAY)".
764db17bf38SDimitry Andric //
765db17bf38SDimitry Andric // An output section name can be followed by an address expression
7664ba319b5SDimitry Andric // and/or directive. This grammar is not LL(1) because "(" can be
7674ba319b5SDimitry Andric // interpreted as either the beginning of some expression or beginning
7684ba319b5SDimitry Andric // of directive.
769db17bf38SDimitry Andric //
770db17bf38SDimitry Andric // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html
771db17bf38SDimitry Andric // https://sourceware.org/binutils/docs/ld/Output-Section-Type.html
readSectionAddressType(OutputSection * Cmd)77210dc89a5SDimitry Andric void ScriptParser::readSectionAddressType(OutputSection *Cmd) {
773*b5893f02SDimitry Andric   if (readSectionDirective(Cmd, peek(), peek2()))
774db17bf38SDimitry Andric     return;
775db17bf38SDimitry Andric 
776*b5893f02SDimitry Andric   Cmd->AddrExpr = readExpr();
777*b5893f02SDimitry Andric   if (peek() == "(" && !readSectionDirective(Cmd, "(", peek2()))
778*b5893f02SDimitry Andric     setError("unknown section directive: " + peek2());
779db17bf38SDimitry Andric }
780db17bf38SDimitry Andric 
checkAlignment(Expr E,std::string & Loc)78110dc89a5SDimitry Andric static Expr checkAlignment(Expr E, std::string &Loc) {
78210dc89a5SDimitry Andric   return [=] {
78310dc89a5SDimitry Andric     uint64_t Alignment = std::max((uint64_t)1, E().getValue());
78410dc89a5SDimitry Andric     if (!isPowerOf2_64(Alignment)) {
78510dc89a5SDimitry Andric       error(Loc + ": alignment must be power of 2");
78610dc89a5SDimitry Andric       return (uint64_t)1; // Return a dummy value.
78710dc89a5SDimitry Andric     }
78810dc89a5SDimitry Andric     return Alignment;
78910dc89a5SDimitry Andric   };
79010dc89a5SDimitry Andric }
79110dc89a5SDimitry Andric 
readOverlaySectionDescription()7924ba319b5SDimitry Andric OutputSection *ScriptParser::readOverlaySectionDescription() {
7934ba319b5SDimitry Andric   OutputSection *Cmd =
7944ba319b5SDimitry Andric       Script->createOutputSection(next(), getCurrentLocation());
7954ba319b5SDimitry Andric   Cmd->InOverlay = true;
7964ba319b5SDimitry Andric   expect("{");
7974ba319b5SDimitry Andric   while (!errorCount() && !consume("}"))
7984ba319b5SDimitry Andric     Cmd->SectionCommands.push_back(readInputSectionRules(next()));
7994ba319b5SDimitry Andric   Cmd->Phdrs = readOutputSectionPhdrs();
8004ba319b5SDimitry Andric   return Cmd;
8014ba319b5SDimitry Andric }
8024ba319b5SDimitry Andric 
readOutputSectionDescription(StringRef OutSec)80310dc89a5SDimitry Andric OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) {
80410dc89a5SDimitry Andric   OutputSection *Cmd =
80510dc89a5SDimitry Andric       Script->createOutputSection(OutSec, getCurrentLocation());
80646b69c69SDimitry Andric 
8074ba319b5SDimitry Andric   size_t SymbolsReferenced = Script->ReferencedSymbols.size();
8084ba319b5SDimitry Andric 
80946b69c69SDimitry Andric   if (peek() != ":")
810db17bf38SDimitry Andric     readSectionAddressType(Cmd);
81146b69c69SDimitry Andric   expect(":");
81246b69c69SDimitry Andric 
81310dc89a5SDimitry Andric   std::string Location = getCurrentLocation();
81446b69c69SDimitry Andric   if (consume("AT"))
81546b69c69SDimitry Andric     Cmd->LMAExpr = readParenExpr();
81646b69c69SDimitry Andric   if (consume("ALIGN"))
81710dc89a5SDimitry Andric     Cmd->AlignExpr = checkAlignment(readParenExpr(), Location);
81846b69c69SDimitry Andric   if (consume("SUBALIGN"))
81910dc89a5SDimitry Andric     Cmd->SubalignExpr = checkAlignment(readParenExpr(), Location);
82046b69c69SDimitry Andric 
82146b69c69SDimitry Andric   // Parse constraints.
82246b69c69SDimitry Andric   if (consume("ONLY_IF_RO"))
82346b69c69SDimitry Andric     Cmd->Constraint = ConstraintKind::ReadOnly;
82446b69c69SDimitry Andric   if (consume("ONLY_IF_RW"))
82546b69c69SDimitry Andric     Cmd->Constraint = ConstraintKind::ReadWrite;
82646b69c69SDimitry Andric   expect("{");
82746b69c69SDimitry Andric 
82810dc89a5SDimitry Andric   while (!errorCount() && !consume("}")) {
82946b69c69SDimitry Andric     StringRef Tok = next();
83046b69c69SDimitry Andric     if (Tok == ";") {
83146b69c69SDimitry Andric       // Empty commands are allowed. Do nothing here.
8324ba319b5SDimitry Andric     } else if (SymbolAssignment *Assign = readAssignment(Tok)) {
83310dc89a5SDimitry Andric       Cmd->SectionCommands.push_back(Assign);
83410dc89a5SDimitry Andric     } else if (ByteCommand *Data = readByteCommand(Tok)) {
83510dc89a5SDimitry Andric       Cmd->SectionCommands.push_back(Data);
83646b69c69SDimitry Andric     } else if (Tok == "CONSTRUCTORS") {
83746b69c69SDimitry Andric       // CONSTRUCTORS is a keyword to make the linker recognize C++ ctors/dtors
83846b69c69SDimitry Andric       // by name. This is for very old file formats such as ECOFF/XCOFF.
83946b69c69SDimitry Andric       // For ELF, we should ignore.
84046b69c69SDimitry Andric     } else if (Tok == "FILL") {
84146b69c69SDimitry Andric       Cmd->Filler = readFill();
84246b69c69SDimitry Andric     } else if (Tok == "SORT") {
84346b69c69SDimitry Andric       readSort();
8444ba319b5SDimitry Andric     } else if (Tok == "INCLUDE") {
8454ba319b5SDimitry Andric       readInclude();
84646b69c69SDimitry Andric     } else if (peek() == "(") {
84710dc89a5SDimitry Andric       Cmd->SectionCommands.push_back(readInputSectionDescription(Tok));
84846b69c69SDimitry Andric     } else {
849*b5893f02SDimitry Andric       // We have a file name and no input sections description. It is not a
850*b5893f02SDimitry Andric       // commonly used syntax, but still acceptable. In that case, all sections
851*b5893f02SDimitry Andric       // from the file will be included.
852*b5893f02SDimitry Andric       auto *ISD = make<InputSectionDescription>(Tok);
853*b5893f02SDimitry Andric       ISD->SectionPatterns.push_back({{}, StringMatcher({"*"})});
854*b5893f02SDimitry Andric       Cmd->SectionCommands.push_back(ISD);
85546b69c69SDimitry Andric     }
85646b69c69SDimitry Andric   }
85746b69c69SDimitry Andric 
85846b69c69SDimitry Andric   if (consume(">"))
85946b69c69SDimitry Andric     Cmd->MemoryRegionName = next();
86046b69c69SDimitry Andric 
861d3f08be7SEd Maste   if (consume("AT")) {
862d3f08be7SEd Maste     expect(">");
863d3f08be7SEd Maste     Cmd->LMARegionName = next();
864d3f08be7SEd Maste   }
865d3f08be7SEd Maste 
866d3f08be7SEd Maste   if (Cmd->LMAExpr && !Cmd->LMARegionName.empty())
867d3f08be7SEd Maste     error("section can't have both LMA and a load region");
868d3f08be7SEd Maste 
86946b69c69SDimitry Andric   Cmd->Phdrs = readOutputSectionPhdrs();
87046b69c69SDimitry Andric 
87146b69c69SDimitry Andric   if (consume("="))
87246b69c69SDimitry Andric     Cmd->Filler = parseFill(next());
87346b69c69SDimitry Andric   else if (peek().startswith("="))
87446b69c69SDimitry Andric     Cmd->Filler = parseFill(next().drop_front());
87546b69c69SDimitry Andric 
87646b69c69SDimitry Andric   // Consume optional comma following output section command.
87746b69c69SDimitry Andric   consume(",");
87846b69c69SDimitry Andric 
8794ba319b5SDimitry Andric   if (Script->ReferencedSymbols.size() > SymbolsReferenced)
8804ba319b5SDimitry Andric     Cmd->ExpressionsUseSymbols = true;
88146b69c69SDimitry Andric   return Cmd;
88246b69c69SDimitry Andric }
88346b69c69SDimitry Andric 
88446b69c69SDimitry Andric // Parses a given string as a octal/decimal/hexadecimal number and
88546b69c69SDimitry Andric // returns it as a big-endian number. Used for `=<fillexp>`.
88646b69c69SDimitry Andric // https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html
88746b69c69SDimitry Andric //
88846b69c69SDimitry Andric // When reading a hexstring, ld.bfd handles it as a blob of arbitrary
88946b69c69SDimitry Andric // size, while ld.gold always handles it as a 32-bit big-endian number.
89046b69c69SDimitry Andric // We are compatible with ld.gold because it's easier to implement.
parseFill(StringRef Tok)891*b5893f02SDimitry Andric std::array<uint8_t, 4> ScriptParser::parseFill(StringRef Tok) {
89246b69c69SDimitry Andric   uint32_t V = 0;
8935517e702SDimitry Andric   if (!to_integer(Tok, V))
89446b69c69SDimitry Andric     setError("invalid filler expression: " + Tok);
89546b69c69SDimitry Andric 
896*b5893f02SDimitry Andric   std::array<uint8_t, 4> Buf;
897*b5893f02SDimitry Andric   write32be(Buf.data(), V);
89846b69c69SDimitry Andric   return Buf;
89946b69c69SDimitry Andric }
90046b69c69SDimitry Andric 
readProvideHidden(bool Provide,bool Hidden)90146b69c69SDimitry Andric SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) {
90246b69c69SDimitry Andric   expect("(");
9034ba319b5SDimitry Andric   SymbolAssignment *Cmd = readSymbolAssignment(next());
90446b69c69SDimitry Andric   Cmd->Provide = Provide;
90546b69c69SDimitry Andric   Cmd->Hidden = Hidden;
90646b69c69SDimitry Andric   expect(")");
90746b69c69SDimitry Andric   return Cmd;
90846b69c69SDimitry Andric }
90946b69c69SDimitry Andric 
readAssignment(StringRef Tok)9104ba319b5SDimitry Andric SymbolAssignment *ScriptParser::readAssignment(StringRef Tok) {
9114ba319b5SDimitry Andric   // Assert expression returns Dot, so this is equal to ".=."
9124ba319b5SDimitry Andric   if (Tok == "ASSERT")
9134ba319b5SDimitry Andric     return make<SymbolAssignment>(".", readAssert(), getCurrentLocation());
9144ba319b5SDimitry Andric 
9154ba319b5SDimitry Andric   size_t OldPos = Pos;
91646b69c69SDimitry Andric   SymbolAssignment *Cmd = nullptr;
9174ba319b5SDimitry Andric   if (peek() == "=" || peek() == "+=")
9184ba319b5SDimitry Andric     Cmd = readSymbolAssignment(Tok);
9194ba319b5SDimitry Andric   else if (Tok == "PROVIDE")
92046b69c69SDimitry Andric     Cmd = readProvideHidden(true, false);
9214ba319b5SDimitry Andric   else if (Tok == "HIDDEN")
92246b69c69SDimitry Andric     Cmd = readProvideHidden(false, true);
9234ba319b5SDimitry Andric   else if (Tok == "PROVIDE_HIDDEN")
92446b69c69SDimitry Andric     Cmd = readProvideHidden(true, true);
9254ba319b5SDimitry Andric 
9264ba319b5SDimitry Andric   if (Cmd) {
9274ba319b5SDimitry Andric     Cmd->CommandString =
9284ba319b5SDimitry Andric         Tok.str() + " " +
9294ba319b5SDimitry Andric         llvm::join(Tokens.begin() + OldPos, Tokens.begin() + Pos, " ");
9304ba319b5SDimitry Andric     expect(";");
93146b69c69SDimitry Andric   }
93246b69c69SDimitry Andric   return Cmd;
93346b69c69SDimitry Andric }
93446b69c69SDimitry Andric 
readSymbolAssignment(StringRef Name)9354ba319b5SDimitry Andric SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef Name) {
93646b69c69SDimitry Andric   StringRef Op = next();
93746b69c69SDimitry Andric   assert(Op == "=" || Op == "+=");
93846b69c69SDimitry Andric   Expr E = readExpr();
93946b69c69SDimitry Andric   if (Op == "+=") {
94046b69c69SDimitry Andric     std::string Loc = getCurrentLocation();
94110dc89a5SDimitry Andric     E = [=] { return add(Script->getSymbolValue(Name, Loc), E()); };
94246b69c69SDimitry Andric   }
94346b69c69SDimitry Andric   return make<SymbolAssignment>(Name, E, getCurrentLocation());
94446b69c69SDimitry Andric }
94546b69c69SDimitry Andric 
94646b69c69SDimitry Andric // This is an operator-precedence parser to parse a linker
94746b69c69SDimitry Andric // script expression.
readExpr()94846b69c69SDimitry Andric Expr ScriptParser::readExpr() {
94946b69c69SDimitry Andric   // Our lexer is context-aware. Set the in-expression bit so that
95046b69c69SDimitry Andric   // they apply different tokenization rules.
95146b69c69SDimitry Andric   bool Orig = InExpr;
95246b69c69SDimitry Andric   InExpr = true;
95346b69c69SDimitry Andric   Expr E = readExpr1(readPrimary(), 0);
95446b69c69SDimitry Andric   InExpr = Orig;
95546b69c69SDimitry Andric   return E;
95646b69c69SDimitry Andric }
95746b69c69SDimitry Andric 
combine(StringRef Op,Expr L,Expr R)9584ba319b5SDimitry Andric Expr ScriptParser::combine(StringRef Op, Expr L, Expr R) {
95946b69c69SDimitry Andric   if (Op == "+")
96046b69c69SDimitry Andric     return [=] { return add(L(), R()); };
96146b69c69SDimitry Andric   if (Op == "-")
96246b69c69SDimitry Andric     return [=] { return sub(L(), R()); };
96346b69c69SDimitry Andric   if (Op == "*")
9644ba319b5SDimitry Andric     return [=] { return L().getValue() * R().getValue(); };
9654ba319b5SDimitry Andric   if (Op == "/") {
9664ba319b5SDimitry Andric     std::string Loc = getCurrentLocation();
9674ba319b5SDimitry Andric     return [=]() -> uint64_t {
9684ba319b5SDimitry Andric       if (uint64_t RV = R().getValue())
9694ba319b5SDimitry Andric         return L().getValue() / RV;
9704ba319b5SDimitry Andric       error(Loc + ": division by zero");
9714ba319b5SDimitry Andric       return 0;
9724ba319b5SDimitry Andric     };
9734ba319b5SDimitry Andric   }
9744ba319b5SDimitry Andric   if (Op == "%") {
9754ba319b5SDimitry Andric     std::string Loc = getCurrentLocation();
9764ba319b5SDimitry Andric     return [=]() -> uint64_t {
9774ba319b5SDimitry Andric       if (uint64_t RV = R().getValue())
9784ba319b5SDimitry Andric         return L().getValue() % RV;
9794ba319b5SDimitry Andric       error(Loc + ": modulo by zero");
9804ba319b5SDimitry Andric       return 0;
9814ba319b5SDimitry Andric     };
9824ba319b5SDimitry Andric   }
98346b69c69SDimitry Andric   if (Op == "<<")
98446b69c69SDimitry Andric     return [=] { return L().getValue() << R().getValue(); };
98546b69c69SDimitry Andric   if (Op == ">>")
98646b69c69SDimitry Andric     return [=] { return L().getValue() >> R().getValue(); };
98746b69c69SDimitry Andric   if (Op == "<")
98846b69c69SDimitry Andric     return [=] { return L().getValue() < R().getValue(); };
98946b69c69SDimitry Andric   if (Op == ">")
99046b69c69SDimitry Andric     return [=] { return L().getValue() > R().getValue(); };
99146b69c69SDimitry Andric   if (Op == ">=")
99246b69c69SDimitry Andric     return [=] { return L().getValue() >= R().getValue(); };
99346b69c69SDimitry Andric   if (Op == "<=")
99446b69c69SDimitry Andric     return [=] { return L().getValue() <= R().getValue(); };
99546b69c69SDimitry Andric   if (Op == "==")
99646b69c69SDimitry Andric     return [=] { return L().getValue() == R().getValue(); };
99746b69c69SDimitry Andric   if (Op == "!=")
99846b69c69SDimitry Andric     return [=] { return L().getValue() != R().getValue(); };
9994ba319b5SDimitry Andric   if (Op == "||")
10004ba319b5SDimitry Andric     return [=] { return L().getValue() || R().getValue(); };
10014ba319b5SDimitry Andric   if (Op == "&&")
10024ba319b5SDimitry Andric     return [=] { return L().getValue() && R().getValue(); };
100346b69c69SDimitry Andric   if (Op == "&")
100446b69c69SDimitry Andric     return [=] { return bitAnd(L(), R()); };
100546b69c69SDimitry Andric   if (Op == "|")
100646b69c69SDimitry Andric     return [=] { return bitOr(L(), R()); };
100746b69c69SDimitry Andric   llvm_unreachable("invalid operator");
100846b69c69SDimitry Andric }
100946b69c69SDimitry Andric 
101046b69c69SDimitry Andric // This is a part of the operator-precedence parser. This function
101146b69c69SDimitry Andric // assumes that the remaining token stream starts with an operator.
readExpr1(Expr Lhs,int MinPrec)101246b69c69SDimitry Andric Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) {
101310dc89a5SDimitry Andric   while (!atEOF() && !errorCount()) {
101446b69c69SDimitry Andric     // Read an operator and an expression.
101546b69c69SDimitry Andric     if (consume("?"))
101646b69c69SDimitry Andric       return readTernary(Lhs);
101746b69c69SDimitry Andric     StringRef Op1 = peek();
101846b69c69SDimitry Andric     if (precedence(Op1) < MinPrec)
101946b69c69SDimitry Andric       break;
102046b69c69SDimitry Andric     skip();
102146b69c69SDimitry Andric     Expr Rhs = readPrimary();
102246b69c69SDimitry Andric 
102346b69c69SDimitry Andric     // Evaluate the remaining part of the expression first if the
102446b69c69SDimitry Andric     // next operator has greater precedence than the previous one.
102546b69c69SDimitry Andric     // For example, if we have read "+" and "3", and if the next
102646b69c69SDimitry Andric     // operator is "*", then we'll evaluate 3 * ... part first.
102746b69c69SDimitry Andric     while (!atEOF()) {
102846b69c69SDimitry Andric       StringRef Op2 = peek();
102946b69c69SDimitry Andric       if (precedence(Op2) <= precedence(Op1))
103046b69c69SDimitry Andric         break;
103146b69c69SDimitry Andric       Rhs = readExpr1(Rhs, precedence(Op2));
103246b69c69SDimitry Andric     }
103346b69c69SDimitry Andric 
103446b69c69SDimitry Andric     Lhs = combine(Op1, Lhs, Rhs);
103546b69c69SDimitry Andric   }
103646b69c69SDimitry Andric   return Lhs;
103746b69c69SDimitry Andric }
103846b69c69SDimitry Andric 
getPageSize()103910dc89a5SDimitry Andric Expr ScriptParser::getPageSize() {
104010dc89a5SDimitry Andric   std::string Location = getCurrentLocation();
104110dc89a5SDimitry Andric   return [=]() -> uint64_t {
104210dc89a5SDimitry Andric     if (Target)
104346b69c69SDimitry Andric       return Target->PageSize;
104410dc89a5SDimitry Andric     error(Location + ": unable to calculate page size");
104510dc89a5SDimitry Andric     return 4096; // Return a dummy value.
104610dc89a5SDimitry Andric   };
104710dc89a5SDimitry Andric }
104810dc89a5SDimitry Andric 
readConstant()104910dc89a5SDimitry Andric Expr ScriptParser::readConstant() {
105010dc89a5SDimitry Andric   StringRef S = readParenLiteral();
105110dc89a5SDimitry Andric   if (S == "COMMONPAGESIZE")
105210dc89a5SDimitry Andric     return getPageSize();
105346b69c69SDimitry Andric   if (S == "MAXPAGESIZE")
105410dc89a5SDimitry Andric     return [] { return Config->MaxPageSize; };
105510dc89a5SDimitry Andric   setError("unknown constant: " + S);
10564ba319b5SDimitry Andric   return [] { return 0; };
105746b69c69SDimitry Andric }
105846b69c69SDimitry Andric 
105946b69c69SDimitry Andric // Parses Tok as an integer. It recognizes hexadecimal (prefixed with
106046b69c69SDimitry Andric // "0x" or suffixed with "H") and decimal numbers. Decimal numbers may
106146b69c69SDimitry Andric // have "K" (Ki) or "M" (Mi) suffixes.
parseInt(StringRef Tok)106246b69c69SDimitry Andric static Optional<uint64_t> parseInt(StringRef Tok) {
106346b69c69SDimitry Andric   // Hexadecimal
106446b69c69SDimitry Andric   uint64_t Val;
106510dc89a5SDimitry Andric   if (Tok.startswith_lower("0x")) {
106610dc89a5SDimitry Andric     if (!to_integer(Tok.substr(2), Val, 16))
106710dc89a5SDimitry Andric       return None;
106846b69c69SDimitry Andric     return Val;
106910dc89a5SDimitry Andric   }
107010dc89a5SDimitry Andric   if (Tok.endswith_lower("H")) {
107110dc89a5SDimitry Andric     if (!to_integer(Tok.drop_back(), Val, 16))
107210dc89a5SDimitry Andric       return None;
107346b69c69SDimitry Andric     return Val;
107410dc89a5SDimitry Andric   }
107546b69c69SDimitry Andric 
107646b69c69SDimitry Andric   // Decimal
107746b69c69SDimitry Andric   if (Tok.endswith_lower("K")) {
10785517e702SDimitry Andric     if (!to_integer(Tok.drop_back(), Val, 10))
107946b69c69SDimitry Andric       return None;
108046b69c69SDimitry Andric     return Val * 1024;
108146b69c69SDimitry Andric   }
108246b69c69SDimitry Andric   if (Tok.endswith_lower("M")) {
10835517e702SDimitry Andric     if (!to_integer(Tok.drop_back(), Val, 10))
108446b69c69SDimitry Andric       return None;
108546b69c69SDimitry Andric     return Val * 1024 * 1024;
108646b69c69SDimitry Andric   }
10875517e702SDimitry Andric   if (!to_integer(Tok, Val, 10))
108846b69c69SDimitry Andric     return None;
108946b69c69SDimitry Andric   return Val;
109046b69c69SDimitry Andric }
109146b69c69SDimitry Andric 
readByteCommand(StringRef Tok)109210dc89a5SDimitry Andric ByteCommand *ScriptParser::readByteCommand(StringRef Tok) {
109346b69c69SDimitry Andric   int Size = StringSwitch<int>(Tok)
109446b69c69SDimitry Andric                  .Case("BYTE", 1)
109546b69c69SDimitry Andric                  .Case("SHORT", 2)
109646b69c69SDimitry Andric                  .Case("LONG", 4)
109746b69c69SDimitry Andric                  .Case("QUAD", 8)
109846b69c69SDimitry Andric                  .Default(-1);
109946b69c69SDimitry Andric   if (Size == -1)
110046b69c69SDimitry Andric     return nullptr;
11014ba319b5SDimitry Andric 
11024ba319b5SDimitry Andric   size_t OldPos = Pos;
11034ba319b5SDimitry Andric   Expr E = readParenExpr();
11044ba319b5SDimitry Andric   std::string CommandString =
11054ba319b5SDimitry Andric       Tok.str() + " " +
11064ba319b5SDimitry Andric       llvm::join(Tokens.begin() + OldPos, Tokens.begin() + Pos, " ");
11074ba319b5SDimitry Andric   return make<ByteCommand>(E, Size, CommandString);
110846b69c69SDimitry Andric }
110946b69c69SDimitry Andric 
readParenLiteral()111046b69c69SDimitry Andric StringRef ScriptParser::readParenLiteral() {
111146b69c69SDimitry Andric   expect("(");
1112cc877d7cSEd Maste   bool Orig = InExpr;
1113cc877d7cSEd Maste   InExpr = false;
111446b69c69SDimitry Andric   StringRef Tok = next();
1115cc877d7cSEd Maste   InExpr = Orig;
111646b69c69SDimitry Andric   expect(")");
111746b69c69SDimitry Andric   return Tok;
111846b69c69SDimitry Andric }
111946b69c69SDimitry Andric 
checkIfExists(OutputSection * Cmd,StringRef Location)112010dc89a5SDimitry Andric static void checkIfExists(OutputSection *Cmd, StringRef Location) {
1121f9448bf3SDimitry Andric   if (Cmd->Location.empty() && Script->ErrorOnMissingSection)
1122f9448bf3SDimitry Andric     error(Location + ": undefined section " + Cmd->Name);
1123f9448bf3SDimitry Andric }
1124f9448bf3SDimitry Andric 
readPrimary()112546b69c69SDimitry Andric Expr ScriptParser::readPrimary() {
112646b69c69SDimitry Andric   if (peek() == "(")
112746b69c69SDimitry Andric     return readParenExpr();
112846b69c69SDimitry Andric 
112946b69c69SDimitry Andric   if (consume("~")) {
113046b69c69SDimitry Andric     Expr E = readPrimary();
113146b69c69SDimitry Andric     return [=] { return ~E().getValue(); };
113246b69c69SDimitry Andric   }
113310dc89a5SDimitry Andric   if (consume("!")) {
113410dc89a5SDimitry Andric     Expr E = readPrimary();
113510dc89a5SDimitry Andric     return [=] { return !E().getValue(); };
113610dc89a5SDimitry Andric   }
113746b69c69SDimitry Andric   if (consume("-")) {
113846b69c69SDimitry Andric     Expr E = readPrimary();
113946b69c69SDimitry Andric     return [=] { return -E().getValue(); };
114046b69c69SDimitry Andric   }
114146b69c69SDimitry Andric 
114246b69c69SDimitry Andric   StringRef Tok = next();
114346b69c69SDimitry Andric   std::string Location = getCurrentLocation();
114446b69c69SDimitry Andric 
114546b69c69SDimitry Andric   // Built-in functions are parsed here.
114646b69c69SDimitry Andric   // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html.
114746b69c69SDimitry Andric   if (Tok == "ABSOLUTE") {
114846b69c69SDimitry Andric     Expr Inner = readParenExpr();
114946b69c69SDimitry Andric     return [=] {
115046b69c69SDimitry Andric       ExprValue I = Inner();
115146b69c69SDimitry Andric       I.ForceAbsolute = true;
115246b69c69SDimitry Andric       return I;
115346b69c69SDimitry Andric     };
115446b69c69SDimitry Andric   }
115546b69c69SDimitry Andric   if (Tok == "ADDR") {
115646b69c69SDimitry Andric     StringRef Name = readParenLiteral();
115710dc89a5SDimitry Andric     OutputSection *Sec = Script->getOrCreateOutputSection(Name);
1158db17bf38SDimitry Andric     return [=]() -> ExprValue {
115910dc89a5SDimitry Andric       checkIfExists(Sec, Location);
116010dc89a5SDimitry Andric       return {Sec, false, 0, Location};
1161db17bf38SDimitry Andric     };
116246b69c69SDimitry Andric   }
116346b69c69SDimitry Andric   if (Tok == "ALIGN") {
116446b69c69SDimitry Andric     expect("(");
116546b69c69SDimitry Andric     Expr E = readExpr();
116610dc89a5SDimitry Andric     if (consume(")")) {
116710dc89a5SDimitry Andric       E = checkAlignment(E, Location);
116846b69c69SDimitry Andric       return [=] { return alignTo(Script->getDot(), E().getValue()); };
116910dc89a5SDimitry Andric     }
117046b69c69SDimitry Andric     expect(",");
117110dc89a5SDimitry Andric     Expr E2 = checkAlignment(readExpr(), Location);
117246b69c69SDimitry Andric     expect(")");
117389cb50c9SDimitry Andric     return [=] {
117489cb50c9SDimitry Andric       ExprValue V = E();
117589cb50c9SDimitry Andric       V.Alignment = E2().getValue();
117689cb50c9SDimitry Andric       return V;
117789cb50c9SDimitry Andric     };
117846b69c69SDimitry Andric   }
117946b69c69SDimitry Andric   if (Tok == "ALIGNOF") {
118046b69c69SDimitry Andric     StringRef Name = readParenLiteral();
118110dc89a5SDimitry Andric     OutputSection *Cmd = Script->getOrCreateOutputSection(Name);
118210dc89a5SDimitry Andric     return [=] {
118310dc89a5SDimitry Andric       checkIfExists(Cmd, Location);
118410dc89a5SDimitry Andric       return Cmd->Alignment;
118510dc89a5SDimitry Andric     };
118646b69c69SDimitry Andric   }
118746b69c69SDimitry Andric   if (Tok == "ASSERT")
11884ba319b5SDimitry Andric     return readAssert();
118910dc89a5SDimitry Andric   if (Tok == "CONSTANT")
119010dc89a5SDimitry Andric     return readConstant();
119146b69c69SDimitry Andric   if (Tok == "DATA_SEGMENT_ALIGN") {
119246b69c69SDimitry Andric     expect("(");
119346b69c69SDimitry Andric     Expr E = readExpr();
119446b69c69SDimitry Andric     expect(",");
119546b69c69SDimitry Andric     readExpr();
119646b69c69SDimitry Andric     expect(")");
119710dc89a5SDimitry Andric     return [=] {
119810dc89a5SDimitry Andric       return alignTo(Script->getDot(), std::max((uint64_t)1, E().getValue()));
119910dc89a5SDimitry Andric     };
120046b69c69SDimitry Andric   }
120146b69c69SDimitry Andric   if (Tok == "DATA_SEGMENT_END") {
120246b69c69SDimitry Andric     expect("(");
120346b69c69SDimitry Andric     expect(".");
120446b69c69SDimitry Andric     expect(")");
120546b69c69SDimitry Andric     return [] { return Script->getDot(); };
120646b69c69SDimitry Andric   }
120746b69c69SDimitry Andric   if (Tok == "DATA_SEGMENT_RELRO_END") {
120846b69c69SDimitry Andric     // GNU linkers implements more complicated logic to handle
120946b69c69SDimitry Andric     // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and
121046b69c69SDimitry Andric     // just align to the next page boundary for simplicity.
121146b69c69SDimitry Andric     expect("(");
121246b69c69SDimitry Andric     readExpr();
121346b69c69SDimitry Andric     expect(",");
121446b69c69SDimitry Andric     readExpr();
121546b69c69SDimitry Andric     expect(")");
121610dc89a5SDimitry Andric     Expr E = getPageSize();
121710dc89a5SDimitry Andric     return [=] { return alignTo(Script->getDot(), E().getValue()); };
121846b69c69SDimitry Andric   }
121946b69c69SDimitry Andric   if (Tok == "DEFINED") {
122046b69c69SDimitry Andric     StringRef Name = readParenLiteral();
122110dc89a5SDimitry Andric     return [=] { return Symtab->find(Name) ? 1 : 0; };
122246b69c69SDimitry Andric   }
12235517e702SDimitry Andric   if (Tok == "LENGTH") {
12245517e702SDimitry Andric     StringRef Name = readParenLiteral();
12254ba319b5SDimitry Andric     if (Script->MemoryRegions.count(Name) == 0) {
12265517e702SDimitry Andric       setError("memory region not defined: " + Name);
12274ba319b5SDimitry Andric       return [] { return 0; };
12284ba319b5SDimitry Andric     }
122910dc89a5SDimitry Andric     return [=] { return Script->MemoryRegions[Name]->Length; };
12305517e702SDimitry Andric   }
123146b69c69SDimitry Andric   if (Tok == "LOADADDR") {
123246b69c69SDimitry Andric     StringRef Name = readParenLiteral();
123310dc89a5SDimitry Andric     OutputSection *Cmd = Script->getOrCreateOutputSection(Name);
123410dc89a5SDimitry Andric     return [=] {
123510dc89a5SDimitry Andric       checkIfExists(Cmd, Location);
123610dc89a5SDimitry Andric       return Cmd->getLMA();
123710dc89a5SDimitry Andric     };
123846b69c69SDimitry Andric   }
12394ba319b5SDimitry Andric   if (Tok == "MAX" || Tok == "MIN") {
12404ba319b5SDimitry Andric     expect("(");
12414ba319b5SDimitry Andric     Expr A = readExpr();
12424ba319b5SDimitry Andric     expect(",");
12434ba319b5SDimitry Andric     Expr B = readExpr();
12444ba319b5SDimitry Andric     expect(")");
12454ba319b5SDimitry Andric     if (Tok == "MIN")
12464ba319b5SDimitry Andric       return [=] { return std::min(A().getValue(), B().getValue()); };
12474ba319b5SDimitry Andric     return [=] { return std::max(A().getValue(), B().getValue()); };
12484ba319b5SDimitry Andric   }
12495517e702SDimitry Andric   if (Tok == "ORIGIN") {
12505517e702SDimitry Andric     StringRef Name = readParenLiteral();
12514ba319b5SDimitry Andric     if (Script->MemoryRegions.count(Name) == 0) {
12525517e702SDimitry Andric       setError("memory region not defined: " + Name);
12534ba319b5SDimitry Andric       return [] { return 0; };
12544ba319b5SDimitry Andric     }
125510dc89a5SDimitry Andric     return [=] { return Script->MemoryRegions[Name]->Origin; };
12565517e702SDimitry Andric   }
125746b69c69SDimitry Andric   if (Tok == "SEGMENT_START") {
125846b69c69SDimitry Andric     expect("(");
125946b69c69SDimitry Andric     skip();
126046b69c69SDimitry Andric     expect(",");
126146b69c69SDimitry Andric     Expr E = readExpr();
126246b69c69SDimitry Andric     expect(")");
126346b69c69SDimitry Andric     return [=] { return E(); };
126446b69c69SDimitry Andric   }
126546b69c69SDimitry Andric   if (Tok == "SIZEOF") {
126646b69c69SDimitry Andric     StringRef Name = readParenLiteral();
126710dc89a5SDimitry Andric     OutputSection *Cmd = Script->getOrCreateOutputSection(Name);
1268f9448bf3SDimitry Andric     // Linker script does not create an output section if its content is empty.
1269f9448bf3SDimitry Andric     // We want to allow SIZEOF(.foo) where .foo is a section which happened to
1270f9448bf3SDimitry Andric     // be empty.
127110dc89a5SDimitry Andric     return [=] { return Cmd->Size; };
127246b69c69SDimitry Andric   }
127346b69c69SDimitry Andric   if (Tok == "SIZEOF_HEADERS")
127446b69c69SDimitry Andric     return [=] { return elf::getHeaderSize(); };
127546b69c69SDimitry Andric 
127646b69c69SDimitry Andric   // Tok is the dot.
127746b69c69SDimitry Andric   if (Tok == ".")
127810dc89a5SDimitry Andric     return [=] { return Script->getSymbolValue(Tok, Location); };
127946b69c69SDimitry Andric 
128046b69c69SDimitry Andric   // Tok is a literal number.
128146b69c69SDimitry Andric   if (Optional<uint64_t> Val = parseInt(Tok))
128246b69c69SDimitry Andric     return [=] { return *Val; };
128346b69c69SDimitry Andric 
128446b69c69SDimitry Andric   // Tok is a symbol name.
128546b69c69SDimitry Andric   if (!isValidCIdentifier(Tok))
128646b69c69SDimitry Andric     setError("malformed number: " + Tok);
128710dc89a5SDimitry Andric   Script->ReferencedSymbols.push_back(Tok);
128810dc89a5SDimitry Andric   return [=] { return Script->getSymbolValue(Tok, Location); };
128946b69c69SDimitry Andric }
129046b69c69SDimitry Andric 
readTernary(Expr Cond)129146b69c69SDimitry Andric Expr ScriptParser::readTernary(Expr Cond) {
129246b69c69SDimitry Andric   Expr L = readExpr();
129346b69c69SDimitry Andric   expect(":");
129446b69c69SDimitry Andric   Expr R = readExpr();
129546b69c69SDimitry Andric   return [=] { return Cond().getValue() ? L() : R(); };
129646b69c69SDimitry Andric }
129746b69c69SDimitry Andric 
readParenExpr()129846b69c69SDimitry Andric Expr ScriptParser::readParenExpr() {
129946b69c69SDimitry Andric   expect("(");
130046b69c69SDimitry Andric   Expr E = readExpr();
130146b69c69SDimitry Andric   expect(")");
130246b69c69SDimitry Andric   return E;
130346b69c69SDimitry Andric }
130446b69c69SDimitry Andric 
readOutputSectionPhdrs()130546b69c69SDimitry Andric std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() {
130646b69c69SDimitry Andric   std::vector<StringRef> Phdrs;
130710dc89a5SDimitry Andric   while (!errorCount() && peek().startswith(":")) {
130846b69c69SDimitry Andric     StringRef Tok = next();
130946b69c69SDimitry Andric     Phdrs.push_back((Tok.size() == 1) ? next() : Tok.substr(1));
131046b69c69SDimitry Andric   }
131146b69c69SDimitry Andric   return Phdrs;
131246b69c69SDimitry Andric }
131346b69c69SDimitry Andric 
131446b69c69SDimitry Andric // Read a program header type name. The next token must be a
131546b69c69SDimitry Andric // name of a program header type or a constant (e.g. "0x3").
readPhdrType()131646b69c69SDimitry Andric unsigned ScriptParser::readPhdrType() {
131746b69c69SDimitry Andric   StringRef Tok = next();
131846b69c69SDimitry Andric   if (Optional<uint64_t> Val = parseInt(Tok))
131946b69c69SDimitry Andric     return *Val;
132046b69c69SDimitry Andric 
132146b69c69SDimitry Andric   unsigned Ret = StringSwitch<unsigned>(Tok)
132246b69c69SDimitry Andric                      .Case("PT_NULL", PT_NULL)
132346b69c69SDimitry Andric                      .Case("PT_LOAD", PT_LOAD)
132446b69c69SDimitry Andric                      .Case("PT_DYNAMIC", PT_DYNAMIC)
132546b69c69SDimitry Andric                      .Case("PT_INTERP", PT_INTERP)
132646b69c69SDimitry Andric                      .Case("PT_NOTE", PT_NOTE)
132746b69c69SDimitry Andric                      .Case("PT_SHLIB", PT_SHLIB)
132846b69c69SDimitry Andric                      .Case("PT_PHDR", PT_PHDR)
132946b69c69SDimitry Andric                      .Case("PT_TLS", PT_TLS)
133046b69c69SDimitry Andric                      .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME)
133146b69c69SDimitry Andric                      .Case("PT_GNU_STACK", PT_GNU_STACK)
133246b69c69SDimitry Andric                      .Case("PT_GNU_RELRO", PT_GNU_RELRO)
133346b69c69SDimitry Andric                      .Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE)
133446b69c69SDimitry Andric                      .Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED)
133546b69c69SDimitry Andric                      .Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA)
133646b69c69SDimitry Andric                      .Default(-1);
133746b69c69SDimitry Andric 
133846b69c69SDimitry Andric   if (Ret == (unsigned)-1) {
133946b69c69SDimitry Andric     setError("invalid program header type: " + Tok);
134046b69c69SDimitry Andric     return PT_NULL;
134146b69c69SDimitry Andric   }
134246b69c69SDimitry Andric   return Ret;
134346b69c69SDimitry Andric }
134446b69c69SDimitry Andric 
134546b69c69SDimitry Andric // Reads an anonymous version declaration.
readAnonymousDeclaration()134646b69c69SDimitry Andric void ScriptParser::readAnonymousDeclaration() {
134746b69c69SDimitry Andric   std::vector<SymbolVersion> Locals;
134846b69c69SDimitry Andric   std::vector<SymbolVersion> Globals;
134946b69c69SDimitry Andric   std::tie(Locals, Globals) = readSymbols();
135046b69c69SDimitry Andric 
135146b69c69SDimitry Andric   for (SymbolVersion V : Locals) {
135246b69c69SDimitry Andric     if (V.Name == "*")
135346b69c69SDimitry Andric       Config->DefaultSymbolVersion = VER_NDX_LOCAL;
135446b69c69SDimitry Andric     else
135546b69c69SDimitry Andric       Config->VersionScriptLocals.push_back(V);
135646b69c69SDimitry Andric   }
135746b69c69SDimitry Andric 
135846b69c69SDimitry Andric   for (SymbolVersion V : Globals)
135946b69c69SDimitry Andric     Config->VersionScriptGlobals.push_back(V);
136046b69c69SDimitry Andric 
136146b69c69SDimitry Andric   expect(";");
136246b69c69SDimitry Andric }
136346b69c69SDimitry Andric 
136446b69c69SDimitry Andric // Reads a non-anonymous version definition,
136546b69c69SDimitry Andric // e.g. "VerStr { global: foo; bar; local: *; };".
readVersionDeclaration(StringRef VerStr)136646b69c69SDimitry Andric void ScriptParser::readVersionDeclaration(StringRef VerStr) {
136746b69c69SDimitry Andric   // Read a symbol list.
136846b69c69SDimitry Andric   std::vector<SymbolVersion> Locals;
136946b69c69SDimitry Andric   std::vector<SymbolVersion> Globals;
137046b69c69SDimitry Andric   std::tie(Locals, Globals) = readSymbols();
137146b69c69SDimitry Andric 
137246b69c69SDimitry Andric   for (SymbolVersion V : Locals) {
137346b69c69SDimitry Andric     if (V.Name == "*")
137446b69c69SDimitry Andric       Config->DefaultSymbolVersion = VER_NDX_LOCAL;
137546b69c69SDimitry Andric     else
137646b69c69SDimitry Andric       Config->VersionScriptLocals.push_back(V);
137746b69c69SDimitry Andric   }
137846b69c69SDimitry Andric 
137946b69c69SDimitry Andric   // Create a new version definition and add that to the global symbols.
138046b69c69SDimitry Andric   VersionDefinition Ver;
138146b69c69SDimitry Andric   Ver.Name = VerStr;
138246b69c69SDimitry Andric   Ver.Globals = Globals;
138346b69c69SDimitry Andric 
138446b69c69SDimitry Andric   // User-defined version number starts from 2 because 0 and 1 are
138546b69c69SDimitry Andric   // reserved for VER_NDX_LOCAL and VER_NDX_GLOBAL, respectively.
138646b69c69SDimitry Andric   Ver.Id = Config->VersionDefinitions.size() + 2;
138746b69c69SDimitry Andric   Config->VersionDefinitions.push_back(Ver);
138846b69c69SDimitry Andric 
138946b69c69SDimitry Andric   // Each version may have a parent version. For example, "Ver2"
139046b69c69SDimitry Andric   // defined as "Ver2 { global: foo; local: *; } Ver1;" has "Ver1"
139146b69c69SDimitry Andric   // as a parent. This version hierarchy is, probably against your
139246b69c69SDimitry Andric   // instinct, purely for hint; the runtime doesn't care about it
139346b69c69SDimitry Andric   // at all. In LLD, we simply ignore it.
139446b69c69SDimitry Andric   if (peek() != ";")
139546b69c69SDimitry Andric     skip();
139646b69c69SDimitry Andric   expect(";");
139746b69c69SDimitry Andric }
139846b69c69SDimitry Andric 
hasWildcard(StringRef S)1399b40b48b8SDimitry Andric static bool hasWildcard(StringRef S) {
1400b40b48b8SDimitry Andric   return S.find_first_of("?*[") != StringRef::npos;
1401b40b48b8SDimitry Andric }
1402b40b48b8SDimitry Andric 
140346b69c69SDimitry Andric // Reads a list of symbols, e.g. "{ global: foo; bar; local: *; };".
140446b69c69SDimitry Andric std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>>
readSymbols()140546b69c69SDimitry Andric ScriptParser::readSymbols() {
140646b69c69SDimitry Andric   std::vector<SymbolVersion> Locals;
140746b69c69SDimitry Andric   std::vector<SymbolVersion> Globals;
140846b69c69SDimitry Andric   std::vector<SymbolVersion> *V = &Globals;
140946b69c69SDimitry Andric 
141010dc89a5SDimitry Andric   while (!errorCount()) {
141146b69c69SDimitry Andric     if (consume("}"))
141246b69c69SDimitry Andric       break;
141346b69c69SDimitry Andric     if (consumeLabel("local")) {
141446b69c69SDimitry Andric       V = &Locals;
141546b69c69SDimitry Andric       continue;
141646b69c69SDimitry Andric     }
141746b69c69SDimitry Andric     if (consumeLabel("global")) {
141846b69c69SDimitry Andric       V = &Globals;
141946b69c69SDimitry Andric       continue;
142046b69c69SDimitry Andric     }
142146b69c69SDimitry Andric 
142246b69c69SDimitry Andric     if (consume("extern")) {
142346b69c69SDimitry Andric       std::vector<SymbolVersion> Ext = readVersionExtern();
142446b69c69SDimitry Andric       V->insert(V->end(), Ext.begin(), Ext.end());
142546b69c69SDimitry Andric     } else {
142646b69c69SDimitry Andric       StringRef Tok = next();
142746b69c69SDimitry Andric       V->push_back({unquote(Tok), false, hasWildcard(Tok)});
142846b69c69SDimitry Andric     }
142946b69c69SDimitry Andric     expect(";");
143046b69c69SDimitry Andric   }
143146b69c69SDimitry Andric   return {Locals, Globals};
143246b69c69SDimitry Andric }
143346b69c69SDimitry Andric 
143446b69c69SDimitry Andric // Reads an "extern C++" directive, e.g.,
143546b69c69SDimitry Andric // "extern "C++" { ns::*; "f(int, double)"; };"
14364ba319b5SDimitry Andric //
14374ba319b5SDimitry Andric // The last semicolon is optional. E.g. this is OK:
14384ba319b5SDimitry Andric // "extern "C++" { ns::*; "f(int, double)" };"
readVersionExtern()143946b69c69SDimitry Andric std::vector<SymbolVersion> ScriptParser::readVersionExtern() {
144046b69c69SDimitry Andric   StringRef Tok = next();
144146b69c69SDimitry Andric   bool IsCXX = Tok == "\"C++\"";
144246b69c69SDimitry Andric   if (!IsCXX && Tok != "\"C\"")
144346b69c69SDimitry Andric     setError("Unknown language");
144446b69c69SDimitry Andric   expect("{");
144546b69c69SDimitry Andric 
144646b69c69SDimitry Andric   std::vector<SymbolVersion> Ret;
144710dc89a5SDimitry Andric   while (!errorCount() && peek() != "}") {
144846b69c69SDimitry Andric     StringRef Tok = next();
144946b69c69SDimitry Andric     bool HasWildcard = !Tok.startswith("\"") && hasWildcard(Tok);
145046b69c69SDimitry Andric     Ret.push_back({unquote(Tok), IsCXX, HasWildcard});
14514ba319b5SDimitry Andric     if (consume("}"))
14524ba319b5SDimitry Andric       return Ret;
145346b69c69SDimitry Andric     expect(";");
145446b69c69SDimitry Andric   }
145546b69c69SDimitry Andric 
145646b69c69SDimitry Andric   expect("}");
145746b69c69SDimitry Andric   return Ret;
145846b69c69SDimitry Andric }
145946b69c69SDimitry Andric 
readMemoryAssignment(StringRef S1,StringRef S2,StringRef S3)146046b69c69SDimitry Andric uint64_t ScriptParser::readMemoryAssignment(StringRef S1, StringRef S2,
146146b69c69SDimitry Andric                                             StringRef S3) {
146246b69c69SDimitry Andric   if (!consume(S1) && !consume(S2) && !consume(S3)) {
146346b69c69SDimitry Andric     setError("expected one of: " + S1 + ", " + S2 + ", or " + S3);
146446b69c69SDimitry Andric     return 0;
146546b69c69SDimitry Andric   }
146646b69c69SDimitry Andric   expect("=");
146746b69c69SDimitry Andric   return readExpr()().getValue();
146846b69c69SDimitry Andric }
146946b69c69SDimitry Andric 
147046b69c69SDimitry Andric // Parse the MEMORY command as specified in:
147146b69c69SDimitry Andric // https://sourceware.org/binutils/docs/ld/MEMORY.html
147246b69c69SDimitry Andric //
147346b69c69SDimitry Andric // MEMORY { name [(attr)] : ORIGIN = origin, LENGTH = len ... }
readMemory()147446b69c69SDimitry Andric void ScriptParser::readMemory() {
147546b69c69SDimitry Andric   expect("{");
147610dc89a5SDimitry Andric   while (!errorCount() && !consume("}")) {
14774ba319b5SDimitry Andric     StringRef Tok = next();
14784ba319b5SDimitry Andric     if (Tok == "INCLUDE") {
14794ba319b5SDimitry Andric       readInclude();
14804ba319b5SDimitry Andric       continue;
14814ba319b5SDimitry Andric     }
148246b69c69SDimitry Andric 
148346b69c69SDimitry Andric     uint32_t Flags = 0;
148446b69c69SDimitry Andric     uint32_t NegFlags = 0;
148546b69c69SDimitry Andric     if (consume("(")) {
148646b69c69SDimitry Andric       std::tie(Flags, NegFlags) = readMemoryAttributes();
148746b69c69SDimitry Andric       expect(")");
148846b69c69SDimitry Andric     }
148946b69c69SDimitry Andric     expect(":");
149046b69c69SDimitry Andric 
149146b69c69SDimitry Andric     uint64_t Origin = readMemoryAssignment("ORIGIN", "org", "o");
149246b69c69SDimitry Andric     expect(",");
149346b69c69SDimitry Andric     uint64_t Length = readMemoryAssignment("LENGTH", "len", "l");
149446b69c69SDimitry Andric 
149510dc89a5SDimitry Andric     // Add the memory region to the region map.
14964ba319b5SDimitry Andric     MemoryRegion *MR = make<MemoryRegion>(Tok, Origin, Length, Flags, NegFlags);
14974ba319b5SDimitry Andric     if (!Script->MemoryRegions.insert({Tok, MR}).second)
14984ba319b5SDimitry Andric       setError("region '" + Tok + "' already defined");
149946b69c69SDimitry Andric   }
150046b69c69SDimitry Andric }
150146b69c69SDimitry Andric 
150246b69c69SDimitry Andric // This function parses the attributes used to match against section
150346b69c69SDimitry Andric // flags when placing output sections in a memory region. These flags
150446b69c69SDimitry Andric // are only used when an explicit memory region name is not used.
readMemoryAttributes()150546b69c69SDimitry Andric std::pair<uint32_t, uint32_t> ScriptParser::readMemoryAttributes() {
150646b69c69SDimitry Andric   uint32_t Flags = 0;
150746b69c69SDimitry Andric   uint32_t NegFlags = 0;
150846b69c69SDimitry Andric   bool Invert = false;
150946b69c69SDimitry Andric 
151046b69c69SDimitry Andric   for (char C : next().lower()) {
151146b69c69SDimitry Andric     uint32_t Flag = 0;
151246b69c69SDimitry Andric     if (C == '!')
151346b69c69SDimitry Andric       Invert = !Invert;
151446b69c69SDimitry Andric     else if (C == 'w')
151546b69c69SDimitry Andric       Flag = SHF_WRITE;
151646b69c69SDimitry Andric     else if (C == 'x')
151746b69c69SDimitry Andric       Flag = SHF_EXECINSTR;
151846b69c69SDimitry Andric     else if (C == 'a')
151946b69c69SDimitry Andric       Flag = SHF_ALLOC;
152046b69c69SDimitry Andric     else if (C != 'r')
152146b69c69SDimitry Andric       setError("invalid memory region attribute");
152246b69c69SDimitry Andric 
152346b69c69SDimitry Andric     if (Invert)
152446b69c69SDimitry Andric       NegFlags |= Flag;
152546b69c69SDimitry Andric     else
152646b69c69SDimitry Andric       Flags |= Flag;
152746b69c69SDimitry Andric   }
152846b69c69SDimitry Andric   return {Flags, NegFlags};
152946b69c69SDimitry Andric }
153046b69c69SDimitry Andric 
readLinkerScript(MemoryBufferRef MB)153146b69c69SDimitry Andric void elf::readLinkerScript(MemoryBufferRef MB) {
153246b69c69SDimitry Andric   ScriptParser(MB).readLinkerScript();
153346b69c69SDimitry Andric }
153446b69c69SDimitry Andric 
readVersionScript(MemoryBufferRef MB)153546b69c69SDimitry Andric void elf::readVersionScript(MemoryBufferRef MB) {
153646b69c69SDimitry Andric   ScriptParser(MB).readVersionScript();
153746b69c69SDimitry Andric }
153846b69c69SDimitry Andric 
readDynamicList(MemoryBufferRef MB)153946b69c69SDimitry Andric void elf::readDynamicList(MemoryBufferRef MB) {
154046b69c69SDimitry Andric   ScriptParser(MB).readDynamicList();
154197c3811cSEd Maste }
154210dc89a5SDimitry Andric 
readDefsym(StringRef Name,MemoryBufferRef MB)154310dc89a5SDimitry Andric void elf::readDefsym(StringRef Name, MemoryBufferRef MB) {
154410dc89a5SDimitry Andric   ScriptParser(MB).readDefsym(Name);
154510dc89a5SDimitry Andric }
1546