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"
35fe0de25bSFangrui Song #include "llvm/Support/SaveAndRestore.h"
36439341b9SJames Henderson #include "llvm/Support/TimeProfiler.h"
372ec34544SRui Ueyama #include <cassert>
382ec34544SRui Ueyama #include <limits>
392ec34544SRui Ueyama #include <vector>
402ec34544SRui Ueyama
412ec34544SRui Ueyama using namespace llvm;
422ec34544SRui Ueyama using namespace llvm::ELF;
43b58079d4SRui Ueyama using namespace llvm::support::endian;
4407837b8fSFangrui Song using namespace lld;
4507837b8fSFangrui Song using namespace lld::elf;
462ec34544SRui Ueyama
4796b3fe02SRui Ueyama namespace {
4896b3fe02SRui Ueyama class ScriptParser final : ScriptLexer {
492ec34544SRui Ueyama public:
ScriptParser(MemoryBufferRef mb)503837f427SRui Ueyama ScriptParser(MemoryBufferRef mb) : ScriptLexer(mb) {
5111ae59f0SRui Ueyama // Initialize IsUnderSysroot
523837f427SRui Ueyama if (config->sysroot == "")
5311ae59f0SRui Ueyama return;
543837f427SRui Ueyama StringRef path = mb.getBufferIdentifier();
553837f427SRui Ueyama for (; !path.empty(); path = sys::path::parent_path(path)) {
563837f427SRui Ueyama if (!sys::fs::equivalent(config->sysroot, path))
5711ae59f0SRui Ueyama continue;
583837f427SRui Ueyama isUnderSysroot = true;
5911ae59f0SRui Ueyama return;
6011ae59f0SRui Ueyama }
6111ae59f0SRui Ueyama }
622ec34544SRui Ueyama
632ec34544SRui Ueyama void readLinkerScript();
642ec34544SRui Ueyama void readVersionScript();
652ec34544SRui Ueyama void readDynamicList();
663837f427SRui Ueyama void readDefsym(StringRef name);
672ec34544SRui Ueyama
682ec34544SRui Ueyama private:
693837f427SRui Ueyama void addFile(StringRef path);
702ec34544SRui Ueyama
712ec34544SRui Ueyama void readAsNeeded();
722ec34544SRui Ueyama void readEntry();
732ec34544SRui Ueyama void readExtern();
742ec34544SRui Ueyama void readGroup();
752ec34544SRui Ueyama void readInclude();
761d92aa73SRui Ueyama void readInput();
772ec34544SRui Ueyama void readMemory();
782ec34544SRui Ueyama void readOutput();
792ec34544SRui Ueyama void readOutputArch();
802ec34544SRui Ueyama void readOutputFormat();
81899fdf54SFangrui Song void readOverwriteSections();
822ec34544SRui Ueyama void readPhdrs();
835f37541cSGeorge Rimar void readRegionAlias();
842ec34544SRui Ueyama void readSearchDir();
852ec34544SRui Ueyama void readSections();
86e262bb1aSRui Ueyama void readTarget();
872ec34544SRui Ueyama void readVersion();
882ec34544SRui Ueyama void readVersionScriptCommand();
892ec34544SRui Ueyama
903837f427SRui Ueyama SymbolAssignment *readSymbolAssignment(StringRef name);
913837f427SRui Ueyama ByteCommand *readByteCommand(StringRef tok);
92b0486051SSimon Atanasyan std::array<uint8_t, 4> readFill();
933837f427SRui Ueyama bool readSectionDirective(OutputSection *cmd, StringRef tok1, StringRef tok2);
943837f427SRui Ueyama void readSectionAddressType(OutputSection *cmd);
956c814931SFangrui Song OutputDesc *readOverlaySectionDescription();
966c814931SFangrui Song OutputDesc *readOutputSectionDescription(StringRef outSec);
9764038ef8SFangrui Song SmallVector<SectionCommand *, 0> readOverlay();
98a1c2ee01SFangrui Song SmallVector<StringRef, 0> readOutputSectionPhdrs();
99dbd0ad33SPeter Smith std::pair<uint64_t, uint64_t> readInputSectionFlags();
1003837f427SRui Ueyama InputSectionDescription *readInputSectionDescription(StringRef tok);
1012ec34544SRui Ueyama StringMatcher readFilePatterns();
10264038ef8SFangrui Song SmallVector<SectionPattern, 0> readInputSectionsList();
103dbd0ad33SPeter Smith InputSectionDescription *readInputSectionRules(StringRef filePattern,
104dbd0ad33SPeter Smith uint64_t withFlags,
105dbd0ad33SPeter Smith uint64_t withoutFlags);
1062ec34544SRui Ueyama unsigned readPhdrType();
1072a9aed0eSFangrui Song SortSectionPolicy peekSortKind();
1082ec34544SRui Ueyama SortSectionPolicy readSortKind();
1093837f427SRui Ueyama SymbolAssignment *readProvideHidden(bool provide, bool hidden);
1103837f427SRui Ueyama SymbolAssignment *readAssignment(StringRef tok);
1112ec34544SRui Ueyama void readSort();
112d30a78b3SGeorge Rimar Expr readAssert();
1135fb17128SGeorge Rimar Expr readConstant();
1145fb17128SGeorge Rimar Expr getPageSize();
1152ec34544SRui Ueyama
11692b5b980SFangrui Song Expr readMemoryAssignment(StringRef, StringRef, StringRef);
1178cdf1c1eSIgor Kudrin void readMemoryAttributes(uint32_t &flags, uint32_t &invFlags,
1188cdf1c1eSIgor Kudrin uint32_t &negFlags, uint32_t &negInvFlags);
1192ec34544SRui Ueyama
1203837f427SRui Ueyama Expr combine(StringRef op, Expr l, Expr r);
1212ec34544SRui Ueyama Expr readExpr();
1223837f427SRui Ueyama Expr readExpr1(Expr lhs, int minPrec);
1232ec34544SRui Ueyama StringRef readParenLiteral();
1242ec34544SRui Ueyama Expr readPrimary();
1253837f427SRui Ueyama Expr readTernary(Expr cond);
1262ec34544SRui Ueyama Expr readParenExpr();
1272ec34544SRui Ueyama
1282ec34544SRui Ueyama // For parsing version script.
12964038ef8SFangrui Song SmallVector<SymbolVersion, 0> readVersionExtern();
1302ec34544SRui Ueyama void readAnonymousDeclaration();
1313837f427SRui Ueyama void readVersionDeclaration(StringRef verStr);
1322ec34544SRui Ueyama
13364038ef8SFangrui Song std::pair<SmallVector<SymbolVersion, 0>, SmallVector<SymbolVersion, 0>>
1342ec34544SRui Ueyama readSymbols();
1352ec34544SRui Ueyama
136bf6e259bSFangrui Song // True if a script being read is in the --sysroot directory.
1373837f427SRui Ueyama bool isUnderSysroot = false;
1380440be4aSRui Ueyama
1395a44980fSFangrui Song bool seenDataAlign = false;
1405a44980fSFangrui Song bool seenRelroEnd = false;
1415a44980fSFangrui Song
1420440be4aSRui Ueyama // A set to detect an INCLUDE() cycle.
1433837f427SRui Ueyama StringSet<> seen;
1442ec34544SRui Ueyama };
14596b3fe02SRui Ueyama } // namespace
1462ec34544SRui Ueyama
unquote(StringRef s)1473837f427SRui Ueyama static StringRef unquote(StringRef s) {
1483837f427SRui Ueyama if (s.startswith("\""))
1493837f427SRui Ueyama return s.substr(1, s.size() - 2);
1503837f427SRui Ueyama return s;
1511e77ad14SRui Ueyama }
1521e77ad14SRui Ueyama
1532ec34544SRui Ueyama // Some operations only support one non absolute value. Move the
1542ec34544SRui Ueyama // absolute one to the right hand side for convenience.
moveAbsRight(ExprValue & a,ExprValue & b)1553837f427SRui Ueyama static void moveAbsRight(ExprValue &a, ExprValue &b) {
1563837f427SRui Ueyama if (a.sec == nullptr || (a.forceAbsolute && !b.isAbsolute()))
1573837f427SRui Ueyama std::swap(a, b);
1583837f427SRui Ueyama if (!b.isAbsolute())
1593837f427SRui Ueyama error(a.loc + ": at least one side of the expression must be absolute");
1602ec34544SRui Ueyama }
1612ec34544SRui Ueyama
add(ExprValue a,ExprValue b)1623837f427SRui Ueyama static ExprValue add(ExprValue a, ExprValue b) {
1633837f427SRui Ueyama moveAbsRight(a, b);
1643837f427SRui Ueyama return {a.sec, a.forceAbsolute, a.getSectionOffset() + b.getValue(), a.loc};
1652ec34544SRui Ueyama }
1662ec34544SRui Ueyama
sub(ExprValue a,ExprValue b)1673837f427SRui Ueyama static ExprValue sub(ExprValue a, ExprValue b) {
16863a4a98eSRafael Espindola // The distance between two symbols in sections is absolute.
1693837f427SRui Ueyama if (!a.isAbsolute() && !b.isAbsolute())
1703837f427SRui Ueyama return a.getValue() - b.getValue();
1713837f427SRui Ueyama return {a.sec, false, a.getSectionOffset() - b.getValue(), a.loc};
1722ec34544SRui Ueyama }
1732ec34544SRui Ueyama
bitAnd(ExprValue a,ExprValue b)1743837f427SRui Ueyama static ExprValue bitAnd(ExprValue a, ExprValue b) {
1753837f427SRui Ueyama moveAbsRight(a, b);
1763837f427SRui Ueyama return {a.sec, a.forceAbsolute,
1773837f427SRui Ueyama (a.getValue() & b.getValue()) - a.getSecAddr(), a.loc};
1782ec34544SRui Ueyama }
1792ec34544SRui Ueyama
bitOr(ExprValue a,ExprValue b)1803837f427SRui Ueyama static ExprValue bitOr(ExprValue a, ExprValue b) {
1813837f427SRui Ueyama moveAbsRight(a, b);
1823837f427SRui Ueyama return {a.sec, a.forceAbsolute,
1833837f427SRui Ueyama (a.getValue() | b.getValue()) - a.getSecAddr(), a.loc};
1842ec34544SRui Ueyama }
1852ec34544SRui Ueyama
readDynamicList()1862ec34544SRui Ueyama void ScriptParser::readDynamicList() {
1872ec34544SRui Ueyama expect("{");
18864038ef8SFangrui Song SmallVector<SymbolVersion, 0> locals;
18964038ef8SFangrui Song SmallVector<SymbolVersion, 0> globals;
1903837f427SRui Ueyama std::tie(locals, globals) = readSymbols();
191d72d97b3SRafael Espindola expect(";");
192d72d97b3SRafael Espindola
193d72d97b3SRafael Espindola if (!atEOF()) {
1942ec34544SRui Ueyama setError("EOF expected, but got " + next());
195d72d97b3SRafael Espindola return;
196d72d97b3SRafael Espindola }
1973837f427SRui Ueyama if (!locals.empty()) {
198d72d97b3SRafael Espindola setError("\"local:\" scope not supported in --dynamic-list");
199d72d97b3SRafael Espindola return;
200d72d97b3SRafael Espindola }
201d72d97b3SRafael Espindola
2023837f427SRui Ueyama for (SymbolVersion v : globals)
2033837f427SRui Ueyama config->dynamicList.push_back(v);
2042ec34544SRui Ueyama }
2052ec34544SRui Ueyama
readVersionScript()2062ec34544SRui Ueyama void ScriptParser::readVersionScript() {
2072ec34544SRui Ueyama readVersionScriptCommand();
2082ec34544SRui Ueyama if (!atEOF())
2092ec34544SRui Ueyama setError("EOF expected, but got " + next());
2102ec34544SRui Ueyama }
2112ec34544SRui Ueyama
readVersionScriptCommand()2122ec34544SRui Ueyama void ScriptParser::readVersionScriptCommand() {
2132ec34544SRui Ueyama if (consume("{")) {
2142ec34544SRui Ueyama readAnonymousDeclaration();
2152ec34544SRui Ueyama return;
2162ec34544SRui Ueyama }
2172ec34544SRui Ueyama
218b8a59c8aSBob Haarman while (!atEOF() && !errorCount() && peek() != "}") {
2193837f427SRui Ueyama StringRef verStr = next();
2203837f427SRui Ueyama if (verStr == "{") {
2212ec34544SRui Ueyama setError("anonymous version definition is used in "
2222ec34544SRui Ueyama "combination with other version definitions");
2232ec34544SRui Ueyama return;
2242ec34544SRui Ueyama }
2252ec34544SRui Ueyama expect("{");
2263837f427SRui Ueyama readVersionDeclaration(verStr);
2272ec34544SRui Ueyama }
2282ec34544SRui Ueyama }
2292ec34544SRui Ueyama
readVersion()2302ec34544SRui Ueyama void ScriptParser::readVersion() {
2312ec34544SRui Ueyama expect("{");
2322ec34544SRui Ueyama readVersionScriptCommand();
2332ec34544SRui Ueyama expect("}");
2342ec34544SRui Ueyama }
2352ec34544SRui Ueyama
readLinkerScript()2362ec34544SRui Ueyama void ScriptParser::readLinkerScript() {
2372ec34544SRui Ueyama while (!atEOF()) {
2383837f427SRui Ueyama StringRef tok = next();
2393837f427SRui Ueyama if (tok == ";")
2402ec34544SRui Ueyama continue;
2412ec34544SRui Ueyama
2423837f427SRui Ueyama if (tok == "ENTRY") {
2432ec34544SRui Ueyama readEntry();
2443837f427SRui Ueyama } else if (tok == "EXTERN") {
2452ec34544SRui Ueyama readExtern();
2463837f427SRui Ueyama } else if (tok == "GROUP") {
2472ec34544SRui Ueyama readGroup();
2483837f427SRui Ueyama } else if (tok == "INCLUDE") {
2492ec34544SRui Ueyama readInclude();
2503837f427SRui Ueyama } else if (tok == "INPUT") {
2511d92aa73SRui Ueyama readInput();
2523837f427SRui Ueyama } else if (tok == "MEMORY") {
2532ec34544SRui Ueyama readMemory();
2543837f427SRui Ueyama } else if (tok == "OUTPUT") {
2552ec34544SRui Ueyama readOutput();
2563837f427SRui Ueyama } else if (tok == "OUTPUT_ARCH") {
2572ec34544SRui Ueyama readOutputArch();
2583837f427SRui Ueyama } else if (tok == "OUTPUT_FORMAT") {
2592ec34544SRui Ueyama readOutputFormat();
260899fdf54SFangrui Song } else if (tok == "OVERWRITE_SECTIONS") {
261899fdf54SFangrui Song readOverwriteSections();
2623837f427SRui Ueyama } else if (tok == "PHDRS") {
2632ec34544SRui Ueyama readPhdrs();
2643837f427SRui Ueyama } else if (tok == "REGION_ALIAS") {
2655f37541cSGeorge Rimar readRegionAlias();
2663837f427SRui Ueyama } else if (tok == "SEARCH_DIR") {
2672ec34544SRui Ueyama readSearchDir();
2683837f427SRui Ueyama } else if (tok == "SECTIONS") {
2692ec34544SRui Ueyama readSections();
2703837f427SRui Ueyama } else if (tok == "TARGET") {
271e262bb1aSRui Ueyama readTarget();
2723837f427SRui Ueyama } else if (tok == "VERSION") {
2732ec34544SRui Ueyama readVersion();
2743837f427SRui Ueyama } else if (SymbolAssignment *cmd = readAssignment(tok)) {
2753837f427SRui Ueyama script->sectionCommands.push_back(cmd);
2762ec34544SRui Ueyama } else {
2773837f427SRui Ueyama setError("unknown directive: " + tok);
2782ec34544SRui Ueyama }
2792ec34544SRui Ueyama }
2802ec34544SRui Ueyama }
2812ec34544SRui Ueyama
readDefsym(StringRef name)2823837f427SRui Ueyama void ScriptParser::readDefsym(StringRef name) {
283c1522816SGeorge Rimar if (errorCount())
284c1522816SGeorge Rimar return;
2853837f427SRui Ueyama Expr e = readExpr();
2868c7e8cceSPetr Hosek if (!atEOF())
2878c7e8cceSPetr Hosek setError("EOF expected, but got " + next());
2883837f427SRui Ueyama SymbolAssignment *cmd = make<SymbolAssignment>(name, e, getCurrentLocation());
2893837f427SRui Ueyama script->sectionCommands.push_back(cmd);
2908c7e8cceSPetr Hosek }
2918c7e8cceSPetr Hosek
addFile(StringRef s)2923837f427SRui Ueyama void ScriptParser::addFile(StringRef s) {
2933837f427SRui Ueyama if (isUnderSysroot && s.startswith("/")) {
2943837f427SRui Ueyama SmallString<128> pathData;
2953837f427SRui Ueyama StringRef path = (config->sysroot + s).toStringRef(pathData);
2962508733eSFangrui Song if (sys::fs::exists(path))
29783d59e05SAlexandre Ganea driver->addFile(saver().save(path), /*withLOption=*/false);
2982508733eSFangrui Song else
2992508733eSFangrui Song setError("cannot find " + s + " inside " + config->sysroot);
3002ec34544SRui Ueyama return;
3012ec34544SRui Ueyama }
3022ec34544SRui Ueyama
3033837f427SRui Ueyama if (s.startswith("/")) {
304c384ca3cSFangrui Song // Case 1: s is an absolute path. Just open it.
30549a3ad21SRui Ueyama driver->addFile(s, /*withLOption=*/false);
3063837f427SRui Ueyama } else if (s.startswith("=")) {
307c384ca3cSFangrui Song // Case 2: relative to the sysroot.
3083837f427SRui Ueyama if (config->sysroot.empty())
30949a3ad21SRui Ueyama driver->addFile(s.substr(1), /*withLOption=*/false);
3102ec34544SRui Ueyama else
31183d59e05SAlexandre Ganea driver->addFile(saver().save(config->sysroot + "/" + s.substr(1)),
31249a3ad21SRui Ueyama /*withLOption=*/false);
3133837f427SRui Ueyama } else if (s.startswith("-l")) {
314c384ca3cSFangrui Song // Case 3: search in the list of library paths.
3153837f427SRui Ueyama driver->addLibrary(s.substr(2));
316c384ca3cSFangrui Song } else {
317c384ca3cSFangrui Song // Case 4: s is a relative path. Search in the directory of the script file.
318c384ca3cSFangrui Song std::string filename = std::string(getCurrentMB().getBufferIdentifier());
319c384ca3cSFangrui Song StringRef directory = sys::path::parent_path(filename);
320c384ca3cSFangrui Song if (!directory.empty()) {
321c384ca3cSFangrui Song SmallString<0> path(directory);
322c384ca3cSFangrui Song sys::path::append(path, s);
323c384ca3cSFangrui Song if (sys::fs::exists(path)) {
324c384ca3cSFangrui Song driver->addFile(path, /*withLOption=*/false);
325c384ca3cSFangrui Song return;
326c384ca3cSFangrui Song }
327c384ca3cSFangrui Song }
328c384ca3cSFangrui Song // Then search in the current working directory.
329c384ca3cSFangrui Song if (sys::fs::exists(s)) {
33049a3ad21SRui Ueyama driver->addFile(s, /*withLOption=*/false);
3312ec34544SRui Ueyama } else {
332c384ca3cSFangrui Song // Finally, search in the list of library paths.
3333837f427SRui Ueyama if (Optional<std::string> path = findFromSearchPaths(s))
33483d59e05SAlexandre Ganea driver->addFile(saver().save(*path), /*withLOption=*/true);
3352ec34544SRui Ueyama else
3363837f427SRui Ueyama setError("unable to find " + s);
3372ec34544SRui Ueyama }
3382ec34544SRui Ueyama }
339c384ca3cSFangrui Song }
3402ec34544SRui Ueyama
readAsNeeded()3412ec34544SRui Ueyama void ScriptParser::readAsNeeded() {
3422ec34544SRui Ueyama expect("(");
3433837f427SRui Ueyama bool orig = config->asNeeded;
3443837f427SRui Ueyama config->asNeeded = true;
345b8a59c8aSBob Haarman while (!errorCount() && !consume(")"))
3462ec34544SRui Ueyama addFile(unquote(next()));
3473837f427SRui Ueyama config->asNeeded = orig;
3482ec34544SRui Ueyama }
3492ec34544SRui Ueyama
readEntry()3502ec34544SRui Ueyama void ScriptParser::readEntry() {
3512ec34544SRui Ueyama // -e <symbol> takes predecence over ENTRY(<symbol>).
3522ec34544SRui Ueyama expect("(");
3533837f427SRui Ueyama StringRef tok = next();
3543837f427SRui Ueyama if (config->entry.empty())
355363b2956SFangrui Song config->entry = unquote(tok);
3562ec34544SRui Ueyama expect(")");
3572ec34544SRui Ueyama }
3582ec34544SRui Ueyama
readExtern()3592ec34544SRui Ueyama void ScriptParser::readExtern() {
3602ec34544SRui Ueyama expect("(");
361b8a59c8aSBob Haarman while (!errorCount() && !consume(")"))
3623837f427SRui Ueyama config->undefined.push_back(unquote(next()));
3632ec34544SRui Ueyama }
3642ec34544SRui Ueyama
readGroup()3652ec34544SRui Ueyama void ScriptParser::readGroup() {
3663837f427SRui Ueyama bool orig = InputFile::isInGroup;
3673837f427SRui Ueyama InputFile::isInGroup = true;
3681d92aa73SRui Ueyama readInput();
3693837f427SRui Ueyama InputFile::isInGroup = orig;
3703837f427SRui Ueyama if (!orig)
3713837f427SRui Ueyama ++InputFile::nextGroupId;
3722ec34544SRui Ueyama }
3732ec34544SRui Ueyama
readInclude()3742ec34544SRui Ueyama void ScriptParser::readInclude() {
3753837f427SRui Ueyama StringRef tok = unquote(next());
3762ec34544SRui Ueyama
3773837f427SRui Ueyama if (!seen.insert(tok).second) {
3780440be4aSRui Ueyama setError("there is a cycle in linker script INCLUDEs");
3790440be4aSRui Ueyama return;
3800440be4aSRui Ueyama }
3810440be4aSRui Ueyama
3823837f427SRui Ueyama if (Optional<std::string> path = searchScript(tok)) {
3833837f427SRui Ueyama if (Optional<MemoryBufferRef> mb = readFile(*path))
3843837f427SRui Ueyama tokenize(*mb);
3852ec34544SRui Ueyama return;
3862ec34544SRui Ueyama }
3873837f427SRui Ueyama setError("cannot find linker script " + tok);
3882ec34544SRui Ueyama }
3892ec34544SRui Ueyama
readInput()3901d92aa73SRui Ueyama void ScriptParser::readInput() {
3911d92aa73SRui Ueyama expect("(");
3921d92aa73SRui Ueyama while (!errorCount() && !consume(")")) {
3931d92aa73SRui Ueyama if (consume("AS_NEEDED"))
3941d92aa73SRui Ueyama readAsNeeded();
3951d92aa73SRui Ueyama else
3961d92aa73SRui Ueyama addFile(unquote(next()));
3971d92aa73SRui Ueyama }
3981d92aa73SRui Ueyama }
3991d92aa73SRui Ueyama
readOutput()4002ec34544SRui Ueyama void ScriptParser::readOutput() {
4012ec34544SRui Ueyama // -o <file> takes predecence over OUTPUT(<file>).
4022ec34544SRui Ueyama expect("(");
4033837f427SRui Ueyama StringRef tok = next();
4043837f427SRui Ueyama if (config->outputFile.empty())
4053837f427SRui Ueyama config->outputFile = unquote(tok);
4062ec34544SRui Ueyama expect(")");
4072ec34544SRui Ueyama }
4082ec34544SRui Ueyama
readOutputArch()4092ec34544SRui Ueyama void ScriptParser::readOutputArch() {
4102ec34544SRui Ueyama // OUTPUT_ARCH is ignored for now.
4112ec34544SRui Ueyama expect("(");
412b8a59c8aSBob Haarman while (!errorCount() && !consume(")"))
4132ec34544SRui Ueyama skip();
4142ec34544SRui Ueyama }
4152ec34544SRui Ueyama
parseBfdName(StringRef s)4163837f427SRui Ueyama static std::pair<ELFKind, uint16_t> parseBfdName(StringRef s) {
4173837f427SRui Ueyama return StringSwitch<std::pair<ELFKind, uint16_t>>(s)
4184f8c8228SRui Ueyama .Case("elf32-i386", {ELF32LEKind, EM_386})
4198527f32fSBen Shi .Case("elf32-avr", {ELF32LEKind, EM_AVR})
4204f8c8228SRui Ueyama .Case("elf32-iamcu", {ELF32LEKind, EM_IAMCU})
4214f8c8228SRui Ueyama .Case("elf32-littlearm", {ELF32LEKind, EM_ARM})
4224f8c8228SRui Ueyama .Case("elf32-x86-64", {ELF32LEKind, EM_X86_64})
42319b134ccSDimitry Andric .Case("elf64-aarch64", {ELF64LEKind, EM_AARCH64})
4244f8c8228SRui Ueyama .Case("elf64-littleaarch64", {ELF64LEKind, EM_AARCH64})
4257605a9a0SFangrui Song .Case("elf64-bigaarch64", {ELF64BEKind, EM_AARCH64})
4264134143cSRui Ueyama .Case("elf32-powerpc", {ELF32BEKind, EM_PPC})
427275eb828SBrandon Bergren .Case("elf32-powerpcle", {ELF32LEKind, EM_PPC})
4284f8c8228SRui Ueyama .Case("elf64-powerpc", {ELF64BEKind, EM_PPC64})
4294f8c8228SRui Ueyama .Case("elf64-powerpcle", {ELF64LEKind, EM_PPC64})
4304f8c8228SRui Ueyama .Case("elf64-x86-64", {ELF64LEKind, EM_X86_64})
4314134143cSRui Ueyama .Cases("elf32-tradbigmips", "elf32-bigmips", {ELF32BEKind, EM_MIPS})
4324f8c8228SRui Ueyama .Case("elf32-ntradbigmips", {ELF32BEKind, EM_MIPS})
4334f8c8228SRui Ueyama .Case("elf32-tradlittlemips", {ELF32LEKind, EM_MIPS})
4344f8c8228SRui Ueyama .Case("elf32-ntradlittlemips", {ELF32LEKind, EM_MIPS})
4354f8c8228SRui Ueyama .Case("elf64-tradbigmips", {ELF64BEKind, EM_MIPS})
4364f8c8228SRui Ueyama .Case("elf64-tradlittlemips", {ELF64LEKind, EM_MIPS})
43744d908d7SFangrui Song .Case("elf32-littleriscv", {ELF32LEKind, EM_RISCV})
43844d908d7SFangrui Song .Case("elf64-littleriscv", {ELF64LEKind, EM_RISCV})
439aff950e9SLemonBoy .Case("elf64-sparc", {ELF64BEKind, EM_SPARCV9})
44092c6141cSLemonBoy .Case("elf32-msp430", {ELF32LEKind, EM_MSP430})
4414f8c8228SRui Ueyama .Default({ELFNoneKind, EM_NONE});
442ea8cd00aSRui Ueyama }
443ea8cd00aSRui Ueyama
444eea34aaeSFangrui Song // Parse OUTPUT_FORMAT(bfdname) or OUTPUT_FORMAT(default, big, little). Choose
445eea34aaeSFangrui Song // big if -EB is specified, little if -EL is specified, or default if neither is
446eea34aaeSFangrui Song // specified.
readOutputFormat()4472ec34544SRui Ueyama void ScriptParser::readOutputFormat() {
4482ec34544SRui Ueyama expect("(");
449ea8cd00aSRui Ueyama
450eea34aaeSFangrui Song StringRef s;
4512822852fSShoaib Meenai config->bfdname = unquote(next());
452eea34aaeSFangrui Song if (!consume(")")) {
453eea34aaeSFangrui Song expect(",");
454eea34aaeSFangrui Song s = unquote(next());
455eea34aaeSFangrui Song if (config->optEB)
456eea34aaeSFangrui Song config->bfdname = s;
457eea34aaeSFangrui Song expect(",");
458eea34aaeSFangrui Song s = unquote(next());
459eea34aaeSFangrui Song if (config->optEL)
460eea34aaeSFangrui Song config->bfdname = s;
461eea34aaeSFangrui Song consume(")");
462eea34aaeSFangrui Song }
463eea34aaeSFangrui Song s = config->bfdname;
4643837f427SRui Ueyama if (s.consume_back("-freebsd"))
4653837f427SRui Ueyama config->osabi = ELFOSABI_FREEBSD;
4664f8c8228SRui Ueyama
4673837f427SRui Ueyama std::tie(config->ekind, config->emachine) = parseBfdName(s);
4683837f427SRui Ueyama if (config->emachine == EM_NONE)
4692822852fSShoaib Meenai setError("unknown output format name: " + config->bfdname);
4703837f427SRui Ueyama if (s == "elf32-ntradlittlemips" || s == "elf32-ntradbigmips")
4713837f427SRui Ueyama config->mipsN32Abi = true;
47292c6141cSLemonBoy if (config->emachine == EM_MSP430)
47392c6141cSLemonBoy config->osabi = ELFOSABI_STANDALONE;
4742ec34544SRui Ueyama }
4752ec34544SRui Ueyama
readPhdrs()4762ec34544SRui Ueyama void ScriptParser::readPhdrs() {
4772ec34544SRui Ueyama expect("{");
4782ec34544SRui Ueyama
479b8a59c8aSBob Haarman while (!errorCount() && !consume("}")) {
4803837f427SRui Ueyama PhdrsCommand cmd;
4813837f427SRui Ueyama cmd.name = next();
4823837f427SRui Ueyama cmd.type = readPhdrType();
483b579c439SRui Ueyama
484b8a59c8aSBob Haarman while (!errorCount() && !consume(";")) {
485b579c439SRui Ueyama if (consume("FILEHDR"))
4863837f427SRui Ueyama cmd.hasFilehdr = true;
487b579c439SRui Ueyama else if (consume("PHDRS"))
4883837f427SRui Ueyama cmd.hasPhdrs = true;
489b579c439SRui Ueyama else if (consume("AT"))
4903837f427SRui Ueyama cmd.lmaExpr = readParenExpr();
491b579c439SRui Ueyama else if (consume("FLAGS"))
4923837f427SRui Ueyama cmd.flags = readParenExpr()().getValue();
493b579c439SRui Ueyama else
494b579c439SRui Ueyama setError("unexpected header attribute: " + next());
495b579c439SRui Ueyama }
4960ae2c24cSRui Ueyama
4973837f427SRui Ueyama script->phdrsCommands.push_back(cmd);
4982ec34544SRui Ueyama }
4992ec34544SRui Ueyama }
5002ec34544SRui Ueyama
readRegionAlias()5015f37541cSGeorge Rimar void ScriptParser::readRegionAlias() {
5025f37541cSGeorge Rimar expect("(");
5033837f427SRui Ueyama StringRef alias = unquote(next());
5045f37541cSGeorge Rimar expect(",");
5053837f427SRui Ueyama StringRef name = next();
5065f37541cSGeorge Rimar expect(")");
5075f37541cSGeorge Rimar
5083837f427SRui Ueyama if (script->memoryRegions.count(alias))
5093837f427SRui Ueyama setError("redefinition of memory region '" + alias + "'");
5103837f427SRui Ueyama if (!script->memoryRegions.count(name))
5113837f427SRui Ueyama setError("memory region '" + name + "' is not defined");
5123837f427SRui Ueyama script->memoryRegions.insert({alias, script->memoryRegions[name]});
5135f37541cSGeorge Rimar }
5145f37541cSGeorge Rimar
readSearchDir()5152ec34544SRui Ueyama void ScriptParser::readSearchDir() {
5162ec34544SRui Ueyama expect("(");
5173837f427SRui Ueyama StringRef tok = next();
5183837f427SRui Ueyama if (!config->nostdlib)
5193837f427SRui Ueyama config->searchPaths.push_back(unquote(tok));
5202ec34544SRui Ueyama expect(")");
5212ec34544SRui Ueyama }
5222ec34544SRui Ueyama
523a582419aSGeorge Rimar // This reads an overlay description. Overlays are used to describe output
524a582419aSGeorge Rimar // sections that use the same virtual memory range and normally would trigger
525a582419aSGeorge Rimar // linker's sections sanity check failures.
526a582419aSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Overlay-Description.html#Overlay-Description
readOverlay()52764038ef8SFangrui Song SmallVector<SectionCommand *, 0> ScriptParser::readOverlay() {
528a582419aSGeorge Rimar // VA and LMA expressions are optional, though for simplicity of
529a582419aSGeorge Rimar // implementation we assume they are not. That is what OVERLAY was designed
530a582419aSGeorge Rimar // for first of all: to allow sections with overlapping VAs at different LMAs.
5313837f427SRui Ueyama Expr addrExpr = readExpr();
532a582419aSGeorge Rimar expect(":");
533a582419aSGeorge Rimar expect("AT");
5343837f427SRui Ueyama Expr lmaExpr = readParenExpr();
535a582419aSGeorge Rimar expect("{");
536a582419aSGeorge Rimar
53764038ef8SFangrui Song SmallVector<SectionCommand *, 0> v;
5383837f427SRui Ueyama OutputSection *prev = nullptr;
539a582419aSGeorge Rimar while (!errorCount() && !consume("}")) {
540a582419aSGeorge Rimar // VA is the same for all sections. The LMAs are consecutive in memory
541a582419aSGeorge Rimar // starting from the base load address specified.
5426c814931SFangrui Song OutputDesc *osd = readOverlaySectionDescription();
5436c814931SFangrui Song osd->osec.addrExpr = addrExpr;
5443837f427SRui Ueyama if (prev)
5456c814931SFangrui Song osd->osec.lmaExpr = [=] { return prev->getLMA() + prev->size; };
546a582419aSGeorge Rimar else
5476c814931SFangrui Song osd->osec.lmaExpr = lmaExpr;
5486c814931SFangrui Song v.push_back(osd);
5496c814931SFangrui Song prev = &osd->osec;
550a582419aSGeorge Rimar }
551a582419aSGeorge Rimar
552a582419aSGeorge Rimar // According to the specification, at the end of the overlay, the location
553a582419aSGeorge Rimar // counter should be equal to the overlay base address plus size of the
554a582419aSGeorge Rimar // largest section seen in the overlay.
555a582419aSGeorge Rimar // Here we want to create the Dot assignment command to achieve that.
5563837f427SRui Ueyama Expr moveDot = [=] {
5573837f427SRui Ueyama uint64_t max = 0;
5587051aeefSFangrui Song for (SectionCommand *cmd : v)
5596c814931SFangrui Song max = std::max(max, cast<OutputDesc>(cmd)->osec.size);
5603837f427SRui Ueyama return addrExpr().getValue() + max;
561a582419aSGeorge Rimar };
5623837f427SRui Ueyama v.push_back(make<SymbolAssignment>(".", moveDot, getCurrentLocation()));
5633837f427SRui Ueyama return v;
564a582419aSGeorge Rimar }
565a582419aSGeorge Rimar
readOverwriteSections()566899fdf54SFangrui Song void ScriptParser::readOverwriteSections() {
567899fdf54SFangrui Song expect("{");
568899fdf54SFangrui Song while (!errorCount() && !consume("}"))
569899fdf54SFangrui Song script->overwriteSections.push_back(readOutputSectionDescription(next()));
570899fdf54SFangrui Song }
571899fdf54SFangrui Song
readSections()5722ec34544SRui Ueyama void ScriptParser::readSections() {
5732ec34544SRui Ueyama expect("{");
57464038ef8SFangrui Song SmallVector<SectionCommand *, 0> v;
575b8a59c8aSBob Haarman while (!errorCount() && !consume("}")) {
5763837f427SRui Ueyama StringRef tok = next();
5773837f427SRui Ueyama if (tok == "OVERLAY") {
5787051aeefSFangrui Song for (SectionCommand *cmd : readOverlay())
5793837f427SRui Ueyama v.push_back(cmd);
580a582419aSGeorge Rimar continue;
5813837f427SRui Ueyama } else if (tok == "INCLUDE") {
5822e9d40d5SRui Ueyama readInclude();
5832e9d40d5SRui Ueyama continue;
584a582419aSGeorge Rimar }
585a582419aSGeorge Rimar
5867051aeefSFangrui Song if (SectionCommand *cmd = readAssignment(tok))
5873837f427SRui Ueyama v.push_back(cmd);
588d30a78b3SGeorge Rimar else
5893837f427SRui Ueyama v.push_back(readOutputSectionDescription(tok));
5902ec34544SRui Ueyama }
5915a44980fSFangrui Song
5925a44980fSFangrui Song // If DATA_SEGMENT_RELRO_END is absent, for sections after DATA_SEGMENT_ALIGN,
5935a44980fSFangrui Song // the relro fields should be cleared.
5945a44980fSFangrui Song if (!seenRelroEnd)
5955a44980fSFangrui Song for (SectionCommand *cmd : v)
5965a44980fSFangrui Song if (auto *osd = dyn_cast<OutputDesc>(cmd))
5975a44980fSFangrui Song osd->osec.relro = false;
5985a44980fSFangrui Song
5997c426fb1SFangrui Song script->sectionCommands.insert(script->sectionCommands.end(), v.begin(),
6007c426fb1SFangrui Song v.end());
6019e2c8a9dSGeorge Rimar
6027c426fb1SFangrui Song if (atEOF() || !consume("INSERT")) {
6037c426fb1SFangrui Song script->hasSectionsCommand = true;
6049e2c8a9dSGeorge Rimar return;
6059e2c8a9dSGeorge Rimar }
6069e2c8a9dSGeorge Rimar
6077c426fb1SFangrui Song bool isAfter = false;
6087c426fb1SFangrui Song if (consume("AFTER"))
6097c426fb1SFangrui Song isAfter = true;
6107c426fb1SFangrui Song else if (!consume("BEFORE"))
6117c426fb1SFangrui Song setError("expected AFTER/BEFORE, but got '" + next() + "'");
6127c426fb1SFangrui Song StringRef where = next();
613a1c2ee01SFangrui Song SmallVector<StringRef, 0> names;
6147051aeefSFangrui Song for (SectionCommand *cmd : v)
6156c814931SFangrui Song if (auto *os = dyn_cast<OutputDesc>(cmd))
6166c814931SFangrui Song names.push_back(os->osec.name);
61703051f7aSFangrui Song if (!names.empty())
61803051f7aSFangrui Song script->insertCommands.push_back({std::move(names), isAfter, where});
6192ec34544SRui Ueyama }
6202ec34544SRui Ueyama
readTarget()621e262bb1aSRui Ueyama void ScriptParser::readTarget() {
622e262bb1aSRui Ueyama // TARGET(foo) is an alias for "--format foo". Unlike GNU linkers,
623e262bb1aSRui Ueyama // we accept only a limited set of BFD names (i.e. "elf" or "binary")
624e262bb1aSRui Ueyama // for --format. We recognize only /^elf/ and "binary" in the linker
625e262bb1aSRui Ueyama // script as well.
626e262bb1aSRui Ueyama expect("(");
6274cb05dc3SFangrui Song StringRef tok = unquote(next());
628e262bb1aSRui Ueyama expect(")");
629e262bb1aSRui Ueyama
6303837f427SRui Ueyama if (tok.startswith("elf"))
6313837f427SRui Ueyama config->formatBinary = false;
6323837f427SRui Ueyama else if (tok == "binary")
6333837f427SRui Ueyama config->formatBinary = true;
634e262bb1aSRui Ueyama else
6353837f427SRui Ueyama setError("unknown target: " + tok);
636e262bb1aSRui Ueyama }
637e262bb1aSRui Ueyama
precedence(StringRef op)6383837f427SRui Ueyama static int precedence(StringRef op) {
6393837f427SRui Ueyama return StringSwitch<int>(op)
640d479b2e4SFangrui Song .Cases("*", "/", "%", 10)
641d479b2e4SFangrui Song .Cases("+", "-", 9)
642d479b2e4SFangrui Song .Cases("<<", ">>", 8)
643d479b2e4SFangrui Song .Cases("<", "<=", ">", ">=", 7)
644d479b2e4SFangrui Song .Cases("==", "!=", 6)
645d479b2e4SFangrui Song .Case("&", 5)
646d479b2e4SFangrui Song .Case("|", 4)
647d479b2e4SFangrui Song .Case("&&", 3)
648d479b2e4SFangrui Song .Case("||", 2)
649b0d6dd39SFangrui Song .Case("?", 1)
6502ec34544SRui Ueyama .Default(-1);
6512ec34544SRui Ueyama }
6522ec34544SRui Ueyama
readFilePatterns()6532ec34544SRui Ueyama StringMatcher ScriptParser::readFilePatterns() {
654c42fe247SThomas Preud'homme StringMatcher Matcher;
655c42fe247SThomas Preud'homme
656b8a59c8aSBob Haarman while (!errorCount() && !consume(")"))
657c42fe247SThomas Preud'homme Matcher.addPattern(SingleStringMatcher(next()));
658c42fe247SThomas Preud'homme return Matcher;
6592ec34544SRui Ueyama }
6602ec34544SRui Ueyama
peekSortKind()6612a9aed0eSFangrui Song SortSectionPolicy ScriptParser::peekSortKind() {
6622a9aed0eSFangrui Song return StringSwitch<SortSectionPolicy>(peek())
6632a9aed0eSFangrui Song .Cases("SORT", "SORT_BY_NAME", SortSectionPolicy::Name)
6642a9aed0eSFangrui Song .Case("SORT_BY_ALIGNMENT", SortSectionPolicy::Alignment)
6652a9aed0eSFangrui Song .Case("SORT_BY_INIT_PRIORITY", SortSectionPolicy::Priority)
6662a9aed0eSFangrui Song .Case("SORT_NONE", SortSectionPolicy::None)
6672a9aed0eSFangrui Song .Default(SortSectionPolicy::Default);
6682a9aed0eSFangrui Song }
6692a9aed0eSFangrui Song
readSortKind()6702ec34544SRui Ueyama SortSectionPolicy ScriptParser::readSortKind() {
6712a9aed0eSFangrui Song SortSectionPolicy ret = peekSortKind();
6722a9aed0eSFangrui Song if (ret != SortSectionPolicy::Default)
6732a9aed0eSFangrui Song skip();
6742a9aed0eSFangrui Song return ret;
6752ec34544SRui Ueyama }
6762ec34544SRui Ueyama
67703fc8d1eSRui Ueyama // Reads SECTIONS command contents in the following form:
67803fc8d1eSRui Ueyama //
67903fc8d1eSRui Ueyama // <contents> ::= <elem>*
68003fc8d1eSRui Ueyama // <elem> ::= <exclude>? <glob-pattern>
68103fc8d1eSRui Ueyama // <exclude> ::= "EXCLUDE_FILE" "(" <glob-pattern>+ ")"
68203fc8d1eSRui Ueyama //
68303fc8d1eSRui Ueyama // For example,
68403fc8d1eSRui Ueyama //
68503fc8d1eSRui Ueyama // *(.foo EXCLUDE_FILE (a.o) .bar EXCLUDE_FILE (b.o) .baz)
68603fc8d1eSRui Ueyama //
68703fc8d1eSRui Ueyama // is parsed as ".foo", ".bar" with "a.o", and ".baz" with "b.o".
68803fc8d1eSRui Ueyama // The semantics of that is section .foo in any file, section .bar in
68903fc8d1eSRui Ueyama // any file but a.o, and section .baz in any file but b.o.
readInputSectionsList()69064038ef8SFangrui Song SmallVector<SectionPattern, 0> ScriptParser::readInputSectionsList() {
69164038ef8SFangrui Song SmallVector<SectionPattern, 0> ret;
692b8a59c8aSBob Haarman while (!errorCount() && peek() != ")") {
6933837f427SRui Ueyama StringMatcher excludeFilePat;
6942ec34544SRui Ueyama if (consume("EXCLUDE_FILE")) {
6952ec34544SRui Ueyama expect("(");
6963837f427SRui Ueyama excludeFilePat = readFilePatterns();
6972ec34544SRui Ueyama }
6982ec34544SRui Ueyama
699c42fe247SThomas Preud'homme StringMatcher SectionMatcher;
7002a9aed0eSFangrui Song // Break if the next token is ), EXCLUDE_FILE, or SORT*.
7012a9aed0eSFangrui Song while (!errorCount() && peek() != ")" && peek() != "EXCLUDE_FILE" &&
7022a9aed0eSFangrui Song peekSortKind() == SortSectionPolicy::Default)
703c42fe247SThomas Preud'homme SectionMatcher.addPattern(unquote(next()));
7042ec34544SRui Ueyama
705c42fe247SThomas Preud'homme if (!SectionMatcher.empty())
706c42fe247SThomas Preud'homme ret.push_back({std::move(excludeFilePat), std::move(SectionMatcher)});
7072a9aed0eSFangrui Song else if (excludeFilePat.empty())
7082a9aed0eSFangrui Song break;
7092ec34544SRui Ueyama else
7102ec34544SRui Ueyama setError("section pattern is expected");
7112ec34544SRui Ueyama }
7123837f427SRui Ueyama return ret;
7132ec34544SRui Ueyama }
7142ec34544SRui Ueyama
7152ec34544SRui Ueyama // Reads contents of "SECTIONS" directive. That directive contains a
7162ec34544SRui Ueyama // list of glob patterns for input sections. The grammar is as follows.
7172ec34544SRui Ueyama //
7182ec34544SRui Ueyama // <patterns> ::= <section-list>
7192ec34544SRui Ueyama // | <sort> "(" <section-list> ")"
7202ec34544SRui Ueyama // | <sort> "(" <sort> "(" <section-list> ")" ")"
7212ec34544SRui Ueyama //
7222ec34544SRui Ueyama // <sort> ::= "SORT" | "SORT_BY_NAME" | "SORT_BY_ALIGNMENT"
7232ec34544SRui Ueyama // | "SORT_BY_INIT_PRIORITY" | "SORT_NONE"
7242ec34544SRui Ueyama //
7252ec34544SRui Ueyama // <section-list> is parsed by readInputSectionsList().
7262ec34544SRui Ueyama InputSectionDescription *
readInputSectionRules(StringRef filePattern,uint64_t withFlags,uint64_t withoutFlags)727dbd0ad33SPeter Smith ScriptParser::readInputSectionRules(StringRef filePattern, uint64_t withFlags,
728dbd0ad33SPeter Smith uint64_t withoutFlags) {
729dbd0ad33SPeter Smith auto *cmd =
730dbd0ad33SPeter Smith make<InputSectionDescription>(filePattern, withFlags, withoutFlags);
7312ec34544SRui Ueyama expect("(");
7322ec34544SRui Ueyama
733b8a59c8aSBob Haarman while (!errorCount() && !consume(")")) {
7343837f427SRui Ueyama SortSectionPolicy outer = readSortKind();
7353837f427SRui Ueyama SortSectionPolicy inner = SortSectionPolicy::Default;
73664038ef8SFangrui Song SmallVector<SectionPattern, 0> v;
7373837f427SRui Ueyama if (outer != SortSectionPolicy::Default) {
7382ec34544SRui Ueyama expect("(");
7393837f427SRui Ueyama inner = readSortKind();
7403837f427SRui Ueyama if (inner != SortSectionPolicy::Default) {
7412ec34544SRui Ueyama expect("(");
7423837f427SRui Ueyama v = readInputSectionsList();
7432ec34544SRui Ueyama expect(")");
7442ec34544SRui Ueyama } else {
7453837f427SRui Ueyama v = readInputSectionsList();
7462ec34544SRui Ueyama }
7472ec34544SRui Ueyama expect(")");
7482ec34544SRui Ueyama } else {
7493837f427SRui Ueyama v = readInputSectionsList();
7502ec34544SRui Ueyama }
7512ec34544SRui Ueyama
7523837f427SRui Ueyama for (SectionPattern &pat : v) {
7533837f427SRui Ueyama pat.sortInner = inner;
7543837f427SRui Ueyama pat.sortOuter = outer;
7552ec34544SRui Ueyama }
7562ec34544SRui Ueyama
7573837f427SRui Ueyama std::move(v.begin(), v.end(), std::back_inserter(cmd->sectionPatterns));
7582ec34544SRui Ueyama }
7593837f427SRui Ueyama return cmd;
7602ec34544SRui Ueyama }
7612ec34544SRui Ueyama
7622ec34544SRui Ueyama InputSectionDescription *
readInputSectionDescription(StringRef tok)7633837f427SRui Ueyama ScriptParser::readInputSectionDescription(StringRef tok) {
7642ec34544SRui Ueyama // Input section wildcard can be surrounded by KEEP.
7652ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep
766dbd0ad33SPeter Smith uint64_t withFlags = 0;
767dbd0ad33SPeter Smith uint64_t withoutFlags = 0;
7683837f427SRui Ueyama if (tok == "KEEP") {
7692ec34544SRui Ueyama expect("(");
770dbd0ad33SPeter Smith if (consume("INPUT_SECTION_FLAGS"))
771dbd0ad33SPeter Smith std::tie(withFlags, withoutFlags) = readInputSectionFlags();
772dbd0ad33SPeter Smith InputSectionDescription *cmd =
773dbd0ad33SPeter Smith readInputSectionRules(next(), withFlags, withoutFlags);
7742ec34544SRui Ueyama expect(")");
7753837f427SRui Ueyama script->keptSections.push_back(cmd);
7763837f427SRui Ueyama return cmd;
7772ec34544SRui Ueyama }
778dbd0ad33SPeter Smith if (tok == "INPUT_SECTION_FLAGS") {
779dbd0ad33SPeter Smith std::tie(withFlags, withoutFlags) = readInputSectionFlags();
780dbd0ad33SPeter Smith tok = next();
781dbd0ad33SPeter Smith }
782dbd0ad33SPeter Smith return readInputSectionRules(tok, withFlags, withoutFlags);
7832ec34544SRui Ueyama }
7842ec34544SRui Ueyama
readSort()7852ec34544SRui Ueyama void ScriptParser::readSort() {
7862ec34544SRui Ueyama expect("(");
7872ec34544SRui Ueyama expect("CONSTRUCTORS");
7882ec34544SRui Ueyama expect(")");
7892ec34544SRui Ueyama }
7902ec34544SRui Ueyama
readAssert()791d30a78b3SGeorge Rimar Expr ScriptParser::readAssert() {
7922ec34544SRui Ueyama expect("(");
7933837f427SRui Ueyama Expr e = readExpr();
7942ec34544SRui Ueyama expect(",");
7953837f427SRui Ueyama StringRef msg = unquote(next());
7962ec34544SRui Ueyama expect(")");
797b579c439SRui Ueyama
7982ec34544SRui Ueyama return [=] {
7993837f427SRui Ueyama if (!e().getValue())
8002682bc3cSFangrui Song errorOrWarn(msg);
8013837f427SRui Ueyama return script->getDot();
8022ec34544SRui Ueyama };
8032ec34544SRui Ueyama }
8042ec34544SRui Ueyama
80566f8ac8dSFangrui Song #define ECase(X) \
80666f8ac8dSFangrui Song { #X, X }
80766f8ac8dSFangrui Song constexpr std::pair<const char *, unsigned> typeMap[] = {
80866f8ac8dSFangrui Song ECase(SHT_PROGBITS), ECase(SHT_NOTE), ECase(SHT_NOBITS),
80966f8ac8dSFangrui Song ECase(SHT_INIT_ARRAY), ECase(SHT_FINI_ARRAY), ECase(SHT_PREINIT_ARRAY),
81066f8ac8dSFangrui Song };
81166f8ac8dSFangrui Song #undef ECase
81266f8ac8dSFangrui Song
813a46d08ebSGeorge Rimar // Tries to read the special directive for an output section definition which
81466f8ac8dSFangrui Song // can be one of following: "(NOLOAD)", "(COPY)", "(INFO)", "(OVERLAY)", and
81566f8ac8dSFangrui Song // "(TYPE=<value>)".
81666f8ac8dSFangrui Song // Tok1 and Tok2 are next 2 tokens peeked. See comment for
81766f8ac8dSFangrui Song // readSectionAddressType below.
readSectionDirective(OutputSection * cmd,StringRef tok1,StringRef tok2)8183837f427SRui Ueyama bool ScriptParser::readSectionDirective(OutputSection *cmd, StringRef tok1, StringRef tok2) {
8193837f427SRui Ueyama if (tok1 != "(")
820a46d08ebSGeorge Rimar return false;
82166f8ac8dSFangrui Song if (tok2 != "NOLOAD" && tok2 != "COPY" && tok2 != "INFO" &&
82266f8ac8dSFangrui Song tok2 != "OVERLAY" && tok2 != "TYPE")
823a46d08ebSGeorge Rimar return false;
824a46d08ebSGeorge Rimar
825a46d08ebSGeorge Rimar expect("(");
826a46d08ebSGeorge Rimar if (consume("NOLOAD")) {
827fdc41aa2SMatt Schulte cmd->type = SHT_NOBITS;
82866f8ac8dSFangrui Song cmd->typeIsSet = true;
82966f8ac8dSFangrui Song } else if (consume("TYPE")) {
83066f8ac8dSFangrui Song expect("=");
83166f8ac8dSFangrui Song StringRef value = peek();
83266f8ac8dSFangrui Song auto it = llvm::find_if(typeMap, [=](auto e) { return e.first == value; });
83366f8ac8dSFangrui Song if (it != std::end(typeMap)) {
83466f8ac8dSFangrui Song // The value is a recognized literal SHT_*.
83566f8ac8dSFangrui Song cmd->type = it->second;
83666f8ac8dSFangrui Song skip();
83766f8ac8dSFangrui Song } else if (value.startswith("SHT_")) {
83866f8ac8dSFangrui Song setError("unknown section type " + value);
83966f8ac8dSFangrui Song } else {
84066f8ac8dSFangrui Song // Otherwise, read an expression.
84166f8ac8dSFangrui Song cmd->type = readExpr()().getValue();
84266f8ac8dSFangrui Song }
84366f8ac8dSFangrui Song cmd->typeIsSet = true;
844a46d08ebSGeorge Rimar } else {
845a46d08ebSGeorge Rimar skip(); // This is "COPY", "INFO" or "OVERLAY".
8463837f427SRui Ueyama cmd->nonAlloc = true;
847a46d08ebSGeorge Rimar }
848a46d08ebSGeorge Rimar expect(")");
849a46d08ebSGeorge Rimar return true;
850a46d08ebSGeorge Rimar }
851a46d08ebSGeorge Rimar
8521c08e9f5SGeorge Rimar // Reads an expression and/or the special directive for an output
8531c08e9f5SGeorge Rimar // section definition. Directive is one of following: "(NOLOAD)",
8541c08e9f5SGeorge Rimar // "(COPY)", "(INFO)" or "(OVERLAY)".
8553271d370SRui Ueyama //
8563271d370SRui Ueyama // An output section name can be followed by an address expression
8571c08e9f5SGeorge Rimar // and/or directive. This grammar is not LL(1) because "(" can be
85897f4d158SGeorge Rimar // interpreted as either the beginning of some expression or beginning
8591c08e9f5SGeorge Rimar // of directive.
8603271d370SRui Ueyama //
861b579c439SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html
862fbb0463fSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Output-Section-Type.html
readSectionAddressType(OutputSection * cmd)8633837f427SRui Ueyama void ScriptParser::readSectionAddressType(OutputSection *cmd) {
86466f8ac8dSFangrui Song // Temporarily set inExpr to support TYPE=<value> without spaces.
86566f8ac8dSFangrui Song bool saved = std::exchange(inExpr, true);
86666f8ac8dSFangrui Song bool isDirective = readSectionDirective(cmd, peek(), peek2());
86766f8ac8dSFangrui Song inExpr = saved;
86866f8ac8dSFangrui Song if (isDirective)
8693271d370SRui Ueyama return;
8703271d370SRui Ueyama
8713837f427SRui Ueyama cmd->addrExpr = readExpr();
8723837f427SRui Ueyama if (peek() == "(" && !readSectionDirective(cmd, "(", peek2()))
873a46d08ebSGeorge Rimar setError("unknown section directive: " + peek2());
874fbb0463fSGeorge Rimar }
875fbb0463fSGeorge Rimar
checkAlignment(Expr e,std::string & loc)8763837f427SRui Ueyama static Expr checkAlignment(Expr e, std::string &loc) {
877f22ec9ddSGeorge Rimar return [=] {
8783837f427SRui Ueyama uint64_t alignment = std::max((uint64_t)1, e().getValue());
8793837f427SRui Ueyama if (!isPowerOf2_64(alignment)) {
8803837f427SRui Ueyama error(loc + ": alignment must be power of 2");
881f22ec9ddSGeorge Rimar return (uint64_t)1; // Return a dummy value.
882f22ec9ddSGeorge Rimar }
8833837f427SRui Ueyama return alignment;
884f22ec9ddSGeorge Rimar };
885f22ec9ddSGeorge Rimar }
886f22ec9ddSGeorge Rimar
readOverlaySectionDescription()8876c814931SFangrui Song OutputDesc *ScriptParser::readOverlaySectionDescription() {
8886c814931SFangrui Song OutputDesc *osd = script->createOutputSection(next(), getCurrentLocation());
8896c814931SFangrui Song osd->osec.inOverlay = true;
890a582419aSGeorge Rimar expect("{");
891dbd0ad33SPeter Smith while (!errorCount() && !consume("}")) {
892dbd0ad33SPeter Smith uint64_t withFlags = 0;
893dbd0ad33SPeter Smith uint64_t withoutFlags = 0;
894dbd0ad33SPeter Smith if (consume("INPUT_SECTION_FLAGS"))
895dbd0ad33SPeter Smith std::tie(withFlags, withoutFlags) = readInputSectionFlags();
8966c814931SFangrui Song osd->osec.commands.push_back(
897dbd0ad33SPeter Smith readInputSectionRules(next(), withFlags, withoutFlags));
898dbd0ad33SPeter Smith }
8996c814931SFangrui Song return osd;
900a582419aSGeorge Rimar }
901a582419aSGeorge Rimar
readOutputSectionDescription(StringRef outSec)9026c814931SFangrui Song OutputDesc *ScriptParser::readOutputSectionDescription(StringRef outSec) {
9036c814931SFangrui Song OutputDesc *cmd = script->createOutputSection(outSec, getCurrentLocation());
9046c814931SFangrui Song OutputSection *osec = &cmd->osec;
9055a44980fSFangrui Song // Maybe relro. Will reset to false if DATA_SEGMENT_RELRO_END is absent.
9065a44980fSFangrui Song osec->relro = seenDataAlign && !seenRelroEnd;
9073271d370SRui Ueyama
9083837f427SRui Ueyama size_t symbolsReferenced = script->referencedSymbols.size();
909c4df670dSGeorge Rimar
9103271d370SRui Ueyama if (peek() != ":")
9116c814931SFangrui Song readSectionAddressType(osec);
9122ec34544SRui Ueyama expect(":");
9132ec34544SRui Ueyama
9143837f427SRui Ueyama std::string location = getCurrentLocation();
9152ec34544SRui Ueyama if (consume("AT"))
9166c814931SFangrui Song osec->lmaExpr = readParenExpr();
9172ec34544SRui Ueyama if (consume("ALIGN"))
9186c814931SFangrui Song osec->alignExpr = checkAlignment(readParenExpr(), location);
9192ec34544SRui Ueyama if (consume("SUBALIGN"))
9206c814931SFangrui Song osec->subalignExpr = checkAlignment(readParenExpr(), location);
9212ec34544SRui Ueyama
9222ec34544SRui Ueyama // Parse constraints.
9232ec34544SRui Ueyama if (consume("ONLY_IF_RO"))
9246c814931SFangrui Song osec->constraint = ConstraintKind::ReadOnly;
9252ec34544SRui Ueyama if (consume("ONLY_IF_RW"))
9266c814931SFangrui Song osec->constraint = ConstraintKind::ReadWrite;
9272ec34544SRui Ueyama expect("{");
9282ec34544SRui Ueyama
929b8a59c8aSBob Haarman while (!errorCount() && !consume("}")) {
9303837f427SRui Ueyama StringRef tok = next();
9313837f427SRui Ueyama if (tok == ";") {
9322ec34544SRui Ueyama // Empty commands are allowed. Do nothing here.
9333837f427SRui Ueyama } else if (SymbolAssignment *assign = readAssignment(tok)) {
9346c814931SFangrui Song osec->commands.push_back(assign);
9353837f427SRui Ueyama } else if (ByteCommand *data = readByteCommand(tok)) {
9366c814931SFangrui Song osec->commands.push_back(data);
9373837f427SRui Ueyama } else if (tok == "CONSTRUCTORS") {
9382ec34544SRui Ueyama // CONSTRUCTORS is a keyword to make the linker recognize C++ ctors/dtors
9392ec34544SRui Ueyama // by name. This is for very old file formats such as ECOFF/XCOFF.
9402ec34544SRui Ueyama // For ELF, we should ignore.
9413837f427SRui Ueyama } else if (tok == "FILL") {
9420810f16fSGeorge Rimar // We handle the FILL command as an alias for =fillexp section attribute,
9430810f16fSGeorge Rimar // which is different from what GNU linkers do.
9440810f16fSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Output-Section-Data.html
945bb7d2b17SGeorgii Rymar if (peek() != "(")
946bb7d2b17SGeorgii Rymar setError("( expected, but got " + peek());
9476c814931SFangrui Song osec->filler = readFill();
9483837f427SRui Ueyama } else if (tok == "SORT") {
9492ec34544SRui Ueyama readSort();
9503837f427SRui Ueyama } else if (tok == "INCLUDE") {
9512e9d40d5SRui Ueyama readInclude();
952177fd72fSFangrui Song } else if (tok == "(" || tok == ")") {
953177fd72fSFangrui Song setError("expected filename pattern");
9542ec34544SRui Ueyama } else if (peek() == "(") {
9556c814931SFangrui Song osec->commands.push_back(readInputSectionDescription(tok));
9562ec34544SRui Ueyama } else {
957f49fe218SGeorge Rimar // We have a file name and no input sections description. It is not a
958f49fe218SGeorge Rimar // commonly used syntax, but still acceptable. In that case, all sections
959f49fe218SGeorge Rimar // from the file will be included.
960dbd0ad33SPeter Smith // FIXME: GNU ld permits INPUT_SECTION_FLAGS to be used here. We do not
961dbd0ad33SPeter Smith // handle this case here as it will already have been matched by the
962dbd0ad33SPeter Smith // case above.
9633837f427SRui Ueyama auto *isd = make<InputSectionDescription>(tok);
964c42fe247SThomas Preud'homme isd->sectionPatterns.push_back({{}, StringMatcher("*")});
9656c814931SFangrui Song osec->commands.push_back(isd);
9662ec34544SRui Ueyama }
9672ec34544SRui Ueyama }
9682ec34544SRui Ueyama
9692ec34544SRui Ueyama if (consume(">"))
9706c814931SFangrui Song osec->memoryRegionName = std::string(next());
9712ec34544SRui Ueyama
9725d01a8beSGeorge Rimar if (consume("AT")) {
9735d01a8beSGeorge Rimar expect(">");
9746c814931SFangrui Song osec->lmaRegionName = std::string(next());
9755d01a8beSGeorge Rimar }
9765d01a8beSGeorge Rimar
9776c814931SFangrui Song if (osec->lmaExpr && !osec->lmaRegionName.empty())
9785d01a8beSGeorge Rimar error("section can't have both LMA and a load region");
9795d01a8beSGeorge Rimar
9806c814931SFangrui Song osec->phdrs = readOutputSectionPhdrs();
9812ec34544SRui Ueyama
9820810f16fSGeorge Rimar if (peek() == "=" || peek().startswith("=")) {
9833837f427SRui Ueyama inExpr = true;
9840810f16fSGeorge Rimar consume("=");
9856c814931SFangrui Song osec->filler = readFill();
9863837f427SRui Ueyama inExpr = false;
9870810f16fSGeorge Rimar }
9882ec34544SRui Ueyama
9892ec34544SRui Ueyama // Consume optional comma following output section command.
9902ec34544SRui Ueyama consume(",");
9912ec34544SRui Ueyama
9923837f427SRui Ueyama if (script->referencedSymbols.size() > symbolsReferenced)
9936c814931SFangrui Song osec->expressionsUseSymbols = true;
9943837f427SRui Ueyama return cmd;
9952ec34544SRui Ueyama }
9962ec34544SRui Ueyama
9970810f16fSGeorge Rimar // Reads a `=<fillexp>` expression and returns its value as a big-endian number.
9982ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html
9990810f16fSGeorge Rimar // We do not support using symbols in such expressions.
10002ec34544SRui Ueyama //
10018acbf1ccSRui Ueyama // When reading a hexstring, ld.bfd handles it as a blob of arbitrary
10028acbf1ccSRui Ueyama // size, while ld.gold always handles it as a 32-bit big-endian number.
10038acbf1ccSRui Ueyama // We are compatible with ld.gold because it's easier to implement.
1004bb7d2b17SGeorgii Rymar // Also, we require that expressions with operators must be wrapped into
1005bb7d2b17SGeorgii Rymar // round brackets. We did it to resolve the ambiguity when parsing scripts like:
1006bb7d2b17SGeorgii Rymar // SECTIONS { .foo : { ... } =120+3 /DISCARD/ : { ... } }
readFill()10070810f16fSGeorge Rimar std::array<uint8_t, 4> ScriptParser::readFill() {
1008bb7d2b17SGeorgii Rymar uint64_t value = readPrimary()().val;
10093837f427SRui Ueyama if (value > UINT32_MAX)
10100810f16fSGeorge Rimar setError("filler expression result does not fit 32-bit: 0x" +
10113837f427SRui Ueyama Twine::utohexstr(value));
1012b58079d4SRui Ueyama
10133837f427SRui Ueyama std::array<uint8_t, 4> buf;
10143837f427SRui Ueyama write32be(buf.data(), (uint32_t)value);
10153837f427SRui Ueyama return buf;
10162ec34544SRui Ueyama }
10172ec34544SRui Ueyama
readProvideHidden(bool provide,bool hidden)10183837f427SRui Ueyama SymbolAssignment *ScriptParser::readProvideHidden(bool provide, bool hidden) {
10192ec34544SRui Ueyama expect("(");
102021bf6bb3SFangrui Song StringRef name = next(), eq = peek();
102121bf6bb3SFangrui Song if (eq != "=") {
102221bf6bb3SFangrui Song setError("= expected, but got " + next());
102321bf6bb3SFangrui Song while (!atEOF() && next() != ")")
102421bf6bb3SFangrui Song ;
102521bf6bb3SFangrui Song return nullptr;
102621bf6bb3SFangrui Song }
102721bf6bb3SFangrui Song SymbolAssignment *cmd = readSymbolAssignment(name);
10283837f427SRui Ueyama cmd->provide = provide;
10293837f427SRui Ueyama cmd->hidden = hidden;
10302ec34544SRui Ueyama expect(")");
10313837f427SRui Ueyama return cmd;
10322ec34544SRui Ueyama }
10332ec34544SRui Ueyama
readAssignment(StringRef tok)10343837f427SRui Ueyama SymbolAssignment *ScriptParser::readAssignment(StringRef tok) {
1035d30a78b3SGeorge Rimar // Assert expression returns Dot, so this is equal to ".=."
10363837f427SRui Ueyama if (tok == "ASSERT")
1037d30a78b3SGeorge Rimar return make<SymbolAssignment>(".", readAssert(), getCurrentLocation());
1038d30a78b3SGeorge Rimar
10393837f427SRui Ueyama size_t oldPos = pos;
10403837f427SRui Ueyama SymbolAssignment *cmd = nullptr;
10410a0effddSFangrui Song const StringRef op = peek();
10420a0effddSFangrui Song if (op.startswith("=")) {
1043fe0de25bSFangrui Song // Support = followed by an expression without whitespace.
1044fe0de25bSFangrui Song SaveAndRestore<bool> saved(inExpr, true);
10453837f427SRui Ueyama cmd = readSymbolAssignment(tok);
1046b95cca03SFangrui Song } else if ((op.size() == 2 && op[1] == '=' && strchr("*/+-&|", op[0])) ||
10470a0effddSFangrui Song op == "<<=" || op == ">>=") {
1048fe0de25bSFangrui Song cmd = readSymbolAssignment(tok);
1049fe0de25bSFangrui Song } else if (tok == "PROVIDE") {
1050fe0de25bSFangrui Song SaveAndRestore<bool> saved(inExpr, true);
10513837f427SRui Ueyama cmd = readProvideHidden(true, false);
1052fe0de25bSFangrui Song } else if (tok == "HIDDEN") {
1053fe0de25bSFangrui Song SaveAndRestore<bool> saved(inExpr, true);
10543837f427SRui Ueyama cmd = readProvideHidden(false, true);
1055fe0de25bSFangrui Song } else if (tok == "PROVIDE_HIDDEN") {
1056fe0de25bSFangrui Song SaveAndRestore<bool> saved(inExpr, true);
10573837f427SRui Ueyama cmd = readProvideHidden(true, true);
1058fe0de25bSFangrui Song }
1059e88b76a9SGeorge Rimar
10603837f427SRui Ueyama if (cmd) {
10613837f427SRui Ueyama cmd->commandString =
10623837f427SRui Ueyama tok.str() + " " +
10633837f427SRui Ueyama llvm::join(tokens.begin() + oldPos, tokens.begin() + pos, " ");
1064e88b76a9SGeorge Rimar expect(";");
10652ec34544SRui Ueyama }
10663837f427SRui Ueyama return cmd;
10672ec34544SRui Ueyama }
10682ec34544SRui Ueyama
readSymbolAssignment(StringRef name)10693837f427SRui Ueyama SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef name) {
1070e7a7ad13SFangrui Song name = unquote(name);
10713837f427SRui Ueyama StringRef op = next();
10720a0effddSFangrui Song assert(op == "=" || op == "*=" || op == "/=" || op == "+=" || op == "-=" ||
10730a0effddSFangrui Song op == "&=" || op == "|=" || op == "<<=" || op == ">>=");
10740a0effddSFangrui Song // Note: GNU ld does not support %= or ^=.
10753837f427SRui Ueyama Expr e = readExpr();
10760a0effddSFangrui Song if (op != "=") {
10773837f427SRui Ueyama std::string loc = getCurrentLocation();
10780a0effddSFangrui Song e = [=, c = op[0]]() -> ExprValue {
10790a0effddSFangrui Song ExprValue lhs = script->getSymbolValue(name, loc);
10800a0effddSFangrui Song switch (c) {
10810a0effddSFangrui Song case '*':
10820a0effddSFangrui Song return lhs.getValue() * e().getValue();
10830a0effddSFangrui Song case '/':
10840a0effddSFangrui Song if (uint64_t rv = e().getValue())
10850a0effddSFangrui Song return lhs.getValue() / rv;
10860a0effddSFangrui Song error(loc + ": division by zero");
10870a0effddSFangrui Song return 0;
10880a0effddSFangrui Song case '+':
10890a0effddSFangrui Song return add(lhs, e());
10900a0effddSFangrui Song case '-':
10910a0effddSFangrui Song return sub(lhs, e());
10920a0effddSFangrui Song case '<':
10930a0effddSFangrui Song return lhs.getValue() << e().getValue();
10940a0effddSFangrui Song case '>':
10950a0effddSFangrui Song return lhs.getValue() >> e().getValue();
10960a0effddSFangrui Song case '&':
10970a0effddSFangrui Song return lhs.getValue() & e().getValue();
10980a0effddSFangrui Song case '|':
10990a0effddSFangrui Song return lhs.getValue() | e().getValue();
11000a0effddSFangrui Song default:
11010a0effddSFangrui Song llvm_unreachable("");
11020a0effddSFangrui Song }
11030a0effddSFangrui Song };
11042ec34544SRui Ueyama }
11053837f427SRui Ueyama return make<SymbolAssignment>(name, e, getCurrentLocation());
11062ec34544SRui Ueyama }
11072ec34544SRui Ueyama
11082ec34544SRui Ueyama // This is an operator-precedence parser to parse a linker
11092ec34544SRui Ueyama // script expression.
readExpr()11102ec34544SRui Ueyama Expr ScriptParser::readExpr() {
11112ec34544SRui Ueyama // Our lexer is context-aware. Set the in-expression bit so that
11122ec34544SRui Ueyama // they apply different tokenization rules.
11133837f427SRui Ueyama bool orig = inExpr;
11143837f427SRui Ueyama inExpr = true;
11153837f427SRui Ueyama Expr e = readExpr1(readPrimary(), 0);
11163837f427SRui Ueyama inExpr = orig;
11173837f427SRui Ueyama return e;
11182ec34544SRui Ueyama }
11192ec34544SRui Ueyama
combine(StringRef op,Expr l,Expr r)11203837f427SRui Ueyama Expr ScriptParser::combine(StringRef op, Expr l, Expr r) {
11213837f427SRui Ueyama if (op == "+")
11223837f427SRui Ueyama return [=] { return add(l(), r()); };
11233837f427SRui Ueyama if (op == "-")
11243837f427SRui Ueyama return [=] { return sub(l(), r()); };
11253837f427SRui Ueyama if (op == "*")
11263837f427SRui Ueyama return [=] { return l().getValue() * r().getValue(); };
11273837f427SRui Ueyama if (op == "/") {
11283837f427SRui Ueyama std::string loc = getCurrentLocation();
11297b91e213SGeorge Rimar return [=]() -> uint64_t {
11303837f427SRui Ueyama if (uint64_t rv = r().getValue())
11313837f427SRui Ueyama return l().getValue() / rv;
11323837f427SRui Ueyama error(loc + ": division by zero");
1133067617f9SRui Ueyama return 0;
11347b91e213SGeorge Rimar };
11357b91e213SGeorge Rimar }
11363837f427SRui Ueyama if (op == "%") {
11373837f427SRui Ueyama std::string loc = getCurrentLocation();
11387b91e213SGeorge Rimar return [=]() -> uint64_t {
11393837f427SRui Ueyama if (uint64_t rv = r().getValue())
11403837f427SRui Ueyama return l().getValue() % rv;
11413837f427SRui Ueyama error(loc + ": modulo by zero");
1142067617f9SRui Ueyama return 0;
11437b91e213SGeorge Rimar };
11447b91e213SGeorge Rimar }
11453837f427SRui Ueyama if (op == "<<")
11463837f427SRui Ueyama return [=] { return l().getValue() << r().getValue(); };
11473837f427SRui Ueyama if (op == ">>")
11483837f427SRui Ueyama return [=] { return l().getValue() >> r().getValue(); };
11493837f427SRui Ueyama if (op == "<")
11503837f427SRui Ueyama return [=] { return l().getValue() < r().getValue(); };
11513837f427SRui Ueyama if (op == ">")
11523837f427SRui Ueyama return [=] { return l().getValue() > r().getValue(); };
11533837f427SRui Ueyama if (op == ">=")
11543837f427SRui Ueyama return [=] { return l().getValue() >= r().getValue(); };
11553837f427SRui Ueyama if (op == "<=")
11563837f427SRui Ueyama return [=] { return l().getValue() <= r().getValue(); };
11573837f427SRui Ueyama if (op == "==")
11583837f427SRui Ueyama return [=] { return l().getValue() == r().getValue(); };
11593837f427SRui Ueyama if (op == "!=")
11603837f427SRui Ueyama return [=] { return l().getValue() != r().getValue(); };
11613837f427SRui Ueyama if (op == "||")
11623837f427SRui Ueyama return [=] { return l().getValue() || r().getValue(); };
11633837f427SRui Ueyama if (op == "&&")
11643837f427SRui Ueyama return [=] { return l().getValue() && r().getValue(); };
11653837f427SRui Ueyama if (op == "&")
11663837f427SRui Ueyama return [=] { return bitAnd(l(), r()); };
11673837f427SRui Ueyama if (op == "|")
11683837f427SRui Ueyama return [=] { return bitOr(l(), r()); };
11692ec34544SRui Ueyama llvm_unreachable("invalid operator");
11702ec34544SRui Ueyama }
11712ec34544SRui Ueyama
11722ec34544SRui Ueyama // This is a part of the operator-precedence parser. This function
11732ec34544SRui Ueyama // assumes that the remaining token stream starts with an operator.
readExpr1(Expr lhs,int minPrec)11743837f427SRui Ueyama Expr ScriptParser::readExpr1(Expr lhs, int minPrec) {
1175b8a59c8aSBob Haarman while (!atEOF() && !errorCount()) {
11762ec34544SRui Ueyama // Read an operator and an expression.
11773837f427SRui Ueyama StringRef op1 = peek();
11783837f427SRui Ueyama if (precedence(op1) < minPrec)
11792ec34544SRui Ueyama break;
1180b0d6dd39SFangrui Song if (consume("?"))
1181b0d6dd39SFangrui Song return readTernary(lhs);
11822ec34544SRui Ueyama skip();
11833837f427SRui Ueyama Expr rhs = readPrimary();
11842ec34544SRui Ueyama
11852ec34544SRui Ueyama // Evaluate the remaining part of the expression first if the
11862ec34544SRui Ueyama // next operator has greater precedence than the previous one.
11872ec34544SRui Ueyama // For example, if we have read "+" and "3", and if the next
11882ec34544SRui Ueyama // operator is "*", then we'll evaluate 3 * ... part first.
11892ec34544SRui Ueyama while (!atEOF()) {
11903837f427SRui Ueyama StringRef op2 = peek();
11913837f427SRui Ueyama if (precedence(op2) <= precedence(op1))
11922ec34544SRui Ueyama break;
11933837f427SRui Ueyama rhs = readExpr1(rhs, precedence(op2));
11942ec34544SRui Ueyama }
11952ec34544SRui Ueyama
11963837f427SRui Ueyama lhs = combine(op1, lhs, rhs);
11972ec34544SRui Ueyama }
11983837f427SRui Ueyama return lhs;
11992ec34544SRui Ueyama }
12002ec34544SRui Ueyama
getPageSize()12015fb17128SGeorge Rimar Expr ScriptParser::getPageSize() {
12023837f427SRui Ueyama std::string location = getCurrentLocation();
12035fb17128SGeorge Rimar return [=]() -> uint64_t {
12043837f427SRui Ueyama if (target)
12053837f427SRui Ueyama return config->commonPageSize;
12063837f427SRui Ueyama error(location + ": unable to calculate page size");
12075fb17128SGeorge Rimar return 4096; // Return a dummy value.
12085fb17128SGeorge Rimar };
12095fb17128SGeorge Rimar }
12105fb17128SGeorge Rimar
readConstant()12115fb17128SGeorge Rimar Expr ScriptParser::readConstant() {
12123837f427SRui Ueyama StringRef s = readParenLiteral();
12133837f427SRui Ueyama if (s == "COMMONPAGESIZE")
12145fb17128SGeorge Rimar return getPageSize();
12153837f427SRui Ueyama if (s == "MAXPAGESIZE")
12163837f427SRui Ueyama return [] { return config->maxPageSize; };
12173837f427SRui Ueyama setError("unknown constant: " + s);
1218b068b037SGeorge Rimar return [] { return 0; };
12192ec34544SRui Ueyama }
12202ec34544SRui Ueyama
12215c65088fSRui Ueyama // Parses Tok as an integer. It recognizes hexadecimal (prefixed with
12225c65088fSRui Ueyama // "0x" or suffixed with "H") and decimal numbers. Decimal numbers may
12235c65088fSRui Ueyama // have "K" (Ki) or "M" (Mi) suffixes.
parseInt(StringRef tok)12243837f427SRui Ueyama static Optional<uint64_t> parseInt(StringRef tok) {
12252ec34544SRui Ueyama // Hexadecimal
12263837f427SRui Ueyama uint64_t val;
12273c6f8ca7SMartin Storsjö if (tok.startswith_insensitive("0x")) {
12283837f427SRui Ueyama if (!to_integer(tok.substr(2), val, 16))
12294092016bSRui Ueyama return None;
12303837f427SRui Ueyama return val;
12314092016bSRui Ueyama }
12323c6f8ca7SMartin Storsjö if (tok.endswith_insensitive("H")) {
12333837f427SRui Ueyama if (!to_integer(tok.drop_back(), val, 16))
12344092016bSRui Ueyama return None;
12353837f427SRui Ueyama return val;
12364092016bSRui Ueyama }
12372ec34544SRui Ueyama
12382ec34544SRui Ueyama // Decimal
12393c6f8ca7SMartin Storsjö if (tok.endswith_insensitive("K")) {
12403837f427SRui Ueyama if (!to_integer(tok.drop_back(), val, 10))
12415c65088fSRui Ueyama return None;
12423837f427SRui Ueyama return val * 1024;
12432ec34544SRui Ueyama }
12443c6f8ca7SMartin Storsjö if (tok.endswith_insensitive("M")) {
12453837f427SRui Ueyama if (!to_integer(tok.drop_back(), val, 10))
12465c65088fSRui Ueyama return None;
12473837f427SRui Ueyama return val * 1024 * 1024;
12485c65088fSRui Ueyama }
12493837f427SRui Ueyama if (!to_integer(tok, val, 10))
12505c65088fSRui Ueyama return None;
12513837f427SRui Ueyama return val;
12522ec34544SRui Ueyama }
12532ec34544SRui Ueyama
readByteCommand(StringRef tok)12543837f427SRui Ueyama ByteCommand *ScriptParser::readByteCommand(StringRef tok) {
12553837f427SRui Ueyama int size = StringSwitch<int>(tok)
12562ec34544SRui Ueyama .Case("BYTE", 1)
12572ec34544SRui Ueyama .Case("SHORT", 2)
12582ec34544SRui Ueyama .Case("LONG", 4)
12592ec34544SRui Ueyama .Case("QUAD", 8)
12602ec34544SRui Ueyama .Default(-1);
12613837f427SRui Ueyama if (size == -1)
12622ec34544SRui Ueyama return nullptr;
126384bcabcbSGeorge Rimar
12643837f427SRui Ueyama size_t oldPos = pos;
12653837f427SRui Ueyama Expr e = readParenExpr();
12663837f427SRui Ueyama std::string commandString =
12673837f427SRui Ueyama tok.str() + " " +
12683837f427SRui Ueyama llvm::join(tokens.begin() + oldPos, tokens.begin() + pos, " ");
12693837f427SRui Ueyama return make<ByteCommand>(e, size, commandString);
12702ec34544SRui Ueyama }
12712ec34544SRui Ueyama
parseFlag(StringRef tok)1272dbd0ad33SPeter Smith static llvm::Optional<uint64_t> parseFlag(StringRef tok) {
1273dbd0ad33SPeter Smith if (llvm::Optional<uint64_t> asInt = parseInt(tok))
1274dbd0ad33SPeter Smith return asInt;
1275dbd0ad33SPeter Smith #define CASE_ENT(enum) #enum, ELF::enum
1276dbd0ad33SPeter Smith return StringSwitch<llvm::Optional<uint64_t>>(tok)
1277dbd0ad33SPeter Smith .Case(CASE_ENT(SHF_WRITE))
1278dbd0ad33SPeter Smith .Case(CASE_ENT(SHF_ALLOC))
1279dbd0ad33SPeter Smith .Case(CASE_ENT(SHF_EXECINSTR))
1280dbd0ad33SPeter Smith .Case(CASE_ENT(SHF_MERGE))
1281dbd0ad33SPeter Smith .Case(CASE_ENT(SHF_STRINGS))
1282dbd0ad33SPeter Smith .Case(CASE_ENT(SHF_INFO_LINK))
1283dbd0ad33SPeter Smith .Case(CASE_ENT(SHF_LINK_ORDER))
1284dbd0ad33SPeter Smith .Case(CASE_ENT(SHF_OS_NONCONFORMING))
1285dbd0ad33SPeter Smith .Case(CASE_ENT(SHF_GROUP))
1286dbd0ad33SPeter Smith .Case(CASE_ENT(SHF_TLS))
1287dbd0ad33SPeter Smith .Case(CASE_ENT(SHF_COMPRESSED))
1288dbd0ad33SPeter Smith .Case(CASE_ENT(SHF_EXCLUDE))
1289dbd0ad33SPeter Smith .Case(CASE_ENT(SHF_ARM_PURECODE))
1290dbd0ad33SPeter Smith .Default(None);
1291dbd0ad33SPeter Smith #undef CASE_ENT
1292dbd0ad33SPeter Smith }
1293dbd0ad33SPeter Smith
1294dbd0ad33SPeter Smith // Reads the '(' <flags> ')' list of section flags in
1295dbd0ad33SPeter Smith // INPUT_SECTION_FLAGS '(' <flags> ')' in the
1296dbd0ad33SPeter Smith // following form:
1297dbd0ad33SPeter Smith // <flags> ::= <flag>
1298dbd0ad33SPeter Smith // | <flags> & flag
1299dbd0ad33SPeter Smith // <flag> ::= Recognized Flag Name, or Integer value of flag.
1300dbd0ad33SPeter Smith // If the first character of <flag> is a ! then this means without flag,
1301dbd0ad33SPeter Smith // otherwise with flag.
1302dbd0ad33SPeter Smith // Example: SHF_EXECINSTR & !SHF_WRITE means with flag SHF_EXECINSTR and
1303dbd0ad33SPeter Smith // without flag SHF_WRITE.
readInputSectionFlags()1304dbd0ad33SPeter Smith std::pair<uint64_t, uint64_t> ScriptParser::readInputSectionFlags() {
1305dbd0ad33SPeter Smith uint64_t withFlags = 0;
1306dbd0ad33SPeter Smith uint64_t withoutFlags = 0;
1307dbd0ad33SPeter Smith expect("(");
1308dbd0ad33SPeter Smith while (!errorCount()) {
1309dbd0ad33SPeter Smith StringRef tok = unquote(next());
1310dbd0ad33SPeter Smith bool without = tok.consume_front("!");
1311dbd0ad33SPeter Smith if (llvm::Optional<uint64_t> flag = parseFlag(tok)) {
1312dbd0ad33SPeter Smith if (without)
1313dbd0ad33SPeter Smith withoutFlags |= *flag;
1314dbd0ad33SPeter Smith else
1315dbd0ad33SPeter Smith withFlags |= *flag;
1316dbd0ad33SPeter Smith } else {
1317dbd0ad33SPeter Smith setError("unrecognised flag: " + tok);
1318dbd0ad33SPeter Smith }
1319dbd0ad33SPeter Smith if (consume(")"))
1320dbd0ad33SPeter Smith break;
1321dbd0ad33SPeter Smith if (!consume("&")) {
1322dbd0ad33SPeter Smith next();
1323dbd0ad33SPeter Smith setError("expected & or )");
1324dbd0ad33SPeter Smith }
1325dbd0ad33SPeter Smith }
1326dbd0ad33SPeter Smith return std::make_pair(withFlags, withoutFlags);
1327dbd0ad33SPeter Smith }
1328dbd0ad33SPeter Smith
readParenLiteral()13292ec34544SRui Ueyama StringRef ScriptParser::readParenLiteral() {
13302ec34544SRui Ueyama expect("(");
13313837f427SRui Ueyama bool orig = inExpr;
13323837f427SRui Ueyama inExpr = false;
13333837f427SRui Ueyama StringRef tok = next();
13343837f427SRui Ueyama inExpr = orig;
13352ec34544SRui Ueyama expect(")");
13363837f427SRui Ueyama return tok;
13372ec34544SRui Ueyama }
13382ec34544SRui Ueyama
checkIfExists(const OutputSection & osec,StringRef location)13399e9c86fdSFangrui Song static void checkIfExists(const OutputSection &osec, StringRef location) {
13409e9c86fdSFangrui Song if (osec.location.empty() && script->errorOnMissingSection)
13419e9c86fdSFangrui Song error(location + ": undefined section " + osec.name);
134205c4f67cSRafael Espindola }
134305c4f67cSRafael Espindola
isValidSymbolName(StringRef s)1344e4f385d8SFangrui Song static bool isValidSymbolName(StringRef s) {
1345e4f385d8SFangrui Song auto valid = [](char c) {
1346e4f385d8SFangrui Song return isAlnum(c) || c == '$' || c == '.' || c == '_';
1347e4f385d8SFangrui Song };
1348e4f385d8SFangrui Song return !s.empty() && !isDigit(s[0]) && llvm::all_of(s, valid);
1349e4f385d8SFangrui Song }
1350e4f385d8SFangrui Song
readPrimary()13512ec34544SRui Ueyama Expr ScriptParser::readPrimary() {
13522ec34544SRui Ueyama if (peek() == "(")
13532ec34544SRui Ueyama return readParenExpr();
13542ec34544SRui Ueyama
13555c65088fSRui Ueyama if (consume("~")) {
13563837f427SRui Ueyama Expr e = readPrimary();
13573837f427SRui Ueyama return [=] { return ~e().getValue(); };
13582ec34544SRui Ueyama }
13596f1d954eSHafiz Abid Qadeer if (consume("!")) {
13603837f427SRui Ueyama Expr e = readPrimary();
13613837f427SRui Ueyama return [=] { return !e().getValue(); };
13626f1d954eSHafiz Abid Qadeer }
13635c65088fSRui Ueyama if (consume("-")) {
13643837f427SRui Ueyama Expr e = readPrimary();
13653837f427SRui Ueyama return [=] { return -e().getValue(); };
13662ec34544SRui Ueyama }
13672ec34544SRui Ueyama
13683837f427SRui Ueyama StringRef tok = next();
13693837f427SRui Ueyama std::string location = getCurrentLocation();
13705c65088fSRui Ueyama
13712ec34544SRui Ueyama // Built-in functions are parsed here.
13722ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html.
13733837f427SRui Ueyama if (tok == "ABSOLUTE") {
13743837f427SRui Ueyama Expr inner = readParenExpr();
13752ec34544SRui Ueyama return [=] {
13763837f427SRui Ueyama ExprValue i = inner();
13773837f427SRui Ueyama i.forceAbsolute = true;
13783837f427SRui Ueyama return i;
13792ec34544SRui Ueyama };
13802ec34544SRui Ueyama }
13813837f427SRui Ueyama if (tok == "ADDR") {
13823837f427SRui Ueyama StringRef name = readParenLiteral();
13836c814931SFangrui Song OutputSection *osec = &script->getOrCreateOutputSection(name)->osec;
13849e9c86fdSFangrui Song osec->usedInExpression = true;
138541c7ab4aSGeorge Rimar return [=]() -> ExprValue {
13869e9c86fdSFangrui Song checkIfExists(*osec, location);
13879e9c86fdSFangrui Song return {osec, false, 0, location};
138841c7ab4aSGeorge Rimar };
13892ec34544SRui Ueyama }
13903837f427SRui Ueyama if (tok == "ALIGN") {
13912ec34544SRui Ueyama expect("(");
13923837f427SRui Ueyama Expr e = readExpr();
1393f22ec9ddSGeorge Rimar if (consume(")")) {
13943837f427SRui Ueyama e = checkAlignment(e, location);
1395*85cfd917SFangrui Song return [=] { return alignToPowerOf2(script->getDot(), e().getValue()); };
1396f22ec9ddSGeorge Rimar }
1397b579c439SRui Ueyama expect(",");
13983837f427SRui Ueyama Expr e2 = checkAlignment(readExpr(), location);
13992ec34544SRui Ueyama expect(")");
14003c6de1a6SPetr Hosek return [=] {
14013837f427SRui Ueyama ExprValue v = e();
14023837f427SRui Ueyama v.alignment = e2().getValue();
14033837f427SRui Ueyama return v;
14043c6de1a6SPetr Hosek };
14052ec34544SRui Ueyama }
14063837f427SRui Ueyama if (tok == "ALIGNOF") {
14073837f427SRui Ueyama StringRef name = readParenLiteral();
14086c814931SFangrui Song OutputSection *osec = &script->getOrCreateOutputSection(name)->osec;
1409617e2f98SRui Ueyama return [=] {
14109e9c86fdSFangrui Song checkIfExists(*osec, location);
14119e9c86fdSFangrui Song return osec->alignment;
1412617e2f98SRui Ueyama };
14132ec34544SRui Ueyama }
14143837f427SRui Ueyama if (tok == "ASSERT")
1415d30a78b3SGeorge Rimar return readAssert();
14163837f427SRui Ueyama if (tok == "CONSTANT")
14175fb17128SGeorge Rimar return readConstant();
14183837f427SRui Ueyama if (tok == "DATA_SEGMENT_ALIGN") {
14192ec34544SRui Ueyama expect("(");
14203837f427SRui Ueyama Expr e = readExpr();
14212ec34544SRui Ueyama expect(",");
14222ec34544SRui Ueyama readExpr();
14232ec34544SRui Ueyama expect(")");
14245a44980fSFangrui Song seenDataAlign = true;
142560833f6eSGeorge Rimar return [=] {
1426*85cfd917SFangrui Song uint64_t align = std::max(uint64_t(1), e().getValue());
1427*85cfd917SFangrui Song return (script->getDot() + align - 1) & -align;
142860833f6eSGeorge Rimar };
14292ec34544SRui Ueyama }
14303837f427SRui Ueyama if (tok == "DATA_SEGMENT_END") {
14312ec34544SRui Ueyama expect("(");
14322ec34544SRui Ueyama expect(".");
14332ec34544SRui Ueyama expect(")");
14343837f427SRui Ueyama return [] { return script->getDot(); };
14352ec34544SRui Ueyama }
14363837f427SRui Ueyama if (tok == "DATA_SEGMENT_RELRO_END") {
14372ec34544SRui Ueyama // GNU linkers implements more complicated logic to handle
14382ec34544SRui Ueyama // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and
14392ec34544SRui Ueyama // just align to the next page boundary for simplicity.
14402ec34544SRui Ueyama expect("(");
14412ec34544SRui Ueyama readExpr();
14422ec34544SRui Ueyama expect(",");
14432ec34544SRui Ueyama readExpr();
14442ec34544SRui Ueyama expect(")");
14455a44980fSFangrui Song seenRelroEnd = true;
14463837f427SRui Ueyama Expr e = getPageSize();
1447*85cfd917SFangrui Song return [=] { return alignToPowerOf2(script->getDot(), e().getValue()); };
14482ec34544SRui Ueyama }
14493837f427SRui Ueyama if (tok == "DEFINED") {
1450e7a7ad13SFangrui Song StringRef name = unquote(readParenLiteral());
14511f166edeSHafiz Abid Qadeer return [=] {
14521f166edeSHafiz Abid Qadeer Symbol *b = symtab->find(name);
14531f166edeSHafiz Abid Qadeer return (b && b->isDefined()) ? 1 : 0;
14541f166edeSHafiz Abid Qadeer };
14552ec34544SRui Ueyama }
14563837f427SRui Ueyama if (tok == "LENGTH") {
14573837f427SRui Ueyama StringRef name = readParenLiteral();
14583837f427SRui Ueyama if (script->memoryRegions.count(name) == 0) {
14593837f427SRui Ueyama setError("memory region not defined: " + name);
1460b068b037SGeorge Rimar return [] { return 0; };
1461b068b037SGeorge Rimar }
146292b5b980SFangrui Song return script->memoryRegions[name]->length;
146391b95b61SRui Ueyama }
14643837f427SRui Ueyama if (tok == "LOADADDR") {
14653837f427SRui Ueyama StringRef name = readParenLiteral();
14666c814931SFangrui Song OutputSection *osec = &script->getOrCreateOutputSection(name)->osec;
14679e9c86fdSFangrui Song osec->usedInExpression = true;
1468617e2f98SRui Ueyama return [=] {
14699e9c86fdSFangrui Song checkIfExists(*osec, location);
14709e9c86fdSFangrui Song return osec->getLMA();
1471617e2f98SRui Ueyama };
14722ec34544SRui Ueyama }
1473fa1145a8SIsaac Richter if (tok == "LOG2CEIL") {
1474fa1145a8SIsaac Richter expect("(");
1475fa1145a8SIsaac Richter Expr a = readExpr();
1476fa1145a8SIsaac Richter expect(")");
1477fa1145a8SIsaac Richter return [=] {
1478fa1145a8SIsaac Richter // LOG2CEIL(0) is defined to be 0.
1479fa1145a8SIsaac Richter return llvm::Log2_64_Ceil(std::max(a().getValue(), UINT64_C(1)));
1480fa1145a8SIsaac Richter };
1481fa1145a8SIsaac Richter }
14823837f427SRui Ueyama if (tok == "MAX" || tok == "MIN") {
1483fd11560fSGeorge Rimar expect("(");
14843837f427SRui Ueyama Expr a = readExpr();
1485fd11560fSGeorge Rimar expect(",");
14863837f427SRui Ueyama Expr b = readExpr();
1487fd11560fSGeorge Rimar expect(")");
14883837f427SRui Ueyama if (tok == "MIN")
14893837f427SRui Ueyama return [=] { return std::min(a().getValue(), b().getValue()); };
14903837f427SRui Ueyama return [=] { return std::max(a().getValue(), b().getValue()); };
1491fd11560fSGeorge Rimar }
14923837f427SRui Ueyama if (tok == "ORIGIN") {
14933837f427SRui Ueyama StringRef name = readParenLiteral();
14943837f427SRui Ueyama if (script->memoryRegions.count(name) == 0) {
14953837f427SRui Ueyama setError("memory region not defined: " + name);
1496b068b037SGeorge Rimar return [] { return 0; };
1497b068b037SGeorge Rimar }
149892b5b980SFangrui Song return script->memoryRegions[name]->origin;
149991b95b61SRui Ueyama }
15003837f427SRui Ueyama if (tok == "SEGMENT_START") {
15012ec34544SRui Ueyama expect("(");
15022ec34544SRui Ueyama skip();
15032ec34544SRui Ueyama expect(",");
15043837f427SRui Ueyama Expr e = readExpr();
15052ec34544SRui Ueyama expect(")");
15063837f427SRui Ueyama return [=] { return e(); };
15072ec34544SRui Ueyama }
15083837f427SRui Ueyama if (tok == "SIZEOF") {
15093837f427SRui Ueyama StringRef name = readParenLiteral();
15106c814931SFangrui Song OutputSection *cmd = &script->getOrCreateOutputSection(name)->osec;
151105c4f67cSRafael Espindola // Linker script does not create an output section if its content is empty.
151205c4f67cSRafael Espindola // We want to allow SIZEOF(.foo) where .foo is a section which happened to
151305c4f67cSRafael Espindola // be empty.
15143837f427SRui Ueyama return [=] { return cmd->size; };
15152ec34544SRui Ueyama }
15163837f427SRui Ueyama if (tok == "SIZEOF_HEADERS")
151707837b8fSFangrui Song return [=] { return elf::getHeaderSize(); };
15182ec34544SRui Ueyama
15194eb2eccbSRui Ueyama // Tok is the dot.
15203837f427SRui Ueyama if (tok == ".")
15213837f427SRui Ueyama return [=] { return script->getSymbolValue(tok, location); };
15224eb2eccbSRui Ueyama
15232ec34544SRui Ueyama // Tok is a literal number.
15243837f427SRui Ueyama if (Optional<uint64_t> val = parseInt(tok))
15253837f427SRui Ueyama return [=] { return *val; };
15262ec34544SRui Ueyama
15272ec34544SRui Ueyama // Tok is a symbol name.
15282bf06d93SFangrui Song if (tok.startswith("\""))
1529e7a7ad13SFangrui Song tok = unquote(tok);
15302bf06d93SFangrui Song else if (!isValidSymbolName(tok))
15313837f427SRui Ueyama setError("malformed number: " + tok);
15323837f427SRui Ueyama script->referencedSymbols.push_back(tok);
15333837f427SRui Ueyama return [=] { return script->getSymbolValue(tok, location); };
15342ec34544SRui Ueyama }
15352ec34544SRui Ueyama
readTernary(Expr cond)15363837f427SRui Ueyama Expr ScriptParser::readTernary(Expr cond) {
15373837f427SRui Ueyama Expr l = readExpr();
15382ec34544SRui Ueyama expect(":");
15393837f427SRui Ueyama Expr r = readExpr();
15403837f427SRui Ueyama return [=] { return cond().getValue() ? l() : r(); };
15412ec34544SRui Ueyama }
15422ec34544SRui Ueyama
readParenExpr()15432ec34544SRui Ueyama Expr ScriptParser::readParenExpr() {
15442ec34544SRui Ueyama expect("(");
15453837f427SRui Ueyama Expr e = readExpr();
15462ec34544SRui Ueyama expect(")");
15473837f427SRui Ueyama return e;
15482ec34544SRui Ueyama }
15492ec34544SRui Ueyama
readOutputSectionPhdrs()1550a1c2ee01SFangrui Song SmallVector<StringRef, 0> ScriptParser::readOutputSectionPhdrs() {
1551a1c2ee01SFangrui Song SmallVector<StringRef, 0> phdrs;
1552b8a59c8aSBob Haarman while (!errorCount() && peek().startswith(":")) {
15533837f427SRui Ueyama StringRef tok = next();
15543837f427SRui Ueyama phdrs.push_back((tok.size() == 1) ? next() : tok.substr(1));
15552ec34544SRui Ueyama }
15563837f427SRui Ueyama return phdrs;
15572ec34544SRui Ueyama }
15582ec34544SRui Ueyama
15592ec34544SRui Ueyama // Read a program header type name. The next token must be a
15602ec34544SRui Ueyama // name of a program header type or a constant (e.g. "0x3").
readPhdrType()15612ec34544SRui Ueyama unsigned ScriptParser::readPhdrType() {
15623837f427SRui Ueyama StringRef tok = next();
15633837f427SRui Ueyama if (Optional<uint64_t> val = parseInt(tok))
15643837f427SRui Ueyama return *val;
15652ec34544SRui Ueyama
15663837f427SRui Ueyama unsigned ret = StringSwitch<unsigned>(tok)
15672ec34544SRui Ueyama .Case("PT_NULL", PT_NULL)
15682ec34544SRui Ueyama .Case("PT_LOAD", PT_LOAD)
15692ec34544SRui Ueyama .Case("PT_DYNAMIC", PT_DYNAMIC)
15702ec34544SRui Ueyama .Case("PT_INTERP", PT_INTERP)
15712ec34544SRui Ueyama .Case("PT_NOTE", PT_NOTE)
15722ec34544SRui Ueyama .Case("PT_SHLIB", PT_SHLIB)
15732ec34544SRui Ueyama .Case("PT_PHDR", PT_PHDR)
15742ec34544SRui Ueyama .Case("PT_TLS", PT_TLS)
15752ec34544SRui Ueyama .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME)
15762ec34544SRui Ueyama .Case("PT_GNU_STACK", PT_GNU_STACK)
15772ec34544SRui Ueyama .Case("PT_GNU_RELRO", PT_GNU_RELRO)
15782ec34544SRui Ueyama .Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE)
15792ec34544SRui Ueyama .Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED)
15802ec34544SRui Ueyama .Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA)
15812ec34544SRui Ueyama .Default(-1);
15822ec34544SRui Ueyama
15833837f427SRui Ueyama if (ret == (unsigned)-1) {
15843837f427SRui Ueyama setError("invalid program header type: " + tok);
15852ec34544SRui Ueyama return PT_NULL;
15862ec34544SRui Ueyama }
15873837f427SRui Ueyama return ret;
15882ec34544SRui Ueyama }
15892ec34544SRui Ueyama
15902ec34544SRui Ueyama // Reads an anonymous version declaration.
readAnonymousDeclaration()15912ec34544SRui Ueyama void ScriptParser::readAnonymousDeclaration() {
159264038ef8SFangrui Song SmallVector<SymbolVersion, 0> locals;
159364038ef8SFangrui Song SmallVector<SymbolVersion, 0> globals;
15943837f427SRui Ueyama std::tie(locals, globals) = readSymbols();
1595e28a70daSFangrui Song for (const SymbolVersion &pat : locals)
159600809c88SFangrui Song config->versionDefinitions[VER_NDX_LOCAL].localPatterns.push_back(pat);
1597e28a70daSFangrui Song for (const SymbolVersion &pat : globals)
159800809c88SFangrui Song config->versionDefinitions[VER_NDX_GLOBAL].nonLocalPatterns.push_back(pat);
15992ec34544SRui Ueyama
16002ec34544SRui Ueyama expect(";");
16012ec34544SRui Ueyama }
16022ec34544SRui Ueyama
16032ec34544SRui Ueyama // Reads a non-anonymous version definition,
16042ec34544SRui Ueyama // e.g. "VerStr { global: foo; bar; local: *; };".
readVersionDeclaration(StringRef verStr)16053837f427SRui Ueyama void ScriptParser::readVersionDeclaration(StringRef verStr) {
16062ec34544SRui Ueyama // Read a symbol list.
160764038ef8SFangrui Song SmallVector<SymbolVersion, 0> locals;
160864038ef8SFangrui Song SmallVector<SymbolVersion, 0> globals;
16093837f427SRui Ueyama std::tie(locals, globals) = readSymbols();
16102ec34544SRui Ueyama
16112ec34544SRui Ueyama // Create a new version definition and add that to the global symbols.
16123837f427SRui Ueyama VersionDefinition ver;
16133837f427SRui Ueyama ver.name = verStr;
161400809c88SFangrui Song ver.nonLocalPatterns = std::move(globals);
161500809c88SFangrui Song ver.localPatterns = std::move(locals);
1616e28a70daSFangrui Song ver.id = config->versionDefinitions.size();
16173837f427SRui Ueyama config->versionDefinitions.push_back(ver);
16182ec34544SRui Ueyama
16192ec34544SRui Ueyama // Each version may have a parent version. For example, "Ver2"
16202ec34544SRui Ueyama // defined as "Ver2 { global: foo; local: *; } Ver1;" has "Ver1"
16212ec34544SRui Ueyama // as a parent. This version hierarchy is, probably against your
16222ec34544SRui Ueyama // instinct, purely for hint; the runtime doesn't care about it
16232ec34544SRui Ueyama // at all. In LLD, we simply ignore it.
16245f380403SFangrui Song if (next() != ";")
16252ec34544SRui Ueyama expect(";");
16262ec34544SRui Ueyama }
16272ec34544SRui Ueyama
hasWildcard(StringRef s)162849279ca1SFangrui Song bool elf::hasWildcard(StringRef s) {
16293837f427SRui Ueyama return s.find_first_of("?*[") != StringRef::npos;
16301e77ad14SRui Ueyama }
16311e77ad14SRui Ueyama
16322ec34544SRui Ueyama // Reads a list of symbols, e.g. "{ global: foo; bar; local: *; };".
163364038ef8SFangrui Song std::pair<SmallVector<SymbolVersion, 0>, SmallVector<SymbolVersion, 0>>
readSymbols()16342ec34544SRui Ueyama ScriptParser::readSymbols() {
163564038ef8SFangrui Song SmallVector<SymbolVersion, 0> locals;
163664038ef8SFangrui Song SmallVector<SymbolVersion, 0> globals;
163764038ef8SFangrui Song SmallVector<SymbolVersion, 0> *v = &globals;
16382ec34544SRui Ueyama
1639b8a59c8aSBob Haarman while (!errorCount()) {
16402ec34544SRui Ueyama if (consume("}"))
16412ec34544SRui Ueyama break;
16422ec34544SRui Ueyama if (consumeLabel("local")) {
16433837f427SRui Ueyama v = &locals;
16442ec34544SRui Ueyama continue;
16452ec34544SRui Ueyama }
16462ec34544SRui Ueyama if (consumeLabel("global")) {
16473837f427SRui Ueyama v = &globals;
16482ec34544SRui Ueyama continue;
16492ec34544SRui Ueyama }
16502ec34544SRui Ueyama
16512ec34544SRui Ueyama if (consume("extern")) {
165264038ef8SFangrui Song SmallVector<SymbolVersion, 0> ext = readVersionExtern();
16533837f427SRui Ueyama v->insert(v->end(), ext.begin(), ext.end());
16542ec34544SRui Ueyama } else {
16553837f427SRui Ueyama StringRef tok = next();
16563837f427SRui Ueyama v->push_back({unquote(tok), false, hasWildcard(tok)});
16572ec34544SRui Ueyama }
16582ec34544SRui Ueyama expect(";");
16592ec34544SRui Ueyama }
16603837f427SRui Ueyama return {locals, globals};
16612ec34544SRui Ueyama }
16622ec34544SRui Ueyama
16632ec34544SRui Ueyama // Reads an "extern C++" directive, e.g.,
16642ec34544SRui Ueyama // "extern "C++" { ns::*; "f(int, double)"; };"
166517324d8bSRui Ueyama //
166617324d8bSRui Ueyama // The last semicolon is optional. E.g. this is OK:
166717324d8bSRui Ueyama // "extern "C++" { ns::*; "f(int, double)" };"
readVersionExtern()166864038ef8SFangrui Song SmallVector<SymbolVersion, 0> ScriptParser::readVersionExtern() {
16693837f427SRui Ueyama StringRef tok = next();
16703837f427SRui Ueyama bool isCXX = tok == "\"C++\"";
16713837f427SRui Ueyama if (!isCXX && tok != "\"C\"")
16722ec34544SRui Ueyama setError("Unknown language");
16732ec34544SRui Ueyama expect("{");
16742ec34544SRui Ueyama
167564038ef8SFangrui Song SmallVector<SymbolVersion, 0> ret;
1676b8a59c8aSBob Haarman while (!errorCount() && peek() != "}") {
16773837f427SRui Ueyama StringRef tok = next();
16783837f427SRui Ueyama ret.push_back(
16793837f427SRui Ueyama {unquote(tok), isCXX, !tok.startswith("\"") && hasWildcard(tok)});
168017324d8bSRui Ueyama if (consume("}"))
16813837f427SRui Ueyama return ret;
16822ec34544SRui Ueyama expect(";");
16832ec34544SRui Ueyama }
16842ec34544SRui Ueyama
16852ec34544SRui Ueyama expect("}");
16863837f427SRui Ueyama return ret;
16872ec34544SRui Ueyama }
16882ec34544SRui Ueyama
readMemoryAssignment(StringRef s1,StringRef s2,StringRef s3)168992b5b980SFangrui Song Expr ScriptParser::readMemoryAssignment(StringRef s1, StringRef s2,
16903837f427SRui Ueyama StringRef s3) {
16913837f427SRui Ueyama if (!consume(s1) && !consume(s2) && !consume(s3)) {
16923837f427SRui Ueyama setError("expected one of: " + s1 + ", " + s2 + ", or " + s3);
169392b5b980SFangrui Song return [] { return 0; };
16942ec34544SRui Ueyama }
16952ec34544SRui Ueyama expect("=");
169692b5b980SFangrui Song return readExpr();
16972ec34544SRui Ueyama }
16982ec34544SRui Ueyama
16992ec34544SRui Ueyama // Parse the MEMORY command as specified in:
17002ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/MEMORY.html
17012ec34544SRui Ueyama //
17022ec34544SRui Ueyama // MEMORY { name [(attr)] : ORIGIN = origin, LENGTH = len ... }
readMemory()17032ec34544SRui Ueyama void ScriptParser::readMemory() {
17042ec34544SRui Ueyama expect("{");
1705b8a59c8aSBob Haarman while (!errorCount() && !consume("}")) {
17063837f427SRui Ueyama StringRef tok = next();
17073837f427SRui Ueyama if (tok == "INCLUDE") {
17082e9d40d5SRui Ueyama readInclude();
17092e9d40d5SRui Ueyama continue;
17102e9d40d5SRui Ueyama }
17112ec34544SRui Ueyama
17123837f427SRui Ueyama uint32_t flags = 0;
17138cdf1c1eSIgor Kudrin uint32_t invFlags = 0;
17143837f427SRui Ueyama uint32_t negFlags = 0;
17158cdf1c1eSIgor Kudrin uint32_t negInvFlags = 0;
17162ec34544SRui Ueyama if (consume("(")) {
17178cdf1c1eSIgor Kudrin readMemoryAttributes(flags, invFlags, negFlags, negInvFlags);
17182ec34544SRui Ueyama expect(")");
17192ec34544SRui Ueyama }
17202ec34544SRui Ueyama expect(":");
17212ec34544SRui Ueyama
172292b5b980SFangrui Song Expr origin = readMemoryAssignment("ORIGIN", "org", "o");
17232ec34544SRui Ueyama expect(",");
172492b5b980SFangrui Song Expr length = readMemoryAssignment("LENGTH", "len", "l");
17252ec34544SRui Ueyama
17265f37541cSGeorge Rimar // Add the memory region to the region map.
17278cdf1c1eSIgor Kudrin MemoryRegion *mr = make<MemoryRegion>(tok, origin, length, flags, invFlags,
17288cdf1c1eSIgor Kudrin negFlags, negInvFlags);
17293837f427SRui Ueyama if (!script->memoryRegions.insert({tok, mr}).second)
17303837f427SRui Ueyama setError("region '" + tok + "' already defined");
17312ec34544SRui Ueyama }
17322ec34544SRui Ueyama }
17332ec34544SRui Ueyama
17342ec34544SRui Ueyama // This function parses the attributes used to match against section
17352ec34544SRui Ueyama // flags when placing output sections in a memory region. These flags
17362ec34544SRui Ueyama // are only used when an explicit memory region name is not used.
readMemoryAttributes(uint32_t & flags,uint32_t & invFlags,uint32_t & negFlags,uint32_t & negInvFlags)17378cdf1c1eSIgor Kudrin void ScriptParser::readMemoryAttributes(uint32_t &flags, uint32_t &invFlags,
17388cdf1c1eSIgor Kudrin uint32_t &negFlags,
17398cdf1c1eSIgor Kudrin uint32_t &negInvFlags) {
17403837f427SRui Ueyama bool invert = false;
17412ec34544SRui Ueyama
17423837f427SRui Ueyama for (char c : next().lower()) {
17438cdf1c1eSIgor Kudrin if (c == '!') {
17443837f427SRui Ueyama invert = !invert;
17458cdf1c1eSIgor Kudrin std::swap(flags, negFlags);
17468cdf1c1eSIgor Kudrin std::swap(invFlags, negInvFlags);
17478cdf1c1eSIgor Kudrin continue;
17482ec34544SRui Ueyama }
17498cdf1c1eSIgor Kudrin if (c == 'w')
17508cdf1c1eSIgor Kudrin flags |= SHF_WRITE;
17518cdf1c1eSIgor Kudrin else if (c == 'x')
17528cdf1c1eSIgor Kudrin flags |= SHF_EXECINSTR;
17538cdf1c1eSIgor Kudrin else if (c == 'a')
17548cdf1c1eSIgor Kudrin flags |= SHF_ALLOC;
17558cdf1c1eSIgor Kudrin else if (c == 'r')
17568cdf1c1eSIgor Kudrin invFlags |= SHF_WRITE;
17578cdf1c1eSIgor Kudrin else
17588cdf1c1eSIgor Kudrin setError("invalid memory region attribute");
17598cdf1c1eSIgor Kudrin }
17608cdf1c1eSIgor Kudrin
17618cdf1c1eSIgor Kudrin if (invert) {
17628cdf1c1eSIgor Kudrin std::swap(flags, negFlags);
17638cdf1c1eSIgor Kudrin std::swap(invFlags, negInvFlags);
17648cdf1c1eSIgor Kudrin }
17652ec34544SRui Ueyama }
17662ec34544SRui Ueyama
readLinkerScript(MemoryBufferRef mb)176707837b8fSFangrui Song void elf::readLinkerScript(MemoryBufferRef mb) {
1768439341b9SJames Henderson llvm::TimeTraceScope timeScope("Read linker script",
1769439341b9SJames Henderson mb.getBufferIdentifier());
17703837f427SRui Ueyama ScriptParser(mb).readLinkerScript();
17712ec34544SRui Ueyama }
17722ec34544SRui Ueyama
readVersionScript(MemoryBufferRef mb)177307837b8fSFangrui Song void elf::readVersionScript(MemoryBufferRef mb) {
1774439341b9SJames Henderson llvm::TimeTraceScope timeScope("Read version script",
1775439341b9SJames Henderson mb.getBufferIdentifier());
17763837f427SRui Ueyama ScriptParser(mb).readVersionScript();
17772ec34544SRui Ueyama }
17782ec34544SRui Ueyama
readDynamicList(MemoryBufferRef mb)177907837b8fSFangrui Song void elf::readDynamicList(MemoryBufferRef mb) {
1780439341b9SJames Henderson llvm::TimeTraceScope timeScope("Read dynamic list", mb.getBufferIdentifier());
178107837b8fSFangrui Song ScriptParser(mb).readDynamicList();
17828c7e8cceSPetr Hosek }
1783bd8cfe65SFangrui Song
readDefsym(StringRef name,MemoryBufferRef mb)178407837b8fSFangrui Song void elf::readDefsym(StringRef name, MemoryBufferRef mb) {
1785439341b9SJames Henderson llvm::TimeTraceScope timeScope("Read defsym input", name);
178607837b8fSFangrui Song ScriptParser(mb).readDefsym(name);
178707837b8fSFangrui Song }
1788