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"
17b01430a0SFangrui Song #include "InputFiles.h"
182ec34544SRui Ueyama #include "LinkerScript.h"
192ec34544SRui Ueyama #include "OutputSections.h"
202ec34544SRui Ueyama #include "ScriptLexer.h"
2127bb7990SFangrui Song #include "SymbolTable.h"
222ec34544SRui Ueyama #include "Symbols.h"
232ec34544SRui Ueyama #include "Target.h"
2483d59e05SAlexandre Ganea #include "lld/Common/CommonLinkerContext.h"
252ec34544SRui Ueyama #include "llvm/ADT/SmallString.h"
262ec34544SRui Ueyama #include "llvm/ADT/StringRef.h"
270440be4aSRui Ueyama #include "llvm/ADT/StringSet.h"
282ec34544SRui Ueyama #include "llvm/ADT/StringSwitch.h"
29264b5d9eSZachary Turner #include "llvm/BinaryFormat/ELF.h"
302ec34544SRui Ueyama #include "llvm/Support/Casting.h"
312ec34544SRui Ueyama #include "llvm/Support/ErrorHandling.h"
322ec34544SRui Ueyama #include "llvm/Support/FileSystem.h"
33fa1145a8SIsaac Richter #include "llvm/Support/MathExtras.h"
342ec34544SRui Ueyama #include "llvm/Support/Path.h"
35439341b9SJames Henderson #include "llvm/Support/TimeProfiler.h"
362ec34544SRui Ueyama #include <cassert>
372ec34544SRui Ueyama #include <limits>
382ec34544SRui Ueyama #include <vector>
392ec34544SRui Ueyama 
402ec34544SRui Ueyama using namespace llvm;
412ec34544SRui Ueyama using namespace llvm::ELF;
42b58079d4SRui Ueyama using namespace llvm::support::endian;
4307837b8fSFangrui Song using namespace lld;
4407837b8fSFangrui Song using namespace lld::elf;
452ec34544SRui Ueyama 
4696b3fe02SRui Ueyama namespace {
4796b3fe02SRui Ueyama class ScriptParser final : ScriptLexer {
482ec34544SRui Ueyama public:
493837f427SRui Ueyama   ScriptParser(MemoryBufferRef mb) : ScriptLexer(mb) {
5011ae59f0SRui Ueyama     // Initialize IsUnderSysroot
513837f427SRui Ueyama     if (config->sysroot == "")
5211ae59f0SRui Ueyama       return;
533837f427SRui Ueyama     StringRef path = mb.getBufferIdentifier();
543837f427SRui Ueyama     for (; !path.empty(); path = sys::path::parent_path(path)) {
553837f427SRui Ueyama       if (!sys::fs::equivalent(config->sysroot, path))
5611ae59f0SRui Ueyama         continue;
573837f427SRui Ueyama       isUnderSysroot = true;
5811ae59f0SRui Ueyama       return;
5911ae59f0SRui Ueyama     }
6011ae59f0SRui Ueyama   }
612ec34544SRui Ueyama 
622ec34544SRui Ueyama   void readLinkerScript();
632ec34544SRui Ueyama   void readVersionScript();
642ec34544SRui Ueyama   void readDynamicList();
653837f427SRui Ueyama   void readDefsym(StringRef name);
662ec34544SRui Ueyama 
672ec34544SRui Ueyama private:
683837f427SRui Ueyama   void addFile(StringRef path);
692ec34544SRui Ueyama 
702ec34544SRui Ueyama   void readAsNeeded();
712ec34544SRui Ueyama   void readEntry();
722ec34544SRui Ueyama   void readExtern();
732ec34544SRui Ueyama   void readGroup();
742ec34544SRui Ueyama   void readInclude();
751d92aa73SRui Ueyama   void readInput();
762ec34544SRui Ueyama   void readMemory();
772ec34544SRui Ueyama   void readOutput();
782ec34544SRui Ueyama   void readOutputArch();
792ec34544SRui Ueyama   void readOutputFormat();
80899fdf54SFangrui Song   void readOverwriteSections();
812ec34544SRui Ueyama   void readPhdrs();
825f37541cSGeorge Rimar   void readRegionAlias();
832ec34544SRui Ueyama   void readSearchDir();
842ec34544SRui Ueyama   void readSections();
85e262bb1aSRui Ueyama   void readTarget();
862ec34544SRui Ueyama   void readVersion();
872ec34544SRui Ueyama   void readVersionScriptCommand();
882ec34544SRui Ueyama 
893837f427SRui Ueyama   SymbolAssignment *readSymbolAssignment(StringRef name);
903837f427SRui Ueyama   ByteCommand *readByteCommand(StringRef tok);
91b0486051SSimon Atanasyan   std::array<uint8_t, 4> readFill();
923837f427SRui Ueyama   bool readSectionDirective(OutputSection *cmd, StringRef tok1, StringRef tok2);
933837f427SRui Ueyama   void readSectionAddressType(OutputSection *cmd);
946c814931SFangrui Song   OutputDesc *readOverlaySectionDescription();
956c814931SFangrui Song   OutputDesc *readOutputSectionDescription(StringRef outSec);
9664038ef8SFangrui Song   SmallVector<SectionCommand *, 0> readOverlay();
97a1c2ee01SFangrui Song   SmallVector<StringRef, 0> readOutputSectionPhdrs();
98dbd0ad33SPeter Smith   std::pair<uint64_t, uint64_t> readInputSectionFlags();
993837f427SRui Ueyama   InputSectionDescription *readInputSectionDescription(StringRef tok);
1002ec34544SRui Ueyama   StringMatcher readFilePatterns();
10164038ef8SFangrui Song   SmallVector<SectionPattern, 0> readInputSectionsList();
102dbd0ad33SPeter Smith   InputSectionDescription *readInputSectionRules(StringRef filePattern,
103dbd0ad33SPeter Smith                                                  uint64_t withFlags,
104dbd0ad33SPeter Smith                                                  uint64_t withoutFlags);
1052ec34544SRui Ueyama   unsigned readPhdrType();
1062a9aed0eSFangrui Song   SortSectionPolicy peekSortKind();
1072ec34544SRui Ueyama   SortSectionPolicy readSortKind();
1083837f427SRui Ueyama   SymbolAssignment *readProvideHidden(bool provide, bool hidden);
1093837f427SRui Ueyama   SymbolAssignment *readAssignment(StringRef tok);
1102ec34544SRui Ueyama   void readSort();
111d30a78b3SGeorge Rimar   Expr readAssert();
1125fb17128SGeorge Rimar   Expr readConstant();
1135fb17128SGeorge Rimar   Expr getPageSize();
1142ec34544SRui Ueyama 
11592b5b980SFangrui Song   Expr readMemoryAssignment(StringRef, StringRef, StringRef);
1168cdf1c1eSIgor Kudrin   void readMemoryAttributes(uint32_t &flags, uint32_t &invFlags,
1178cdf1c1eSIgor Kudrin                             uint32_t &negFlags, uint32_t &negInvFlags);
1182ec34544SRui Ueyama 
1193837f427SRui Ueyama   Expr combine(StringRef op, Expr l, Expr r);
1202ec34544SRui Ueyama   Expr readExpr();
1213837f427SRui Ueyama   Expr readExpr1(Expr lhs, int minPrec);
1222ec34544SRui Ueyama   StringRef readParenLiteral();
1232ec34544SRui Ueyama   Expr readPrimary();
1243837f427SRui Ueyama   Expr readTernary(Expr cond);
1252ec34544SRui Ueyama   Expr readParenExpr();
1262ec34544SRui Ueyama 
1272ec34544SRui Ueyama   // For parsing version script.
12864038ef8SFangrui Song   SmallVector<SymbolVersion, 0> readVersionExtern();
1292ec34544SRui Ueyama   void readAnonymousDeclaration();
1303837f427SRui Ueyama   void readVersionDeclaration(StringRef verStr);
1312ec34544SRui Ueyama 
13264038ef8SFangrui Song   std::pair<SmallVector<SymbolVersion, 0>, SmallVector<SymbolVersion, 0>>
1332ec34544SRui Ueyama   readSymbols();
1342ec34544SRui Ueyama 
135bf6e259bSFangrui Song   // True if a script being read is in the --sysroot directory.
1363837f427SRui Ueyama   bool isUnderSysroot = false;
1370440be4aSRui Ueyama 
1385a44980fSFangrui Song   bool seenDataAlign = false;
1395a44980fSFangrui Song   bool seenRelroEnd = false;
1405a44980fSFangrui Song 
1410440be4aSRui Ueyama   // A set to detect an INCLUDE() cycle.
1423837f427SRui Ueyama   StringSet<> seen;
1432ec34544SRui Ueyama };
14496b3fe02SRui Ueyama } // namespace
1452ec34544SRui Ueyama 
1463837f427SRui Ueyama static StringRef unquote(StringRef s) {
1473837f427SRui Ueyama   if (s.startswith("\""))
1483837f427SRui Ueyama     return s.substr(1, s.size() - 2);
1493837f427SRui Ueyama   return s;
1501e77ad14SRui Ueyama }
1511e77ad14SRui Ueyama 
1522ec34544SRui Ueyama // Some operations only support one non absolute value. Move the
1532ec34544SRui Ueyama // absolute one to the right hand side for convenience.
1543837f427SRui Ueyama static void moveAbsRight(ExprValue &a, ExprValue &b) {
1553837f427SRui Ueyama   if (a.sec == nullptr || (a.forceAbsolute && !b.isAbsolute()))
1563837f427SRui Ueyama     std::swap(a, b);
1573837f427SRui Ueyama   if (!b.isAbsolute())
1583837f427SRui Ueyama     error(a.loc + ": at least one side of the expression must be absolute");
1592ec34544SRui Ueyama }
1602ec34544SRui Ueyama 
1613837f427SRui Ueyama static ExprValue add(ExprValue a, ExprValue b) {
1623837f427SRui Ueyama   moveAbsRight(a, b);
1633837f427SRui Ueyama   return {a.sec, a.forceAbsolute, a.getSectionOffset() + b.getValue(), a.loc};
1642ec34544SRui Ueyama }
1652ec34544SRui Ueyama 
1663837f427SRui Ueyama static ExprValue sub(ExprValue a, ExprValue b) {
16763a4a98eSRafael Espindola   // The distance between two symbols in sections is absolute.
1683837f427SRui Ueyama   if (!a.isAbsolute() && !b.isAbsolute())
1693837f427SRui Ueyama     return a.getValue() - b.getValue();
1703837f427SRui Ueyama   return {a.sec, false, a.getSectionOffset() - b.getValue(), a.loc};
1712ec34544SRui Ueyama }
1722ec34544SRui Ueyama 
1733837f427SRui Ueyama static ExprValue bitAnd(ExprValue a, ExprValue b) {
1743837f427SRui Ueyama   moveAbsRight(a, b);
1753837f427SRui Ueyama   return {a.sec, a.forceAbsolute,
1763837f427SRui Ueyama           (a.getValue() & b.getValue()) - a.getSecAddr(), a.loc};
1772ec34544SRui Ueyama }
1782ec34544SRui Ueyama 
1793837f427SRui Ueyama static ExprValue bitOr(ExprValue a, ExprValue b) {
1803837f427SRui Ueyama   moveAbsRight(a, b);
1813837f427SRui Ueyama   return {a.sec, a.forceAbsolute,
1823837f427SRui Ueyama           (a.getValue() | b.getValue()) - a.getSecAddr(), a.loc};
1832ec34544SRui Ueyama }
1842ec34544SRui Ueyama 
1852ec34544SRui Ueyama void ScriptParser::readDynamicList() {
1862ec34544SRui Ueyama   expect("{");
18764038ef8SFangrui Song   SmallVector<SymbolVersion, 0> locals;
18864038ef8SFangrui Song   SmallVector<SymbolVersion, 0> globals;
1893837f427SRui Ueyama   std::tie(locals, globals) = readSymbols();
190d72d97b3SRafael Espindola   expect(";");
191d72d97b3SRafael Espindola 
192d72d97b3SRafael Espindola   if (!atEOF()) {
1932ec34544SRui Ueyama     setError("EOF expected, but got " + next());
194d72d97b3SRafael Espindola     return;
195d72d97b3SRafael Espindola   }
1963837f427SRui Ueyama   if (!locals.empty()) {
197d72d97b3SRafael Espindola     setError("\"local:\" scope not supported in --dynamic-list");
198d72d97b3SRafael Espindola     return;
199d72d97b3SRafael Espindola   }
200d72d97b3SRafael Espindola 
2013837f427SRui Ueyama   for (SymbolVersion v : globals)
2023837f427SRui Ueyama     config->dynamicList.push_back(v);
2032ec34544SRui Ueyama }
2042ec34544SRui Ueyama 
2052ec34544SRui Ueyama void ScriptParser::readVersionScript() {
2062ec34544SRui Ueyama   readVersionScriptCommand();
2072ec34544SRui Ueyama   if (!atEOF())
2082ec34544SRui Ueyama     setError("EOF expected, but got " + next());
2092ec34544SRui Ueyama }
2102ec34544SRui Ueyama 
2112ec34544SRui Ueyama void ScriptParser::readVersionScriptCommand() {
2122ec34544SRui Ueyama   if (consume("{")) {
2132ec34544SRui Ueyama     readAnonymousDeclaration();
2142ec34544SRui Ueyama     return;
2152ec34544SRui Ueyama   }
2162ec34544SRui Ueyama 
217b8a59c8aSBob Haarman   while (!atEOF() && !errorCount() && peek() != "}") {
2183837f427SRui Ueyama     StringRef verStr = next();
2193837f427SRui Ueyama     if (verStr == "{") {
2202ec34544SRui Ueyama       setError("anonymous version definition is used in "
2212ec34544SRui Ueyama                "combination with other version definitions");
2222ec34544SRui Ueyama       return;
2232ec34544SRui Ueyama     }
2242ec34544SRui Ueyama     expect("{");
2253837f427SRui Ueyama     readVersionDeclaration(verStr);
2262ec34544SRui Ueyama   }
2272ec34544SRui Ueyama }
2282ec34544SRui Ueyama 
2292ec34544SRui Ueyama void ScriptParser::readVersion() {
2302ec34544SRui Ueyama   expect("{");
2312ec34544SRui Ueyama   readVersionScriptCommand();
2322ec34544SRui Ueyama   expect("}");
2332ec34544SRui Ueyama }
2342ec34544SRui Ueyama 
2352ec34544SRui Ueyama void ScriptParser::readLinkerScript() {
2362ec34544SRui Ueyama   while (!atEOF()) {
2373837f427SRui Ueyama     StringRef tok = next();
2383837f427SRui Ueyama     if (tok == ";")
2392ec34544SRui Ueyama       continue;
2402ec34544SRui Ueyama 
2413837f427SRui Ueyama     if (tok == "ENTRY") {
2422ec34544SRui Ueyama       readEntry();
2433837f427SRui Ueyama     } else if (tok == "EXTERN") {
2442ec34544SRui Ueyama       readExtern();
2453837f427SRui Ueyama     } else if (tok == "GROUP") {
2462ec34544SRui Ueyama       readGroup();
2473837f427SRui Ueyama     } else if (tok == "INCLUDE") {
2482ec34544SRui Ueyama       readInclude();
2493837f427SRui Ueyama     } else if (tok == "INPUT") {
2501d92aa73SRui Ueyama       readInput();
2513837f427SRui Ueyama     } else if (tok == "MEMORY") {
2522ec34544SRui Ueyama       readMemory();
2533837f427SRui Ueyama     } else if (tok == "OUTPUT") {
2542ec34544SRui Ueyama       readOutput();
2553837f427SRui Ueyama     } else if (tok == "OUTPUT_ARCH") {
2562ec34544SRui Ueyama       readOutputArch();
2573837f427SRui Ueyama     } else if (tok == "OUTPUT_FORMAT") {
2582ec34544SRui Ueyama       readOutputFormat();
259899fdf54SFangrui Song     } else if (tok == "OVERWRITE_SECTIONS") {
260899fdf54SFangrui Song       readOverwriteSections();
2613837f427SRui Ueyama     } else if (tok == "PHDRS") {
2622ec34544SRui Ueyama       readPhdrs();
2633837f427SRui Ueyama     } else if (tok == "REGION_ALIAS") {
2645f37541cSGeorge Rimar       readRegionAlias();
2653837f427SRui Ueyama     } else if (tok == "SEARCH_DIR") {
2662ec34544SRui Ueyama       readSearchDir();
2673837f427SRui Ueyama     } else if (tok == "SECTIONS") {
2682ec34544SRui Ueyama       readSections();
2693837f427SRui Ueyama     } else if (tok == "TARGET") {
270e262bb1aSRui Ueyama       readTarget();
2713837f427SRui Ueyama     } else if (tok == "VERSION") {
2722ec34544SRui Ueyama       readVersion();
2733837f427SRui Ueyama     } else if (SymbolAssignment *cmd = readAssignment(tok)) {
2743837f427SRui Ueyama       script->sectionCommands.push_back(cmd);
2752ec34544SRui Ueyama     } else {
2763837f427SRui Ueyama       setError("unknown directive: " + tok);
2772ec34544SRui Ueyama     }
2782ec34544SRui Ueyama   }
2792ec34544SRui Ueyama }
2802ec34544SRui Ueyama 
2813837f427SRui Ueyama void ScriptParser::readDefsym(StringRef name) {
282c1522816SGeorge Rimar   if (errorCount())
283c1522816SGeorge Rimar     return;
2843837f427SRui Ueyama   Expr e = readExpr();
2858c7e8cceSPetr Hosek   if (!atEOF())
2868c7e8cceSPetr Hosek     setError("EOF expected, but got " + next());
2873837f427SRui Ueyama   SymbolAssignment *cmd = make<SymbolAssignment>(name, e, getCurrentLocation());
2883837f427SRui Ueyama   script->sectionCommands.push_back(cmd);
2898c7e8cceSPetr Hosek }
2908c7e8cceSPetr Hosek 
2913837f427SRui Ueyama void ScriptParser::addFile(StringRef s) {
2923837f427SRui Ueyama   if (isUnderSysroot && s.startswith("/")) {
2933837f427SRui Ueyama     SmallString<128> pathData;
2943837f427SRui Ueyama     StringRef path = (config->sysroot + s).toStringRef(pathData);
2952508733eSFangrui Song     if (sys::fs::exists(path))
29683d59e05SAlexandre Ganea       driver->addFile(saver().save(path), /*withLOption=*/false);
2972508733eSFangrui Song     else
2982508733eSFangrui Song       setError("cannot find " + s + " inside " + config->sysroot);
2992ec34544SRui Ueyama     return;
3002ec34544SRui Ueyama   }
3012ec34544SRui Ueyama 
3023837f427SRui Ueyama   if (s.startswith("/")) {
303c384ca3cSFangrui Song     // Case 1: s is an absolute path. Just open it.
30449a3ad21SRui Ueyama     driver->addFile(s, /*withLOption=*/false);
3053837f427SRui Ueyama   } else if (s.startswith("=")) {
306c384ca3cSFangrui Song     // Case 2: relative to the sysroot.
3073837f427SRui Ueyama     if (config->sysroot.empty())
30849a3ad21SRui Ueyama       driver->addFile(s.substr(1), /*withLOption=*/false);
3092ec34544SRui Ueyama     else
31083d59e05SAlexandre Ganea       driver->addFile(saver().save(config->sysroot + "/" + s.substr(1)),
31149a3ad21SRui Ueyama                       /*withLOption=*/false);
3123837f427SRui Ueyama   } else if (s.startswith("-l")) {
313c384ca3cSFangrui Song     // Case 3: search in the list of library paths.
3143837f427SRui Ueyama     driver->addLibrary(s.substr(2));
315c384ca3cSFangrui Song   } else {
316c384ca3cSFangrui Song     // Case 4: s is a relative path. Search in the directory of the script file.
317c384ca3cSFangrui Song     std::string filename = std::string(getCurrentMB().getBufferIdentifier());
318c384ca3cSFangrui Song     StringRef directory = sys::path::parent_path(filename);
319c384ca3cSFangrui Song     if (!directory.empty()) {
320c384ca3cSFangrui Song       SmallString<0> path(directory);
321c384ca3cSFangrui Song       sys::path::append(path, s);
322c384ca3cSFangrui Song       if (sys::fs::exists(path)) {
323c384ca3cSFangrui Song         driver->addFile(path, /*withLOption=*/false);
324c384ca3cSFangrui Song         return;
325c384ca3cSFangrui Song       }
326c384ca3cSFangrui Song     }
327c384ca3cSFangrui Song     // Then search in the current working directory.
328c384ca3cSFangrui Song     if (sys::fs::exists(s)) {
32949a3ad21SRui Ueyama       driver->addFile(s, /*withLOption=*/false);
3302ec34544SRui Ueyama     } else {
331c384ca3cSFangrui Song       // Finally, search in the list of library paths.
3323837f427SRui Ueyama       if (Optional<std::string> path = findFromSearchPaths(s))
33383d59e05SAlexandre Ganea         driver->addFile(saver().save(*path), /*withLOption=*/true);
3342ec34544SRui Ueyama       else
3353837f427SRui Ueyama         setError("unable to find " + s);
3362ec34544SRui Ueyama     }
3372ec34544SRui Ueyama   }
338c384ca3cSFangrui Song }
3392ec34544SRui Ueyama 
3402ec34544SRui Ueyama void ScriptParser::readAsNeeded() {
3412ec34544SRui Ueyama   expect("(");
3423837f427SRui Ueyama   bool orig = config->asNeeded;
3433837f427SRui Ueyama   config->asNeeded = true;
344b8a59c8aSBob Haarman   while (!errorCount() && !consume(")"))
3452ec34544SRui Ueyama     addFile(unquote(next()));
3463837f427SRui Ueyama   config->asNeeded = orig;
3472ec34544SRui Ueyama }
3482ec34544SRui Ueyama 
3492ec34544SRui Ueyama void ScriptParser::readEntry() {
3502ec34544SRui Ueyama   // -e <symbol> takes predecence over ENTRY(<symbol>).
3512ec34544SRui Ueyama   expect("(");
3523837f427SRui Ueyama   StringRef tok = next();
3533837f427SRui Ueyama   if (config->entry.empty())
354363b2956SFangrui Song     config->entry = unquote(tok);
3552ec34544SRui Ueyama   expect(")");
3562ec34544SRui Ueyama }
3572ec34544SRui Ueyama 
3582ec34544SRui Ueyama void ScriptParser::readExtern() {
3592ec34544SRui Ueyama   expect("(");
360b8a59c8aSBob Haarman   while (!errorCount() && !consume(")"))
3613837f427SRui Ueyama     config->undefined.push_back(unquote(next()));
3622ec34544SRui Ueyama }
3632ec34544SRui Ueyama 
3642ec34544SRui Ueyama void ScriptParser::readGroup() {
3653837f427SRui Ueyama   bool orig = InputFile::isInGroup;
3663837f427SRui Ueyama   InputFile::isInGroup = true;
3671d92aa73SRui Ueyama   readInput();
3683837f427SRui Ueyama   InputFile::isInGroup = orig;
3693837f427SRui Ueyama   if (!orig)
3703837f427SRui Ueyama     ++InputFile::nextGroupId;
3712ec34544SRui Ueyama }
3722ec34544SRui Ueyama 
3732ec34544SRui Ueyama void ScriptParser::readInclude() {
3743837f427SRui Ueyama   StringRef tok = unquote(next());
3752ec34544SRui Ueyama 
3763837f427SRui Ueyama   if (!seen.insert(tok).second) {
3770440be4aSRui Ueyama     setError("there is a cycle in linker script INCLUDEs");
3780440be4aSRui Ueyama     return;
3790440be4aSRui Ueyama   }
3800440be4aSRui Ueyama 
3813837f427SRui Ueyama   if (Optional<std::string> path = searchScript(tok)) {
3823837f427SRui Ueyama     if (Optional<MemoryBufferRef> mb = readFile(*path))
3833837f427SRui Ueyama       tokenize(*mb);
3842ec34544SRui Ueyama     return;
3852ec34544SRui Ueyama   }
3863837f427SRui Ueyama   setError("cannot find linker script " + tok);
3872ec34544SRui Ueyama }
3882ec34544SRui Ueyama 
3891d92aa73SRui Ueyama void ScriptParser::readInput() {
3901d92aa73SRui Ueyama   expect("(");
3911d92aa73SRui Ueyama   while (!errorCount() && !consume(")")) {
3921d92aa73SRui Ueyama     if (consume("AS_NEEDED"))
3931d92aa73SRui Ueyama       readAsNeeded();
3941d92aa73SRui Ueyama     else
3951d92aa73SRui Ueyama       addFile(unquote(next()));
3961d92aa73SRui Ueyama   }
3971d92aa73SRui Ueyama }
3981d92aa73SRui Ueyama 
3992ec34544SRui Ueyama void ScriptParser::readOutput() {
4002ec34544SRui Ueyama   // -o <file> takes predecence over OUTPUT(<file>).
4012ec34544SRui Ueyama   expect("(");
4023837f427SRui Ueyama   StringRef tok = next();
4033837f427SRui Ueyama   if (config->outputFile.empty())
4043837f427SRui Ueyama     config->outputFile = unquote(tok);
4052ec34544SRui Ueyama   expect(")");
4062ec34544SRui Ueyama }
4072ec34544SRui Ueyama 
4082ec34544SRui Ueyama void ScriptParser::readOutputArch() {
4092ec34544SRui Ueyama   // OUTPUT_ARCH is ignored for now.
4102ec34544SRui Ueyama   expect("(");
411b8a59c8aSBob Haarman   while (!errorCount() && !consume(")"))
4122ec34544SRui Ueyama     skip();
4132ec34544SRui Ueyama }
4142ec34544SRui Ueyama 
4153837f427SRui Ueyama static std::pair<ELFKind, uint16_t> parseBfdName(StringRef s) {
4163837f427SRui Ueyama   return StringSwitch<std::pair<ELFKind, uint16_t>>(s)
4174f8c8228SRui Ueyama       .Case("elf32-i386", {ELF32LEKind, EM_386})
4188527f32fSBen Shi       .Case("elf32-avr", {ELF32LEKind, EM_AVR})
4194f8c8228SRui Ueyama       .Case("elf32-iamcu", {ELF32LEKind, EM_IAMCU})
4204f8c8228SRui Ueyama       .Case("elf32-littlearm", {ELF32LEKind, EM_ARM})
4214f8c8228SRui Ueyama       .Case("elf32-x86-64", {ELF32LEKind, EM_X86_64})
42219b134ccSDimitry Andric       .Case("elf64-aarch64", {ELF64LEKind, EM_AARCH64})
4234f8c8228SRui Ueyama       .Case("elf64-littleaarch64", {ELF64LEKind, EM_AARCH64})
4247605a9a0SFangrui Song       .Case("elf64-bigaarch64", {ELF64BEKind, EM_AARCH64})
4254134143cSRui Ueyama       .Case("elf32-powerpc", {ELF32BEKind, EM_PPC})
426275eb828SBrandon Bergren       .Case("elf32-powerpcle", {ELF32LEKind, EM_PPC})
4274f8c8228SRui Ueyama       .Case("elf64-powerpc", {ELF64BEKind, EM_PPC64})
4284f8c8228SRui Ueyama       .Case("elf64-powerpcle", {ELF64LEKind, EM_PPC64})
4294f8c8228SRui Ueyama       .Case("elf64-x86-64", {ELF64LEKind, EM_X86_64})
4304134143cSRui Ueyama       .Cases("elf32-tradbigmips", "elf32-bigmips", {ELF32BEKind, EM_MIPS})
4314f8c8228SRui Ueyama       .Case("elf32-ntradbigmips", {ELF32BEKind, EM_MIPS})
4324f8c8228SRui Ueyama       .Case("elf32-tradlittlemips", {ELF32LEKind, EM_MIPS})
4334f8c8228SRui Ueyama       .Case("elf32-ntradlittlemips", {ELF32LEKind, EM_MIPS})
4344f8c8228SRui Ueyama       .Case("elf64-tradbigmips", {ELF64BEKind, EM_MIPS})
4354f8c8228SRui Ueyama       .Case("elf64-tradlittlemips", {ELF64LEKind, EM_MIPS})
43644d908d7SFangrui Song       .Case("elf32-littleriscv", {ELF32LEKind, EM_RISCV})
43744d908d7SFangrui Song       .Case("elf64-littleriscv", {ELF64LEKind, EM_RISCV})
438aff950e9SLemonBoy       .Case("elf64-sparc", {ELF64BEKind, EM_SPARCV9})
43992c6141cSLemonBoy       .Case("elf32-msp430", {ELF32LEKind, EM_MSP430})
4404f8c8228SRui Ueyama       .Default({ELFNoneKind, EM_NONE});
441ea8cd00aSRui Ueyama }
442ea8cd00aSRui Ueyama 
443eea34aaeSFangrui Song // Parse OUTPUT_FORMAT(bfdname) or OUTPUT_FORMAT(default, big, little). Choose
444eea34aaeSFangrui Song // big if -EB is specified, little if -EL is specified, or default if neither is
445eea34aaeSFangrui Song // specified.
4462ec34544SRui Ueyama void ScriptParser::readOutputFormat() {
4472ec34544SRui Ueyama   expect("(");
448ea8cd00aSRui Ueyama 
449eea34aaeSFangrui Song   StringRef s;
4502822852fSShoaib Meenai   config->bfdname = unquote(next());
451eea34aaeSFangrui Song   if (!consume(")")) {
452eea34aaeSFangrui Song     expect(",");
453eea34aaeSFangrui Song     s = unquote(next());
454eea34aaeSFangrui Song     if (config->optEB)
455eea34aaeSFangrui Song       config->bfdname = s;
456eea34aaeSFangrui Song     expect(",");
457eea34aaeSFangrui Song     s = unquote(next());
458eea34aaeSFangrui Song     if (config->optEL)
459eea34aaeSFangrui Song       config->bfdname = s;
460eea34aaeSFangrui Song     consume(")");
461eea34aaeSFangrui Song   }
462eea34aaeSFangrui Song   s = config->bfdname;
4633837f427SRui Ueyama   if (s.consume_back("-freebsd"))
4643837f427SRui Ueyama     config->osabi = ELFOSABI_FREEBSD;
4654f8c8228SRui Ueyama 
4663837f427SRui Ueyama   std::tie(config->ekind, config->emachine) = parseBfdName(s);
4673837f427SRui Ueyama   if (config->emachine == EM_NONE)
4682822852fSShoaib Meenai     setError("unknown output format name: " + config->bfdname);
4693837f427SRui Ueyama   if (s == "elf32-ntradlittlemips" || s == "elf32-ntradbigmips")
4703837f427SRui Ueyama     config->mipsN32Abi = true;
47192c6141cSLemonBoy   if (config->emachine == EM_MSP430)
47292c6141cSLemonBoy     config->osabi = ELFOSABI_STANDALONE;
4732ec34544SRui Ueyama }
4742ec34544SRui Ueyama 
4752ec34544SRui Ueyama void ScriptParser::readPhdrs() {
4762ec34544SRui Ueyama   expect("{");
4772ec34544SRui Ueyama 
478b8a59c8aSBob Haarman   while (!errorCount() && !consume("}")) {
4793837f427SRui Ueyama     PhdrsCommand cmd;
4803837f427SRui Ueyama     cmd.name = next();
4813837f427SRui Ueyama     cmd.type = readPhdrType();
482b579c439SRui Ueyama 
483b8a59c8aSBob Haarman     while (!errorCount() && !consume(";")) {
484b579c439SRui Ueyama       if (consume("FILEHDR"))
4853837f427SRui Ueyama         cmd.hasFilehdr = true;
486b579c439SRui Ueyama       else if (consume("PHDRS"))
4873837f427SRui Ueyama         cmd.hasPhdrs = true;
488b579c439SRui Ueyama       else if (consume("AT"))
4893837f427SRui Ueyama         cmd.lmaExpr = readParenExpr();
490b579c439SRui Ueyama       else if (consume("FLAGS"))
4913837f427SRui Ueyama         cmd.flags = readParenExpr()().getValue();
492b579c439SRui Ueyama       else
493b579c439SRui Ueyama         setError("unexpected header attribute: " + next());
494b579c439SRui Ueyama     }
4950ae2c24cSRui Ueyama 
4963837f427SRui Ueyama     script->phdrsCommands.push_back(cmd);
4972ec34544SRui Ueyama   }
4982ec34544SRui Ueyama }
4992ec34544SRui Ueyama 
5005f37541cSGeorge Rimar void ScriptParser::readRegionAlias() {
5015f37541cSGeorge Rimar   expect("(");
5023837f427SRui Ueyama   StringRef alias = unquote(next());
5035f37541cSGeorge Rimar   expect(",");
5043837f427SRui Ueyama   StringRef name = next();
5055f37541cSGeorge Rimar   expect(")");
5065f37541cSGeorge Rimar 
5073837f427SRui Ueyama   if (script->memoryRegions.count(alias))
5083837f427SRui Ueyama     setError("redefinition of memory region '" + alias + "'");
5093837f427SRui Ueyama   if (!script->memoryRegions.count(name))
5103837f427SRui Ueyama     setError("memory region '" + name + "' is not defined");
5113837f427SRui Ueyama   script->memoryRegions.insert({alias, script->memoryRegions[name]});
5125f37541cSGeorge Rimar }
5135f37541cSGeorge Rimar 
5142ec34544SRui Ueyama void ScriptParser::readSearchDir() {
5152ec34544SRui Ueyama   expect("(");
5163837f427SRui Ueyama   StringRef tok = next();
5173837f427SRui Ueyama   if (!config->nostdlib)
5183837f427SRui Ueyama     config->searchPaths.push_back(unquote(tok));
5192ec34544SRui Ueyama   expect(")");
5202ec34544SRui Ueyama }
5212ec34544SRui Ueyama 
522a582419aSGeorge Rimar // This reads an overlay description. Overlays are used to describe output
523a582419aSGeorge Rimar // sections that use the same virtual memory range and normally would trigger
524a582419aSGeorge Rimar // linker's sections sanity check failures.
525a582419aSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Overlay-Description.html#Overlay-Description
52664038ef8SFangrui Song SmallVector<SectionCommand *, 0> ScriptParser::readOverlay() {
527a582419aSGeorge Rimar   // VA and LMA expressions are optional, though for simplicity of
528a582419aSGeorge Rimar   // implementation we assume they are not. That is what OVERLAY was designed
529a582419aSGeorge Rimar   // for first of all: to allow sections with overlapping VAs at different LMAs.
5303837f427SRui Ueyama   Expr addrExpr = readExpr();
531a582419aSGeorge Rimar   expect(":");
532a582419aSGeorge Rimar   expect("AT");
5333837f427SRui Ueyama   Expr lmaExpr = readParenExpr();
534a582419aSGeorge Rimar   expect("{");
535a582419aSGeorge Rimar 
53664038ef8SFangrui Song   SmallVector<SectionCommand *, 0> v;
5373837f427SRui Ueyama   OutputSection *prev = nullptr;
538a582419aSGeorge Rimar   while (!errorCount() && !consume("}")) {
539a582419aSGeorge Rimar     // VA is the same for all sections. The LMAs are consecutive in memory
540a582419aSGeorge Rimar     // starting from the base load address specified.
5416c814931SFangrui Song     OutputDesc *osd = readOverlaySectionDescription();
5426c814931SFangrui Song     osd->osec.addrExpr = addrExpr;
5433837f427SRui Ueyama     if (prev)
5446c814931SFangrui Song       osd->osec.lmaExpr = [=] { return prev->getLMA() + prev->size; };
545a582419aSGeorge Rimar     else
5466c814931SFangrui Song       osd->osec.lmaExpr = lmaExpr;
5476c814931SFangrui Song     v.push_back(osd);
5486c814931SFangrui Song     prev = &osd->osec;
549a582419aSGeorge Rimar   }
550a582419aSGeorge Rimar 
551a582419aSGeorge Rimar   // According to the specification, at the end of the overlay, the location
552a582419aSGeorge Rimar   // counter should be equal to the overlay base address plus size of the
553a582419aSGeorge Rimar   // largest section seen in the overlay.
554a582419aSGeorge Rimar   // Here we want to create the Dot assignment command to achieve that.
5553837f427SRui Ueyama   Expr moveDot = [=] {
5563837f427SRui Ueyama     uint64_t max = 0;
5577051aeefSFangrui Song     for (SectionCommand *cmd : v)
5586c814931SFangrui Song       max = std::max(max, cast<OutputDesc>(cmd)->osec.size);
5593837f427SRui Ueyama     return addrExpr().getValue() + max;
560a582419aSGeorge Rimar   };
5613837f427SRui Ueyama   v.push_back(make<SymbolAssignment>(".", moveDot, getCurrentLocation()));
5623837f427SRui Ueyama   return v;
563a582419aSGeorge Rimar }
564a582419aSGeorge Rimar 
565899fdf54SFangrui Song void ScriptParser::readOverwriteSections() {
566899fdf54SFangrui Song   expect("{");
567899fdf54SFangrui Song   while (!errorCount() && !consume("}"))
568899fdf54SFangrui Song     script->overwriteSections.push_back(readOutputSectionDescription(next()));
569899fdf54SFangrui Song }
570899fdf54SFangrui Song 
5712ec34544SRui Ueyama void ScriptParser::readSections() {
5722ec34544SRui Ueyama   expect("{");
57364038ef8SFangrui Song   SmallVector<SectionCommand *, 0> v;
574b8a59c8aSBob Haarman   while (!errorCount() && !consume("}")) {
5753837f427SRui Ueyama     StringRef tok = next();
5763837f427SRui Ueyama     if (tok == "OVERLAY") {
5777051aeefSFangrui Song       for (SectionCommand *cmd : readOverlay())
5783837f427SRui Ueyama         v.push_back(cmd);
579a582419aSGeorge Rimar       continue;
5803837f427SRui Ueyama     } else if (tok == "INCLUDE") {
5812e9d40d5SRui Ueyama       readInclude();
5822e9d40d5SRui Ueyama       continue;
583a582419aSGeorge Rimar     }
584a582419aSGeorge Rimar 
5857051aeefSFangrui Song     if (SectionCommand *cmd = readAssignment(tok))
5863837f427SRui Ueyama       v.push_back(cmd);
587d30a78b3SGeorge Rimar     else
5883837f427SRui Ueyama       v.push_back(readOutputSectionDescription(tok));
5892ec34544SRui Ueyama   }
5905a44980fSFangrui Song 
5915a44980fSFangrui Song   // If DATA_SEGMENT_RELRO_END is absent, for sections after DATA_SEGMENT_ALIGN,
5925a44980fSFangrui Song   // the relro fields should be cleared.
5935a44980fSFangrui Song   if (!seenRelroEnd)
5945a44980fSFangrui Song     for (SectionCommand *cmd : v)
5955a44980fSFangrui Song       if (auto *osd = dyn_cast<OutputDesc>(cmd))
5965a44980fSFangrui Song         osd->osec.relro = false;
5975a44980fSFangrui Song 
5987c426fb1SFangrui Song   script->sectionCommands.insert(script->sectionCommands.end(), v.begin(),
5997c426fb1SFangrui Song                                  v.end());
6009e2c8a9dSGeorge Rimar 
6017c426fb1SFangrui Song   if (atEOF() || !consume("INSERT")) {
6027c426fb1SFangrui Song     script->hasSectionsCommand = true;
6039e2c8a9dSGeorge Rimar     return;
6049e2c8a9dSGeorge Rimar   }
6059e2c8a9dSGeorge Rimar 
6067c426fb1SFangrui Song   bool isAfter = false;
6077c426fb1SFangrui Song   if (consume("AFTER"))
6087c426fb1SFangrui Song     isAfter = true;
6097c426fb1SFangrui Song   else if (!consume("BEFORE"))
6107c426fb1SFangrui Song     setError("expected AFTER/BEFORE, but got '" + next() + "'");
6117c426fb1SFangrui Song   StringRef where = next();
612a1c2ee01SFangrui Song   SmallVector<StringRef, 0> names;
6137051aeefSFangrui Song   for (SectionCommand *cmd : v)
6146c814931SFangrui Song     if (auto *os = dyn_cast<OutputDesc>(cmd))
6156c814931SFangrui Song       names.push_back(os->osec.name);
61603051f7aSFangrui Song   if (!names.empty())
61703051f7aSFangrui Song     script->insertCommands.push_back({std::move(names), isAfter, where});
6182ec34544SRui Ueyama }
6192ec34544SRui Ueyama 
620e262bb1aSRui Ueyama void ScriptParser::readTarget() {
621e262bb1aSRui Ueyama   // TARGET(foo) is an alias for "--format foo". Unlike GNU linkers,
622e262bb1aSRui Ueyama   // we accept only a limited set of BFD names (i.e. "elf" or "binary")
623e262bb1aSRui Ueyama   // for --format. We recognize only /^elf/ and "binary" in the linker
624e262bb1aSRui Ueyama   // script as well.
625e262bb1aSRui Ueyama   expect("(");
6264cb05dc3SFangrui Song   StringRef tok = unquote(next());
627e262bb1aSRui Ueyama   expect(")");
628e262bb1aSRui Ueyama 
6293837f427SRui Ueyama   if (tok.startswith("elf"))
6303837f427SRui Ueyama     config->formatBinary = false;
6313837f427SRui Ueyama   else if (tok == "binary")
6323837f427SRui Ueyama     config->formatBinary = true;
633e262bb1aSRui Ueyama   else
6343837f427SRui Ueyama     setError("unknown target: " + tok);
635e262bb1aSRui Ueyama }
636e262bb1aSRui Ueyama 
6373837f427SRui Ueyama static int precedence(StringRef op) {
6383837f427SRui Ueyama   return StringSwitch<int>(op)
639d479b2e4SFangrui Song       .Cases("*", "/", "%", 10)
640d479b2e4SFangrui Song       .Cases("+", "-", 9)
641d479b2e4SFangrui Song       .Cases("<<", ">>", 8)
642d479b2e4SFangrui Song       .Cases("<", "<=", ">", ">=", 7)
643d479b2e4SFangrui Song       .Cases("==", "!=", 6)
644d479b2e4SFangrui Song       .Case("&", 5)
645d479b2e4SFangrui Song       .Case("|", 4)
646d479b2e4SFangrui Song       .Case("&&", 3)
647d479b2e4SFangrui Song       .Case("||", 2)
648*b0d6dd39SFangrui Song       .Case("?", 1)
6492ec34544SRui Ueyama       .Default(-1);
6502ec34544SRui Ueyama }
6512ec34544SRui Ueyama 
6522ec34544SRui Ueyama StringMatcher ScriptParser::readFilePatterns() {
653c42fe247SThomas Preud'homme   StringMatcher Matcher;
654c42fe247SThomas Preud'homme 
655b8a59c8aSBob Haarman   while (!errorCount() && !consume(")"))
656c42fe247SThomas Preud'homme     Matcher.addPattern(SingleStringMatcher(next()));
657c42fe247SThomas Preud'homme   return Matcher;
6582ec34544SRui Ueyama }
6592ec34544SRui Ueyama 
6602a9aed0eSFangrui Song SortSectionPolicy ScriptParser::peekSortKind() {
6612a9aed0eSFangrui Song   return StringSwitch<SortSectionPolicy>(peek())
6622a9aed0eSFangrui Song       .Cases("SORT", "SORT_BY_NAME", SortSectionPolicy::Name)
6632a9aed0eSFangrui Song       .Case("SORT_BY_ALIGNMENT", SortSectionPolicy::Alignment)
6642a9aed0eSFangrui Song       .Case("SORT_BY_INIT_PRIORITY", SortSectionPolicy::Priority)
6652a9aed0eSFangrui Song       .Case("SORT_NONE", SortSectionPolicy::None)
6662a9aed0eSFangrui Song       .Default(SortSectionPolicy::Default);
6672a9aed0eSFangrui Song }
6682a9aed0eSFangrui Song 
6692ec34544SRui Ueyama SortSectionPolicy ScriptParser::readSortKind() {
6702a9aed0eSFangrui Song   SortSectionPolicy ret = peekSortKind();
6712a9aed0eSFangrui Song   if (ret != SortSectionPolicy::Default)
6722a9aed0eSFangrui Song     skip();
6732a9aed0eSFangrui Song   return ret;
6742ec34544SRui Ueyama }
6752ec34544SRui Ueyama 
67603fc8d1eSRui Ueyama // Reads SECTIONS command contents in the following form:
67703fc8d1eSRui Ueyama //
67803fc8d1eSRui Ueyama // <contents> ::= <elem>*
67903fc8d1eSRui Ueyama // <elem>     ::= <exclude>? <glob-pattern>
68003fc8d1eSRui Ueyama // <exclude>  ::= "EXCLUDE_FILE" "(" <glob-pattern>+ ")"
68103fc8d1eSRui Ueyama //
68203fc8d1eSRui Ueyama // For example,
68303fc8d1eSRui Ueyama //
68403fc8d1eSRui Ueyama // *(.foo EXCLUDE_FILE (a.o) .bar EXCLUDE_FILE (b.o) .baz)
68503fc8d1eSRui Ueyama //
68603fc8d1eSRui Ueyama // is parsed as ".foo", ".bar" with "a.o", and ".baz" with "b.o".
68703fc8d1eSRui Ueyama // The semantics of that is section .foo in any file, section .bar in
68803fc8d1eSRui Ueyama // any file but a.o, and section .baz in any file but b.o.
68964038ef8SFangrui Song SmallVector<SectionPattern, 0> ScriptParser::readInputSectionsList() {
69064038ef8SFangrui Song   SmallVector<SectionPattern, 0> ret;
691b8a59c8aSBob Haarman   while (!errorCount() && peek() != ")") {
6923837f427SRui Ueyama     StringMatcher excludeFilePat;
6932ec34544SRui Ueyama     if (consume("EXCLUDE_FILE")) {
6942ec34544SRui Ueyama       expect("(");
6953837f427SRui Ueyama       excludeFilePat = readFilePatterns();
6962ec34544SRui Ueyama     }
6972ec34544SRui Ueyama 
698c42fe247SThomas Preud'homme     StringMatcher SectionMatcher;
6992a9aed0eSFangrui Song     // Break if the next token is ), EXCLUDE_FILE, or SORT*.
7002a9aed0eSFangrui Song     while (!errorCount() && peek() != ")" && peek() != "EXCLUDE_FILE" &&
7012a9aed0eSFangrui Song            peekSortKind() == SortSectionPolicy::Default)
702c42fe247SThomas Preud'homme       SectionMatcher.addPattern(unquote(next()));
7032ec34544SRui Ueyama 
704c42fe247SThomas Preud'homme     if (!SectionMatcher.empty())
705c42fe247SThomas Preud'homme       ret.push_back({std::move(excludeFilePat), std::move(SectionMatcher)});
7062a9aed0eSFangrui Song     else if (excludeFilePat.empty())
7072a9aed0eSFangrui Song       break;
7082ec34544SRui Ueyama     else
7092ec34544SRui Ueyama       setError("section pattern is expected");
7102ec34544SRui Ueyama   }
7113837f427SRui Ueyama   return ret;
7122ec34544SRui Ueyama }
7132ec34544SRui Ueyama 
7142ec34544SRui Ueyama // Reads contents of "SECTIONS" directive. That directive contains a
7152ec34544SRui Ueyama // list of glob patterns for input sections. The grammar is as follows.
7162ec34544SRui Ueyama //
7172ec34544SRui Ueyama // <patterns> ::= <section-list>
7182ec34544SRui Ueyama //              | <sort> "(" <section-list> ")"
7192ec34544SRui Ueyama //              | <sort> "(" <sort> "(" <section-list> ")" ")"
7202ec34544SRui Ueyama //
7212ec34544SRui Ueyama // <sort>     ::= "SORT" | "SORT_BY_NAME" | "SORT_BY_ALIGNMENT"
7222ec34544SRui Ueyama //              | "SORT_BY_INIT_PRIORITY" | "SORT_NONE"
7232ec34544SRui Ueyama //
7242ec34544SRui Ueyama // <section-list> is parsed by readInputSectionsList().
7252ec34544SRui Ueyama InputSectionDescription *
726dbd0ad33SPeter Smith ScriptParser::readInputSectionRules(StringRef filePattern, uint64_t withFlags,
727dbd0ad33SPeter Smith                                     uint64_t withoutFlags) {
728dbd0ad33SPeter Smith   auto *cmd =
729dbd0ad33SPeter Smith       make<InputSectionDescription>(filePattern, withFlags, withoutFlags);
7302ec34544SRui Ueyama   expect("(");
7312ec34544SRui Ueyama 
732b8a59c8aSBob Haarman   while (!errorCount() && !consume(")")) {
7333837f427SRui Ueyama     SortSectionPolicy outer = readSortKind();
7343837f427SRui Ueyama     SortSectionPolicy inner = SortSectionPolicy::Default;
73564038ef8SFangrui Song     SmallVector<SectionPattern, 0> v;
7363837f427SRui Ueyama     if (outer != SortSectionPolicy::Default) {
7372ec34544SRui Ueyama       expect("(");
7383837f427SRui Ueyama       inner = readSortKind();
7393837f427SRui Ueyama       if (inner != SortSectionPolicy::Default) {
7402ec34544SRui Ueyama         expect("(");
7413837f427SRui Ueyama         v = readInputSectionsList();
7422ec34544SRui Ueyama         expect(")");
7432ec34544SRui Ueyama       } else {
7443837f427SRui Ueyama         v = readInputSectionsList();
7452ec34544SRui Ueyama       }
7462ec34544SRui Ueyama       expect(")");
7472ec34544SRui Ueyama     } else {
7483837f427SRui Ueyama       v = readInputSectionsList();
7492ec34544SRui Ueyama     }
7502ec34544SRui Ueyama 
7513837f427SRui Ueyama     for (SectionPattern &pat : v) {
7523837f427SRui Ueyama       pat.sortInner = inner;
7533837f427SRui Ueyama       pat.sortOuter = outer;
7542ec34544SRui Ueyama     }
7552ec34544SRui Ueyama 
7563837f427SRui Ueyama     std::move(v.begin(), v.end(), std::back_inserter(cmd->sectionPatterns));
7572ec34544SRui Ueyama   }
7583837f427SRui Ueyama   return cmd;
7592ec34544SRui Ueyama }
7602ec34544SRui Ueyama 
7612ec34544SRui Ueyama InputSectionDescription *
7623837f427SRui Ueyama ScriptParser::readInputSectionDescription(StringRef tok) {
7632ec34544SRui Ueyama   // Input section wildcard can be surrounded by KEEP.
7642ec34544SRui Ueyama   // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep
765dbd0ad33SPeter Smith   uint64_t withFlags = 0;
766dbd0ad33SPeter Smith   uint64_t withoutFlags = 0;
7673837f427SRui Ueyama   if (tok == "KEEP") {
7682ec34544SRui Ueyama     expect("(");
769dbd0ad33SPeter Smith     if (consume("INPUT_SECTION_FLAGS"))
770dbd0ad33SPeter Smith       std::tie(withFlags, withoutFlags) = readInputSectionFlags();
771dbd0ad33SPeter Smith     InputSectionDescription *cmd =
772dbd0ad33SPeter Smith         readInputSectionRules(next(), withFlags, withoutFlags);
7732ec34544SRui Ueyama     expect(")");
7743837f427SRui Ueyama     script->keptSections.push_back(cmd);
7753837f427SRui Ueyama     return cmd;
7762ec34544SRui Ueyama   }
777dbd0ad33SPeter Smith   if (tok == "INPUT_SECTION_FLAGS") {
778dbd0ad33SPeter Smith     std::tie(withFlags, withoutFlags) = readInputSectionFlags();
779dbd0ad33SPeter Smith     tok = next();
780dbd0ad33SPeter Smith   }
781dbd0ad33SPeter Smith   return readInputSectionRules(tok, withFlags, withoutFlags);
7822ec34544SRui Ueyama }
7832ec34544SRui Ueyama 
7842ec34544SRui Ueyama void ScriptParser::readSort() {
7852ec34544SRui Ueyama   expect("(");
7862ec34544SRui Ueyama   expect("CONSTRUCTORS");
7872ec34544SRui Ueyama   expect(")");
7882ec34544SRui Ueyama }
7892ec34544SRui Ueyama 
790d30a78b3SGeorge Rimar Expr ScriptParser::readAssert() {
7912ec34544SRui Ueyama   expect("(");
7923837f427SRui Ueyama   Expr e = readExpr();
7932ec34544SRui Ueyama   expect(",");
7943837f427SRui Ueyama   StringRef msg = unquote(next());
7952ec34544SRui Ueyama   expect(")");
796b579c439SRui Ueyama 
7972ec34544SRui Ueyama   return [=] {
7983837f427SRui Ueyama     if (!e().getValue())
7992682bc3cSFangrui Song       errorOrWarn(msg);
8003837f427SRui Ueyama     return script->getDot();
8012ec34544SRui Ueyama   };
8022ec34544SRui Ueyama }
8032ec34544SRui Ueyama 
80466f8ac8dSFangrui Song #define ECase(X)                                                               \
80566f8ac8dSFangrui Song   { #X, X }
80666f8ac8dSFangrui Song constexpr std::pair<const char *, unsigned> typeMap[] = {
80766f8ac8dSFangrui Song     ECase(SHT_PROGBITS),   ECase(SHT_NOTE),       ECase(SHT_NOBITS),
80866f8ac8dSFangrui Song     ECase(SHT_INIT_ARRAY), ECase(SHT_FINI_ARRAY), ECase(SHT_PREINIT_ARRAY),
80966f8ac8dSFangrui Song };
81066f8ac8dSFangrui Song #undef ECase
81166f8ac8dSFangrui Song 
812a46d08ebSGeorge Rimar // Tries to read the special directive for an output section definition which
81366f8ac8dSFangrui Song // can be one of following: "(NOLOAD)", "(COPY)", "(INFO)", "(OVERLAY)", and
81466f8ac8dSFangrui Song // "(TYPE=<value>)".
81566f8ac8dSFangrui Song // Tok1 and Tok2 are next 2 tokens peeked. See comment for
81666f8ac8dSFangrui Song // readSectionAddressType below.
8173837f427SRui Ueyama bool ScriptParser::readSectionDirective(OutputSection *cmd, StringRef tok1, StringRef tok2) {
8183837f427SRui Ueyama   if (tok1 != "(")
819a46d08ebSGeorge Rimar     return false;
82066f8ac8dSFangrui Song   if (tok2 != "NOLOAD" && tok2 != "COPY" && tok2 != "INFO" &&
82166f8ac8dSFangrui Song       tok2 != "OVERLAY" && tok2 != "TYPE")
822a46d08ebSGeorge Rimar     return false;
823a46d08ebSGeorge Rimar 
824a46d08ebSGeorge Rimar   expect("(");
825a46d08ebSGeorge Rimar   if (consume("NOLOAD")) {
826fdc41aa2SMatt Schulte     cmd->type = SHT_NOBITS;
82766f8ac8dSFangrui Song     cmd->typeIsSet = true;
82866f8ac8dSFangrui Song   } else if (consume("TYPE")) {
82966f8ac8dSFangrui Song     expect("=");
83066f8ac8dSFangrui Song     StringRef value = peek();
83166f8ac8dSFangrui Song     auto it = llvm::find_if(typeMap, [=](auto e) { return e.first == value; });
83266f8ac8dSFangrui Song     if (it != std::end(typeMap)) {
83366f8ac8dSFangrui Song       // The value is a recognized literal SHT_*.
83466f8ac8dSFangrui Song       cmd->type = it->second;
83566f8ac8dSFangrui Song       skip();
83666f8ac8dSFangrui Song     } else if (value.startswith("SHT_")) {
83766f8ac8dSFangrui Song       setError("unknown section type " + value);
83866f8ac8dSFangrui Song     } else {
83966f8ac8dSFangrui Song       // Otherwise, read an expression.
84066f8ac8dSFangrui Song       cmd->type = readExpr()().getValue();
84166f8ac8dSFangrui Song     }
84266f8ac8dSFangrui Song     cmd->typeIsSet = true;
843a46d08ebSGeorge Rimar   } else {
844a46d08ebSGeorge Rimar     skip(); // This is "COPY", "INFO" or "OVERLAY".
8453837f427SRui Ueyama     cmd->nonAlloc = true;
846a46d08ebSGeorge Rimar   }
847a46d08ebSGeorge Rimar   expect(")");
848a46d08ebSGeorge Rimar   return true;
849a46d08ebSGeorge Rimar }
850a46d08ebSGeorge Rimar 
8511c08e9f5SGeorge Rimar // Reads an expression and/or the special directive for an output
8521c08e9f5SGeorge Rimar // section definition. Directive is one of following: "(NOLOAD)",
8531c08e9f5SGeorge Rimar // "(COPY)", "(INFO)" or "(OVERLAY)".
8543271d370SRui Ueyama //
8553271d370SRui Ueyama // An output section name can be followed by an address expression
8561c08e9f5SGeorge Rimar // and/or directive. This grammar is not LL(1) because "(" can be
85797f4d158SGeorge Rimar // interpreted as either the beginning of some expression or beginning
8581c08e9f5SGeorge Rimar // of directive.
8593271d370SRui Ueyama //
860b579c439SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html
861fbb0463fSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Output-Section-Type.html
8623837f427SRui Ueyama void ScriptParser::readSectionAddressType(OutputSection *cmd) {
86366f8ac8dSFangrui Song   // Temporarily set inExpr to support TYPE=<value> without spaces.
86466f8ac8dSFangrui Song   bool saved = std::exchange(inExpr, true);
86566f8ac8dSFangrui Song   bool isDirective = readSectionDirective(cmd, peek(), peek2());
86666f8ac8dSFangrui Song   inExpr = saved;
86766f8ac8dSFangrui Song   if (isDirective)
8683271d370SRui Ueyama     return;
8693271d370SRui Ueyama 
8703837f427SRui Ueyama   cmd->addrExpr = readExpr();
8713837f427SRui Ueyama   if (peek() == "(" && !readSectionDirective(cmd, "(", peek2()))
872a46d08ebSGeorge Rimar     setError("unknown section directive: " + peek2());
873fbb0463fSGeorge Rimar }
874fbb0463fSGeorge Rimar 
8753837f427SRui Ueyama static Expr checkAlignment(Expr e, std::string &loc) {
876f22ec9ddSGeorge Rimar   return [=] {
8773837f427SRui Ueyama     uint64_t alignment = std::max((uint64_t)1, e().getValue());
8783837f427SRui Ueyama     if (!isPowerOf2_64(alignment)) {
8793837f427SRui Ueyama       error(loc + ": alignment must be power of 2");
880f22ec9ddSGeorge Rimar       return (uint64_t)1; // Return a dummy value.
881f22ec9ddSGeorge Rimar     }
8823837f427SRui Ueyama     return alignment;
883f22ec9ddSGeorge Rimar   };
884f22ec9ddSGeorge Rimar }
885f22ec9ddSGeorge Rimar 
8866c814931SFangrui Song OutputDesc *ScriptParser::readOverlaySectionDescription() {
8876c814931SFangrui Song   OutputDesc *osd = script->createOutputSection(next(), getCurrentLocation());
8886c814931SFangrui Song   osd->osec.inOverlay = true;
889a582419aSGeorge Rimar   expect("{");
890dbd0ad33SPeter Smith   while (!errorCount() && !consume("}")) {
891dbd0ad33SPeter Smith     uint64_t withFlags = 0;
892dbd0ad33SPeter Smith     uint64_t withoutFlags = 0;
893dbd0ad33SPeter Smith     if (consume("INPUT_SECTION_FLAGS"))
894dbd0ad33SPeter Smith       std::tie(withFlags, withoutFlags) = readInputSectionFlags();
8956c814931SFangrui Song     osd->osec.commands.push_back(
896dbd0ad33SPeter Smith         readInputSectionRules(next(), withFlags, withoutFlags));
897dbd0ad33SPeter Smith   }
8986c814931SFangrui Song   return osd;
899a582419aSGeorge Rimar }
900a582419aSGeorge Rimar 
9016c814931SFangrui Song OutputDesc *ScriptParser::readOutputSectionDescription(StringRef outSec) {
9026c814931SFangrui Song   OutputDesc *cmd = script->createOutputSection(outSec, getCurrentLocation());
9036c814931SFangrui Song   OutputSection *osec = &cmd->osec;
9045a44980fSFangrui Song   // Maybe relro. Will reset to false if DATA_SEGMENT_RELRO_END is absent.
9055a44980fSFangrui Song   osec->relro = seenDataAlign && !seenRelroEnd;
9063271d370SRui Ueyama 
9073837f427SRui Ueyama   size_t symbolsReferenced = script->referencedSymbols.size();
908c4df670dSGeorge Rimar 
9093271d370SRui Ueyama   if (peek() != ":")
9106c814931SFangrui Song     readSectionAddressType(osec);
9112ec34544SRui Ueyama   expect(":");
9122ec34544SRui Ueyama 
9133837f427SRui Ueyama   std::string location = getCurrentLocation();
9142ec34544SRui Ueyama   if (consume("AT"))
9156c814931SFangrui Song     osec->lmaExpr = readParenExpr();
9162ec34544SRui Ueyama   if (consume("ALIGN"))
9176c814931SFangrui Song     osec->alignExpr = checkAlignment(readParenExpr(), location);
9182ec34544SRui Ueyama   if (consume("SUBALIGN"))
9196c814931SFangrui Song     osec->subalignExpr = checkAlignment(readParenExpr(), location);
9202ec34544SRui Ueyama 
9212ec34544SRui Ueyama   // Parse constraints.
9222ec34544SRui Ueyama   if (consume("ONLY_IF_RO"))
9236c814931SFangrui Song     osec->constraint = ConstraintKind::ReadOnly;
9242ec34544SRui Ueyama   if (consume("ONLY_IF_RW"))
9256c814931SFangrui Song     osec->constraint = ConstraintKind::ReadWrite;
9262ec34544SRui Ueyama   expect("{");
9272ec34544SRui Ueyama 
928b8a59c8aSBob Haarman   while (!errorCount() && !consume("}")) {
9293837f427SRui Ueyama     StringRef tok = next();
9303837f427SRui Ueyama     if (tok == ";") {
9312ec34544SRui Ueyama       // Empty commands are allowed. Do nothing here.
9323837f427SRui Ueyama     } else if (SymbolAssignment *assign = readAssignment(tok)) {
9336c814931SFangrui Song       osec->commands.push_back(assign);
9343837f427SRui Ueyama     } else if (ByteCommand *data = readByteCommand(tok)) {
9356c814931SFangrui Song       osec->commands.push_back(data);
9363837f427SRui Ueyama     } else if (tok == "CONSTRUCTORS") {
9372ec34544SRui Ueyama       // CONSTRUCTORS is a keyword to make the linker recognize C++ ctors/dtors
9382ec34544SRui Ueyama       // by name. This is for very old file formats such as ECOFF/XCOFF.
9392ec34544SRui Ueyama       // For ELF, we should ignore.
9403837f427SRui Ueyama     } else if (tok == "FILL") {
9410810f16fSGeorge Rimar       // We handle the FILL command as an alias for =fillexp section attribute,
9420810f16fSGeorge Rimar       // which is different from what GNU linkers do.
9430810f16fSGeorge Rimar       // https://sourceware.org/binutils/docs/ld/Output-Section-Data.html
944bb7d2b17SGeorgii Rymar       if (peek() != "(")
945bb7d2b17SGeorgii Rymar         setError("( expected, but got " + peek());
9466c814931SFangrui Song       osec->filler = readFill();
9473837f427SRui Ueyama     } else if (tok == "SORT") {
9482ec34544SRui Ueyama       readSort();
9493837f427SRui Ueyama     } else if (tok == "INCLUDE") {
9502e9d40d5SRui Ueyama       readInclude();
951177fd72fSFangrui Song     } else if (tok == "(" || tok == ")") {
952177fd72fSFangrui Song       setError("expected filename pattern");
9532ec34544SRui Ueyama     } else if (peek() == "(") {
9546c814931SFangrui Song       osec->commands.push_back(readInputSectionDescription(tok));
9552ec34544SRui Ueyama     } else {
956f49fe218SGeorge Rimar       // We have a file name and no input sections description. It is not a
957f49fe218SGeorge Rimar       // commonly used syntax, but still acceptable. In that case, all sections
958f49fe218SGeorge Rimar       // from the file will be included.
959dbd0ad33SPeter Smith       // FIXME: GNU ld permits INPUT_SECTION_FLAGS to be used here. We do not
960dbd0ad33SPeter Smith       // handle this case here as it will already have been matched by the
961dbd0ad33SPeter Smith       // case above.
9623837f427SRui Ueyama       auto *isd = make<InputSectionDescription>(tok);
963c42fe247SThomas Preud'homme       isd->sectionPatterns.push_back({{}, StringMatcher("*")});
9646c814931SFangrui Song       osec->commands.push_back(isd);
9652ec34544SRui Ueyama     }
9662ec34544SRui Ueyama   }
9672ec34544SRui Ueyama 
9682ec34544SRui Ueyama   if (consume(">"))
9696c814931SFangrui Song     osec->memoryRegionName = std::string(next());
9702ec34544SRui Ueyama 
9715d01a8beSGeorge Rimar   if (consume("AT")) {
9725d01a8beSGeorge Rimar     expect(">");
9736c814931SFangrui Song     osec->lmaRegionName = std::string(next());
9745d01a8beSGeorge Rimar   }
9755d01a8beSGeorge Rimar 
9766c814931SFangrui Song   if (osec->lmaExpr && !osec->lmaRegionName.empty())
9775d01a8beSGeorge Rimar     error("section can't have both LMA and a load region");
9785d01a8beSGeorge Rimar 
9796c814931SFangrui Song   osec->phdrs = readOutputSectionPhdrs();
9802ec34544SRui Ueyama 
9810810f16fSGeorge Rimar   if (peek() == "=" || peek().startswith("=")) {
9823837f427SRui Ueyama     inExpr = true;
9830810f16fSGeorge Rimar     consume("=");
9846c814931SFangrui Song     osec->filler = readFill();
9853837f427SRui Ueyama     inExpr = false;
9860810f16fSGeorge Rimar   }
9872ec34544SRui Ueyama 
9882ec34544SRui Ueyama   // Consume optional comma following output section command.
9892ec34544SRui Ueyama   consume(",");
9902ec34544SRui Ueyama 
9913837f427SRui Ueyama   if (script->referencedSymbols.size() > symbolsReferenced)
9926c814931SFangrui Song     osec->expressionsUseSymbols = true;
9933837f427SRui Ueyama   return cmd;
9942ec34544SRui Ueyama }
9952ec34544SRui Ueyama 
9960810f16fSGeorge Rimar // Reads a `=<fillexp>` expression and returns its value as a big-endian number.
9972ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html
9980810f16fSGeorge Rimar // We do not support using symbols in such expressions.
9992ec34544SRui Ueyama //
10008acbf1ccSRui Ueyama // When reading a hexstring, ld.bfd handles it as a blob of arbitrary
10018acbf1ccSRui Ueyama // size, while ld.gold always handles it as a 32-bit big-endian number.
10028acbf1ccSRui Ueyama // We are compatible with ld.gold because it's easier to implement.
1003bb7d2b17SGeorgii Rymar // Also, we require that expressions with operators must be wrapped into
1004bb7d2b17SGeorgii Rymar // round brackets. We did it to resolve the ambiguity when parsing scripts like:
1005bb7d2b17SGeorgii Rymar // SECTIONS { .foo : { ... } =120+3 /DISCARD/ : { ... } }
10060810f16fSGeorge Rimar std::array<uint8_t, 4> ScriptParser::readFill() {
1007bb7d2b17SGeorgii Rymar   uint64_t value = readPrimary()().val;
10083837f427SRui Ueyama   if (value > UINT32_MAX)
10090810f16fSGeorge Rimar     setError("filler expression result does not fit 32-bit: 0x" +
10103837f427SRui Ueyama              Twine::utohexstr(value));
1011b58079d4SRui Ueyama 
10123837f427SRui Ueyama   std::array<uint8_t, 4> buf;
10133837f427SRui Ueyama   write32be(buf.data(), (uint32_t)value);
10143837f427SRui Ueyama   return buf;
10152ec34544SRui Ueyama }
10162ec34544SRui Ueyama 
10173837f427SRui Ueyama SymbolAssignment *ScriptParser::readProvideHidden(bool provide, bool hidden) {
10182ec34544SRui Ueyama   expect("(");
10193837f427SRui Ueyama   SymbolAssignment *cmd = readSymbolAssignment(next());
10203837f427SRui Ueyama   cmd->provide = provide;
10213837f427SRui Ueyama   cmd->hidden = hidden;
10222ec34544SRui Ueyama   expect(")");
10233837f427SRui Ueyama   return cmd;
10242ec34544SRui Ueyama }
10252ec34544SRui Ueyama 
10263837f427SRui Ueyama SymbolAssignment *ScriptParser::readAssignment(StringRef tok) {
1027d30a78b3SGeorge Rimar   // Assert expression returns Dot, so this is equal to ".=."
10283837f427SRui Ueyama   if (tok == "ASSERT")
1029d30a78b3SGeorge Rimar     return make<SymbolAssignment>(".", readAssert(), getCurrentLocation());
1030d30a78b3SGeorge Rimar 
10313837f427SRui Ueyama   size_t oldPos = pos;
10323837f427SRui Ueyama   SymbolAssignment *cmd = nullptr;
1033e88b76a9SGeorge Rimar   if (peek() == "=" || peek() == "+=")
10343837f427SRui Ueyama     cmd = readSymbolAssignment(tok);
10353837f427SRui Ueyama   else if (tok == "PROVIDE")
10363837f427SRui Ueyama     cmd = readProvideHidden(true, false);
10373837f427SRui Ueyama   else if (tok == "HIDDEN")
10383837f427SRui Ueyama     cmd = readProvideHidden(false, true);
10393837f427SRui Ueyama   else if (tok == "PROVIDE_HIDDEN")
10403837f427SRui Ueyama     cmd = readProvideHidden(true, true);
1041e88b76a9SGeorge Rimar 
10423837f427SRui Ueyama   if (cmd) {
10433837f427SRui Ueyama     cmd->commandString =
10443837f427SRui Ueyama         tok.str() + " " +
10453837f427SRui Ueyama         llvm::join(tokens.begin() + oldPos, tokens.begin() + pos, " ");
1046e88b76a9SGeorge Rimar     expect(";");
10472ec34544SRui Ueyama   }
10483837f427SRui Ueyama   return cmd;
10492ec34544SRui Ueyama }
10502ec34544SRui Ueyama 
10513837f427SRui Ueyama SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef name) {
1052e7a7ad13SFangrui Song   name = unquote(name);
10533837f427SRui Ueyama   StringRef op = next();
10543837f427SRui Ueyama   assert(op == "=" || op == "+=");
10553837f427SRui Ueyama   Expr e = readExpr();
10563837f427SRui Ueyama   if (op == "+=") {
10573837f427SRui Ueyama     std::string loc = getCurrentLocation();
10583837f427SRui Ueyama     e = [=] { return add(script->getSymbolValue(name, loc), e()); };
10592ec34544SRui Ueyama   }
10603837f427SRui Ueyama   return make<SymbolAssignment>(name, e, getCurrentLocation());
10612ec34544SRui Ueyama }
10622ec34544SRui Ueyama 
10632ec34544SRui Ueyama // This is an operator-precedence parser to parse a linker
10642ec34544SRui Ueyama // script expression.
10652ec34544SRui Ueyama Expr ScriptParser::readExpr() {
10662ec34544SRui Ueyama   // Our lexer is context-aware. Set the in-expression bit so that
10672ec34544SRui Ueyama   // they apply different tokenization rules.
10683837f427SRui Ueyama   bool orig = inExpr;
10693837f427SRui Ueyama   inExpr = true;
10703837f427SRui Ueyama   Expr e = readExpr1(readPrimary(), 0);
10713837f427SRui Ueyama   inExpr = orig;
10723837f427SRui Ueyama   return e;
10732ec34544SRui Ueyama }
10742ec34544SRui Ueyama 
10753837f427SRui Ueyama Expr ScriptParser::combine(StringRef op, Expr l, Expr r) {
10763837f427SRui Ueyama   if (op == "+")
10773837f427SRui Ueyama     return [=] { return add(l(), r()); };
10783837f427SRui Ueyama   if (op == "-")
10793837f427SRui Ueyama     return [=] { return sub(l(), r()); };
10803837f427SRui Ueyama   if (op == "*")
10813837f427SRui Ueyama     return [=] { return l().getValue() * r().getValue(); };
10823837f427SRui Ueyama   if (op == "/") {
10833837f427SRui Ueyama     std::string loc = getCurrentLocation();
10847b91e213SGeorge Rimar     return [=]() -> uint64_t {
10853837f427SRui Ueyama       if (uint64_t rv = r().getValue())
10863837f427SRui Ueyama         return l().getValue() / rv;
10873837f427SRui Ueyama       error(loc + ": division by zero");
1088067617f9SRui Ueyama       return 0;
10897b91e213SGeorge Rimar     };
10907b91e213SGeorge Rimar   }
10913837f427SRui Ueyama   if (op == "%") {
10923837f427SRui Ueyama     std::string loc = getCurrentLocation();
10937b91e213SGeorge Rimar     return [=]() -> uint64_t {
10943837f427SRui Ueyama       if (uint64_t rv = r().getValue())
10953837f427SRui Ueyama         return l().getValue() % rv;
10963837f427SRui Ueyama       error(loc + ": modulo by zero");
1097067617f9SRui Ueyama       return 0;
10987b91e213SGeorge Rimar     };
10997b91e213SGeorge Rimar   }
11003837f427SRui Ueyama   if (op == "<<")
11013837f427SRui Ueyama     return [=] { return l().getValue() << r().getValue(); };
11023837f427SRui Ueyama   if (op == ">>")
11033837f427SRui Ueyama     return [=] { return l().getValue() >> r().getValue(); };
11043837f427SRui Ueyama   if (op == "<")
11053837f427SRui Ueyama     return [=] { return l().getValue() < r().getValue(); };
11063837f427SRui Ueyama   if (op == ">")
11073837f427SRui Ueyama     return [=] { return l().getValue() > r().getValue(); };
11083837f427SRui Ueyama   if (op == ">=")
11093837f427SRui Ueyama     return [=] { return l().getValue() >= r().getValue(); };
11103837f427SRui Ueyama   if (op == "<=")
11113837f427SRui Ueyama     return [=] { return l().getValue() <= r().getValue(); };
11123837f427SRui Ueyama   if (op == "==")
11133837f427SRui Ueyama     return [=] { return l().getValue() == r().getValue(); };
11143837f427SRui Ueyama   if (op == "!=")
11153837f427SRui Ueyama     return [=] { return l().getValue() != r().getValue(); };
11163837f427SRui Ueyama   if (op == "||")
11173837f427SRui Ueyama     return [=] { return l().getValue() || r().getValue(); };
11183837f427SRui Ueyama   if (op == "&&")
11193837f427SRui Ueyama     return [=] { return l().getValue() && r().getValue(); };
11203837f427SRui Ueyama   if (op == "&")
11213837f427SRui Ueyama     return [=] { return bitAnd(l(), r()); };
11223837f427SRui Ueyama   if (op == "|")
11233837f427SRui Ueyama     return [=] { return bitOr(l(), r()); };
11242ec34544SRui Ueyama   llvm_unreachable("invalid operator");
11252ec34544SRui Ueyama }
11262ec34544SRui Ueyama 
11272ec34544SRui Ueyama // This is a part of the operator-precedence parser. This function
11282ec34544SRui Ueyama // assumes that the remaining token stream starts with an operator.
11293837f427SRui Ueyama Expr ScriptParser::readExpr1(Expr lhs, int minPrec) {
1130b8a59c8aSBob Haarman   while (!atEOF() && !errorCount()) {
11312ec34544SRui Ueyama     // Read an operator and an expression.
11323837f427SRui Ueyama     StringRef op1 = peek();
11333837f427SRui Ueyama     if (precedence(op1) < minPrec)
11342ec34544SRui Ueyama       break;
1135*b0d6dd39SFangrui Song     if (consume("?"))
1136*b0d6dd39SFangrui Song       return readTernary(lhs);
11372ec34544SRui Ueyama     skip();
11383837f427SRui Ueyama     Expr rhs = readPrimary();
11392ec34544SRui Ueyama 
11402ec34544SRui Ueyama     // Evaluate the remaining part of the expression first if the
11412ec34544SRui Ueyama     // next operator has greater precedence than the previous one.
11422ec34544SRui Ueyama     // For example, if we have read "+" and "3", and if the next
11432ec34544SRui Ueyama     // operator is "*", then we'll evaluate 3 * ... part first.
11442ec34544SRui Ueyama     while (!atEOF()) {
11453837f427SRui Ueyama       StringRef op2 = peek();
11463837f427SRui Ueyama       if (precedence(op2) <= precedence(op1))
11472ec34544SRui Ueyama         break;
11483837f427SRui Ueyama       rhs = readExpr1(rhs, precedence(op2));
11492ec34544SRui Ueyama     }
11502ec34544SRui Ueyama 
11513837f427SRui Ueyama     lhs = combine(op1, lhs, rhs);
11522ec34544SRui Ueyama   }
11533837f427SRui Ueyama   return lhs;
11542ec34544SRui Ueyama }
11552ec34544SRui Ueyama 
11565fb17128SGeorge Rimar Expr ScriptParser::getPageSize() {
11573837f427SRui Ueyama   std::string location = getCurrentLocation();
11585fb17128SGeorge Rimar   return [=]() -> uint64_t {
11593837f427SRui Ueyama     if (target)
11603837f427SRui Ueyama       return config->commonPageSize;
11613837f427SRui Ueyama     error(location + ": unable to calculate page size");
11625fb17128SGeorge Rimar     return 4096; // Return a dummy value.
11635fb17128SGeorge Rimar   };
11645fb17128SGeorge Rimar }
11655fb17128SGeorge Rimar 
11665fb17128SGeorge Rimar Expr ScriptParser::readConstant() {
11673837f427SRui Ueyama   StringRef s = readParenLiteral();
11683837f427SRui Ueyama   if (s == "COMMONPAGESIZE")
11695fb17128SGeorge Rimar     return getPageSize();
11703837f427SRui Ueyama   if (s == "MAXPAGESIZE")
11713837f427SRui Ueyama     return [] { return config->maxPageSize; };
11723837f427SRui Ueyama   setError("unknown constant: " + s);
1173b068b037SGeorge Rimar   return [] { return 0; };
11742ec34544SRui Ueyama }
11752ec34544SRui Ueyama 
11765c65088fSRui Ueyama // Parses Tok as an integer. It recognizes hexadecimal (prefixed with
11775c65088fSRui Ueyama // "0x" or suffixed with "H") and decimal numbers. Decimal numbers may
11785c65088fSRui Ueyama // have "K" (Ki) or "M" (Mi) suffixes.
11793837f427SRui Ueyama static Optional<uint64_t> parseInt(StringRef tok) {
11802ec34544SRui Ueyama   // Hexadecimal
11813837f427SRui Ueyama   uint64_t val;
11823c6f8ca7SMartin Storsjö   if (tok.startswith_insensitive("0x")) {
11833837f427SRui Ueyama     if (!to_integer(tok.substr(2), val, 16))
11844092016bSRui Ueyama       return None;
11853837f427SRui Ueyama     return val;
11864092016bSRui Ueyama   }
11873c6f8ca7SMartin Storsjö   if (tok.endswith_insensitive("H")) {
11883837f427SRui Ueyama     if (!to_integer(tok.drop_back(), val, 16))
11894092016bSRui Ueyama       return None;
11903837f427SRui Ueyama     return val;
11914092016bSRui Ueyama   }
11922ec34544SRui Ueyama 
11932ec34544SRui Ueyama   // Decimal
11943c6f8ca7SMartin Storsjö   if (tok.endswith_insensitive("K")) {
11953837f427SRui Ueyama     if (!to_integer(tok.drop_back(), val, 10))
11965c65088fSRui Ueyama       return None;
11973837f427SRui Ueyama     return val * 1024;
11982ec34544SRui Ueyama   }
11993c6f8ca7SMartin Storsjö   if (tok.endswith_insensitive("M")) {
12003837f427SRui Ueyama     if (!to_integer(tok.drop_back(), val, 10))
12015c65088fSRui Ueyama       return None;
12023837f427SRui Ueyama     return val * 1024 * 1024;
12035c65088fSRui Ueyama   }
12043837f427SRui Ueyama   if (!to_integer(tok, val, 10))
12055c65088fSRui Ueyama     return None;
12063837f427SRui Ueyama   return val;
12072ec34544SRui Ueyama }
12082ec34544SRui Ueyama 
12093837f427SRui Ueyama ByteCommand *ScriptParser::readByteCommand(StringRef tok) {
12103837f427SRui Ueyama   int size = StringSwitch<int>(tok)
12112ec34544SRui Ueyama                  .Case("BYTE", 1)
12122ec34544SRui Ueyama                  .Case("SHORT", 2)
12132ec34544SRui Ueyama                  .Case("LONG", 4)
12142ec34544SRui Ueyama                  .Case("QUAD", 8)
12152ec34544SRui Ueyama                  .Default(-1);
12163837f427SRui Ueyama   if (size == -1)
12172ec34544SRui Ueyama     return nullptr;
121884bcabcbSGeorge Rimar 
12193837f427SRui Ueyama   size_t oldPos = pos;
12203837f427SRui Ueyama   Expr e = readParenExpr();
12213837f427SRui Ueyama   std::string commandString =
12223837f427SRui Ueyama       tok.str() + " " +
12233837f427SRui Ueyama       llvm::join(tokens.begin() + oldPos, tokens.begin() + pos, " ");
12243837f427SRui Ueyama   return make<ByteCommand>(e, size, commandString);
12252ec34544SRui Ueyama }
12262ec34544SRui Ueyama 
1227dbd0ad33SPeter Smith static llvm::Optional<uint64_t> parseFlag(StringRef tok) {
1228dbd0ad33SPeter Smith   if (llvm::Optional<uint64_t> asInt = parseInt(tok))
1229dbd0ad33SPeter Smith     return asInt;
1230dbd0ad33SPeter Smith #define CASE_ENT(enum) #enum, ELF::enum
1231dbd0ad33SPeter Smith   return StringSwitch<llvm::Optional<uint64_t>>(tok)
1232dbd0ad33SPeter Smith       .Case(CASE_ENT(SHF_WRITE))
1233dbd0ad33SPeter Smith       .Case(CASE_ENT(SHF_ALLOC))
1234dbd0ad33SPeter Smith       .Case(CASE_ENT(SHF_EXECINSTR))
1235dbd0ad33SPeter Smith       .Case(CASE_ENT(SHF_MERGE))
1236dbd0ad33SPeter Smith       .Case(CASE_ENT(SHF_STRINGS))
1237dbd0ad33SPeter Smith       .Case(CASE_ENT(SHF_INFO_LINK))
1238dbd0ad33SPeter Smith       .Case(CASE_ENT(SHF_LINK_ORDER))
1239dbd0ad33SPeter Smith       .Case(CASE_ENT(SHF_OS_NONCONFORMING))
1240dbd0ad33SPeter Smith       .Case(CASE_ENT(SHF_GROUP))
1241dbd0ad33SPeter Smith       .Case(CASE_ENT(SHF_TLS))
1242dbd0ad33SPeter Smith       .Case(CASE_ENT(SHF_COMPRESSED))
1243dbd0ad33SPeter Smith       .Case(CASE_ENT(SHF_EXCLUDE))
1244dbd0ad33SPeter Smith       .Case(CASE_ENT(SHF_ARM_PURECODE))
1245dbd0ad33SPeter Smith       .Default(None);
1246dbd0ad33SPeter Smith #undef CASE_ENT
1247dbd0ad33SPeter Smith }
1248dbd0ad33SPeter Smith 
1249dbd0ad33SPeter Smith // Reads the '(' <flags> ')' list of section flags in
1250dbd0ad33SPeter Smith // INPUT_SECTION_FLAGS '(' <flags> ')' in the
1251dbd0ad33SPeter Smith // following form:
1252dbd0ad33SPeter Smith // <flags> ::= <flag>
1253dbd0ad33SPeter Smith //           | <flags> & flag
1254dbd0ad33SPeter Smith // <flag>  ::= Recognized Flag Name, or Integer value of flag.
1255dbd0ad33SPeter Smith // If the first character of <flag> is a ! then this means without flag,
1256dbd0ad33SPeter Smith // otherwise with flag.
1257dbd0ad33SPeter Smith // Example: SHF_EXECINSTR & !SHF_WRITE means with flag SHF_EXECINSTR and
1258dbd0ad33SPeter Smith // without flag SHF_WRITE.
1259dbd0ad33SPeter Smith std::pair<uint64_t, uint64_t> ScriptParser::readInputSectionFlags() {
1260dbd0ad33SPeter Smith    uint64_t withFlags = 0;
1261dbd0ad33SPeter Smith    uint64_t withoutFlags = 0;
1262dbd0ad33SPeter Smith    expect("(");
1263dbd0ad33SPeter Smith    while (!errorCount()) {
1264dbd0ad33SPeter Smith     StringRef tok = unquote(next());
1265dbd0ad33SPeter Smith     bool without = tok.consume_front("!");
1266dbd0ad33SPeter Smith     if (llvm::Optional<uint64_t> flag = parseFlag(tok)) {
1267dbd0ad33SPeter Smith       if (without)
1268dbd0ad33SPeter Smith         withoutFlags |= *flag;
1269dbd0ad33SPeter Smith       else
1270dbd0ad33SPeter Smith         withFlags |= *flag;
1271dbd0ad33SPeter Smith     } else {
1272dbd0ad33SPeter Smith       setError("unrecognised flag: " + tok);
1273dbd0ad33SPeter Smith     }
1274dbd0ad33SPeter Smith     if (consume(")"))
1275dbd0ad33SPeter Smith       break;
1276dbd0ad33SPeter Smith     if (!consume("&")) {
1277dbd0ad33SPeter Smith       next();
1278dbd0ad33SPeter Smith       setError("expected & or )");
1279dbd0ad33SPeter Smith     }
1280dbd0ad33SPeter Smith   }
1281dbd0ad33SPeter Smith   return std::make_pair(withFlags, withoutFlags);
1282dbd0ad33SPeter Smith }
1283dbd0ad33SPeter Smith 
12842ec34544SRui Ueyama StringRef ScriptParser::readParenLiteral() {
12852ec34544SRui Ueyama   expect("(");
12863837f427SRui Ueyama   bool orig = inExpr;
12873837f427SRui Ueyama   inExpr = false;
12883837f427SRui Ueyama   StringRef tok = next();
12893837f427SRui Ueyama   inExpr = orig;
12902ec34544SRui Ueyama   expect(")");
12913837f427SRui Ueyama   return tok;
12922ec34544SRui Ueyama }
12932ec34544SRui Ueyama 
12949e9c86fdSFangrui Song static void checkIfExists(const OutputSection &osec, StringRef location) {
12959e9c86fdSFangrui Song   if (osec.location.empty() && script->errorOnMissingSection)
12969e9c86fdSFangrui Song     error(location + ": undefined section " + osec.name);
129705c4f67cSRafael Espindola }
129805c4f67cSRafael Espindola 
1299e4f385d8SFangrui Song static bool isValidSymbolName(StringRef s) {
1300e4f385d8SFangrui Song   auto valid = [](char c) {
1301e4f385d8SFangrui Song     return isAlnum(c) || c == '$' || c == '.' || c == '_';
1302e4f385d8SFangrui Song   };
1303e4f385d8SFangrui Song   return !s.empty() && !isDigit(s[0]) && llvm::all_of(s, valid);
1304e4f385d8SFangrui Song }
1305e4f385d8SFangrui Song 
13062ec34544SRui Ueyama Expr ScriptParser::readPrimary() {
13072ec34544SRui Ueyama   if (peek() == "(")
13082ec34544SRui Ueyama     return readParenExpr();
13092ec34544SRui Ueyama 
13105c65088fSRui Ueyama   if (consume("~")) {
13113837f427SRui Ueyama     Expr e = readPrimary();
13123837f427SRui Ueyama     return [=] { return ~e().getValue(); };
13132ec34544SRui Ueyama   }
13146f1d954eSHafiz Abid Qadeer   if (consume("!")) {
13153837f427SRui Ueyama     Expr e = readPrimary();
13163837f427SRui Ueyama     return [=] { return !e().getValue(); };
13176f1d954eSHafiz Abid Qadeer   }
13185c65088fSRui Ueyama   if (consume("-")) {
13193837f427SRui Ueyama     Expr e = readPrimary();
13203837f427SRui Ueyama     return [=] { return -e().getValue(); };
13212ec34544SRui Ueyama   }
13222ec34544SRui Ueyama 
13233837f427SRui Ueyama   StringRef tok = next();
13243837f427SRui Ueyama   std::string location = getCurrentLocation();
13255c65088fSRui Ueyama 
13262ec34544SRui Ueyama   // Built-in functions are parsed here.
13272ec34544SRui Ueyama   // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html.
13283837f427SRui Ueyama   if (tok == "ABSOLUTE") {
13293837f427SRui Ueyama     Expr inner = readParenExpr();
13302ec34544SRui Ueyama     return [=] {
13313837f427SRui Ueyama       ExprValue i = inner();
13323837f427SRui Ueyama       i.forceAbsolute = true;
13333837f427SRui Ueyama       return i;
13342ec34544SRui Ueyama     };
13352ec34544SRui Ueyama   }
13363837f427SRui Ueyama   if (tok == "ADDR") {
13373837f427SRui Ueyama     StringRef name = readParenLiteral();
13386c814931SFangrui Song     OutputSection *osec = &script->getOrCreateOutputSection(name)->osec;
13399e9c86fdSFangrui Song     osec->usedInExpression = true;
134041c7ab4aSGeorge Rimar     return [=]() -> ExprValue {
13419e9c86fdSFangrui Song       checkIfExists(*osec, location);
13429e9c86fdSFangrui Song       return {osec, false, 0, location};
134341c7ab4aSGeorge Rimar     };
13442ec34544SRui Ueyama   }
13453837f427SRui Ueyama   if (tok == "ALIGN") {
13462ec34544SRui Ueyama     expect("(");
13473837f427SRui Ueyama     Expr e = readExpr();
1348f22ec9ddSGeorge Rimar     if (consume(")")) {
13493837f427SRui Ueyama       e = checkAlignment(e, location);
13503837f427SRui Ueyama       return [=] { return alignTo(script->getDot(), e().getValue()); };
1351f22ec9ddSGeorge Rimar     }
1352b579c439SRui Ueyama     expect(",");
13533837f427SRui Ueyama     Expr e2 = checkAlignment(readExpr(), location);
13542ec34544SRui Ueyama     expect(")");
13553c6de1a6SPetr Hosek     return [=] {
13563837f427SRui Ueyama       ExprValue v = e();
13573837f427SRui Ueyama       v.alignment = e2().getValue();
13583837f427SRui Ueyama       return v;
13593c6de1a6SPetr Hosek     };
13602ec34544SRui Ueyama   }
13613837f427SRui Ueyama   if (tok == "ALIGNOF") {
13623837f427SRui Ueyama     StringRef name = readParenLiteral();
13636c814931SFangrui Song     OutputSection *osec = &script->getOrCreateOutputSection(name)->osec;
1364617e2f98SRui Ueyama     return [=] {
13659e9c86fdSFangrui Song       checkIfExists(*osec, location);
13669e9c86fdSFangrui Song       return osec->alignment;
1367617e2f98SRui Ueyama     };
13682ec34544SRui Ueyama   }
13693837f427SRui Ueyama   if (tok == "ASSERT")
1370d30a78b3SGeorge Rimar     return readAssert();
13713837f427SRui Ueyama   if (tok == "CONSTANT")
13725fb17128SGeorge Rimar     return readConstant();
13733837f427SRui Ueyama   if (tok == "DATA_SEGMENT_ALIGN") {
13742ec34544SRui Ueyama     expect("(");
13753837f427SRui Ueyama     Expr e = readExpr();
13762ec34544SRui Ueyama     expect(",");
13772ec34544SRui Ueyama     readExpr();
13782ec34544SRui Ueyama     expect(")");
13795a44980fSFangrui Song     seenDataAlign = true;
138060833f6eSGeorge Rimar     return [=] {
13813837f427SRui Ueyama       return alignTo(script->getDot(), std::max((uint64_t)1, e().getValue()));
138260833f6eSGeorge Rimar     };
13832ec34544SRui Ueyama   }
13843837f427SRui Ueyama   if (tok == "DATA_SEGMENT_END") {
13852ec34544SRui Ueyama     expect("(");
13862ec34544SRui Ueyama     expect(".");
13872ec34544SRui Ueyama     expect(")");
13883837f427SRui Ueyama     return [] { return script->getDot(); };
13892ec34544SRui Ueyama   }
13903837f427SRui Ueyama   if (tok == "DATA_SEGMENT_RELRO_END") {
13912ec34544SRui Ueyama     // GNU linkers implements more complicated logic to handle
13922ec34544SRui Ueyama     // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and
13932ec34544SRui Ueyama     // just align to the next page boundary for simplicity.
13942ec34544SRui Ueyama     expect("(");
13952ec34544SRui Ueyama     readExpr();
13962ec34544SRui Ueyama     expect(",");
13972ec34544SRui Ueyama     readExpr();
13982ec34544SRui Ueyama     expect(")");
13995a44980fSFangrui Song     seenRelroEnd = true;
14003837f427SRui Ueyama     Expr e = getPageSize();
14013837f427SRui Ueyama     return [=] { return alignTo(script->getDot(), e().getValue()); };
14022ec34544SRui Ueyama   }
14033837f427SRui Ueyama   if (tok == "DEFINED") {
1404e7a7ad13SFangrui Song     StringRef name = unquote(readParenLiteral());
14051f166edeSHafiz Abid Qadeer     return [=] {
14061f166edeSHafiz Abid Qadeer       Symbol *b = symtab->find(name);
14071f166edeSHafiz Abid Qadeer       return (b && b->isDefined()) ? 1 : 0;
14081f166edeSHafiz Abid Qadeer     };
14092ec34544SRui Ueyama   }
14103837f427SRui Ueyama   if (tok == "LENGTH") {
14113837f427SRui Ueyama     StringRef name = readParenLiteral();
14123837f427SRui Ueyama     if (script->memoryRegions.count(name) == 0) {
14133837f427SRui Ueyama       setError("memory region not defined: " + name);
1414b068b037SGeorge Rimar       return [] { return 0; };
1415b068b037SGeorge Rimar     }
141692b5b980SFangrui Song     return script->memoryRegions[name]->length;
141791b95b61SRui Ueyama   }
14183837f427SRui Ueyama   if (tok == "LOADADDR") {
14193837f427SRui Ueyama     StringRef name = readParenLiteral();
14206c814931SFangrui Song     OutputSection *osec = &script->getOrCreateOutputSection(name)->osec;
14219e9c86fdSFangrui Song     osec->usedInExpression = true;
1422617e2f98SRui Ueyama     return [=] {
14239e9c86fdSFangrui Song       checkIfExists(*osec, location);
14249e9c86fdSFangrui Song       return osec->getLMA();
1425617e2f98SRui Ueyama     };
14262ec34544SRui Ueyama   }
1427fa1145a8SIsaac Richter   if (tok == "LOG2CEIL") {
1428fa1145a8SIsaac Richter     expect("(");
1429fa1145a8SIsaac Richter     Expr a = readExpr();
1430fa1145a8SIsaac Richter     expect(")");
1431fa1145a8SIsaac Richter     return [=] {
1432fa1145a8SIsaac Richter       // LOG2CEIL(0) is defined to be 0.
1433fa1145a8SIsaac Richter       return llvm::Log2_64_Ceil(std::max(a().getValue(), UINT64_C(1)));
1434fa1145a8SIsaac Richter     };
1435fa1145a8SIsaac Richter   }
14363837f427SRui Ueyama   if (tok == "MAX" || tok == "MIN") {
1437fd11560fSGeorge Rimar     expect("(");
14383837f427SRui Ueyama     Expr a = readExpr();
1439fd11560fSGeorge Rimar     expect(",");
14403837f427SRui Ueyama     Expr b = readExpr();
1441fd11560fSGeorge Rimar     expect(")");
14423837f427SRui Ueyama     if (tok == "MIN")
14433837f427SRui Ueyama       return [=] { return std::min(a().getValue(), b().getValue()); };
14443837f427SRui Ueyama     return [=] { return std::max(a().getValue(), b().getValue()); };
1445fd11560fSGeorge Rimar   }
14463837f427SRui Ueyama   if (tok == "ORIGIN") {
14473837f427SRui Ueyama     StringRef name = readParenLiteral();
14483837f427SRui Ueyama     if (script->memoryRegions.count(name) == 0) {
14493837f427SRui Ueyama       setError("memory region not defined: " + name);
1450b068b037SGeorge Rimar       return [] { return 0; };
1451b068b037SGeorge Rimar     }
145292b5b980SFangrui Song     return script->memoryRegions[name]->origin;
145391b95b61SRui Ueyama   }
14543837f427SRui Ueyama   if (tok == "SEGMENT_START") {
14552ec34544SRui Ueyama     expect("(");
14562ec34544SRui Ueyama     skip();
14572ec34544SRui Ueyama     expect(",");
14583837f427SRui Ueyama     Expr e = readExpr();
14592ec34544SRui Ueyama     expect(")");
14603837f427SRui Ueyama     return [=] { return e(); };
14612ec34544SRui Ueyama   }
14623837f427SRui Ueyama   if (tok == "SIZEOF") {
14633837f427SRui Ueyama     StringRef name = readParenLiteral();
14646c814931SFangrui Song     OutputSection *cmd = &script->getOrCreateOutputSection(name)->osec;
146505c4f67cSRafael Espindola     // Linker script does not create an output section if its content is empty.
146605c4f67cSRafael Espindola     // We want to allow SIZEOF(.foo) where .foo is a section which happened to
146705c4f67cSRafael Espindola     // be empty.
14683837f427SRui Ueyama     return [=] { return cmd->size; };
14692ec34544SRui Ueyama   }
14703837f427SRui Ueyama   if (tok == "SIZEOF_HEADERS")
147107837b8fSFangrui Song     return [=] { return elf::getHeaderSize(); };
14722ec34544SRui Ueyama 
14734eb2eccbSRui Ueyama   // Tok is the dot.
14743837f427SRui Ueyama   if (tok == ".")
14753837f427SRui Ueyama     return [=] { return script->getSymbolValue(tok, location); };
14764eb2eccbSRui Ueyama 
14772ec34544SRui Ueyama   // Tok is a literal number.
14783837f427SRui Ueyama   if (Optional<uint64_t> val = parseInt(tok))
14793837f427SRui Ueyama     return [=] { return *val; };
14802ec34544SRui Ueyama 
14812ec34544SRui Ueyama   // Tok is a symbol name.
14822bf06d93SFangrui Song   if (tok.startswith("\""))
1483e7a7ad13SFangrui Song     tok = unquote(tok);
14842bf06d93SFangrui Song   else if (!isValidSymbolName(tok))
14853837f427SRui Ueyama     setError("malformed number: " + tok);
14863837f427SRui Ueyama   script->referencedSymbols.push_back(tok);
14873837f427SRui Ueyama   return [=] { return script->getSymbolValue(tok, location); };
14882ec34544SRui Ueyama }
14892ec34544SRui Ueyama 
14903837f427SRui Ueyama Expr ScriptParser::readTernary(Expr cond) {
14913837f427SRui Ueyama   Expr l = readExpr();
14922ec34544SRui Ueyama   expect(":");
14933837f427SRui Ueyama   Expr r = readExpr();
14943837f427SRui Ueyama   return [=] { return cond().getValue() ? l() : r(); };
14952ec34544SRui Ueyama }
14962ec34544SRui Ueyama 
14972ec34544SRui Ueyama Expr ScriptParser::readParenExpr() {
14982ec34544SRui Ueyama   expect("(");
14993837f427SRui Ueyama   Expr e = readExpr();
15002ec34544SRui Ueyama   expect(")");
15013837f427SRui Ueyama   return e;
15022ec34544SRui Ueyama }
15032ec34544SRui Ueyama 
1504a1c2ee01SFangrui Song SmallVector<StringRef, 0> ScriptParser::readOutputSectionPhdrs() {
1505a1c2ee01SFangrui Song   SmallVector<StringRef, 0> phdrs;
1506b8a59c8aSBob Haarman   while (!errorCount() && peek().startswith(":")) {
15073837f427SRui Ueyama     StringRef tok = next();
15083837f427SRui Ueyama     phdrs.push_back((tok.size() == 1) ? next() : tok.substr(1));
15092ec34544SRui Ueyama   }
15103837f427SRui Ueyama   return phdrs;
15112ec34544SRui Ueyama }
15122ec34544SRui Ueyama 
15132ec34544SRui Ueyama // Read a program header type name. The next token must be a
15142ec34544SRui Ueyama // name of a program header type or a constant (e.g. "0x3").
15152ec34544SRui Ueyama unsigned ScriptParser::readPhdrType() {
15163837f427SRui Ueyama   StringRef tok = next();
15173837f427SRui Ueyama   if (Optional<uint64_t> val = parseInt(tok))
15183837f427SRui Ueyama     return *val;
15192ec34544SRui Ueyama 
15203837f427SRui Ueyama   unsigned ret = StringSwitch<unsigned>(tok)
15212ec34544SRui Ueyama                      .Case("PT_NULL", PT_NULL)
15222ec34544SRui Ueyama                      .Case("PT_LOAD", PT_LOAD)
15232ec34544SRui Ueyama                      .Case("PT_DYNAMIC", PT_DYNAMIC)
15242ec34544SRui Ueyama                      .Case("PT_INTERP", PT_INTERP)
15252ec34544SRui Ueyama                      .Case("PT_NOTE", PT_NOTE)
15262ec34544SRui Ueyama                      .Case("PT_SHLIB", PT_SHLIB)
15272ec34544SRui Ueyama                      .Case("PT_PHDR", PT_PHDR)
15282ec34544SRui Ueyama                      .Case("PT_TLS", PT_TLS)
15292ec34544SRui Ueyama                      .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME)
15302ec34544SRui Ueyama                      .Case("PT_GNU_STACK", PT_GNU_STACK)
15312ec34544SRui Ueyama                      .Case("PT_GNU_RELRO", PT_GNU_RELRO)
15322ec34544SRui Ueyama                      .Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE)
15332ec34544SRui Ueyama                      .Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED)
15342ec34544SRui Ueyama                      .Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA)
15352ec34544SRui Ueyama                      .Default(-1);
15362ec34544SRui Ueyama 
15373837f427SRui Ueyama   if (ret == (unsigned)-1) {
15383837f427SRui Ueyama     setError("invalid program header type: " + tok);
15392ec34544SRui Ueyama     return PT_NULL;
15402ec34544SRui Ueyama   }
15413837f427SRui Ueyama   return ret;
15422ec34544SRui Ueyama }
15432ec34544SRui Ueyama 
15442ec34544SRui Ueyama // Reads an anonymous version declaration.
15452ec34544SRui Ueyama void ScriptParser::readAnonymousDeclaration() {
154664038ef8SFangrui Song   SmallVector<SymbolVersion, 0> locals;
154764038ef8SFangrui Song   SmallVector<SymbolVersion, 0> globals;
15483837f427SRui Ueyama   std::tie(locals, globals) = readSymbols();
1549e28a70daSFangrui Song   for (const SymbolVersion &pat : locals)
155000809c88SFangrui Song     config->versionDefinitions[VER_NDX_LOCAL].localPatterns.push_back(pat);
1551e28a70daSFangrui Song   for (const SymbolVersion &pat : globals)
155200809c88SFangrui Song     config->versionDefinitions[VER_NDX_GLOBAL].nonLocalPatterns.push_back(pat);
15532ec34544SRui Ueyama 
15542ec34544SRui Ueyama   expect(";");
15552ec34544SRui Ueyama }
15562ec34544SRui Ueyama 
15572ec34544SRui Ueyama // Reads a non-anonymous version definition,
15582ec34544SRui Ueyama // e.g. "VerStr { global: foo; bar; local: *; };".
15593837f427SRui Ueyama void ScriptParser::readVersionDeclaration(StringRef verStr) {
15602ec34544SRui Ueyama   // Read a symbol list.
156164038ef8SFangrui Song   SmallVector<SymbolVersion, 0> locals;
156264038ef8SFangrui Song   SmallVector<SymbolVersion, 0> globals;
15633837f427SRui Ueyama   std::tie(locals, globals) = readSymbols();
15642ec34544SRui Ueyama 
15652ec34544SRui Ueyama   // Create a new version definition and add that to the global symbols.
15663837f427SRui Ueyama   VersionDefinition ver;
15673837f427SRui Ueyama   ver.name = verStr;
156800809c88SFangrui Song   ver.nonLocalPatterns = std::move(globals);
156900809c88SFangrui Song   ver.localPatterns = std::move(locals);
1570e28a70daSFangrui Song   ver.id = config->versionDefinitions.size();
15713837f427SRui Ueyama   config->versionDefinitions.push_back(ver);
15722ec34544SRui Ueyama 
15732ec34544SRui Ueyama   // Each version may have a parent version. For example, "Ver2"
15742ec34544SRui Ueyama   // defined as "Ver2 { global: foo; local: *; } Ver1;" has "Ver1"
15752ec34544SRui Ueyama   // as a parent. This version hierarchy is, probably against your
15762ec34544SRui Ueyama   // instinct, purely for hint; the runtime doesn't care about it
15772ec34544SRui Ueyama   // at all. In LLD, we simply ignore it.
15785f380403SFangrui Song   if (next() != ";")
15792ec34544SRui Ueyama     expect(";");
15802ec34544SRui Ueyama }
15812ec34544SRui Ueyama 
158249279ca1SFangrui Song bool elf::hasWildcard(StringRef s) {
15833837f427SRui Ueyama   return s.find_first_of("?*[") != StringRef::npos;
15841e77ad14SRui Ueyama }
15851e77ad14SRui Ueyama 
15862ec34544SRui Ueyama // Reads a list of symbols, e.g. "{ global: foo; bar; local: *; };".
158764038ef8SFangrui Song std::pair<SmallVector<SymbolVersion, 0>, SmallVector<SymbolVersion, 0>>
15882ec34544SRui Ueyama ScriptParser::readSymbols() {
158964038ef8SFangrui Song   SmallVector<SymbolVersion, 0> locals;
159064038ef8SFangrui Song   SmallVector<SymbolVersion, 0> globals;
159164038ef8SFangrui Song   SmallVector<SymbolVersion, 0> *v = &globals;
15922ec34544SRui Ueyama 
1593b8a59c8aSBob Haarman   while (!errorCount()) {
15942ec34544SRui Ueyama     if (consume("}"))
15952ec34544SRui Ueyama       break;
15962ec34544SRui Ueyama     if (consumeLabel("local")) {
15973837f427SRui Ueyama       v = &locals;
15982ec34544SRui Ueyama       continue;
15992ec34544SRui Ueyama     }
16002ec34544SRui Ueyama     if (consumeLabel("global")) {
16013837f427SRui Ueyama       v = &globals;
16022ec34544SRui Ueyama       continue;
16032ec34544SRui Ueyama     }
16042ec34544SRui Ueyama 
16052ec34544SRui Ueyama     if (consume("extern")) {
160664038ef8SFangrui Song       SmallVector<SymbolVersion, 0> ext = readVersionExtern();
16073837f427SRui Ueyama       v->insert(v->end(), ext.begin(), ext.end());
16082ec34544SRui Ueyama     } else {
16093837f427SRui Ueyama       StringRef tok = next();
16103837f427SRui Ueyama       v->push_back({unquote(tok), false, hasWildcard(tok)});
16112ec34544SRui Ueyama     }
16122ec34544SRui Ueyama     expect(";");
16132ec34544SRui Ueyama   }
16143837f427SRui Ueyama   return {locals, globals};
16152ec34544SRui Ueyama }
16162ec34544SRui Ueyama 
16172ec34544SRui Ueyama // Reads an "extern C++" directive, e.g.,
16182ec34544SRui Ueyama // "extern "C++" { ns::*; "f(int, double)"; };"
161917324d8bSRui Ueyama //
162017324d8bSRui Ueyama // The last semicolon is optional. E.g. this is OK:
162117324d8bSRui Ueyama // "extern "C++" { ns::*; "f(int, double)" };"
162264038ef8SFangrui Song SmallVector<SymbolVersion, 0> ScriptParser::readVersionExtern() {
16233837f427SRui Ueyama   StringRef tok = next();
16243837f427SRui Ueyama   bool isCXX = tok == "\"C++\"";
16253837f427SRui Ueyama   if (!isCXX && tok != "\"C\"")
16262ec34544SRui Ueyama     setError("Unknown language");
16272ec34544SRui Ueyama   expect("{");
16282ec34544SRui Ueyama 
162964038ef8SFangrui Song   SmallVector<SymbolVersion, 0> ret;
1630b8a59c8aSBob Haarman   while (!errorCount() && peek() != "}") {
16313837f427SRui Ueyama     StringRef tok = next();
16323837f427SRui Ueyama     ret.push_back(
16333837f427SRui Ueyama         {unquote(tok), isCXX, !tok.startswith("\"") && hasWildcard(tok)});
163417324d8bSRui Ueyama     if (consume("}"))
16353837f427SRui Ueyama       return ret;
16362ec34544SRui Ueyama     expect(";");
16372ec34544SRui Ueyama   }
16382ec34544SRui Ueyama 
16392ec34544SRui Ueyama   expect("}");
16403837f427SRui Ueyama   return ret;
16412ec34544SRui Ueyama }
16422ec34544SRui Ueyama 
164392b5b980SFangrui Song Expr ScriptParser::readMemoryAssignment(StringRef s1, StringRef s2,
16443837f427SRui Ueyama                                         StringRef s3) {
16453837f427SRui Ueyama   if (!consume(s1) && !consume(s2) && !consume(s3)) {
16463837f427SRui Ueyama     setError("expected one of: " + s1 + ", " + s2 + ", or " + s3);
164792b5b980SFangrui Song     return [] { return 0; };
16482ec34544SRui Ueyama   }
16492ec34544SRui Ueyama   expect("=");
165092b5b980SFangrui Song   return readExpr();
16512ec34544SRui Ueyama }
16522ec34544SRui Ueyama 
16532ec34544SRui Ueyama // Parse the MEMORY command as specified in:
16542ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/MEMORY.html
16552ec34544SRui Ueyama //
16562ec34544SRui Ueyama // MEMORY { name [(attr)] : ORIGIN = origin, LENGTH = len ... }
16572ec34544SRui Ueyama void ScriptParser::readMemory() {
16582ec34544SRui Ueyama   expect("{");
1659b8a59c8aSBob Haarman   while (!errorCount() && !consume("}")) {
16603837f427SRui Ueyama     StringRef tok = next();
16613837f427SRui Ueyama     if (tok == "INCLUDE") {
16622e9d40d5SRui Ueyama       readInclude();
16632e9d40d5SRui Ueyama       continue;
16642e9d40d5SRui Ueyama     }
16652ec34544SRui Ueyama 
16663837f427SRui Ueyama     uint32_t flags = 0;
16678cdf1c1eSIgor Kudrin     uint32_t invFlags = 0;
16683837f427SRui Ueyama     uint32_t negFlags = 0;
16698cdf1c1eSIgor Kudrin     uint32_t negInvFlags = 0;
16702ec34544SRui Ueyama     if (consume("(")) {
16718cdf1c1eSIgor Kudrin       readMemoryAttributes(flags, invFlags, negFlags, negInvFlags);
16722ec34544SRui Ueyama       expect(")");
16732ec34544SRui Ueyama     }
16742ec34544SRui Ueyama     expect(":");
16752ec34544SRui Ueyama 
167692b5b980SFangrui Song     Expr origin = readMemoryAssignment("ORIGIN", "org", "o");
16772ec34544SRui Ueyama     expect(",");
167892b5b980SFangrui Song     Expr length = readMemoryAssignment("LENGTH", "len", "l");
16792ec34544SRui Ueyama 
16805f37541cSGeorge Rimar     // Add the memory region to the region map.
16818cdf1c1eSIgor Kudrin     MemoryRegion *mr = make<MemoryRegion>(tok, origin, length, flags, invFlags,
16828cdf1c1eSIgor Kudrin                                           negFlags, negInvFlags);
16833837f427SRui Ueyama     if (!script->memoryRegions.insert({tok, mr}).second)
16843837f427SRui Ueyama       setError("region '" + tok + "' already defined");
16852ec34544SRui Ueyama   }
16862ec34544SRui Ueyama }
16872ec34544SRui Ueyama 
16882ec34544SRui Ueyama // This function parses the attributes used to match against section
16892ec34544SRui Ueyama // flags when placing output sections in a memory region. These flags
16902ec34544SRui Ueyama // are only used when an explicit memory region name is not used.
16918cdf1c1eSIgor Kudrin void ScriptParser::readMemoryAttributes(uint32_t &flags, uint32_t &invFlags,
16928cdf1c1eSIgor Kudrin                                         uint32_t &negFlags,
16938cdf1c1eSIgor Kudrin                                         uint32_t &negInvFlags) {
16943837f427SRui Ueyama   bool invert = false;
16952ec34544SRui Ueyama 
16963837f427SRui Ueyama   for (char c : next().lower()) {
16978cdf1c1eSIgor Kudrin     if (c == '!') {
16983837f427SRui Ueyama       invert = !invert;
16998cdf1c1eSIgor Kudrin       std::swap(flags, negFlags);
17008cdf1c1eSIgor Kudrin       std::swap(invFlags, negInvFlags);
17018cdf1c1eSIgor Kudrin       continue;
17022ec34544SRui Ueyama     }
17038cdf1c1eSIgor Kudrin     if (c == 'w')
17048cdf1c1eSIgor Kudrin       flags |= SHF_WRITE;
17058cdf1c1eSIgor Kudrin     else if (c == 'x')
17068cdf1c1eSIgor Kudrin       flags |= SHF_EXECINSTR;
17078cdf1c1eSIgor Kudrin     else if (c == 'a')
17088cdf1c1eSIgor Kudrin       flags |= SHF_ALLOC;
17098cdf1c1eSIgor Kudrin     else if (c == 'r')
17108cdf1c1eSIgor Kudrin       invFlags |= SHF_WRITE;
17118cdf1c1eSIgor Kudrin     else
17128cdf1c1eSIgor Kudrin       setError("invalid memory region attribute");
17138cdf1c1eSIgor Kudrin   }
17148cdf1c1eSIgor Kudrin 
17158cdf1c1eSIgor Kudrin   if (invert) {
17168cdf1c1eSIgor Kudrin     std::swap(flags, negFlags);
17178cdf1c1eSIgor Kudrin     std::swap(invFlags, negInvFlags);
17188cdf1c1eSIgor Kudrin   }
17192ec34544SRui Ueyama }
17202ec34544SRui Ueyama 
172107837b8fSFangrui Song void elf::readLinkerScript(MemoryBufferRef mb) {
1722439341b9SJames Henderson   llvm::TimeTraceScope timeScope("Read linker script",
1723439341b9SJames Henderson                                  mb.getBufferIdentifier());
17243837f427SRui Ueyama   ScriptParser(mb).readLinkerScript();
17252ec34544SRui Ueyama }
17262ec34544SRui Ueyama 
172707837b8fSFangrui Song void elf::readVersionScript(MemoryBufferRef mb) {
1728439341b9SJames Henderson   llvm::TimeTraceScope timeScope("Read version script",
1729439341b9SJames Henderson                                  mb.getBufferIdentifier());
17303837f427SRui Ueyama   ScriptParser(mb).readVersionScript();
17312ec34544SRui Ueyama }
17322ec34544SRui Ueyama 
173307837b8fSFangrui Song void elf::readDynamicList(MemoryBufferRef mb) {
1734439341b9SJames Henderson   llvm::TimeTraceScope timeScope("Read dynamic list", mb.getBufferIdentifier());
173507837b8fSFangrui Song   ScriptParser(mb).readDynamicList();
17368c7e8cceSPetr Hosek }
1737bd8cfe65SFangrui Song 
173807837b8fSFangrui Song void elf::readDefsym(StringRef name, MemoryBufferRef mb) {
1739439341b9SJames Henderson   llvm::TimeTraceScope timeScope("Read defsym input", name);
174007837b8fSFangrui Song   ScriptParser(mb).readDefsym(name);
174107837b8fSFangrui Song }
1742