12ec34544SRui Ueyama //===- ScriptParser.cpp ---------------------------------------------------===//
22ec34544SRui Ueyama //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
62ec34544SRui Ueyama //
72ec34544SRui Ueyama //===----------------------------------------------------------------------===//
805f6b852SRui Ueyama //
905f6b852SRui Ueyama // This file contains a recursive-descendent parser for linker scripts.
1005f6b852SRui Ueyama // Parsed results are stored to Config and Script global objects.
1105f6b852SRui Ueyama //
1205f6b852SRui Ueyama //===----------------------------------------------------------------------===//
132ec34544SRui Ueyama 
142ec34544SRui Ueyama #include "ScriptParser.h"
152ec34544SRui Ueyama #include "Config.h"
162ec34544SRui Ueyama #include "Driver.h"
172ec34544SRui Ueyama #include "InputSection.h"
182ec34544SRui Ueyama #include "LinkerScript.h"
192ec34544SRui Ueyama #include "OutputSections.h"
202ec34544SRui Ueyama #include "ScriptLexer.h"
212ec34544SRui Ueyama #include "Symbols.h"
222ec34544SRui Ueyama #include "Target.h"
232017d52bSRui Ueyama #include "lld/Common/Memory.h"
242ec34544SRui Ueyama #include "llvm/ADT/SmallString.h"
252ec34544SRui Ueyama #include "llvm/ADT/StringRef.h"
260440be4aSRui Ueyama #include "llvm/ADT/StringSet.h"
272ec34544SRui Ueyama #include "llvm/ADT/StringSwitch.h"
28264b5d9eSZachary Turner #include "llvm/BinaryFormat/ELF.h"
292ec34544SRui Ueyama #include "llvm/Support/Casting.h"
302ec34544SRui Ueyama #include "llvm/Support/ErrorHandling.h"
312ec34544SRui Ueyama #include "llvm/Support/FileSystem.h"
322ec34544SRui Ueyama #include "llvm/Support/Path.h"
33dbd0ad33SPeter Smith #include "llvm/Support/ScopedPrinter.h"
342ec34544SRui Ueyama #include <cassert>
352ec34544SRui Ueyama #include <limits>
362ec34544SRui Ueyama #include <vector>
372ec34544SRui Ueyama 
382ec34544SRui Ueyama using namespace llvm;
392ec34544SRui Ueyama using namespace llvm::ELF;
40b58079d4SRui Ueyama using namespace llvm::support::endian;
412ec34544SRui Ueyama 
42bd8cfe65SFangrui Song namespace lld {
43bd8cfe65SFangrui Song namespace elf {
4496b3fe02SRui Ueyama namespace {
4596b3fe02SRui Ueyama class ScriptParser final : ScriptLexer {
462ec34544SRui Ueyama public:
473837f427SRui Ueyama   ScriptParser(MemoryBufferRef mb) : ScriptLexer(mb) {
4811ae59f0SRui Ueyama     // Initialize IsUnderSysroot
493837f427SRui Ueyama     if (config->sysroot == "")
5011ae59f0SRui Ueyama       return;
513837f427SRui Ueyama     StringRef path = mb.getBufferIdentifier();
523837f427SRui Ueyama     for (; !path.empty(); path = sys::path::parent_path(path)) {
533837f427SRui Ueyama       if (!sys::fs::equivalent(config->sysroot, path))
5411ae59f0SRui Ueyama         continue;
553837f427SRui Ueyama       isUnderSysroot = true;
5611ae59f0SRui Ueyama       return;
5711ae59f0SRui Ueyama     }
5811ae59f0SRui Ueyama   }
592ec34544SRui Ueyama 
602ec34544SRui Ueyama   void readLinkerScript();
612ec34544SRui Ueyama   void readVersionScript();
622ec34544SRui Ueyama   void readDynamicList();
633837f427SRui Ueyama   void readDefsym(StringRef name);
642ec34544SRui Ueyama 
652ec34544SRui Ueyama private:
663837f427SRui Ueyama   void addFile(StringRef path);
672ec34544SRui Ueyama 
682ec34544SRui Ueyama   void readAsNeeded();
692ec34544SRui Ueyama   void readEntry();
702ec34544SRui Ueyama   void readExtern();
712ec34544SRui Ueyama   void readGroup();
722ec34544SRui Ueyama   void readInclude();
731d92aa73SRui Ueyama   void readInput();
742ec34544SRui Ueyama   void readMemory();
752ec34544SRui Ueyama   void readOutput();
762ec34544SRui Ueyama   void readOutputArch();
772ec34544SRui Ueyama   void readOutputFormat();
782ec34544SRui Ueyama   void readPhdrs();
795f37541cSGeorge Rimar   void readRegionAlias();
802ec34544SRui Ueyama   void readSearchDir();
812ec34544SRui Ueyama   void readSections();
82e262bb1aSRui Ueyama   void readTarget();
832ec34544SRui Ueyama   void readVersion();
842ec34544SRui Ueyama   void readVersionScriptCommand();
852ec34544SRui Ueyama 
863837f427SRui Ueyama   SymbolAssignment *readSymbolAssignment(StringRef name);
873837f427SRui Ueyama   ByteCommand *readByteCommand(StringRef tok);
88b0486051SSimon Atanasyan   std::array<uint8_t, 4> readFill();
893837f427SRui Ueyama   bool readSectionDirective(OutputSection *cmd, StringRef tok1, StringRef tok2);
903837f427SRui Ueyama   void readSectionAddressType(OutputSection *cmd);
91a582419aSGeorge Rimar   OutputSection *readOverlaySectionDescription();
923837f427SRui Ueyama   OutputSection *readOutputSectionDescription(StringRef outSec);
93a582419aSGeorge Rimar   std::vector<BaseCommand *> readOverlay();
942ec34544SRui Ueyama   std::vector<StringRef> readOutputSectionPhdrs();
95dbd0ad33SPeter Smith   std::pair<uint64_t, uint64_t> readInputSectionFlags();
963837f427SRui Ueyama   InputSectionDescription *readInputSectionDescription(StringRef tok);
972ec34544SRui Ueyama   StringMatcher readFilePatterns();
982ec34544SRui Ueyama   std::vector<SectionPattern> readInputSectionsList();
99dbd0ad33SPeter Smith   InputSectionDescription *readInputSectionRules(StringRef filePattern,
100dbd0ad33SPeter Smith                                                  uint64_t withFlags,
101dbd0ad33SPeter Smith                                                  uint64_t withoutFlags);
1022ec34544SRui Ueyama   unsigned readPhdrType();
1032ec34544SRui Ueyama   SortSectionPolicy readSortKind();
1043837f427SRui Ueyama   SymbolAssignment *readProvideHidden(bool provide, bool hidden);
1053837f427SRui Ueyama   SymbolAssignment *readAssignment(StringRef tok);
1062ec34544SRui Ueyama   void readSort();
107d30a78b3SGeorge Rimar   Expr readAssert();
1085fb17128SGeorge Rimar   Expr readConstant();
1095fb17128SGeorge Rimar   Expr getPageSize();
1102ec34544SRui Ueyama 
11192b5b980SFangrui Song   Expr readMemoryAssignment(StringRef, StringRef, StringRef);
1122ec34544SRui Ueyama   std::pair<uint32_t, uint32_t> readMemoryAttributes();
1132ec34544SRui Ueyama 
1143837f427SRui Ueyama   Expr combine(StringRef op, Expr l, Expr r);
1152ec34544SRui Ueyama   Expr readExpr();
1163837f427SRui Ueyama   Expr readExpr1(Expr lhs, int minPrec);
1172ec34544SRui Ueyama   StringRef readParenLiteral();
1182ec34544SRui Ueyama   Expr readPrimary();
1193837f427SRui Ueyama   Expr readTernary(Expr cond);
1202ec34544SRui Ueyama   Expr readParenExpr();
1212ec34544SRui Ueyama 
1222ec34544SRui Ueyama   // For parsing version script.
1232ec34544SRui Ueyama   std::vector<SymbolVersion> readVersionExtern();
1242ec34544SRui Ueyama   void readAnonymousDeclaration();
1253837f427SRui Ueyama   void readVersionDeclaration(StringRef verStr);
1262ec34544SRui Ueyama 
1272ec34544SRui Ueyama   std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>>
1282ec34544SRui Ueyama   readSymbols();
1292ec34544SRui Ueyama 
130fd06b025SRui Ueyama   // True if a script being read is in a subdirectory specified by -sysroot.
1313837f427SRui Ueyama   bool isUnderSysroot = false;
1320440be4aSRui Ueyama 
1330440be4aSRui Ueyama   // A set to detect an INCLUDE() cycle.
1343837f427SRui Ueyama   StringSet<> seen;
1352ec34544SRui Ueyama };
13696b3fe02SRui Ueyama } // namespace
1372ec34544SRui Ueyama 
1383837f427SRui Ueyama static StringRef unquote(StringRef s) {
1393837f427SRui Ueyama   if (s.startswith("\""))
1403837f427SRui Ueyama     return s.substr(1, s.size() - 2);
1413837f427SRui Ueyama   return s;
1421e77ad14SRui Ueyama }
1431e77ad14SRui Ueyama 
1442ec34544SRui Ueyama // Some operations only support one non absolute value. Move the
1452ec34544SRui Ueyama // absolute one to the right hand side for convenience.
1463837f427SRui Ueyama static void moveAbsRight(ExprValue &a, ExprValue &b) {
1473837f427SRui Ueyama   if (a.sec == nullptr || (a.forceAbsolute && !b.isAbsolute()))
1483837f427SRui Ueyama     std::swap(a, b);
1493837f427SRui Ueyama   if (!b.isAbsolute())
1503837f427SRui Ueyama     error(a.loc + ": at least one side of the expression must be absolute");
1512ec34544SRui Ueyama }
1522ec34544SRui Ueyama 
1533837f427SRui Ueyama static ExprValue add(ExprValue a, ExprValue b) {
1543837f427SRui Ueyama   moveAbsRight(a, b);
1553837f427SRui Ueyama   return {a.sec, a.forceAbsolute, a.getSectionOffset() + b.getValue(), a.loc};
1562ec34544SRui Ueyama }
1572ec34544SRui Ueyama 
1583837f427SRui Ueyama static ExprValue sub(ExprValue a, ExprValue b) {
15963a4a98eSRafael Espindola   // The distance between two symbols in sections is absolute.
1603837f427SRui Ueyama   if (!a.isAbsolute() && !b.isAbsolute())
1613837f427SRui Ueyama     return a.getValue() - b.getValue();
1623837f427SRui Ueyama   return {a.sec, false, a.getSectionOffset() - b.getValue(), a.loc};
1632ec34544SRui Ueyama }
1642ec34544SRui Ueyama 
1653837f427SRui Ueyama static ExprValue bitAnd(ExprValue a, ExprValue b) {
1663837f427SRui Ueyama   moveAbsRight(a, b);
1673837f427SRui Ueyama   return {a.sec, a.forceAbsolute,
1683837f427SRui Ueyama           (a.getValue() & b.getValue()) - a.getSecAddr(), a.loc};
1692ec34544SRui Ueyama }
1702ec34544SRui Ueyama 
1713837f427SRui Ueyama static ExprValue bitOr(ExprValue a, ExprValue b) {
1723837f427SRui Ueyama   moveAbsRight(a, b);
1733837f427SRui Ueyama   return {a.sec, a.forceAbsolute,
1743837f427SRui Ueyama           (a.getValue() | b.getValue()) - a.getSecAddr(), a.loc};
1752ec34544SRui Ueyama }
1762ec34544SRui Ueyama 
1772ec34544SRui Ueyama void ScriptParser::readDynamicList() {
1783837f427SRui Ueyama   config->hasDynamicList = true;
1792ec34544SRui Ueyama   expect("{");
1803837f427SRui Ueyama   std::vector<SymbolVersion> locals;
1813837f427SRui Ueyama   std::vector<SymbolVersion> globals;
1823837f427SRui Ueyama   std::tie(locals, globals) = readSymbols();
183d72d97b3SRafael Espindola   expect(";");
184d72d97b3SRafael Espindola 
185d72d97b3SRafael Espindola   if (!atEOF()) {
1862ec34544SRui Ueyama     setError("EOF expected, but got " + next());
187d72d97b3SRafael Espindola     return;
188d72d97b3SRafael Espindola   }
1893837f427SRui Ueyama   if (!locals.empty()) {
190d72d97b3SRafael Espindola     setError("\"local:\" scope not supported in --dynamic-list");
191d72d97b3SRafael Espindola     return;
192d72d97b3SRafael Espindola   }
193d72d97b3SRafael Espindola 
1943837f427SRui Ueyama   for (SymbolVersion v : globals)
1953837f427SRui Ueyama     config->dynamicList.push_back(v);
1962ec34544SRui Ueyama }
1972ec34544SRui Ueyama 
1982ec34544SRui Ueyama void ScriptParser::readVersionScript() {
1992ec34544SRui Ueyama   readVersionScriptCommand();
2002ec34544SRui Ueyama   if (!atEOF())
2012ec34544SRui Ueyama     setError("EOF expected, but got " + next());
2022ec34544SRui Ueyama }
2032ec34544SRui Ueyama 
2042ec34544SRui Ueyama void ScriptParser::readVersionScriptCommand() {
2052ec34544SRui Ueyama   if (consume("{")) {
2062ec34544SRui Ueyama     readAnonymousDeclaration();
2072ec34544SRui Ueyama     return;
2082ec34544SRui Ueyama   }
2092ec34544SRui Ueyama 
210b8a59c8aSBob Haarman   while (!atEOF() && !errorCount() && peek() != "}") {
2113837f427SRui Ueyama     StringRef verStr = next();
2123837f427SRui Ueyama     if (verStr == "{") {
2132ec34544SRui Ueyama       setError("anonymous version definition is used in "
2142ec34544SRui Ueyama                "combination with other version definitions");
2152ec34544SRui Ueyama       return;
2162ec34544SRui Ueyama     }
2172ec34544SRui Ueyama     expect("{");
2183837f427SRui Ueyama     readVersionDeclaration(verStr);
2192ec34544SRui Ueyama   }
2202ec34544SRui Ueyama }
2212ec34544SRui Ueyama 
2222ec34544SRui Ueyama void ScriptParser::readVersion() {
2232ec34544SRui Ueyama   expect("{");
2242ec34544SRui Ueyama   readVersionScriptCommand();
2252ec34544SRui Ueyama   expect("}");
2262ec34544SRui Ueyama }
2272ec34544SRui Ueyama 
2282ec34544SRui Ueyama void ScriptParser::readLinkerScript() {
2292ec34544SRui Ueyama   while (!atEOF()) {
2303837f427SRui Ueyama     StringRef tok = next();
2313837f427SRui Ueyama     if (tok == ";")
2322ec34544SRui Ueyama       continue;
2332ec34544SRui Ueyama 
2343837f427SRui Ueyama     if (tok == "ENTRY") {
2352ec34544SRui Ueyama       readEntry();
2363837f427SRui Ueyama     } else if (tok == "EXTERN") {
2372ec34544SRui Ueyama       readExtern();
2383837f427SRui Ueyama     } else if (tok == "GROUP") {
2392ec34544SRui Ueyama       readGroup();
2403837f427SRui Ueyama     } else if (tok == "INCLUDE") {
2412ec34544SRui Ueyama       readInclude();
2423837f427SRui Ueyama     } else if (tok == "INPUT") {
2431d92aa73SRui Ueyama       readInput();
2443837f427SRui Ueyama     } else if (tok == "MEMORY") {
2452ec34544SRui Ueyama       readMemory();
2463837f427SRui Ueyama     } else if (tok == "OUTPUT") {
2472ec34544SRui Ueyama       readOutput();
2483837f427SRui Ueyama     } else if (tok == "OUTPUT_ARCH") {
2492ec34544SRui Ueyama       readOutputArch();
2503837f427SRui Ueyama     } else if (tok == "OUTPUT_FORMAT") {
2512ec34544SRui Ueyama       readOutputFormat();
2523837f427SRui Ueyama     } else if (tok == "PHDRS") {
2532ec34544SRui Ueyama       readPhdrs();
2543837f427SRui Ueyama     } else if (tok == "REGION_ALIAS") {
2555f37541cSGeorge Rimar       readRegionAlias();
2563837f427SRui Ueyama     } else if (tok == "SEARCH_DIR") {
2572ec34544SRui Ueyama       readSearchDir();
2583837f427SRui Ueyama     } else if (tok == "SECTIONS") {
2592ec34544SRui Ueyama       readSections();
2603837f427SRui Ueyama     } else if (tok == "TARGET") {
261e262bb1aSRui Ueyama       readTarget();
2623837f427SRui Ueyama     } else if (tok == "VERSION") {
2632ec34544SRui Ueyama       readVersion();
2643837f427SRui Ueyama     } else if (SymbolAssignment *cmd = readAssignment(tok)) {
2653837f427SRui Ueyama       script->sectionCommands.push_back(cmd);
2662ec34544SRui Ueyama     } else {
2673837f427SRui Ueyama       setError("unknown directive: " + tok);
2682ec34544SRui Ueyama     }
2692ec34544SRui Ueyama   }
2702ec34544SRui Ueyama }
2712ec34544SRui Ueyama 
2723837f427SRui Ueyama void ScriptParser::readDefsym(StringRef name) {
273c1522816SGeorge Rimar   if (errorCount())
274c1522816SGeorge Rimar     return;
2753837f427SRui Ueyama   Expr e = readExpr();
2768c7e8cceSPetr Hosek   if (!atEOF())
2778c7e8cceSPetr Hosek     setError("EOF expected, but got " + next());
2783837f427SRui Ueyama   SymbolAssignment *cmd = make<SymbolAssignment>(name, e, getCurrentLocation());
2793837f427SRui Ueyama   script->sectionCommands.push_back(cmd);
2808c7e8cceSPetr Hosek }
2818c7e8cceSPetr Hosek 
2823837f427SRui Ueyama void ScriptParser::addFile(StringRef s) {
2833837f427SRui Ueyama   if (isUnderSysroot && s.startswith("/")) {
2843837f427SRui Ueyama     SmallString<128> pathData;
2853837f427SRui Ueyama     StringRef path = (config->sysroot + s).toStringRef(pathData);
2863837f427SRui Ueyama     if (sys::fs::exists(path)) {
28749a3ad21SRui Ueyama       driver->addFile(saver.save(path), /*withLOption=*/false);
2882ec34544SRui Ueyama       return;
2892ec34544SRui Ueyama     }
2902ec34544SRui Ueyama   }
2912ec34544SRui Ueyama 
2923837f427SRui Ueyama   if (s.startswith("/")) {
293*c384ca3cSFangrui Song     // Case 1: s is an absolute path. Just open it.
29449a3ad21SRui Ueyama     driver->addFile(s, /*withLOption=*/false);
2953837f427SRui Ueyama   } else if (s.startswith("=")) {
296*c384ca3cSFangrui Song     // Case 2: relative to the sysroot.
2973837f427SRui Ueyama     if (config->sysroot.empty())
29849a3ad21SRui Ueyama       driver->addFile(s.substr(1), /*withLOption=*/false);
2992ec34544SRui Ueyama     else
300136d27abSRui Ueyama       driver->addFile(saver.save(config->sysroot + "/" + s.substr(1)),
30149a3ad21SRui Ueyama                       /*withLOption=*/false);
3023837f427SRui Ueyama   } else if (s.startswith("-l")) {
303*c384ca3cSFangrui Song     // Case 3: search in the list of library paths.
3043837f427SRui Ueyama     driver->addLibrary(s.substr(2));
305*c384ca3cSFangrui Song   } else {
306*c384ca3cSFangrui Song     // Case 4: s is a relative path. Search in the directory of the script file.
307*c384ca3cSFangrui Song     std::string filename = std::string(getCurrentMB().getBufferIdentifier());
308*c384ca3cSFangrui Song     StringRef directory = sys::path::parent_path(filename);
309*c384ca3cSFangrui Song     if (!directory.empty()) {
310*c384ca3cSFangrui Song       SmallString<0> path(directory);
311*c384ca3cSFangrui Song       sys::path::append(path, s);
312*c384ca3cSFangrui Song       if (sys::fs::exists(path)) {
313*c384ca3cSFangrui Song         driver->addFile(path, /*withLOption=*/false);
314*c384ca3cSFangrui Song         return;
315*c384ca3cSFangrui Song       }
316*c384ca3cSFangrui Song     }
317*c384ca3cSFangrui Song     // Then search in the current working directory.
318*c384ca3cSFangrui Song     if (sys::fs::exists(s)) {
31949a3ad21SRui Ueyama       driver->addFile(s, /*withLOption=*/false);
3202ec34544SRui Ueyama     } else {
321*c384ca3cSFangrui Song       // Finally, search in the list of library paths.
3223837f427SRui Ueyama       if (Optional<std::string> path = findFromSearchPaths(s))
32349a3ad21SRui Ueyama         driver->addFile(saver.save(*path), /*withLOption=*/true);
3242ec34544SRui Ueyama       else
3253837f427SRui Ueyama         setError("unable to find " + s);
3262ec34544SRui Ueyama     }
3272ec34544SRui Ueyama   }
328*c384ca3cSFangrui Song }
3292ec34544SRui Ueyama 
3302ec34544SRui Ueyama void ScriptParser::readAsNeeded() {
3312ec34544SRui Ueyama   expect("(");
3323837f427SRui Ueyama   bool orig = config->asNeeded;
3333837f427SRui Ueyama   config->asNeeded = true;
334b8a59c8aSBob Haarman   while (!errorCount() && !consume(")"))
3352ec34544SRui Ueyama     addFile(unquote(next()));
3363837f427SRui Ueyama   config->asNeeded = orig;
3372ec34544SRui Ueyama }
3382ec34544SRui Ueyama 
3392ec34544SRui Ueyama void ScriptParser::readEntry() {
3402ec34544SRui Ueyama   // -e <symbol> takes predecence over ENTRY(<symbol>).
3412ec34544SRui Ueyama   expect("(");
3423837f427SRui Ueyama   StringRef tok = next();
3433837f427SRui Ueyama   if (config->entry.empty())
3443837f427SRui Ueyama     config->entry = tok;
3452ec34544SRui Ueyama   expect(")");
3462ec34544SRui Ueyama }
3472ec34544SRui Ueyama 
3482ec34544SRui Ueyama void ScriptParser::readExtern() {
3492ec34544SRui Ueyama   expect("(");
350b8a59c8aSBob Haarman   while (!errorCount() && !consume(")"))
3513837f427SRui Ueyama     config->undefined.push_back(unquote(next()));
3522ec34544SRui Ueyama }
3532ec34544SRui Ueyama 
3542ec34544SRui Ueyama void ScriptParser::readGroup() {
3553837f427SRui Ueyama   bool orig = InputFile::isInGroup;
3563837f427SRui Ueyama   InputFile::isInGroup = true;
3571d92aa73SRui Ueyama   readInput();
3583837f427SRui Ueyama   InputFile::isInGroup = orig;
3593837f427SRui Ueyama   if (!orig)
3603837f427SRui Ueyama     ++InputFile::nextGroupId;
3612ec34544SRui Ueyama }
3622ec34544SRui Ueyama 
3632ec34544SRui Ueyama void ScriptParser::readInclude() {
3643837f427SRui Ueyama   StringRef tok = unquote(next());
3652ec34544SRui Ueyama 
3663837f427SRui Ueyama   if (!seen.insert(tok).second) {
3670440be4aSRui Ueyama     setError("there is a cycle in linker script INCLUDEs");
3680440be4aSRui Ueyama     return;
3690440be4aSRui Ueyama   }
3700440be4aSRui Ueyama 
3713837f427SRui Ueyama   if (Optional<std::string> path = searchScript(tok)) {
3723837f427SRui Ueyama     if (Optional<MemoryBufferRef> mb = readFile(*path))
3733837f427SRui Ueyama       tokenize(*mb);
3742ec34544SRui Ueyama     return;
3752ec34544SRui Ueyama   }
3763837f427SRui Ueyama   setError("cannot find linker script " + tok);
3772ec34544SRui Ueyama }
3782ec34544SRui Ueyama 
3791d92aa73SRui Ueyama void ScriptParser::readInput() {
3801d92aa73SRui Ueyama   expect("(");
3811d92aa73SRui Ueyama   while (!errorCount() && !consume(")")) {
3821d92aa73SRui Ueyama     if (consume("AS_NEEDED"))
3831d92aa73SRui Ueyama       readAsNeeded();
3841d92aa73SRui Ueyama     else
3851d92aa73SRui Ueyama       addFile(unquote(next()));
3861d92aa73SRui Ueyama   }
3871d92aa73SRui Ueyama }
3881d92aa73SRui Ueyama 
3892ec34544SRui Ueyama void ScriptParser::readOutput() {
3902ec34544SRui Ueyama   // -o <file> takes predecence over OUTPUT(<file>).
3912ec34544SRui Ueyama   expect("(");
3923837f427SRui Ueyama   StringRef tok = next();
3933837f427SRui Ueyama   if (config->outputFile.empty())
3943837f427SRui Ueyama     config->outputFile = unquote(tok);
3952ec34544SRui Ueyama   expect(")");
3962ec34544SRui Ueyama }
3972ec34544SRui Ueyama 
3982ec34544SRui Ueyama void ScriptParser::readOutputArch() {
3992ec34544SRui Ueyama   // OUTPUT_ARCH is ignored for now.
4002ec34544SRui Ueyama   expect("(");
401b8a59c8aSBob Haarman   while (!errorCount() && !consume(")"))
4022ec34544SRui Ueyama     skip();
4032ec34544SRui Ueyama }
4042ec34544SRui Ueyama 
4053837f427SRui Ueyama static std::pair<ELFKind, uint16_t> parseBfdName(StringRef s) {
4063837f427SRui Ueyama   return StringSwitch<std::pair<ELFKind, uint16_t>>(s)
4074f8c8228SRui Ueyama       .Case("elf32-i386", {ELF32LEKind, EM_386})
4084f8c8228SRui Ueyama       .Case("elf32-iamcu", {ELF32LEKind, EM_IAMCU})
4094f8c8228SRui Ueyama       .Case("elf32-littlearm", {ELF32LEKind, EM_ARM})
4104f8c8228SRui Ueyama       .Case("elf32-x86-64", {ELF32LEKind, EM_X86_64})
41119b134ccSDimitry Andric       .Case("elf64-aarch64", {ELF64LEKind, EM_AARCH64})
4124f8c8228SRui Ueyama       .Case("elf64-littleaarch64", {ELF64LEKind, EM_AARCH64})
4134134143cSRui Ueyama       .Case("elf32-powerpc", {ELF32BEKind, EM_PPC})
4144f8c8228SRui Ueyama       .Case("elf64-powerpc", {ELF64BEKind, EM_PPC64})
4154f8c8228SRui Ueyama       .Case("elf64-powerpcle", {ELF64LEKind, EM_PPC64})
4164f8c8228SRui Ueyama       .Case("elf64-x86-64", {ELF64LEKind, EM_X86_64})
4174134143cSRui Ueyama       .Cases("elf32-tradbigmips", "elf32-bigmips", {ELF32BEKind, EM_MIPS})
4184f8c8228SRui Ueyama       .Case("elf32-ntradbigmips", {ELF32BEKind, EM_MIPS})
4194f8c8228SRui Ueyama       .Case("elf32-tradlittlemips", {ELF32LEKind, EM_MIPS})
4204f8c8228SRui Ueyama       .Case("elf32-ntradlittlemips", {ELF32LEKind, EM_MIPS})
4214f8c8228SRui Ueyama       .Case("elf64-tradbigmips", {ELF64BEKind, EM_MIPS})
4224f8c8228SRui Ueyama       .Case("elf64-tradlittlemips", {ELF64LEKind, EM_MIPS})
42344d908d7SFangrui Song       .Case("elf32-littleriscv", {ELF32LEKind, EM_RISCV})
42444d908d7SFangrui Song       .Case("elf64-littleriscv", {ELF64LEKind, EM_RISCV})
425aff950e9SLemonBoy       .Case("elf64-sparc", {ELF64BEKind, EM_SPARCV9})
4264f8c8228SRui Ueyama       .Default({ELFNoneKind, EM_NONE});
427ea8cd00aSRui Ueyama }
428ea8cd00aSRui Ueyama 
429ea8cd00aSRui Ueyama // Parse OUTPUT_FORMAT(bfdname) or OUTPUT_FORMAT(bfdname, big, little).
430ea8cd00aSRui Ueyama // Currently we ignore big and little parameters.
4312ec34544SRui Ueyama void ScriptParser::readOutputFormat() {
4322ec34544SRui Ueyama   expect("(");
433ea8cd00aSRui Ueyama 
4342822852fSShoaib Meenai   config->bfdname = unquote(next());
4352822852fSShoaib Meenai   StringRef s = config->bfdname;
4363837f427SRui Ueyama   if (s.consume_back("-freebsd"))
4373837f427SRui Ueyama     config->osabi = ELFOSABI_FREEBSD;
4384f8c8228SRui Ueyama 
4393837f427SRui Ueyama   std::tie(config->ekind, config->emachine) = parseBfdName(s);
4403837f427SRui Ueyama   if (config->emachine == EM_NONE)
4412822852fSShoaib Meenai     setError("unknown output format name: " + config->bfdname);
4423837f427SRui Ueyama   if (s == "elf32-ntradlittlemips" || s == "elf32-ntradbigmips")
4433837f427SRui Ueyama     config->mipsN32Abi = true;
444ea8cd00aSRui Ueyama 
445b579c439SRui Ueyama   if (consume(")"))
4462ec34544SRui Ueyama     return;
447b579c439SRui Ueyama   expect(",");
4482ec34544SRui Ueyama   skip();
4492ec34544SRui Ueyama   expect(",");
4502ec34544SRui Ueyama   skip();
4512ec34544SRui Ueyama   expect(")");
4522ec34544SRui Ueyama }
4532ec34544SRui Ueyama 
4542ec34544SRui Ueyama void ScriptParser::readPhdrs() {
4552ec34544SRui Ueyama   expect("{");
4562ec34544SRui Ueyama 
457b8a59c8aSBob Haarman   while (!errorCount() && !consume("}")) {
4583837f427SRui Ueyama     PhdrsCommand cmd;
4593837f427SRui Ueyama     cmd.name = next();
4603837f427SRui Ueyama     cmd.type = readPhdrType();
461b579c439SRui Ueyama 
462b8a59c8aSBob Haarman     while (!errorCount() && !consume(";")) {
463b579c439SRui Ueyama       if (consume("FILEHDR"))
4643837f427SRui Ueyama         cmd.hasFilehdr = true;
465b579c439SRui Ueyama       else if (consume("PHDRS"))
4663837f427SRui Ueyama         cmd.hasPhdrs = true;
467b579c439SRui Ueyama       else if (consume("AT"))
4683837f427SRui Ueyama         cmd.lmaExpr = readParenExpr();
469b579c439SRui Ueyama       else if (consume("FLAGS"))
4703837f427SRui Ueyama         cmd.flags = readParenExpr()().getValue();
471b579c439SRui Ueyama       else
472b579c439SRui Ueyama         setError("unexpected header attribute: " + next());
473b579c439SRui Ueyama     }
4740ae2c24cSRui Ueyama 
4753837f427SRui Ueyama     script->phdrsCommands.push_back(cmd);
4762ec34544SRui Ueyama   }
4772ec34544SRui Ueyama }
4782ec34544SRui Ueyama 
4795f37541cSGeorge Rimar void ScriptParser::readRegionAlias() {
4805f37541cSGeorge Rimar   expect("(");
4813837f427SRui Ueyama   StringRef alias = unquote(next());
4825f37541cSGeorge Rimar   expect(",");
4833837f427SRui Ueyama   StringRef name = next();
4845f37541cSGeorge Rimar   expect(")");
4855f37541cSGeorge Rimar 
4863837f427SRui Ueyama   if (script->memoryRegions.count(alias))
4873837f427SRui Ueyama     setError("redefinition of memory region '" + alias + "'");
4883837f427SRui Ueyama   if (!script->memoryRegions.count(name))
4893837f427SRui Ueyama     setError("memory region '" + name + "' is not defined");
4903837f427SRui Ueyama   script->memoryRegions.insert({alias, script->memoryRegions[name]});
4915f37541cSGeorge Rimar }
4925f37541cSGeorge Rimar 
4932ec34544SRui Ueyama void ScriptParser::readSearchDir() {
4942ec34544SRui Ueyama   expect("(");
4953837f427SRui Ueyama   StringRef tok = next();
4963837f427SRui Ueyama   if (!config->nostdlib)
4973837f427SRui Ueyama     config->searchPaths.push_back(unquote(tok));
4982ec34544SRui Ueyama   expect(")");
4992ec34544SRui Ueyama }
5002ec34544SRui Ueyama 
501a582419aSGeorge Rimar // This reads an overlay description. Overlays are used to describe output
502a582419aSGeorge Rimar // sections that use the same virtual memory range and normally would trigger
503a582419aSGeorge Rimar // linker's sections sanity check failures.
504a582419aSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Overlay-Description.html#Overlay-Description
505a582419aSGeorge Rimar std::vector<BaseCommand *> ScriptParser::readOverlay() {
506a582419aSGeorge Rimar   // VA and LMA expressions are optional, though for simplicity of
507a582419aSGeorge Rimar   // implementation we assume they are not. That is what OVERLAY was designed
508a582419aSGeorge Rimar   // for first of all: to allow sections with overlapping VAs at different LMAs.
5093837f427SRui Ueyama   Expr addrExpr = readExpr();
510a582419aSGeorge Rimar   expect(":");
511a582419aSGeorge Rimar   expect("AT");
5123837f427SRui Ueyama   Expr lmaExpr = readParenExpr();
513a582419aSGeorge Rimar   expect("{");
514a582419aSGeorge Rimar 
5153837f427SRui Ueyama   std::vector<BaseCommand *> v;
5163837f427SRui Ueyama   OutputSection *prev = nullptr;
517a582419aSGeorge Rimar   while (!errorCount() && !consume("}")) {
518a582419aSGeorge Rimar     // VA is the same for all sections. The LMAs are consecutive in memory
519a582419aSGeorge Rimar     // starting from the base load address specified.
5203837f427SRui Ueyama     OutputSection *os = readOverlaySectionDescription();
5213837f427SRui Ueyama     os->addrExpr = addrExpr;
5223837f427SRui Ueyama     if (prev)
5233837f427SRui Ueyama       os->lmaExpr = [=] { return prev->getLMA() + prev->size; };
524a582419aSGeorge Rimar     else
5253837f427SRui Ueyama       os->lmaExpr = lmaExpr;
5263837f427SRui Ueyama     v.push_back(os);
5273837f427SRui Ueyama     prev = os;
528a582419aSGeorge Rimar   }
529a582419aSGeorge Rimar 
530a582419aSGeorge Rimar   // According to the specification, at the end of the overlay, the location
531a582419aSGeorge Rimar   // counter should be equal to the overlay base address plus size of the
532a582419aSGeorge Rimar   // largest section seen in the overlay.
533a582419aSGeorge Rimar   // Here we want to create the Dot assignment command to achieve that.
5343837f427SRui Ueyama   Expr moveDot = [=] {
5353837f427SRui Ueyama     uint64_t max = 0;
5363837f427SRui Ueyama     for (BaseCommand *cmd : v)
5373837f427SRui Ueyama       max = std::max(max, cast<OutputSection>(cmd)->size);
5383837f427SRui Ueyama     return addrExpr().getValue() + max;
539a582419aSGeorge Rimar   };
5403837f427SRui Ueyama   v.push_back(make<SymbolAssignment>(".", moveDot, getCurrentLocation()));
5413837f427SRui Ueyama   return v;
542a582419aSGeorge Rimar }
543a582419aSGeorge Rimar 
5442ec34544SRui Ueyama void ScriptParser::readSections() {
5452ec34544SRui Ueyama   expect("{");
5463837f427SRui Ueyama   std::vector<BaseCommand *> v;
547b8a59c8aSBob Haarman   while (!errorCount() && !consume("}")) {
5483837f427SRui Ueyama     StringRef tok = next();
5493837f427SRui Ueyama     if (tok == "OVERLAY") {
5503837f427SRui Ueyama       for (BaseCommand *cmd : readOverlay())
5513837f427SRui Ueyama         v.push_back(cmd);
552a582419aSGeorge Rimar       continue;
5533837f427SRui Ueyama     } else if (tok == "INCLUDE") {
5542e9d40d5SRui Ueyama       readInclude();
5552e9d40d5SRui Ueyama       continue;
556a582419aSGeorge Rimar     }
557a582419aSGeorge Rimar 
5583837f427SRui Ueyama     if (BaseCommand *cmd = readAssignment(tok))
5593837f427SRui Ueyama       v.push_back(cmd);
560d30a78b3SGeorge Rimar     else
5613837f427SRui Ueyama       v.push_back(readOutputSectionDescription(tok));
5622ec34544SRui Ueyama   }
5637c426fb1SFangrui Song   script->sectionCommands.insert(script->sectionCommands.end(), v.begin(),
5647c426fb1SFangrui Song                                  v.end());
5659e2c8a9dSGeorge Rimar 
5667c426fb1SFangrui Song   if (atEOF() || !consume("INSERT")) {
5677c426fb1SFangrui Song     script->hasSectionsCommand = true;
5689e2c8a9dSGeorge Rimar     return;
5699e2c8a9dSGeorge Rimar   }
5709e2c8a9dSGeorge Rimar 
5717c426fb1SFangrui Song   bool isAfter = false;
5727c426fb1SFangrui Song   if (consume("AFTER"))
5737c426fb1SFangrui Song     isAfter = true;
5747c426fb1SFangrui Song   else if (!consume("BEFORE"))
5757c426fb1SFangrui Song     setError("expected AFTER/BEFORE, but got '" + next() + "'");
5767c426fb1SFangrui Song   StringRef where = next();
5777c426fb1SFangrui Song   for (BaseCommand *cmd : v)
5787c426fb1SFangrui Song     if (auto *os = dyn_cast<OutputSection>(cmd))
5797c426fb1SFangrui Song       script->insertCommands.push_back({os, isAfter, where});
5802ec34544SRui Ueyama }
5812ec34544SRui Ueyama 
582e262bb1aSRui Ueyama void ScriptParser::readTarget() {
583e262bb1aSRui Ueyama   // TARGET(foo) is an alias for "--format foo". Unlike GNU linkers,
584e262bb1aSRui Ueyama   // we accept only a limited set of BFD names (i.e. "elf" or "binary")
585e262bb1aSRui Ueyama   // for --format. We recognize only /^elf/ and "binary" in the linker
586e262bb1aSRui Ueyama   // script as well.
587e262bb1aSRui Ueyama   expect("(");
5883837f427SRui Ueyama   StringRef tok = next();
589e262bb1aSRui Ueyama   expect(")");
590e262bb1aSRui Ueyama 
5913837f427SRui Ueyama   if (tok.startswith("elf"))
5923837f427SRui Ueyama     config->formatBinary = false;
5933837f427SRui Ueyama   else if (tok == "binary")
5943837f427SRui Ueyama     config->formatBinary = true;
595e262bb1aSRui Ueyama   else
5963837f427SRui Ueyama     setError("unknown target: " + tok);
597e262bb1aSRui Ueyama }
598e262bb1aSRui Ueyama 
5993837f427SRui Ueyama static int precedence(StringRef op) {
6003837f427SRui Ueyama   return StringSwitch<int>(op)
601a5005482SGeorge Rimar       .Cases("*", "/", "%", 8)
602a5005482SGeorge Rimar       .Cases("+", "-", 7)
603a5005482SGeorge Rimar       .Cases("<<", ">>", 6)
604a5005482SGeorge Rimar       .Cases("<", "<=", ">", ">=", "==", "!=", 5)
605a5005482SGeorge Rimar       .Case("&", 4)
606a5005482SGeorge Rimar       .Case("|", 3)
607a5005482SGeorge Rimar       .Case("&&", 2)
608a5005482SGeorge Rimar       .Case("||", 1)
6092ec34544SRui Ueyama       .Default(-1);
6102ec34544SRui Ueyama }
6112ec34544SRui Ueyama 
6122ec34544SRui Ueyama StringMatcher ScriptParser::readFilePatterns() {
613c42fe247SThomas Preud'homme   StringMatcher Matcher;
614c42fe247SThomas Preud'homme 
615b8a59c8aSBob Haarman   while (!errorCount() && !consume(")"))
616c42fe247SThomas Preud'homme     Matcher.addPattern(SingleStringMatcher(next()));
617c42fe247SThomas Preud'homme   return Matcher;
6182ec34544SRui Ueyama }
6192ec34544SRui Ueyama 
6202ec34544SRui Ueyama SortSectionPolicy ScriptParser::readSortKind() {
6212ec34544SRui Ueyama   if (consume("SORT") || consume("SORT_BY_NAME"))
6222ec34544SRui Ueyama     return SortSectionPolicy::Name;
6232ec34544SRui Ueyama   if (consume("SORT_BY_ALIGNMENT"))
6242ec34544SRui Ueyama     return SortSectionPolicy::Alignment;
6252ec34544SRui Ueyama   if (consume("SORT_BY_INIT_PRIORITY"))
6262ec34544SRui Ueyama     return SortSectionPolicy::Priority;
6272ec34544SRui Ueyama   if (consume("SORT_NONE"))
6282ec34544SRui Ueyama     return SortSectionPolicy::None;
6292ec34544SRui Ueyama   return SortSectionPolicy::Default;
6302ec34544SRui Ueyama }
6312ec34544SRui Ueyama 
63203fc8d1eSRui Ueyama // Reads SECTIONS command contents in the following form:
63303fc8d1eSRui Ueyama //
63403fc8d1eSRui Ueyama // <contents> ::= <elem>*
63503fc8d1eSRui Ueyama // <elem>     ::= <exclude>? <glob-pattern>
63603fc8d1eSRui Ueyama // <exclude>  ::= "EXCLUDE_FILE" "(" <glob-pattern>+ ")"
63703fc8d1eSRui Ueyama //
63803fc8d1eSRui Ueyama // For example,
63903fc8d1eSRui Ueyama //
64003fc8d1eSRui Ueyama // *(.foo EXCLUDE_FILE (a.o) .bar EXCLUDE_FILE (b.o) .baz)
64103fc8d1eSRui Ueyama //
64203fc8d1eSRui Ueyama // is parsed as ".foo", ".bar" with "a.o", and ".baz" with "b.o".
64303fc8d1eSRui Ueyama // The semantics of that is section .foo in any file, section .bar in
64403fc8d1eSRui Ueyama // any file but a.o, and section .baz in any file but b.o.
6452ec34544SRui Ueyama std::vector<SectionPattern> ScriptParser::readInputSectionsList() {
6463837f427SRui Ueyama   std::vector<SectionPattern> ret;
647b8a59c8aSBob Haarman   while (!errorCount() && peek() != ")") {
6483837f427SRui Ueyama     StringMatcher excludeFilePat;
6492ec34544SRui Ueyama     if (consume("EXCLUDE_FILE")) {
6502ec34544SRui Ueyama       expect("(");
6513837f427SRui Ueyama       excludeFilePat = readFilePatterns();
6522ec34544SRui Ueyama     }
6532ec34544SRui Ueyama 
654c42fe247SThomas Preud'homme     StringMatcher SectionMatcher;
655b8a59c8aSBob Haarman     while (!errorCount() && peek() != ")" && peek() != "EXCLUDE_FILE")
656c42fe247SThomas Preud'homme       SectionMatcher.addPattern(unquote(next()));
6572ec34544SRui Ueyama 
658c42fe247SThomas Preud'homme     if (!SectionMatcher.empty())
659c42fe247SThomas Preud'homme       ret.push_back({std::move(excludeFilePat), std::move(SectionMatcher)});
6602ec34544SRui Ueyama     else
6612ec34544SRui Ueyama       setError("section pattern is expected");
6622ec34544SRui Ueyama   }
6633837f427SRui Ueyama   return ret;
6642ec34544SRui Ueyama }
6652ec34544SRui Ueyama 
6662ec34544SRui Ueyama // Reads contents of "SECTIONS" directive. That directive contains a
6672ec34544SRui Ueyama // list of glob patterns for input sections. The grammar is as follows.
6682ec34544SRui Ueyama //
6692ec34544SRui Ueyama // <patterns> ::= <section-list>
6702ec34544SRui Ueyama //              | <sort> "(" <section-list> ")"
6712ec34544SRui Ueyama //              | <sort> "(" <sort> "(" <section-list> ")" ")"
6722ec34544SRui Ueyama //
6732ec34544SRui Ueyama // <sort>     ::= "SORT" | "SORT_BY_NAME" | "SORT_BY_ALIGNMENT"
6742ec34544SRui Ueyama //              | "SORT_BY_INIT_PRIORITY" | "SORT_NONE"
6752ec34544SRui Ueyama //
6762ec34544SRui Ueyama // <section-list> is parsed by readInputSectionsList().
6772ec34544SRui Ueyama InputSectionDescription *
678dbd0ad33SPeter Smith ScriptParser::readInputSectionRules(StringRef filePattern, uint64_t withFlags,
679dbd0ad33SPeter Smith                                     uint64_t withoutFlags) {
680dbd0ad33SPeter Smith   auto *cmd =
681dbd0ad33SPeter Smith       make<InputSectionDescription>(filePattern, withFlags, withoutFlags);
6822ec34544SRui Ueyama   expect("(");
6832ec34544SRui Ueyama 
684b8a59c8aSBob Haarman   while (!errorCount() && !consume(")")) {
6853837f427SRui Ueyama     SortSectionPolicy outer = readSortKind();
6863837f427SRui Ueyama     SortSectionPolicy inner = SortSectionPolicy::Default;
6873837f427SRui Ueyama     std::vector<SectionPattern> v;
6883837f427SRui Ueyama     if (outer != SortSectionPolicy::Default) {
6892ec34544SRui Ueyama       expect("(");
6903837f427SRui Ueyama       inner = readSortKind();
6913837f427SRui Ueyama       if (inner != SortSectionPolicy::Default) {
6922ec34544SRui Ueyama         expect("(");
6933837f427SRui Ueyama         v = readInputSectionsList();
6942ec34544SRui Ueyama         expect(")");
6952ec34544SRui Ueyama       } else {
6963837f427SRui Ueyama         v = readInputSectionsList();
6972ec34544SRui Ueyama       }
6982ec34544SRui Ueyama       expect(")");
6992ec34544SRui Ueyama     } else {
7003837f427SRui Ueyama       v = readInputSectionsList();
7012ec34544SRui Ueyama     }
7022ec34544SRui Ueyama 
7033837f427SRui Ueyama     for (SectionPattern &pat : v) {
7043837f427SRui Ueyama       pat.sortInner = inner;
7053837f427SRui Ueyama       pat.sortOuter = outer;
7062ec34544SRui Ueyama     }
7072ec34544SRui Ueyama 
7083837f427SRui Ueyama     std::move(v.begin(), v.end(), std::back_inserter(cmd->sectionPatterns));
7092ec34544SRui Ueyama   }
7103837f427SRui Ueyama   return cmd;
7112ec34544SRui Ueyama }
7122ec34544SRui Ueyama 
7132ec34544SRui Ueyama InputSectionDescription *
7143837f427SRui Ueyama ScriptParser::readInputSectionDescription(StringRef tok) {
7152ec34544SRui Ueyama   // Input section wildcard can be surrounded by KEEP.
7162ec34544SRui Ueyama   // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep
717dbd0ad33SPeter Smith   uint64_t withFlags = 0;
718dbd0ad33SPeter Smith   uint64_t withoutFlags = 0;
7193837f427SRui Ueyama   if (tok == "KEEP") {
7202ec34544SRui Ueyama     expect("(");
721dbd0ad33SPeter Smith     if (consume("INPUT_SECTION_FLAGS"))
722dbd0ad33SPeter Smith       std::tie(withFlags, withoutFlags) = readInputSectionFlags();
723dbd0ad33SPeter Smith     InputSectionDescription *cmd =
724dbd0ad33SPeter Smith         readInputSectionRules(next(), withFlags, withoutFlags);
7252ec34544SRui Ueyama     expect(")");
7263837f427SRui Ueyama     script->keptSections.push_back(cmd);
7273837f427SRui Ueyama     return cmd;
7282ec34544SRui Ueyama   }
729dbd0ad33SPeter Smith   if (tok == "INPUT_SECTION_FLAGS") {
730dbd0ad33SPeter Smith     std::tie(withFlags, withoutFlags) = readInputSectionFlags();
731dbd0ad33SPeter Smith     tok = next();
732dbd0ad33SPeter Smith   }
733dbd0ad33SPeter Smith   return readInputSectionRules(tok, withFlags, withoutFlags);
7342ec34544SRui Ueyama }
7352ec34544SRui Ueyama 
7362ec34544SRui Ueyama void ScriptParser::readSort() {
7372ec34544SRui Ueyama   expect("(");
7382ec34544SRui Ueyama   expect("CONSTRUCTORS");
7392ec34544SRui Ueyama   expect(")");
7402ec34544SRui Ueyama }
7412ec34544SRui Ueyama 
742d30a78b3SGeorge Rimar Expr ScriptParser::readAssert() {
7432ec34544SRui Ueyama   expect("(");
7443837f427SRui Ueyama   Expr e = readExpr();
7452ec34544SRui Ueyama   expect(",");
7463837f427SRui Ueyama   StringRef msg = unquote(next());
7472ec34544SRui Ueyama   expect(")");
748b579c439SRui Ueyama 
7492ec34544SRui Ueyama   return [=] {
7503837f427SRui Ueyama     if (!e().getValue())
7512682bc3cSFangrui Song       errorOrWarn(msg);
7523837f427SRui Ueyama     return script->getDot();
7532ec34544SRui Ueyama   };
7542ec34544SRui Ueyama }
7552ec34544SRui Ueyama 
756a46d08ebSGeorge Rimar // Tries to read the special directive for an output section definition which
757a46d08ebSGeorge Rimar // can be one of following: "(NOLOAD)", "(COPY)", "(INFO)" or "(OVERLAY)".
758a46d08ebSGeorge Rimar // Tok1 and Tok2 are next 2 tokens peeked. See comment for readSectionAddressType below.
7593837f427SRui Ueyama bool ScriptParser::readSectionDirective(OutputSection *cmd, StringRef tok1, StringRef tok2) {
7603837f427SRui Ueyama   if (tok1 != "(")
761a46d08ebSGeorge Rimar     return false;
7623837f427SRui Ueyama   if (tok2 != "NOLOAD" && tok2 != "COPY" && tok2 != "INFO" && tok2 != "OVERLAY")
763a46d08ebSGeorge Rimar     return false;
764a46d08ebSGeorge Rimar 
765a46d08ebSGeorge Rimar   expect("(");
766a46d08ebSGeorge Rimar   if (consume("NOLOAD")) {
7673837f427SRui Ueyama     cmd->noload = true;
768fdc41aa2SMatt Schulte     cmd->type = SHT_NOBITS;
769a46d08ebSGeorge Rimar   } else {
770a46d08ebSGeorge Rimar     skip(); // This is "COPY", "INFO" or "OVERLAY".
7713837f427SRui Ueyama     cmd->nonAlloc = true;
772a46d08ebSGeorge Rimar   }
773a46d08ebSGeorge Rimar   expect(")");
774a46d08ebSGeorge Rimar   return true;
775a46d08ebSGeorge Rimar }
776a46d08ebSGeorge Rimar 
7771c08e9f5SGeorge Rimar // Reads an expression and/or the special directive for an output
7781c08e9f5SGeorge Rimar // section definition. Directive is one of following: "(NOLOAD)",
7791c08e9f5SGeorge Rimar // "(COPY)", "(INFO)" or "(OVERLAY)".
7803271d370SRui Ueyama //
7813271d370SRui Ueyama // An output section name can be followed by an address expression
7821c08e9f5SGeorge Rimar // and/or directive. This grammar is not LL(1) because "(" can be
78397f4d158SGeorge Rimar // interpreted as either the beginning of some expression or beginning
7841c08e9f5SGeorge Rimar // of directive.
7853271d370SRui Ueyama //
786b579c439SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html
787fbb0463fSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Output-Section-Type.html
7883837f427SRui Ueyama void ScriptParser::readSectionAddressType(OutputSection *cmd) {
7893837f427SRui Ueyama   if (readSectionDirective(cmd, peek(), peek2()))
7903271d370SRui Ueyama     return;
7913271d370SRui Ueyama 
7923837f427SRui Ueyama   cmd->addrExpr = readExpr();
7933837f427SRui Ueyama   if (peek() == "(" && !readSectionDirective(cmd, "(", peek2()))
794a46d08ebSGeorge Rimar     setError("unknown section directive: " + peek2());
795fbb0463fSGeorge Rimar }
796fbb0463fSGeorge Rimar 
7973837f427SRui Ueyama static Expr checkAlignment(Expr e, std::string &loc) {
798f22ec9ddSGeorge Rimar   return [=] {
7993837f427SRui Ueyama     uint64_t alignment = std::max((uint64_t)1, e().getValue());
8003837f427SRui Ueyama     if (!isPowerOf2_64(alignment)) {
8013837f427SRui Ueyama       error(loc + ": alignment must be power of 2");
802f22ec9ddSGeorge Rimar       return (uint64_t)1; // Return a dummy value.
803f22ec9ddSGeorge Rimar     }
8043837f427SRui Ueyama     return alignment;
805f22ec9ddSGeorge Rimar   };
806f22ec9ddSGeorge Rimar }
807f22ec9ddSGeorge Rimar 
808a582419aSGeorge Rimar OutputSection *ScriptParser::readOverlaySectionDescription() {
8093837f427SRui Ueyama   OutputSection *cmd =
8103837f427SRui Ueyama       script->createOutputSection(next(), getCurrentLocation());
8113837f427SRui Ueyama   cmd->inOverlay = true;
812a582419aSGeorge Rimar   expect("{");
813dbd0ad33SPeter Smith   while (!errorCount() && !consume("}")) {
814dbd0ad33SPeter Smith     uint64_t withFlags = 0;
815dbd0ad33SPeter Smith     uint64_t withoutFlags = 0;
816dbd0ad33SPeter Smith     if (consume("INPUT_SECTION_FLAGS"))
817dbd0ad33SPeter Smith       std::tie(withFlags, withoutFlags) = readInputSectionFlags();
818dbd0ad33SPeter Smith     cmd->sectionCommands.push_back(
819dbd0ad33SPeter Smith         readInputSectionRules(next(), withFlags, withoutFlags));
820dbd0ad33SPeter Smith   }
8213837f427SRui Ueyama   return cmd;
822a582419aSGeorge Rimar }
823a582419aSGeorge Rimar 
8243837f427SRui Ueyama OutputSection *ScriptParser::readOutputSectionDescription(StringRef outSec) {
8253837f427SRui Ueyama   OutputSection *cmd =
8263837f427SRui Ueyama       script->createOutputSection(outSec, getCurrentLocation());
8273271d370SRui Ueyama 
8283837f427SRui Ueyama   size_t symbolsReferenced = script->referencedSymbols.size();
829c4df670dSGeorge Rimar 
8303271d370SRui Ueyama   if (peek() != ":")
8313837f427SRui Ueyama     readSectionAddressType(cmd);
8322ec34544SRui Ueyama   expect(":");
8332ec34544SRui Ueyama 
8343837f427SRui Ueyama   std::string location = getCurrentLocation();
8352ec34544SRui Ueyama   if (consume("AT"))
8363837f427SRui Ueyama     cmd->lmaExpr = readParenExpr();
8372ec34544SRui Ueyama   if (consume("ALIGN"))
8383837f427SRui Ueyama     cmd->alignExpr = checkAlignment(readParenExpr(), location);
8392ec34544SRui Ueyama   if (consume("SUBALIGN"))
8403837f427SRui Ueyama     cmd->subalignExpr = checkAlignment(readParenExpr(), location);
8412ec34544SRui Ueyama 
8422ec34544SRui Ueyama   // Parse constraints.
8432ec34544SRui Ueyama   if (consume("ONLY_IF_RO"))
8443837f427SRui Ueyama     cmd->constraint = ConstraintKind::ReadOnly;
8452ec34544SRui Ueyama   if (consume("ONLY_IF_RW"))
8463837f427SRui Ueyama     cmd->constraint = ConstraintKind::ReadWrite;
8472ec34544SRui Ueyama   expect("{");
8482ec34544SRui Ueyama 
849b8a59c8aSBob Haarman   while (!errorCount() && !consume("}")) {
8503837f427SRui Ueyama     StringRef tok = next();
8513837f427SRui Ueyama     if (tok == ";") {
8522ec34544SRui Ueyama       // Empty commands are allowed. Do nothing here.
8533837f427SRui Ueyama     } else if (SymbolAssignment *assign = readAssignment(tok)) {
8543837f427SRui Ueyama       cmd->sectionCommands.push_back(assign);
8553837f427SRui Ueyama     } else if (ByteCommand *data = readByteCommand(tok)) {
8563837f427SRui Ueyama       cmd->sectionCommands.push_back(data);
8573837f427SRui Ueyama     } else if (tok == "CONSTRUCTORS") {
8582ec34544SRui Ueyama       // CONSTRUCTORS is a keyword to make the linker recognize C++ ctors/dtors
8592ec34544SRui Ueyama       // by name. This is for very old file formats such as ECOFF/XCOFF.
8602ec34544SRui Ueyama       // For ELF, we should ignore.
8613837f427SRui Ueyama     } else if (tok == "FILL") {
8620810f16fSGeorge Rimar       // We handle the FILL command as an alias for =fillexp section attribute,
8630810f16fSGeorge Rimar       // which is different from what GNU linkers do.
8640810f16fSGeorge Rimar       // https://sourceware.org/binutils/docs/ld/Output-Section-Data.html
865bb7d2b17SGeorgii Rymar       if (peek() != "(")
866bb7d2b17SGeorgii Rymar         setError("( expected, but got " + peek());
8673837f427SRui Ueyama       cmd->filler = readFill();
8683837f427SRui Ueyama     } else if (tok == "SORT") {
8692ec34544SRui Ueyama       readSort();
8703837f427SRui Ueyama     } else if (tok == "INCLUDE") {
8712e9d40d5SRui Ueyama       readInclude();
8722ec34544SRui Ueyama     } else if (peek() == "(") {
8733837f427SRui Ueyama       cmd->sectionCommands.push_back(readInputSectionDescription(tok));
8742ec34544SRui Ueyama     } else {
875f49fe218SGeorge Rimar       // We have a file name and no input sections description. It is not a
876f49fe218SGeorge Rimar       // commonly used syntax, but still acceptable. In that case, all sections
877f49fe218SGeorge Rimar       // from the file will be included.
878dbd0ad33SPeter Smith       // FIXME: GNU ld permits INPUT_SECTION_FLAGS to be used here. We do not
879dbd0ad33SPeter Smith       // handle this case here as it will already have been matched by the
880dbd0ad33SPeter Smith       // case above.
8813837f427SRui Ueyama       auto *isd = make<InputSectionDescription>(tok);
882c42fe247SThomas Preud'homme       isd->sectionPatterns.push_back({{}, StringMatcher("*")});
8833837f427SRui Ueyama       cmd->sectionCommands.push_back(isd);
8842ec34544SRui Ueyama     }
8852ec34544SRui Ueyama   }
8862ec34544SRui Ueyama 
8872ec34544SRui Ueyama   if (consume(">"))
888adcd0268SBenjamin Kramer     cmd->memoryRegionName = std::string(next());
8892ec34544SRui Ueyama 
8905d01a8beSGeorge Rimar   if (consume("AT")) {
8915d01a8beSGeorge Rimar     expect(">");
892adcd0268SBenjamin Kramer     cmd->lmaRegionName = std::string(next());
8935d01a8beSGeorge Rimar   }
8945d01a8beSGeorge Rimar 
8953837f427SRui Ueyama   if (cmd->lmaExpr && !cmd->lmaRegionName.empty())
8965d01a8beSGeorge Rimar     error("section can't have both LMA and a load region");
8975d01a8beSGeorge Rimar 
8983837f427SRui Ueyama   cmd->phdrs = readOutputSectionPhdrs();
8992ec34544SRui Ueyama 
9000810f16fSGeorge Rimar   if (peek() == "=" || peek().startswith("=")) {
9013837f427SRui Ueyama     inExpr = true;
9020810f16fSGeorge Rimar     consume("=");
9033837f427SRui Ueyama     cmd->filler = readFill();
9043837f427SRui Ueyama     inExpr = false;
9050810f16fSGeorge Rimar   }
9062ec34544SRui Ueyama 
9072ec34544SRui Ueyama   // Consume optional comma following output section command.
9082ec34544SRui Ueyama   consume(",");
9092ec34544SRui Ueyama 
9103837f427SRui Ueyama   if (script->referencedSymbols.size() > symbolsReferenced)
9113837f427SRui Ueyama     cmd->expressionsUseSymbols = true;
9123837f427SRui Ueyama   return cmd;
9132ec34544SRui Ueyama }
9142ec34544SRui Ueyama 
9150810f16fSGeorge Rimar // Reads a `=<fillexp>` expression and returns its value as a big-endian number.
9162ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html
9170810f16fSGeorge Rimar // We do not support using symbols in such expressions.
9182ec34544SRui Ueyama //
9198acbf1ccSRui Ueyama // When reading a hexstring, ld.bfd handles it as a blob of arbitrary
9208acbf1ccSRui Ueyama // size, while ld.gold always handles it as a 32-bit big-endian number.
9218acbf1ccSRui Ueyama // We are compatible with ld.gold because it's easier to implement.
922bb7d2b17SGeorgii Rymar // Also, we require that expressions with operators must be wrapped into
923bb7d2b17SGeorgii Rymar // round brackets. We did it to resolve the ambiguity when parsing scripts like:
924bb7d2b17SGeorgii Rymar // SECTIONS { .foo : { ... } =120+3 /DISCARD/ : { ... } }
9250810f16fSGeorge Rimar std::array<uint8_t, 4> ScriptParser::readFill() {
926bb7d2b17SGeorgii Rymar   uint64_t value = readPrimary()().val;
9273837f427SRui Ueyama   if (value > UINT32_MAX)
9280810f16fSGeorge Rimar     setError("filler expression result does not fit 32-bit: 0x" +
9293837f427SRui Ueyama              Twine::utohexstr(value));
930b58079d4SRui Ueyama 
9313837f427SRui Ueyama   std::array<uint8_t, 4> buf;
9323837f427SRui Ueyama   write32be(buf.data(), (uint32_t)value);
9333837f427SRui Ueyama   return buf;
9342ec34544SRui Ueyama }
9352ec34544SRui Ueyama 
9363837f427SRui Ueyama SymbolAssignment *ScriptParser::readProvideHidden(bool provide, bool hidden) {
9372ec34544SRui Ueyama   expect("(");
9383837f427SRui Ueyama   SymbolAssignment *cmd = readSymbolAssignment(next());
9393837f427SRui Ueyama   cmd->provide = provide;
9403837f427SRui Ueyama   cmd->hidden = hidden;
9412ec34544SRui Ueyama   expect(")");
9423837f427SRui Ueyama   return cmd;
9432ec34544SRui Ueyama }
9442ec34544SRui Ueyama 
9453837f427SRui Ueyama SymbolAssignment *ScriptParser::readAssignment(StringRef tok) {
946d30a78b3SGeorge Rimar   // Assert expression returns Dot, so this is equal to ".=."
9473837f427SRui Ueyama   if (tok == "ASSERT")
948d30a78b3SGeorge Rimar     return make<SymbolAssignment>(".", readAssert(), getCurrentLocation());
949d30a78b3SGeorge Rimar 
9503837f427SRui Ueyama   size_t oldPos = pos;
9513837f427SRui Ueyama   SymbolAssignment *cmd = nullptr;
952e88b76a9SGeorge Rimar   if (peek() == "=" || peek() == "+=")
9533837f427SRui Ueyama     cmd = readSymbolAssignment(tok);
9543837f427SRui Ueyama   else if (tok == "PROVIDE")
9553837f427SRui Ueyama     cmd = readProvideHidden(true, false);
9563837f427SRui Ueyama   else if (tok == "HIDDEN")
9573837f427SRui Ueyama     cmd = readProvideHidden(false, true);
9583837f427SRui Ueyama   else if (tok == "PROVIDE_HIDDEN")
9593837f427SRui Ueyama     cmd = readProvideHidden(true, true);
960e88b76a9SGeorge Rimar 
9613837f427SRui Ueyama   if (cmd) {
9623837f427SRui Ueyama     cmd->commandString =
9633837f427SRui Ueyama         tok.str() + " " +
9643837f427SRui Ueyama         llvm::join(tokens.begin() + oldPos, tokens.begin() + pos, " ");
965e88b76a9SGeorge Rimar     expect(";");
9662ec34544SRui Ueyama   }
9673837f427SRui Ueyama   return cmd;
9682ec34544SRui Ueyama }
9692ec34544SRui Ueyama 
9703837f427SRui Ueyama SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef name) {
9713837f427SRui Ueyama   StringRef op = next();
9723837f427SRui Ueyama   assert(op == "=" || op == "+=");
9733837f427SRui Ueyama   Expr e = readExpr();
9743837f427SRui Ueyama   if (op == "+=") {
9753837f427SRui Ueyama     std::string loc = getCurrentLocation();
9763837f427SRui Ueyama     e = [=] { return add(script->getSymbolValue(name, loc), e()); };
9772ec34544SRui Ueyama   }
9783837f427SRui Ueyama   return make<SymbolAssignment>(name, e, getCurrentLocation());
9792ec34544SRui Ueyama }
9802ec34544SRui Ueyama 
9812ec34544SRui Ueyama // This is an operator-precedence parser to parse a linker
9822ec34544SRui Ueyama // script expression.
9832ec34544SRui Ueyama Expr ScriptParser::readExpr() {
9842ec34544SRui Ueyama   // Our lexer is context-aware. Set the in-expression bit so that
9852ec34544SRui Ueyama   // they apply different tokenization rules.
9863837f427SRui Ueyama   bool orig = inExpr;
9873837f427SRui Ueyama   inExpr = true;
9883837f427SRui Ueyama   Expr e = readExpr1(readPrimary(), 0);
9893837f427SRui Ueyama   inExpr = orig;
9903837f427SRui Ueyama   return e;
9912ec34544SRui Ueyama }
9922ec34544SRui Ueyama 
9933837f427SRui Ueyama Expr ScriptParser::combine(StringRef op, Expr l, Expr r) {
9943837f427SRui Ueyama   if (op == "+")
9953837f427SRui Ueyama     return [=] { return add(l(), r()); };
9963837f427SRui Ueyama   if (op == "-")
9973837f427SRui Ueyama     return [=] { return sub(l(), r()); };
9983837f427SRui Ueyama   if (op == "*")
9993837f427SRui Ueyama     return [=] { return l().getValue() * r().getValue(); };
10003837f427SRui Ueyama   if (op == "/") {
10013837f427SRui Ueyama     std::string loc = getCurrentLocation();
10027b91e213SGeorge Rimar     return [=]() -> uint64_t {
10033837f427SRui Ueyama       if (uint64_t rv = r().getValue())
10043837f427SRui Ueyama         return l().getValue() / rv;
10053837f427SRui Ueyama       error(loc + ": division by zero");
1006067617f9SRui Ueyama       return 0;
10077b91e213SGeorge Rimar     };
10087b91e213SGeorge Rimar   }
10093837f427SRui Ueyama   if (op == "%") {
10103837f427SRui Ueyama     std::string loc = getCurrentLocation();
10117b91e213SGeorge Rimar     return [=]() -> uint64_t {
10123837f427SRui Ueyama       if (uint64_t rv = r().getValue())
10133837f427SRui Ueyama         return l().getValue() % rv;
10143837f427SRui Ueyama       error(loc + ": modulo by zero");
1015067617f9SRui Ueyama       return 0;
10167b91e213SGeorge Rimar     };
10177b91e213SGeorge Rimar   }
10183837f427SRui Ueyama   if (op == "<<")
10193837f427SRui Ueyama     return [=] { return l().getValue() << r().getValue(); };
10203837f427SRui Ueyama   if (op == ">>")
10213837f427SRui Ueyama     return [=] { return l().getValue() >> r().getValue(); };
10223837f427SRui Ueyama   if (op == "<")
10233837f427SRui Ueyama     return [=] { return l().getValue() < r().getValue(); };
10243837f427SRui Ueyama   if (op == ">")
10253837f427SRui Ueyama     return [=] { return l().getValue() > r().getValue(); };
10263837f427SRui Ueyama   if (op == ">=")
10273837f427SRui Ueyama     return [=] { return l().getValue() >= r().getValue(); };
10283837f427SRui Ueyama   if (op == "<=")
10293837f427SRui Ueyama     return [=] { return l().getValue() <= r().getValue(); };
10303837f427SRui Ueyama   if (op == "==")
10313837f427SRui Ueyama     return [=] { return l().getValue() == r().getValue(); };
10323837f427SRui Ueyama   if (op == "!=")
10333837f427SRui Ueyama     return [=] { return l().getValue() != r().getValue(); };
10343837f427SRui Ueyama   if (op == "||")
10353837f427SRui Ueyama     return [=] { return l().getValue() || r().getValue(); };
10363837f427SRui Ueyama   if (op == "&&")
10373837f427SRui Ueyama     return [=] { return l().getValue() && r().getValue(); };
10383837f427SRui Ueyama   if (op == "&")
10393837f427SRui Ueyama     return [=] { return bitAnd(l(), r()); };
10403837f427SRui Ueyama   if (op == "|")
10413837f427SRui Ueyama     return [=] { return bitOr(l(), r()); };
10422ec34544SRui Ueyama   llvm_unreachable("invalid operator");
10432ec34544SRui Ueyama }
10442ec34544SRui Ueyama 
10452ec34544SRui Ueyama // This is a part of the operator-precedence parser. This function
10462ec34544SRui Ueyama // assumes that the remaining token stream starts with an operator.
10473837f427SRui Ueyama Expr ScriptParser::readExpr1(Expr lhs, int minPrec) {
1048b8a59c8aSBob Haarman   while (!atEOF() && !errorCount()) {
10492ec34544SRui Ueyama     // Read an operator and an expression.
10502ec34544SRui Ueyama     if (consume("?"))
10513837f427SRui Ueyama       return readTernary(lhs);
10523837f427SRui Ueyama     StringRef op1 = peek();
10533837f427SRui Ueyama     if (precedence(op1) < minPrec)
10542ec34544SRui Ueyama       break;
10552ec34544SRui Ueyama     skip();
10563837f427SRui Ueyama     Expr rhs = readPrimary();
10572ec34544SRui Ueyama 
10582ec34544SRui Ueyama     // Evaluate the remaining part of the expression first if the
10592ec34544SRui Ueyama     // next operator has greater precedence than the previous one.
10602ec34544SRui Ueyama     // For example, if we have read "+" and "3", and if the next
10612ec34544SRui Ueyama     // operator is "*", then we'll evaluate 3 * ... part first.
10622ec34544SRui Ueyama     while (!atEOF()) {
10633837f427SRui Ueyama       StringRef op2 = peek();
10643837f427SRui Ueyama       if (precedence(op2) <= precedence(op1))
10652ec34544SRui Ueyama         break;
10663837f427SRui Ueyama       rhs = readExpr1(rhs, precedence(op2));
10672ec34544SRui Ueyama     }
10682ec34544SRui Ueyama 
10693837f427SRui Ueyama     lhs = combine(op1, lhs, rhs);
10702ec34544SRui Ueyama   }
10713837f427SRui Ueyama   return lhs;
10722ec34544SRui Ueyama }
10732ec34544SRui Ueyama 
10745fb17128SGeorge Rimar Expr ScriptParser::getPageSize() {
10753837f427SRui Ueyama   std::string location = getCurrentLocation();
10765fb17128SGeorge Rimar   return [=]() -> uint64_t {
10773837f427SRui Ueyama     if (target)
10783837f427SRui Ueyama       return config->commonPageSize;
10793837f427SRui Ueyama     error(location + ": unable to calculate page size");
10805fb17128SGeorge Rimar     return 4096; // Return a dummy value.
10815fb17128SGeorge Rimar   };
10825fb17128SGeorge Rimar }
10835fb17128SGeorge Rimar 
10845fb17128SGeorge Rimar Expr ScriptParser::readConstant() {
10853837f427SRui Ueyama   StringRef s = readParenLiteral();
10863837f427SRui Ueyama   if (s == "COMMONPAGESIZE")
10875fb17128SGeorge Rimar     return getPageSize();
10883837f427SRui Ueyama   if (s == "MAXPAGESIZE")
10893837f427SRui Ueyama     return [] { return config->maxPageSize; };
10903837f427SRui Ueyama   setError("unknown constant: " + s);
1091b068b037SGeorge Rimar   return [] { return 0; };
10922ec34544SRui Ueyama }
10932ec34544SRui Ueyama 
10945c65088fSRui Ueyama // Parses Tok as an integer. It recognizes hexadecimal (prefixed with
10955c65088fSRui Ueyama // "0x" or suffixed with "H") and decimal numbers. Decimal numbers may
10965c65088fSRui Ueyama // have "K" (Ki) or "M" (Mi) suffixes.
10973837f427SRui Ueyama static Optional<uint64_t> parseInt(StringRef tok) {
10982ec34544SRui Ueyama   // Hexadecimal
10993837f427SRui Ueyama   uint64_t val;
11003837f427SRui Ueyama   if (tok.startswith_lower("0x")) {
11013837f427SRui Ueyama     if (!to_integer(tok.substr(2), val, 16))
11024092016bSRui Ueyama       return None;
11033837f427SRui Ueyama     return val;
11044092016bSRui Ueyama   }
11053837f427SRui Ueyama   if (tok.endswith_lower("H")) {
11063837f427SRui Ueyama     if (!to_integer(tok.drop_back(), val, 16))
11074092016bSRui Ueyama       return None;
11083837f427SRui Ueyama     return val;
11094092016bSRui Ueyama   }
11102ec34544SRui Ueyama 
11112ec34544SRui Ueyama   // Decimal
11123837f427SRui Ueyama   if (tok.endswith_lower("K")) {
11133837f427SRui Ueyama     if (!to_integer(tok.drop_back(), val, 10))
11145c65088fSRui Ueyama       return None;
11153837f427SRui Ueyama     return val * 1024;
11162ec34544SRui Ueyama   }
11173837f427SRui Ueyama   if (tok.endswith_lower("M")) {
11183837f427SRui Ueyama     if (!to_integer(tok.drop_back(), val, 10))
11195c65088fSRui Ueyama       return None;
11203837f427SRui Ueyama     return val * 1024 * 1024;
11215c65088fSRui Ueyama   }
11223837f427SRui Ueyama   if (!to_integer(tok, val, 10))
11235c65088fSRui Ueyama     return None;
11243837f427SRui Ueyama   return val;
11252ec34544SRui Ueyama }
11262ec34544SRui Ueyama 
11273837f427SRui Ueyama ByteCommand *ScriptParser::readByteCommand(StringRef tok) {
11283837f427SRui Ueyama   int size = StringSwitch<int>(tok)
11292ec34544SRui Ueyama                  .Case("BYTE", 1)
11302ec34544SRui Ueyama                  .Case("SHORT", 2)
11312ec34544SRui Ueyama                  .Case("LONG", 4)
11322ec34544SRui Ueyama                  .Case("QUAD", 8)
11332ec34544SRui Ueyama                  .Default(-1);
11343837f427SRui Ueyama   if (size == -1)
11352ec34544SRui Ueyama     return nullptr;
113684bcabcbSGeorge Rimar 
11373837f427SRui Ueyama   size_t oldPos = pos;
11383837f427SRui Ueyama   Expr e = readParenExpr();
11393837f427SRui Ueyama   std::string commandString =
11403837f427SRui Ueyama       tok.str() + " " +
11413837f427SRui Ueyama       llvm::join(tokens.begin() + oldPos, tokens.begin() + pos, " ");
11423837f427SRui Ueyama   return make<ByteCommand>(e, size, commandString);
11432ec34544SRui Ueyama }
11442ec34544SRui Ueyama 
1145dbd0ad33SPeter Smith static llvm::Optional<uint64_t> parseFlag(StringRef tok) {
1146dbd0ad33SPeter Smith   if (llvm::Optional<uint64_t> asInt = parseInt(tok))
1147dbd0ad33SPeter Smith     return asInt;
1148dbd0ad33SPeter Smith #define CASE_ENT(enum) #enum, ELF::enum
1149dbd0ad33SPeter Smith   return StringSwitch<llvm::Optional<uint64_t>>(tok)
1150dbd0ad33SPeter Smith       .Case(CASE_ENT(SHF_WRITE))
1151dbd0ad33SPeter Smith       .Case(CASE_ENT(SHF_ALLOC))
1152dbd0ad33SPeter Smith       .Case(CASE_ENT(SHF_EXECINSTR))
1153dbd0ad33SPeter Smith       .Case(CASE_ENT(SHF_MERGE))
1154dbd0ad33SPeter Smith       .Case(CASE_ENT(SHF_STRINGS))
1155dbd0ad33SPeter Smith       .Case(CASE_ENT(SHF_INFO_LINK))
1156dbd0ad33SPeter Smith       .Case(CASE_ENT(SHF_LINK_ORDER))
1157dbd0ad33SPeter Smith       .Case(CASE_ENT(SHF_OS_NONCONFORMING))
1158dbd0ad33SPeter Smith       .Case(CASE_ENT(SHF_GROUP))
1159dbd0ad33SPeter Smith       .Case(CASE_ENT(SHF_TLS))
1160dbd0ad33SPeter Smith       .Case(CASE_ENT(SHF_COMPRESSED))
1161dbd0ad33SPeter Smith       .Case(CASE_ENT(SHF_EXCLUDE))
1162dbd0ad33SPeter Smith       .Case(CASE_ENT(SHF_ARM_PURECODE))
1163dbd0ad33SPeter Smith       .Default(None);
1164dbd0ad33SPeter Smith #undef CASE_ENT
1165dbd0ad33SPeter Smith }
1166dbd0ad33SPeter Smith 
1167dbd0ad33SPeter Smith // Reads the '(' <flags> ')' list of section flags in
1168dbd0ad33SPeter Smith // INPUT_SECTION_FLAGS '(' <flags> ')' in the
1169dbd0ad33SPeter Smith // following form:
1170dbd0ad33SPeter Smith // <flags> ::= <flag>
1171dbd0ad33SPeter Smith //           | <flags> & flag
1172dbd0ad33SPeter Smith // <flag>  ::= Recognized Flag Name, or Integer value of flag.
1173dbd0ad33SPeter Smith // If the first character of <flag> is a ! then this means without flag,
1174dbd0ad33SPeter Smith // otherwise with flag.
1175dbd0ad33SPeter Smith // Example: SHF_EXECINSTR & !SHF_WRITE means with flag SHF_EXECINSTR and
1176dbd0ad33SPeter Smith // without flag SHF_WRITE.
1177dbd0ad33SPeter Smith std::pair<uint64_t, uint64_t> ScriptParser::readInputSectionFlags() {
1178dbd0ad33SPeter Smith    uint64_t withFlags = 0;
1179dbd0ad33SPeter Smith    uint64_t withoutFlags = 0;
1180dbd0ad33SPeter Smith    expect("(");
1181dbd0ad33SPeter Smith    while (!errorCount()) {
1182dbd0ad33SPeter Smith     StringRef tok = unquote(next());
1183dbd0ad33SPeter Smith     bool without = tok.consume_front("!");
1184dbd0ad33SPeter Smith     if (llvm::Optional<uint64_t> flag = parseFlag(tok)) {
1185dbd0ad33SPeter Smith       if (without)
1186dbd0ad33SPeter Smith         withoutFlags |= *flag;
1187dbd0ad33SPeter Smith       else
1188dbd0ad33SPeter Smith         withFlags |= *flag;
1189dbd0ad33SPeter Smith     } else {
1190dbd0ad33SPeter Smith       setError("unrecognised flag: " + tok);
1191dbd0ad33SPeter Smith     }
1192dbd0ad33SPeter Smith     if (consume(")"))
1193dbd0ad33SPeter Smith       break;
1194dbd0ad33SPeter Smith     if (!consume("&")) {
1195dbd0ad33SPeter Smith       next();
1196dbd0ad33SPeter Smith       setError("expected & or )");
1197dbd0ad33SPeter Smith     }
1198dbd0ad33SPeter Smith   }
1199dbd0ad33SPeter Smith   return std::make_pair(withFlags, withoutFlags);
1200dbd0ad33SPeter Smith }
1201dbd0ad33SPeter Smith 
12022ec34544SRui Ueyama StringRef ScriptParser::readParenLiteral() {
12032ec34544SRui Ueyama   expect("(");
12043837f427SRui Ueyama   bool orig = inExpr;
12053837f427SRui Ueyama   inExpr = false;
12063837f427SRui Ueyama   StringRef tok = next();
12073837f427SRui Ueyama   inExpr = orig;
12082ec34544SRui Ueyama   expect(")");
12093837f427SRui Ueyama   return tok;
12102ec34544SRui Ueyama }
12112ec34544SRui Ueyama 
12123837f427SRui Ueyama static void checkIfExists(OutputSection *cmd, StringRef location) {
12133837f427SRui Ueyama   if (cmd->location.empty() && script->errorOnMissingSection)
12143837f427SRui Ueyama     error(location + ": undefined section " + cmd->name);
121505c4f67cSRafael Espindola }
121605c4f67cSRafael Espindola 
12172ec34544SRui Ueyama Expr ScriptParser::readPrimary() {
12182ec34544SRui Ueyama   if (peek() == "(")
12192ec34544SRui Ueyama     return readParenExpr();
12202ec34544SRui Ueyama 
12215c65088fSRui Ueyama   if (consume("~")) {
12223837f427SRui Ueyama     Expr e = readPrimary();
12233837f427SRui Ueyama     return [=] { return ~e().getValue(); };
12242ec34544SRui Ueyama   }
12256f1d954eSHafiz Abid Qadeer   if (consume("!")) {
12263837f427SRui Ueyama     Expr e = readPrimary();
12273837f427SRui Ueyama     return [=] { return !e().getValue(); };
12286f1d954eSHafiz Abid Qadeer   }
12295c65088fSRui Ueyama   if (consume("-")) {
12303837f427SRui Ueyama     Expr e = readPrimary();
12313837f427SRui Ueyama     return [=] { return -e().getValue(); };
12322ec34544SRui Ueyama   }
12332ec34544SRui Ueyama 
12343837f427SRui Ueyama   StringRef tok = next();
12353837f427SRui Ueyama   std::string location = getCurrentLocation();
12365c65088fSRui Ueyama 
12372ec34544SRui Ueyama   // Built-in functions are parsed here.
12382ec34544SRui Ueyama   // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html.
12393837f427SRui Ueyama   if (tok == "ABSOLUTE") {
12403837f427SRui Ueyama     Expr inner = readParenExpr();
12412ec34544SRui Ueyama     return [=] {
12423837f427SRui Ueyama       ExprValue i = inner();
12433837f427SRui Ueyama       i.forceAbsolute = true;
12443837f427SRui Ueyama       return i;
12452ec34544SRui Ueyama     };
12462ec34544SRui Ueyama   }
12473837f427SRui Ueyama   if (tok == "ADDR") {
12483837f427SRui Ueyama     StringRef name = readParenLiteral();
12493837f427SRui Ueyama     OutputSection *sec = script->getOrCreateOutputSection(name);
12503837f427SRui Ueyama     sec->usedInExpression = true;
125141c7ab4aSGeorge Rimar     return [=]() -> ExprValue {
12523837f427SRui Ueyama       checkIfExists(sec, location);
12533837f427SRui Ueyama       return {sec, false, 0, location};
125441c7ab4aSGeorge Rimar     };
12552ec34544SRui Ueyama   }
12563837f427SRui Ueyama   if (tok == "ALIGN") {
12572ec34544SRui Ueyama     expect("(");
12583837f427SRui Ueyama     Expr e = readExpr();
1259f22ec9ddSGeorge Rimar     if (consume(")")) {
12603837f427SRui Ueyama       e = checkAlignment(e, location);
12613837f427SRui Ueyama       return [=] { return alignTo(script->getDot(), e().getValue()); };
1262f22ec9ddSGeorge Rimar     }
1263b579c439SRui Ueyama     expect(",");
12643837f427SRui Ueyama     Expr e2 = checkAlignment(readExpr(), location);
12652ec34544SRui Ueyama     expect(")");
12663c6de1a6SPetr Hosek     return [=] {
12673837f427SRui Ueyama       ExprValue v = e();
12683837f427SRui Ueyama       v.alignment = e2().getValue();
12693837f427SRui Ueyama       return v;
12703c6de1a6SPetr Hosek     };
12712ec34544SRui Ueyama   }
12723837f427SRui Ueyama   if (tok == "ALIGNOF") {
12733837f427SRui Ueyama     StringRef name = readParenLiteral();
12743837f427SRui Ueyama     OutputSection *cmd = script->getOrCreateOutputSection(name);
1275617e2f98SRui Ueyama     return [=] {
12763837f427SRui Ueyama       checkIfExists(cmd, location);
12773837f427SRui Ueyama       return cmd->alignment;
1278617e2f98SRui Ueyama     };
12792ec34544SRui Ueyama   }
12803837f427SRui Ueyama   if (tok == "ASSERT")
1281d30a78b3SGeorge Rimar     return readAssert();
12823837f427SRui Ueyama   if (tok == "CONSTANT")
12835fb17128SGeorge Rimar     return readConstant();
12843837f427SRui Ueyama   if (tok == "DATA_SEGMENT_ALIGN") {
12852ec34544SRui Ueyama     expect("(");
12863837f427SRui Ueyama     Expr e = readExpr();
12872ec34544SRui Ueyama     expect(",");
12882ec34544SRui Ueyama     readExpr();
12892ec34544SRui Ueyama     expect(")");
129060833f6eSGeorge Rimar     return [=] {
12913837f427SRui Ueyama       return alignTo(script->getDot(), std::max((uint64_t)1, e().getValue()));
129260833f6eSGeorge Rimar     };
12932ec34544SRui Ueyama   }
12943837f427SRui Ueyama   if (tok == "DATA_SEGMENT_END") {
12952ec34544SRui Ueyama     expect("(");
12962ec34544SRui Ueyama     expect(".");
12972ec34544SRui Ueyama     expect(")");
12983837f427SRui Ueyama     return [] { return script->getDot(); };
12992ec34544SRui Ueyama   }
13003837f427SRui Ueyama   if (tok == "DATA_SEGMENT_RELRO_END") {
13012ec34544SRui Ueyama     // GNU linkers implements more complicated logic to handle
13022ec34544SRui Ueyama     // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and
13032ec34544SRui Ueyama     // just align to the next page boundary for simplicity.
13042ec34544SRui Ueyama     expect("(");
13052ec34544SRui Ueyama     readExpr();
13062ec34544SRui Ueyama     expect(",");
13072ec34544SRui Ueyama     readExpr();
13082ec34544SRui Ueyama     expect(")");
13093837f427SRui Ueyama     Expr e = getPageSize();
13103837f427SRui Ueyama     return [=] { return alignTo(script->getDot(), e().getValue()); };
13112ec34544SRui Ueyama   }
13123837f427SRui Ueyama   if (tok == "DEFINED") {
13133837f427SRui Ueyama     StringRef name = readParenLiteral();
13143837f427SRui Ueyama     return [=] { return symtab->find(name) ? 1 : 0; };
13152ec34544SRui Ueyama   }
13163837f427SRui Ueyama   if (tok == "LENGTH") {
13173837f427SRui Ueyama     StringRef name = readParenLiteral();
13183837f427SRui Ueyama     if (script->memoryRegions.count(name) == 0) {
13193837f427SRui Ueyama       setError("memory region not defined: " + name);
1320b068b037SGeorge Rimar       return [] { return 0; };
1321b068b037SGeorge Rimar     }
132292b5b980SFangrui Song     return script->memoryRegions[name]->length;
132391b95b61SRui Ueyama   }
13243837f427SRui Ueyama   if (tok == "LOADADDR") {
13253837f427SRui Ueyama     StringRef name = readParenLiteral();
13263837f427SRui Ueyama     OutputSection *cmd = script->getOrCreateOutputSection(name);
13273837f427SRui Ueyama     cmd->usedInExpression = true;
1328617e2f98SRui Ueyama     return [=] {
13293837f427SRui Ueyama       checkIfExists(cmd, location);
13303837f427SRui Ueyama       return cmd->getLMA();
1331617e2f98SRui Ueyama     };
13322ec34544SRui Ueyama   }
13333837f427SRui Ueyama   if (tok == "MAX" || tok == "MIN") {
1334fd11560fSGeorge Rimar     expect("(");
13353837f427SRui Ueyama     Expr a = readExpr();
1336fd11560fSGeorge Rimar     expect(",");
13373837f427SRui Ueyama     Expr b = readExpr();
1338fd11560fSGeorge Rimar     expect(")");
13393837f427SRui Ueyama     if (tok == "MIN")
13403837f427SRui Ueyama       return [=] { return std::min(a().getValue(), b().getValue()); };
13413837f427SRui Ueyama     return [=] { return std::max(a().getValue(), b().getValue()); };
1342fd11560fSGeorge Rimar   }
13433837f427SRui Ueyama   if (tok == "ORIGIN") {
13443837f427SRui Ueyama     StringRef name = readParenLiteral();
13453837f427SRui Ueyama     if (script->memoryRegions.count(name) == 0) {
13463837f427SRui Ueyama       setError("memory region not defined: " + name);
1347b068b037SGeorge Rimar       return [] { return 0; };
1348b068b037SGeorge Rimar     }
134992b5b980SFangrui Song     return script->memoryRegions[name]->origin;
135091b95b61SRui Ueyama   }
13513837f427SRui Ueyama   if (tok == "SEGMENT_START") {
13522ec34544SRui Ueyama     expect("(");
13532ec34544SRui Ueyama     skip();
13542ec34544SRui Ueyama     expect(",");
13553837f427SRui Ueyama     Expr e = readExpr();
13562ec34544SRui Ueyama     expect(")");
13573837f427SRui Ueyama     return [=] { return e(); };
13582ec34544SRui Ueyama   }
13593837f427SRui Ueyama   if (tok == "SIZEOF") {
13603837f427SRui Ueyama     StringRef name = readParenLiteral();
13613837f427SRui Ueyama     OutputSection *cmd = script->getOrCreateOutputSection(name);
136205c4f67cSRafael Espindola     // Linker script does not create an output section if its content is empty.
136305c4f67cSRafael Espindola     // We want to allow SIZEOF(.foo) where .foo is a section which happened to
136405c4f67cSRafael Espindola     // be empty.
13653837f427SRui Ueyama     return [=] { return cmd->size; };
13662ec34544SRui Ueyama   }
13673837f427SRui Ueyama   if (tok == "SIZEOF_HEADERS")
1368bd8cfe65SFangrui Song     return [=] { return getHeaderSize(); };
13692ec34544SRui Ueyama 
13704eb2eccbSRui Ueyama   // Tok is the dot.
13713837f427SRui Ueyama   if (tok == ".")
13723837f427SRui Ueyama     return [=] { return script->getSymbolValue(tok, location); };
13734eb2eccbSRui Ueyama 
13742ec34544SRui Ueyama   // Tok is a literal number.
13753837f427SRui Ueyama   if (Optional<uint64_t> val = parseInt(tok))
13763837f427SRui Ueyama     return [=] { return *val; };
13772ec34544SRui Ueyama 
13782ec34544SRui Ueyama   // Tok is a symbol name.
13793837f427SRui Ueyama   if (!isValidCIdentifier(tok))
13803837f427SRui Ueyama     setError("malformed number: " + tok);
13813837f427SRui Ueyama   script->referencedSymbols.push_back(tok);
13823837f427SRui Ueyama   return [=] { return script->getSymbolValue(tok, location); };
13832ec34544SRui Ueyama }
13842ec34544SRui Ueyama 
13853837f427SRui Ueyama Expr ScriptParser::readTernary(Expr cond) {
13863837f427SRui Ueyama   Expr l = readExpr();
13872ec34544SRui Ueyama   expect(":");
13883837f427SRui Ueyama   Expr r = readExpr();
13893837f427SRui Ueyama   return [=] { return cond().getValue() ? l() : r(); };
13902ec34544SRui Ueyama }
13912ec34544SRui Ueyama 
13922ec34544SRui Ueyama Expr ScriptParser::readParenExpr() {
13932ec34544SRui Ueyama   expect("(");
13943837f427SRui Ueyama   Expr e = readExpr();
13952ec34544SRui Ueyama   expect(")");
13963837f427SRui Ueyama   return e;
13972ec34544SRui Ueyama }
13982ec34544SRui Ueyama 
13992ec34544SRui Ueyama std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() {
14003837f427SRui Ueyama   std::vector<StringRef> phdrs;
1401b8a59c8aSBob Haarman   while (!errorCount() && peek().startswith(":")) {
14023837f427SRui Ueyama     StringRef tok = next();
14033837f427SRui Ueyama     phdrs.push_back((tok.size() == 1) ? next() : tok.substr(1));
14042ec34544SRui Ueyama   }
14053837f427SRui Ueyama   return phdrs;
14062ec34544SRui Ueyama }
14072ec34544SRui Ueyama 
14082ec34544SRui Ueyama // Read a program header type name. The next token must be a
14092ec34544SRui Ueyama // name of a program header type or a constant (e.g. "0x3").
14102ec34544SRui Ueyama unsigned ScriptParser::readPhdrType() {
14113837f427SRui Ueyama   StringRef tok = next();
14123837f427SRui Ueyama   if (Optional<uint64_t> val = parseInt(tok))
14133837f427SRui Ueyama     return *val;
14142ec34544SRui Ueyama 
14153837f427SRui Ueyama   unsigned ret = StringSwitch<unsigned>(tok)
14162ec34544SRui Ueyama                      .Case("PT_NULL", PT_NULL)
14172ec34544SRui Ueyama                      .Case("PT_LOAD", PT_LOAD)
14182ec34544SRui Ueyama                      .Case("PT_DYNAMIC", PT_DYNAMIC)
14192ec34544SRui Ueyama                      .Case("PT_INTERP", PT_INTERP)
14202ec34544SRui Ueyama                      .Case("PT_NOTE", PT_NOTE)
14212ec34544SRui Ueyama                      .Case("PT_SHLIB", PT_SHLIB)
14222ec34544SRui Ueyama                      .Case("PT_PHDR", PT_PHDR)
14232ec34544SRui Ueyama                      .Case("PT_TLS", PT_TLS)
14242ec34544SRui Ueyama                      .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME)
14252ec34544SRui Ueyama                      .Case("PT_GNU_STACK", PT_GNU_STACK)
14262ec34544SRui Ueyama                      .Case("PT_GNU_RELRO", PT_GNU_RELRO)
14272ec34544SRui Ueyama                      .Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE)
14282ec34544SRui Ueyama                      .Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED)
14292ec34544SRui Ueyama                      .Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA)
14302ec34544SRui Ueyama                      .Default(-1);
14312ec34544SRui Ueyama 
14323837f427SRui Ueyama   if (ret == (unsigned)-1) {
14333837f427SRui Ueyama     setError("invalid program header type: " + tok);
14342ec34544SRui Ueyama     return PT_NULL;
14352ec34544SRui Ueyama   }
14363837f427SRui Ueyama   return ret;
14372ec34544SRui Ueyama }
14382ec34544SRui Ueyama 
14392ec34544SRui Ueyama // Reads an anonymous version declaration.
14402ec34544SRui Ueyama void ScriptParser::readAnonymousDeclaration() {
14413837f427SRui Ueyama   std::vector<SymbolVersion> locals;
14423837f427SRui Ueyama   std::vector<SymbolVersion> globals;
14433837f427SRui Ueyama   std::tie(locals, globals) = readSymbols();
1444e28a70daSFangrui Song   for (const SymbolVersion &pat : locals)
1445e28a70daSFangrui Song     config->versionDefinitions[VER_NDX_LOCAL].patterns.push_back(pat);
1446e28a70daSFangrui Song   for (const SymbolVersion &pat : globals)
1447e28a70daSFangrui Song     config->versionDefinitions[VER_NDX_GLOBAL].patterns.push_back(pat);
14482ec34544SRui Ueyama 
14492ec34544SRui Ueyama   expect(";");
14502ec34544SRui Ueyama }
14512ec34544SRui Ueyama 
14522ec34544SRui Ueyama // Reads a non-anonymous version definition,
14532ec34544SRui Ueyama // e.g. "VerStr { global: foo; bar; local: *; };".
14543837f427SRui Ueyama void ScriptParser::readVersionDeclaration(StringRef verStr) {
14552ec34544SRui Ueyama   // Read a symbol list.
14563837f427SRui Ueyama   std::vector<SymbolVersion> locals;
14573837f427SRui Ueyama   std::vector<SymbolVersion> globals;
14583837f427SRui Ueyama   std::tie(locals, globals) = readSymbols();
1459e28a70daSFangrui Song   for (const SymbolVersion &pat : locals)
1460e28a70daSFangrui Song     config->versionDefinitions[VER_NDX_LOCAL].patterns.push_back(pat);
14612ec34544SRui Ueyama 
14622ec34544SRui Ueyama   // Create a new version definition and add that to the global symbols.
14633837f427SRui Ueyama   VersionDefinition ver;
14643837f427SRui Ueyama   ver.name = verStr;
1465e28a70daSFangrui Song   ver.patterns = globals;
1466e28a70daSFangrui Song   ver.id = config->versionDefinitions.size();
14673837f427SRui Ueyama   config->versionDefinitions.push_back(ver);
14682ec34544SRui Ueyama 
14692ec34544SRui Ueyama   // Each version may have a parent version. For example, "Ver2"
14702ec34544SRui Ueyama   // defined as "Ver2 { global: foo; local: *; } Ver1;" has "Ver1"
14712ec34544SRui Ueyama   // as a parent. This version hierarchy is, probably against your
14722ec34544SRui Ueyama   // instinct, purely for hint; the runtime doesn't care about it
14732ec34544SRui Ueyama   // at all. In LLD, we simply ignore it.
14745f380403SFangrui Song   if (next() != ";")
14752ec34544SRui Ueyama     expect(";");
14762ec34544SRui Ueyama }
14772ec34544SRui Ueyama 
14783837f427SRui Ueyama static bool hasWildcard(StringRef s) {
14793837f427SRui Ueyama   return s.find_first_of("?*[") != StringRef::npos;
14801e77ad14SRui Ueyama }
14811e77ad14SRui Ueyama 
14822ec34544SRui Ueyama // Reads a list of symbols, e.g. "{ global: foo; bar; local: *; };".
14832ec34544SRui Ueyama std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>>
14842ec34544SRui Ueyama ScriptParser::readSymbols() {
14853837f427SRui Ueyama   std::vector<SymbolVersion> locals;
14863837f427SRui Ueyama   std::vector<SymbolVersion> globals;
14873837f427SRui Ueyama   std::vector<SymbolVersion> *v = &globals;
14882ec34544SRui Ueyama 
1489b8a59c8aSBob Haarman   while (!errorCount()) {
14902ec34544SRui Ueyama     if (consume("}"))
14912ec34544SRui Ueyama       break;
14922ec34544SRui Ueyama     if (consumeLabel("local")) {
14933837f427SRui Ueyama       v = &locals;
14942ec34544SRui Ueyama       continue;
14952ec34544SRui Ueyama     }
14962ec34544SRui Ueyama     if (consumeLabel("global")) {
14973837f427SRui Ueyama       v = &globals;
14982ec34544SRui Ueyama       continue;
14992ec34544SRui Ueyama     }
15002ec34544SRui Ueyama 
15012ec34544SRui Ueyama     if (consume("extern")) {
15023837f427SRui Ueyama       std::vector<SymbolVersion> ext = readVersionExtern();
15033837f427SRui Ueyama       v->insert(v->end(), ext.begin(), ext.end());
15042ec34544SRui Ueyama     } else {
15053837f427SRui Ueyama       StringRef tok = next();
15063837f427SRui Ueyama       v->push_back({unquote(tok), false, hasWildcard(tok)});
15072ec34544SRui Ueyama     }
15082ec34544SRui Ueyama     expect(";");
15092ec34544SRui Ueyama   }
15103837f427SRui Ueyama   return {locals, globals};
15112ec34544SRui Ueyama }
15122ec34544SRui Ueyama 
15132ec34544SRui Ueyama // Reads an "extern C++" directive, e.g.,
15142ec34544SRui Ueyama // "extern "C++" { ns::*; "f(int, double)"; };"
151517324d8bSRui Ueyama //
151617324d8bSRui Ueyama // The last semicolon is optional. E.g. this is OK:
151717324d8bSRui Ueyama // "extern "C++" { ns::*; "f(int, double)" };"
15182ec34544SRui Ueyama std::vector<SymbolVersion> ScriptParser::readVersionExtern() {
15193837f427SRui Ueyama   StringRef tok = next();
15203837f427SRui Ueyama   bool isCXX = tok == "\"C++\"";
15213837f427SRui Ueyama   if (!isCXX && tok != "\"C\"")
15222ec34544SRui Ueyama     setError("Unknown language");
15232ec34544SRui Ueyama   expect("{");
15242ec34544SRui Ueyama 
15253837f427SRui Ueyama   std::vector<SymbolVersion> ret;
1526b8a59c8aSBob Haarman   while (!errorCount() && peek() != "}") {
15273837f427SRui Ueyama     StringRef tok = next();
15283837f427SRui Ueyama     ret.push_back(
15293837f427SRui Ueyama         {unquote(tok), isCXX, !tok.startswith("\"") && hasWildcard(tok)});
153017324d8bSRui Ueyama     if (consume("}"))
15313837f427SRui Ueyama       return ret;
15322ec34544SRui Ueyama     expect(";");
15332ec34544SRui Ueyama   }
15342ec34544SRui Ueyama 
15352ec34544SRui Ueyama   expect("}");
15363837f427SRui Ueyama   return ret;
15372ec34544SRui Ueyama }
15382ec34544SRui Ueyama 
153992b5b980SFangrui Song Expr ScriptParser::readMemoryAssignment(StringRef s1, StringRef s2,
15403837f427SRui Ueyama                                         StringRef s3) {
15413837f427SRui Ueyama   if (!consume(s1) && !consume(s2) && !consume(s3)) {
15423837f427SRui Ueyama     setError("expected one of: " + s1 + ", " + s2 + ", or " + s3);
154392b5b980SFangrui Song     return [] { return 0; };
15442ec34544SRui Ueyama   }
15452ec34544SRui Ueyama   expect("=");
154692b5b980SFangrui Song   return readExpr();
15472ec34544SRui Ueyama }
15482ec34544SRui Ueyama 
15492ec34544SRui Ueyama // Parse the MEMORY command as specified in:
15502ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/MEMORY.html
15512ec34544SRui Ueyama //
15522ec34544SRui Ueyama // MEMORY { name [(attr)] : ORIGIN = origin, LENGTH = len ... }
15532ec34544SRui Ueyama void ScriptParser::readMemory() {
15542ec34544SRui Ueyama   expect("{");
1555b8a59c8aSBob Haarman   while (!errorCount() && !consume("}")) {
15563837f427SRui Ueyama     StringRef tok = next();
15573837f427SRui Ueyama     if (tok == "INCLUDE") {
15582e9d40d5SRui Ueyama       readInclude();
15592e9d40d5SRui Ueyama       continue;
15602e9d40d5SRui Ueyama     }
15612ec34544SRui Ueyama 
15623837f427SRui Ueyama     uint32_t flags = 0;
15633837f427SRui Ueyama     uint32_t negFlags = 0;
15642ec34544SRui Ueyama     if (consume("(")) {
15653837f427SRui Ueyama       std::tie(flags, negFlags) = readMemoryAttributes();
15662ec34544SRui Ueyama       expect(")");
15672ec34544SRui Ueyama     }
15682ec34544SRui Ueyama     expect(":");
15692ec34544SRui Ueyama 
157092b5b980SFangrui Song     Expr origin = readMemoryAssignment("ORIGIN", "org", "o");
15712ec34544SRui Ueyama     expect(",");
157292b5b980SFangrui Song     Expr length = readMemoryAssignment("LENGTH", "len", "l");
15732ec34544SRui Ueyama 
15745f37541cSGeorge Rimar     // Add the memory region to the region map.
15753837f427SRui Ueyama     MemoryRegion *mr = make<MemoryRegion>(tok, origin, length, flags, negFlags);
15763837f427SRui Ueyama     if (!script->memoryRegions.insert({tok, mr}).second)
15773837f427SRui Ueyama       setError("region '" + tok + "' already defined");
15782ec34544SRui Ueyama   }
15792ec34544SRui Ueyama }
15802ec34544SRui Ueyama 
15812ec34544SRui Ueyama // This function parses the attributes used to match against section
15822ec34544SRui Ueyama // flags when placing output sections in a memory region. These flags
15832ec34544SRui Ueyama // are only used when an explicit memory region name is not used.
15842ec34544SRui Ueyama std::pair<uint32_t, uint32_t> ScriptParser::readMemoryAttributes() {
15853837f427SRui Ueyama   uint32_t flags = 0;
15863837f427SRui Ueyama   uint32_t negFlags = 0;
15873837f427SRui Ueyama   bool invert = false;
15882ec34544SRui Ueyama 
15893837f427SRui Ueyama   for (char c : next().lower()) {
15903837f427SRui Ueyama     uint32_t flag = 0;
15913837f427SRui Ueyama     if (c == '!')
15923837f427SRui Ueyama       invert = !invert;
15933837f427SRui Ueyama     else if (c == 'w')
15943837f427SRui Ueyama       flag = SHF_WRITE;
15953837f427SRui Ueyama     else if (c == 'x')
15963837f427SRui Ueyama       flag = SHF_EXECINSTR;
15973837f427SRui Ueyama     else if (c == 'a')
15983837f427SRui Ueyama       flag = SHF_ALLOC;
15993837f427SRui Ueyama     else if (c != 'r')
16002ec34544SRui Ueyama       setError("invalid memory region attribute");
16012ec34544SRui Ueyama 
16023837f427SRui Ueyama     if (invert)
16033837f427SRui Ueyama       negFlags |= flag;
16042ec34544SRui Ueyama     else
16053837f427SRui Ueyama       flags |= flag;
16062ec34544SRui Ueyama   }
16073837f427SRui Ueyama   return {flags, negFlags};
16082ec34544SRui Ueyama }
16092ec34544SRui Ueyama 
1610bd8cfe65SFangrui Song void readLinkerScript(MemoryBufferRef mb) {
16113837f427SRui Ueyama   ScriptParser(mb).readLinkerScript();
16122ec34544SRui Ueyama }
16132ec34544SRui Ueyama 
1614bd8cfe65SFangrui Song void readVersionScript(MemoryBufferRef mb) {
16153837f427SRui Ueyama   ScriptParser(mb).readVersionScript();
16162ec34544SRui Ueyama }
16172ec34544SRui Ueyama 
1618bd8cfe65SFangrui Song void readDynamicList(MemoryBufferRef mb) { ScriptParser(mb).readDynamicList(); }
16198c7e8cceSPetr Hosek 
1620bd8cfe65SFangrui Song void readDefsym(StringRef name, MemoryBufferRef mb) {
16213837f427SRui Ueyama   ScriptParser(mb).readDefsym(name);
16228c7e8cceSPetr Hosek }
1623bd8cfe65SFangrui Song 
1624bd8cfe65SFangrui Song } // namespace elf
1625bd8cfe65SFangrui Song } // namespace lld
1626