12ec34544SRui Ueyama //===- ScriptParser.cpp ---------------------------------------------------===// 22ec34544SRui Ueyama // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 62ec34544SRui Ueyama // 72ec34544SRui Ueyama //===----------------------------------------------------------------------===// 805f6b852SRui Ueyama // 905f6b852SRui Ueyama // This file contains a recursive-descendent parser for linker scripts. 1005f6b852SRui Ueyama // Parsed results are stored to Config and Script global objects. 1105f6b852SRui Ueyama // 1205f6b852SRui Ueyama //===----------------------------------------------------------------------===// 132ec34544SRui Ueyama 142ec34544SRui Ueyama #include "ScriptParser.h" 152ec34544SRui Ueyama #include "Config.h" 162ec34544SRui Ueyama #include "Driver.h" 172ec34544SRui Ueyama #include "InputSection.h" 182ec34544SRui Ueyama #include "LinkerScript.h" 192ec34544SRui Ueyama #include "OutputSections.h" 202ec34544SRui Ueyama #include "ScriptLexer.h" 212ec34544SRui Ueyama #include "Symbols.h" 222ec34544SRui Ueyama #include "Target.h" 232017d52bSRui Ueyama #include "lld/Common/Memory.h" 242ec34544SRui Ueyama #include "llvm/ADT/SmallString.h" 252ec34544SRui Ueyama #include "llvm/ADT/StringRef.h" 260440be4aSRui Ueyama #include "llvm/ADT/StringSet.h" 272ec34544SRui Ueyama #include "llvm/ADT/StringSwitch.h" 28264b5d9eSZachary Turner #include "llvm/BinaryFormat/ELF.h" 292ec34544SRui Ueyama #include "llvm/Support/Casting.h" 302ec34544SRui Ueyama #include "llvm/Support/ErrorHandling.h" 312ec34544SRui Ueyama #include "llvm/Support/FileSystem.h" 32fa1145a8SIsaac Richter #include "llvm/Support/MathExtras.h" 332ec34544SRui Ueyama #include "llvm/Support/Path.h" 34dbd0ad33SPeter Smith #include "llvm/Support/ScopedPrinter.h" 35439341b9SJames Henderson #include "llvm/Support/TimeProfiler.h" 362ec34544SRui Ueyama #include <cassert> 372ec34544SRui Ueyama #include <limits> 382ec34544SRui Ueyama #include <vector> 392ec34544SRui Ueyama 402ec34544SRui Ueyama using namespace llvm; 412ec34544SRui Ueyama using namespace llvm::ELF; 42b58079d4SRui Ueyama using namespace llvm::support::endian; 4307837b8fSFangrui Song using namespace lld; 4407837b8fSFangrui Song using namespace lld::elf; 452ec34544SRui Ueyama 4696b3fe02SRui Ueyama namespace { 4796b3fe02SRui Ueyama class ScriptParser final : ScriptLexer { 482ec34544SRui Ueyama public: 493837f427SRui Ueyama ScriptParser(MemoryBufferRef mb) : ScriptLexer(mb) { 5011ae59f0SRui Ueyama // Initialize IsUnderSysroot 513837f427SRui Ueyama if (config->sysroot == "") 5211ae59f0SRui Ueyama return; 533837f427SRui Ueyama StringRef path = mb.getBufferIdentifier(); 543837f427SRui Ueyama for (; !path.empty(); path = sys::path::parent_path(path)) { 553837f427SRui Ueyama if (!sys::fs::equivalent(config->sysroot, path)) 5611ae59f0SRui Ueyama continue; 573837f427SRui Ueyama isUnderSysroot = true; 5811ae59f0SRui Ueyama return; 5911ae59f0SRui Ueyama } 6011ae59f0SRui Ueyama } 612ec34544SRui Ueyama 622ec34544SRui Ueyama void readLinkerScript(); 632ec34544SRui Ueyama void readVersionScript(); 642ec34544SRui Ueyama void readDynamicList(); 653837f427SRui Ueyama void readDefsym(StringRef name); 662ec34544SRui Ueyama 672ec34544SRui Ueyama private: 683837f427SRui Ueyama void addFile(StringRef path); 692ec34544SRui Ueyama 702ec34544SRui Ueyama void readAsNeeded(); 712ec34544SRui Ueyama void readEntry(); 722ec34544SRui Ueyama void readExtern(); 732ec34544SRui Ueyama void readGroup(); 742ec34544SRui Ueyama void readInclude(); 751d92aa73SRui Ueyama void readInput(); 762ec34544SRui Ueyama void readMemory(); 772ec34544SRui Ueyama void readOutput(); 782ec34544SRui Ueyama void readOutputArch(); 792ec34544SRui Ueyama void readOutputFormat(); 802ec34544SRui Ueyama void readPhdrs(); 815f37541cSGeorge Rimar void readRegionAlias(); 822ec34544SRui Ueyama void readSearchDir(); 832ec34544SRui Ueyama void readSections(); 84e262bb1aSRui Ueyama void readTarget(); 852ec34544SRui Ueyama void readVersion(); 862ec34544SRui Ueyama void readVersionScriptCommand(); 872ec34544SRui Ueyama 883837f427SRui Ueyama SymbolAssignment *readSymbolAssignment(StringRef name); 893837f427SRui Ueyama ByteCommand *readByteCommand(StringRef tok); 90b0486051SSimon Atanasyan std::array<uint8_t, 4> readFill(); 913837f427SRui Ueyama bool readSectionDirective(OutputSection *cmd, StringRef tok1, StringRef tok2); 923837f427SRui Ueyama void readSectionAddressType(OutputSection *cmd); 93a582419aSGeorge Rimar OutputSection *readOverlaySectionDescription(); 943837f427SRui Ueyama OutputSection *readOutputSectionDescription(StringRef outSec); 95a582419aSGeorge Rimar std::vector<BaseCommand *> readOverlay(); 962ec34544SRui Ueyama std::vector<StringRef> readOutputSectionPhdrs(); 97dbd0ad33SPeter Smith std::pair<uint64_t, uint64_t> readInputSectionFlags(); 983837f427SRui Ueyama InputSectionDescription *readInputSectionDescription(StringRef tok); 992ec34544SRui Ueyama StringMatcher readFilePatterns(); 1002ec34544SRui Ueyama std::vector<SectionPattern> readInputSectionsList(); 101dbd0ad33SPeter Smith InputSectionDescription *readInputSectionRules(StringRef filePattern, 102dbd0ad33SPeter Smith uint64_t withFlags, 103dbd0ad33SPeter Smith uint64_t withoutFlags); 1042ec34544SRui Ueyama unsigned readPhdrType(); 1052a9aed0eSFangrui Song SortSectionPolicy peekSortKind(); 1062ec34544SRui Ueyama SortSectionPolicy readSortKind(); 1073837f427SRui Ueyama SymbolAssignment *readProvideHidden(bool provide, bool hidden); 1083837f427SRui Ueyama SymbolAssignment *readAssignment(StringRef tok); 1092ec34544SRui Ueyama void readSort(); 110d30a78b3SGeorge Rimar Expr readAssert(); 1115fb17128SGeorge Rimar Expr readConstant(); 1125fb17128SGeorge Rimar Expr getPageSize(); 1132ec34544SRui Ueyama 11492b5b980SFangrui Song Expr readMemoryAssignment(StringRef, StringRef, StringRef); 1152ec34544SRui Ueyama std::pair<uint32_t, uint32_t> readMemoryAttributes(); 1162ec34544SRui Ueyama 1173837f427SRui Ueyama Expr combine(StringRef op, Expr l, Expr r); 1182ec34544SRui Ueyama Expr readExpr(); 1193837f427SRui Ueyama Expr readExpr1(Expr lhs, int minPrec); 1202ec34544SRui Ueyama StringRef readParenLiteral(); 1212ec34544SRui Ueyama Expr readPrimary(); 1223837f427SRui Ueyama Expr readTernary(Expr cond); 1232ec34544SRui Ueyama Expr readParenExpr(); 1242ec34544SRui Ueyama 1252ec34544SRui Ueyama // For parsing version script. 1262ec34544SRui Ueyama std::vector<SymbolVersion> readVersionExtern(); 1272ec34544SRui Ueyama void readAnonymousDeclaration(); 1283837f427SRui Ueyama void readVersionDeclaration(StringRef verStr); 1292ec34544SRui Ueyama 1302ec34544SRui Ueyama std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>> 1312ec34544SRui Ueyama readSymbols(); 1322ec34544SRui Ueyama 133fd06b025SRui Ueyama // True if a script being read is in a subdirectory specified by -sysroot. 1343837f427SRui Ueyama bool isUnderSysroot = false; 1350440be4aSRui Ueyama 1360440be4aSRui Ueyama // A set to detect an INCLUDE() cycle. 1373837f427SRui Ueyama StringSet<> seen; 1382ec34544SRui Ueyama }; 13996b3fe02SRui Ueyama } // namespace 1402ec34544SRui Ueyama 1413837f427SRui Ueyama static StringRef unquote(StringRef s) { 1423837f427SRui Ueyama if (s.startswith("\"")) 1433837f427SRui Ueyama return s.substr(1, s.size() - 2); 1443837f427SRui Ueyama return s; 1451e77ad14SRui Ueyama } 1461e77ad14SRui Ueyama 1472ec34544SRui Ueyama // Some operations only support one non absolute value. Move the 1482ec34544SRui Ueyama // absolute one to the right hand side for convenience. 1493837f427SRui Ueyama static void moveAbsRight(ExprValue &a, ExprValue &b) { 1503837f427SRui Ueyama if (a.sec == nullptr || (a.forceAbsolute && !b.isAbsolute())) 1513837f427SRui Ueyama std::swap(a, b); 1523837f427SRui Ueyama if (!b.isAbsolute()) 1533837f427SRui Ueyama error(a.loc + ": at least one side of the expression must be absolute"); 1542ec34544SRui Ueyama } 1552ec34544SRui Ueyama 1563837f427SRui Ueyama static ExprValue add(ExprValue a, ExprValue b) { 1573837f427SRui Ueyama moveAbsRight(a, b); 1583837f427SRui Ueyama return {a.sec, a.forceAbsolute, a.getSectionOffset() + b.getValue(), a.loc}; 1592ec34544SRui Ueyama } 1602ec34544SRui Ueyama 1613837f427SRui Ueyama static ExprValue sub(ExprValue a, ExprValue b) { 16263a4a98eSRafael Espindola // The distance between two symbols in sections is absolute. 1633837f427SRui Ueyama if (!a.isAbsolute() && !b.isAbsolute()) 1643837f427SRui Ueyama return a.getValue() - b.getValue(); 1653837f427SRui Ueyama return {a.sec, false, a.getSectionOffset() - b.getValue(), a.loc}; 1662ec34544SRui Ueyama } 1672ec34544SRui Ueyama 1683837f427SRui Ueyama static ExprValue bitAnd(ExprValue a, ExprValue b) { 1693837f427SRui Ueyama moveAbsRight(a, b); 1703837f427SRui Ueyama return {a.sec, a.forceAbsolute, 1713837f427SRui Ueyama (a.getValue() & b.getValue()) - a.getSecAddr(), a.loc}; 1722ec34544SRui Ueyama } 1732ec34544SRui Ueyama 1743837f427SRui Ueyama static ExprValue bitOr(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 1802ec34544SRui Ueyama void ScriptParser::readDynamicList() { 1812ec34544SRui Ueyama expect("{"); 1823837f427SRui Ueyama std::vector<SymbolVersion> locals; 1833837f427SRui Ueyama std::vector<SymbolVersion> globals; 1843837f427SRui Ueyama std::tie(locals, globals) = readSymbols(); 185d72d97b3SRafael Espindola expect(";"); 186d72d97b3SRafael Espindola 187d72d97b3SRafael Espindola if (!atEOF()) { 1882ec34544SRui Ueyama setError("EOF expected, but got " + next()); 189d72d97b3SRafael Espindola return; 190d72d97b3SRafael Espindola } 1913837f427SRui Ueyama if (!locals.empty()) { 192d72d97b3SRafael Espindola setError("\"local:\" scope not supported in --dynamic-list"); 193d72d97b3SRafael Espindola return; 194d72d97b3SRafael Espindola } 195d72d97b3SRafael Espindola 1963837f427SRui Ueyama for (SymbolVersion v : globals) 1973837f427SRui Ueyama config->dynamicList.push_back(v); 1982ec34544SRui Ueyama } 1992ec34544SRui Ueyama 2002ec34544SRui Ueyama void ScriptParser::readVersionScript() { 2012ec34544SRui Ueyama readVersionScriptCommand(); 2022ec34544SRui Ueyama if (!atEOF()) 2032ec34544SRui Ueyama setError("EOF expected, but got " + next()); 2042ec34544SRui Ueyama } 2052ec34544SRui Ueyama 2062ec34544SRui Ueyama void ScriptParser::readVersionScriptCommand() { 2072ec34544SRui Ueyama if (consume("{")) { 2082ec34544SRui Ueyama readAnonymousDeclaration(); 2092ec34544SRui Ueyama return; 2102ec34544SRui Ueyama } 2112ec34544SRui Ueyama 212b8a59c8aSBob Haarman while (!atEOF() && !errorCount() && peek() != "}") { 2133837f427SRui Ueyama StringRef verStr = next(); 2143837f427SRui Ueyama if (verStr == "{") { 2152ec34544SRui Ueyama setError("anonymous version definition is used in " 2162ec34544SRui Ueyama "combination with other version definitions"); 2172ec34544SRui Ueyama return; 2182ec34544SRui Ueyama } 2192ec34544SRui Ueyama expect("{"); 2203837f427SRui Ueyama readVersionDeclaration(verStr); 2212ec34544SRui Ueyama } 2222ec34544SRui Ueyama } 2232ec34544SRui Ueyama 2242ec34544SRui Ueyama void ScriptParser::readVersion() { 2252ec34544SRui Ueyama expect("{"); 2262ec34544SRui Ueyama readVersionScriptCommand(); 2272ec34544SRui Ueyama expect("}"); 2282ec34544SRui Ueyama } 2292ec34544SRui Ueyama 2302ec34544SRui Ueyama void ScriptParser::readLinkerScript() { 2312ec34544SRui Ueyama while (!atEOF()) { 2323837f427SRui Ueyama StringRef tok = next(); 2333837f427SRui Ueyama if (tok == ";") 2342ec34544SRui Ueyama continue; 2352ec34544SRui Ueyama 2363837f427SRui Ueyama if (tok == "ENTRY") { 2372ec34544SRui Ueyama readEntry(); 2383837f427SRui Ueyama } else if (tok == "EXTERN") { 2392ec34544SRui Ueyama readExtern(); 2403837f427SRui Ueyama } else if (tok == "GROUP") { 2412ec34544SRui Ueyama readGroup(); 2423837f427SRui Ueyama } else if (tok == "INCLUDE") { 2432ec34544SRui Ueyama readInclude(); 2443837f427SRui Ueyama } else if (tok == "INPUT") { 2451d92aa73SRui Ueyama readInput(); 2463837f427SRui Ueyama } else if (tok == "MEMORY") { 2472ec34544SRui Ueyama readMemory(); 2483837f427SRui Ueyama } else if (tok == "OUTPUT") { 2492ec34544SRui Ueyama readOutput(); 2503837f427SRui Ueyama } else if (tok == "OUTPUT_ARCH") { 2512ec34544SRui Ueyama readOutputArch(); 2523837f427SRui Ueyama } else if (tok == "OUTPUT_FORMAT") { 2532ec34544SRui Ueyama readOutputFormat(); 2543837f427SRui Ueyama } else if (tok == "PHDRS") { 2552ec34544SRui Ueyama readPhdrs(); 2563837f427SRui Ueyama } else if (tok == "REGION_ALIAS") { 2575f37541cSGeorge Rimar readRegionAlias(); 2583837f427SRui Ueyama } else if (tok == "SEARCH_DIR") { 2592ec34544SRui Ueyama readSearchDir(); 2603837f427SRui Ueyama } else if (tok == "SECTIONS") { 2612ec34544SRui Ueyama readSections(); 2623837f427SRui Ueyama } else if (tok == "TARGET") { 263e262bb1aSRui Ueyama readTarget(); 2643837f427SRui Ueyama } else if (tok == "VERSION") { 2652ec34544SRui Ueyama readVersion(); 2663837f427SRui Ueyama } else if (SymbolAssignment *cmd = readAssignment(tok)) { 2673837f427SRui Ueyama script->sectionCommands.push_back(cmd); 2682ec34544SRui Ueyama } else { 2693837f427SRui Ueyama setError("unknown directive: " + tok); 2702ec34544SRui Ueyama } 2712ec34544SRui Ueyama } 2722ec34544SRui Ueyama } 2732ec34544SRui Ueyama 2743837f427SRui Ueyama void ScriptParser::readDefsym(StringRef name) { 275c1522816SGeorge Rimar if (errorCount()) 276c1522816SGeorge Rimar return; 2773837f427SRui Ueyama Expr e = readExpr(); 2788c7e8cceSPetr Hosek if (!atEOF()) 2798c7e8cceSPetr Hosek setError("EOF expected, but got " + next()); 2803837f427SRui Ueyama SymbolAssignment *cmd = make<SymbolAssignment>(name, e, getCurrentLocation()); 2813837f427SRui Ueyama script->sectionCommands.push_back(cmd); 2828c7e8cceSPetr Hosek } 2838c7e8cceSPetr Hosek 2843837f427SRui Ueyama void ScriptParser::addFile(StringRef s) { 2853837f427SRui Ueyama if (isUnderSysroot && s.startswith("/")) { 2863837f427SRui Ueyama SmallString<128> pathData; 2873837f427SRui Ueyama StringRef path = (config->sysroot + s).toStringRef(pathData); 2883837f427SRui Ueyama if (sys::fs::exists(path)) { 28949a3ad21SRui Ueyama driver->addFile(saver.save(path), /*withLOption=*/false); 2902ec34544SRui Ueyama return; 2912ec34544SRui Ueyama } 2922ec34544SRui Ueyama } 2932ec34544SRui Ueyama 2943837f427SRui Ueyama if (s.startswith("/")) { 295c384ca3cSFangrui Song // Case 1: s is an absolute path. Just open it. 29649a3ad21SRui Ueyama driver->addFile(s, /*withLOption=*/false); 2973837f427SRui Ueyama } else if (s.startswith("=")) { 298c384ca3cSFangrui Song // Case 2: relative to the sysroot. 2993837f427SRui Ueyama if (config->sysroot.empty()) 30049a3ad21SRui Ueyama driver->addFile(s.substr(1), /*withLOption=*/false); 3012ec34544SRui Ueyama else 302136d27abSRui Ueyama driver->addFile(saver.save(config->sysroot + "/" + s.substr(1)), 30349a3ad21SRui Ueyama /*withLOption=*/false); 3043837f427SRui Ueyama } else if (s.startswith("-l")) { 305c384ca3cSFangrui Song // Case 3: search in the list of library paths. 3063837f427SRui Ueyama driver->addLibrary(s.substr(2)); 307c384ca3cSFangrui Song } else { 308c384ca3cSFangrui Song // Case 4: s is a relative path. Search in the directory of the script file. 309c384ca3cSFangrui Song std::string filename = std::string(getCurrentMB().getBufferIdentifier()); 310c384ca3cSFangrui Song StringRef directory = sys::path::parent_path(filename); 311c384ca3cSFangrui Song if (!directory.empty()) { 312c384ca3cSFangrui Song SmallString<0> path(directory); 313c384ca3cSFangrui Song sys::path::append(path, s); 314c384ca3cSFangrui Song if (sys::fs::exists(path)) { 315c384ca3cSFangrui Song driver->addFile(path, /*withLOption=*/false); 316c384ca3cSFangrui Song return; 317c384ca3cSFangrui Song } 318c384ca3cSFangrui Song } 319c384ca3cSFangrui Song // Then search in the current working directory. 320c384ca3cSFangrui Song if (sys::fs::exists(s)) { 32149a3ad21SRui Ueyama driver->addFile(s, /*withLOption=*/false); 3222ec34544SRui Ueyama } else { 323c384ca3cSFangrui Song // Finally, search in the list of library paths. 3243837f427SRui Ueyama if (Optional<std::string> path = findFromSearchPaths(s)) 32549a3ad21SRui Ueyama driver->addFile(saver.save(*path), /*withLOption=*/true); 3262ec34544SRui Ueyama else 3273837f427SRui Ueyama setError("unable to find " + s); 3282ec34544SRui Ueyama } 3292ec34544SRui Ueyama } 330c384ca3cSFangrui Song } 3312ec34544SRui Ueyama 3322ec34544SRui Ueyama void ScriptParser::readAsNeeded() { 3332ec34544SRui Ueyama expect("("); 3343837f427SRui Ueyama bool orig = config->asNeeded; 3353837f427SRui Ueyama config->asNeeded = true; 336b8a59c8aSBob Haarman while (!errorCount() && !consume(")")) 3372ec34544SRui Ueyama addFile(unquote(next())); 3383837f427SRui Ueyama config->asNeeded = orig; 3392ec34544SRui Ueyama } 3402ec34544SRui Ueyama 3412ec34544SRui Ueyama void ScriptParser::readEntry() { 3422ec34544SRui Ueyama // -e <symbol> takes predecence over ENTRY(<symbol>). 3432ec34544SRui Ueyama expect("("); 3443837f427SRui Ueyama StringRef tok = next(); 3453837f427SRui Ueyama if (config->entry.empty()) 3463837f427SRui Ueyama config->entry = tok; 3472ec34544SRui Ueyama expect(")"); 3482ec34544SRui Ueyama } 3492ec34544SRui Ueyama 3502ec34544SRui Ueyama void ScriptParser::readExtern() { 3512ec34544SRui Ueyama expect("("); 352b8a59c8aSBob Haarman while (!errorCount() && !consume(")")) 3533837f427SRui Ueyama config->undefined.push_back(unquote(next())); 3542ec34544SRui Ueyama } 3552ec34544SRui Ueyama 3562ec34544SRui Ueyama void ScriptParser::readGroup() { 3573837f427SRui Ueyama bool orig = InputFile::isInGroup; 3583837f427SRui Ueyama InputFile::isInGroup = true; 3591d92aa73SRui Ueyama readInput(); 3603837f427SRui Ueyama InputFile::isInGroup = orig; 3613837f427SRui Ueyama if (!orig) 3623837f427SRui Ueyama ++InputFile::nextGroupId; 3632ec34544SRui Ueyama } 3642ec34544SRui Ueyama 3652ec34544SRui Ueyama void ScriptParser::readInclude() { 3663837f427SRui Ueyama StringRef tok = unquote(next()); 3672ec34544SRui Ueyama 3683837f427SRui Ueyama if (!seen.insert(tok).second) { 3690440be4aSRui Ueyama setError("there is a cycle in linker script INCLUDEs"); 3700440be4aSRui Ueyama return; 3710440be4aSRui Ueyama } 3720440be4aSRui Ueyama 3733837f427SRui Ueyama if (Optional<std::string> path = searchScript(tok)) { 3743837f427SRui Ueyama if (Optional<MemoryBufferRef> mb = readFile(*path)) 3753837f427SRui Ueyama tokenize(*mb); 3762ec34544SRui Ueyama return; 3772ec34544SRui Ueyama } 3783837f427SRui Ueyama setError("cannot find linker script " + tok); 3792ec34544SRui Ueyama } 3802ec34544SRui Ueyama 3811d92aa73SRui Ueyama void ScriptParser::readInput() { 3821d92aa73SRui Ueyama expect("("); 3831d92aa73SRui Ueyama while (!errorCount() && !consume(")")) { 3841d92aa73SRui Ueyama if (consume("AS_NEEDED")) 3851d92aa73SRui Ueyama readAsNeeded(); 3861d92aa73SRui Ueyama else 3871d92aa73SRui Ueyama addFile(unquote(next())); 3881d92aa73SRui Ueyama } 3891d92aa73SRui Ueyama } 3901d92aa73SRui Ueyama 3912ec34544SRui Ueyama void ScriptParser::readOutput() { 3922ec34544SRui Ueyama // -o <file> takes predecence over OUTPUT(<file>). 3932ec34544SRui Ueyama expect("("); 3943837f427SRui Ueyama StringRef tok = next(); 3953837f427SRui Ueyama if (config->outputFile.empty()) 3963837f427SRui Ueyama config->outputFile = unquote(tok); 3972ec34544SRui Ueyama expect(")"); 3982ec34544SRui Ueyama } 3992ec34544SRui Ueyama 4002ec34544SRui Ueyama void ScriptParser::readOutputArch() { 4012ec34544SRui Ueyama // OUTPUT_ARCH is ignored for now. 4022ec34544SRui Ueyama expect("("); 403b8a59c8aSBob Haarman while (!errorCount() && !consume(")")) 4042ec34544SRui Ueyama skip(); 4052ec34544SRui Ueyama } 4062ec34544SRui Ueyama 4073837f427SRui Ueyama static std::pair<ELFKind, uint16_t> parseBfdName(StringRef s) { 4083837f427SRui Ueyama return StringSwitch<std::pair<ELFKind, uint16_t>>(s) 4094f8c8228SRui Ueyama .Case("elf32-i386", {ELF32LEKind, EM_386}) 4104f8c8228SRui Ueyama .Case("elf32-iamcu", {ELF32LEKind, EM_IAMCU}) 4114f8c8228SRui Ueyama .Case("elf32-littlearm", {ELF32LEKind, EM_ARM}) 4124f8c8228SRui Ueyama .Case("elf32-x86-64", {ELF32LEKind, EM_X86_64}) 41319b134ccSDimitry Andric .Case("elf64-aarch64", {ELF64LEKind, EM_AARCH64}) 4144f8c8228SRui Ueyama .Case("elf64-littleaarch64", {ELF64LEKind, EM_AARCH64}) 4157605a9a0SFangrui Song .Case("elf64-bigaarch64", {ELF64BEKind, EM_AARCH64}) 4164134143cSRui Ueyama .Case("elf32-powerpc", {ELF32BEKind, EM_PPC}) 417275eb828SBrandon Bergren .Case("elf32-powerpcle", {ELF32LEKind, EM_PPC}) 4184f8c8228SRui Ueyama .Case("elf64-powerpc", {ELF64BEKind, EM_PPC64}) 4194f8c8228SRui Ueyama .Case("elf64-powerpcle", {ELF64LEKind, EM_PPC64}) 4204f8c8228SRui Ueyama .Case("elf64-x86-64", {ELF64LEKind, EM_X86_64}) 4214134143cSRui Ueyama .Cases("elf32-tradbigmips", "elf32-bigmips", {ELF32BEKind, EM_MIPS}) 4224f8c8228SRui Ueyama .Case("elf32-ntradbigmips", {ELF32BEKind, EM_MIPS}) 4234f8c8228SRui Ueyama .Case("elf32-tradlittlemips", {ELF32LEKind, EM_MIPS}) 4244f8c8228SRui Ueyama .Case("elf32-ntradlittlemips", {ELF32LEKind, EM_MIPS}) 4254f8c8228SRui Ueyama .Case("elf64-tradbigmips", {ELF64BEKind, EM_MIPS}) 4264f8c8228SRui Ueyama .Case("elf64-tradlittlemips", {ELF64LEKind, EM_MIPS}) 42744d908d7SFangrui Song .Case("elf32-littleriscv", {ELF32LEKind, EM_RISCV}) 42844d908d7SFangrui Song .Case("elf64-littleriscv", {ELF64LEKind, EM_RISCV}) 429aff950e9SLemonBoy .Case("elf64-sparc", {ELF64BEKind, EM_SPARCV9}) 43092c6141cSLemonBoy .Case("elf32-msp430", {ELF32LEKind, EM_MSP430}) 4314f8c8228SRui Ueyama .Default({ELFNoneKind, EM_NONE}); 432ea8cd00aSRui Ueyama } 433ea8cd00aSRui Ueyama 434*eea34aaeSFangrui Song // Parse OUTPUT_FORMAT(bfdname) or OUTPUT_FORMAT(default, big, little). Choose 435*eea34aaeSFangrui Song // big if -EB is specified, little if -EL is specified, or default if neither is 436*eea34aaeSFangrui Song // specified. 4372ec34544SRui Ueyama void ScriptParser::readOutputFormat() { 4382ec34544SRui Ueyama expect("("); 439ea8cd00aSRui Ueyama 440*eea34aaeSFangrui Song StringRef s; 4412822852fSShoaib Meenai config->bfdname = unquote(next()); 442*eea34aaeSFangrui Song if (!consume(")")) { 443*eea34aaeSFangrui Song expect(","); 444*eea34aaeSFangrui Song s = unquote(next()); 445*eea34aaeSFangrui Song if (config->optEB) 446*eea34aaeSFangrui Song config->bfdname = s; 447*eea34aaeSFangrui Song expect(","); 448*eea34aaeSFangrui Song s = unquote(next()); 449*eea34aaeSFangrui Song if (config->optEL) 450*eea34aaeSFangrui Song config->bfdname = s; 451*eea34aaeSFangrui Song consume(")"); 452*eea34aaeSFangrui Song } 453*eea34aaeSFangrui Song s = config->bfdname; 4543837f427SRui Ueyama if (s.consume_back("-freebsd")) 4553837f427SRui Ueyama config->osabi = ELFOSABI_FREEBSD; 4564f8c8228SRui Ueyama 4573837f427SRui Ueyama std::tie(config->ekind, config->emachine) = parseBfdName(s); 4583837f427SRui Ueyama if (config->emachine == EM_NONE) 4592822852fSShoaib Meenai setError("unknown output format name: " + config->bfdname); 4603837f427SRui Ueyama if (s == "elf32-ntradlittlemips" || s == "elf32-ntradbigmips") 4613837f427SRui Ueyama config->mipsN32Abi = true; 46292c6141cSLemonBoy if (config->emachine == EM_MSP430) 46392c6141cSLemonBoy config->osabi = ELFOSABI_STANDALONE; 4642ec34544SRui Ueyama } 4652ec34544SRui Ueyama 4662ec34544SRui Ueyama void ScriptParser::readPhdrs() { 4672ec34544SRui Ueyama expect("{"); 4682ec34544SRui Ueyama 469b8a59c8aSBob Haarman while (!errorCount() && !consume("}")) { 4703837f427SRui Ueyama PhdrsCommand cmd; 4713837f427SRui Ueyama cmd.name = next(); 4723837f427SRui Ueyama cmd.type = readPhdrType(); 473b579c439SRui Ueyama 474b8a59c8aSBob Haarman while (!errorCount() && !consume(";")) { 475b579c439SRui Ueyama if (consume("FILEHDR")) 4763837f427SRui Ueyama cmd.hasFilehdr = true; 477b579c439SRui Ueyama else if (consume("PHDRS")) 4783837f427SRui Ueyama cmd.hasPhdrs = true; 479b579c439SRui Ueyama else if (consume("AT")) 4803837f427SRui Ueyama cmd.lmaExpr = readParenExpr(); 481b579c439SRui Ueyama else if (consume("FLAGS")) 4823837f427SRui Ueyama cmd.flags = readParenExpr()().getValue(); 483b579c439SRui Ueyama else 484b579c439SRui Ueyama setError("unexpected header attribute: " + next()); 485b579c439SRui Ueyama } 4860ae2c24cSRui Ueyama 4873837f427SRui Ueyama script->phdrsCommands.push_back(cmd); 4882ec34544SRui Ueyama } 4892ec34544SRui Ueyama } 4902ec34544SRui Ueyama 4915f37541cSGeorge Rimar void ScriptParser::readRegionAlias() { 4925f37541cSGeorge Rimar expect("("); 4933837f427SRui Ueyama StringRef alias = unquote(next()); 4945f37541cSGeorge Rimar expect(","); 4953837f427SRui Ueyama StringRef name = next(); 4965f37541cSGeorge Rimar expect(")"); 4975f37541cSGeorge Rimar 4983837f427SRui Ueyama if (script->memoryRegions.count(alias)) 4993837f427SRui Ueyama setError("redefinition of memory region '" + alias + "'"); 5003837f427SRui Ueyama if (!script->memoryRegions.count(name)) 5013837f427SRui Ueyama setError("memory region '" + name + "' is not defined"); 5023837f427SRui Ueyama script->memoryRegions.insert({alias, script->memoryRegions[name]}); 5035f37541cSGeorge Rimar } 5045f37541cSGeorge Rimar 5052ec34544SRui Ueyama void ScriptParser::readSearchDir() { 5062ec34544SRui Ueyama expect("("); 5073837f427SRui Ueyama StringRef tok = next(); 5083837f427SRui Ueyama if (!config->nostdlib) 5093837f427SRui Ueyama config->searchPaths.push_back(unquote(tok)); 5102ec34544SRui Ueyama expect(")"); 5112ec34544SRui Ueyama } 5122ec34544SRui Ueyama 513a582419aSGeorge Rimar // This reads an overlay description. Overlays are used to describe output 514a582419aSGeorge Rimar // sections that use the same virtual memory range and normally would trigger 515a582419aSGeorge Rimar // linker's sections sanity check failures. 516a582419aSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Overlay-Description.html#Overlay-Description 517a582419aSGeorge Rimar std::vector<BaseCommand *> ScriptParser::readOverlay() { 518a582419aSGeorge Rimar // VA and LMA expressions are optional, though for simplicity of 519a582419aSGeorge Rimar // implementation we assume they are not. That is what OVERLAY was designed 520a582419aSGeorge Rimar // for first of all: to allow sections with overlapping VAs at different LMAs. 5213837f427SRui Ueyama Expr addrExpr = readExpr(); 522a582419aSGeorge Rimar expect(":"); 523a582419aSGeorge Rimar expect("AT"); 5243837f427SRui Ueyama Expr lmaExpr = readParenExpr(); 525a582419aSGeorge Rimar expect("{"); 526a582419aSGeorge Rimar 5273837f427SRui Ueyama std::vector<BaseCommand *> v; 5283837f427SRui Ueyama OutputSection *prev = nullptr; 529a582419aSGeorge Rimar while (!errorCount() && !consume("}")) { 530a582419aSGeorge Rimar // VA is the same for all sections. The LMAs are consecutive in memory 531a582419aSGeorge Rimar // starting from the base load address specified. 5323837f427SRui Ueyama OutputSection *os = readOverlaySectionDescription(); 5333837f427SRui Ueyama os->addrExpr = addrExpr; 5343837f427SRui Ueyama if (prev) 5353837f427SRui Ueyama os->lmaExpr = [=] { return prev->getLMA() + prev->size; }; 536a582419aSGeorge Rimar else 5373837f427SRui Ueyama os->lmaExpr = lmaExpr; 5383837f427SRui Ueyama v.push_back(os); 5393837f427SRui Ueyama prev = os; 540a582419aSGeorge Rimar } 541a582419aSGeorge Rimar 542a582419aSGeorge Rimar // According to the specification, at the end of the overlay, the location 543a582419aSGeorge Rimar // counter should be equal to the overlay base address plus size of the 544a582419aSGeorge Rimar // largest section seen in the overlay. 545a582419aSGeorge Rimar // Here we want to create the Dot assignment command to achieve that. 5463837f427SRui Ueyama Expr moveDot = [=] { 5473837f427SRui Ueyama uint64_t max = 0; 5483837f427SRui Ueyama for (BaseCommand *cmd : v) 5493837f427SRui Ueyama max = std::max(max, cast<OutputSection>(cmd)->size); 5503837f427SRui Ueyama return addrExpr().getValue() + max; 551a582419aSGeorge Rimar }; 5523837f427SRui Ueyama v.push_back(make<SymbolAssignment>(".", moveDot, getCurrentLocation())); 5533837f427SRui Ueyama return v; 554a582419aSGeorge Rimar } 555a582419aSGeorge Rimar 5562ec34544SRui Ueyama void ScriptParser::readSections() { 5572ec34544SRui Ueyama expect("{"); 5583837f427SRui Ueyama std::vector<BaseCommand *> v; 559b8a59c8aSBob Haarman while (!errorCount() && !consume("}")) { 5603837f427SRui Ueyama StringRef tok = next(); 5613837f427SRui Ueyama if (tok == "OVERLAY") { 5623837f427SRui Ueyama for (BaseCommand *cmd : readOverlay()) 5633837f427SRui Ueyama v.push_back(cmd); 564a582419aSGeorge Rimar continue; 5653837f427SRui Ueyama } else if (tok == "INCLUDE") { 5662e9d40d5SRui Ueyama readInclude(); 5672e9d40d5SRui Ueyama continue; 568a582419aSGeorge Rimar } 569a582419aSGeorge Rimar 5703837f427SRui Ueyama if (BaseCommand *cmd = readAssignment(tok)) 5713837f427SRui Ueyama v.push_back(cmd); 572d30a78b3SGeorge Rimar else 5733837f427SRui Ueyama v.push_back(readOutputSectionDescription(tok)); 5742ec34544SRui Ueyama } 5757c426fb1SFangrui Song script->sectionCommands.insert(script->sectionCommands.end(), v.begin(), 5767c426fb1SFangrui Song v.end()); 5779e2c8a9dSGeorge Rimar 5787c426fb1SFangrui Song if (atEOF() || !consume("INSERT")) { 5797c426fb1SFangrui Song script->hasSectionsCommand = true; 5809e2c8a9dSGeorge Rimar return; 5819e2c8a9dSGeorge Rimar } 5829e2c8a9dSGeorge Rimar 5837c426fb1SFangrui Song bool isAfter = false; 5847c426fb1SFangrui Song if (consume("AFTER")) 5857c426fb1SFangrui Song isAfter = true; 5867c426fb1SFangrui Song else if (!consume("BEFORE")) 5877c426fb1SFangrui Song setError("expected AFTER/BEFORE, but got '" + next() + "'"); 5887c426fb1SFangrui Song StringRef where = next(); 5897c426fb1SFangrui Song for (BaseCommand *cmd : v) 5907c426fb1SFangrui Song if (auto *os = dyn_cast<OutputSection>(cmd)) 5917c426fb1SFangrui Song script->insertCommands.push_back({os, isAfter, where}); 5922ec34544SRui Ueyama } 5932ec34544SRui Ueyama 594e262bb1aSRui Ueyama void ScriptParser::readTarget() { 595e262bb1aSRui Ueyama // TARGET(foo) is an alias for "--format foo". Unlike GNU linkers, 596e262bb1aSRui Ueyama // we accept only a limited set of BFD names (i.e. "elf" or "binary") 597e262bb1aSRui Ueyama // for --format. We recognize only /^elf/ and "binary" in the linker 598e262bb1aSRui Ueyama // script as well. 599e262bb1aSRui Ueyama expect("("); 6003837f427SRui Ueyama StringRef tok = next(); 601e262bb1aSRui Ueyama expect(")"); 602e262bb1aSRui Ueyama 6033837f427SRui Ueyama if (tok.startswith("elf")) 6043837f427SRui Ueyama config->formatBinary = false; 6053837f427SRui Ueyama else if (tok == "binary") 6063837f427SRui Ueyama config->formatBinary = true; 607e262bb1aSRui Ueyama else 6083837f427SRui Ueyama setError("unknown target: " + tok); 609e262bb1aSRui Ueyama } 610e262bb1aSRui Ueyama 6113837f427SRui Ueyama static int precedence(StringRef op) { 6123837f427SRui Ueyama return StringSwitch<int>(op) 613a5005482SGeorge Rimar .Cases("*", "/", "%", 8) 614a5005482SGeorge Rimar .Cases("+", "-", 7) 615a5005482SGeorge Rimar .Cases("<<", ">>", 6) 616a5005482SGeorge Rimar .Cases("<", "<=", ">", ">=", "==", "!=", 5) 617a5005482SGeorge Rimar .Case("&", 4) 618a5005482SGeorge Rimar .Case("|", 3) 619a5005482SGeorge Rimar .Case("&&", 2) 620a5005482SGeorge Rimar .Case("||", 1) 6212ec34544SRui Ueyama .Default(-1); 6222ec34544SRui Ueyama } 6232ec34544SRui Ueyama 6242ec34544SRui Ueyama StringMatcher ScriptParser::readFilePatterns() { 625c42fe247SThomas Preud'homme StringMatcher Matcher; 626c42fe247SThomas Preud'homme 627b8a59c8aSBob Haarman while (!errorCount() && !consume(")")) 628c42fe247SThomas Preud'homme Matcher.addPattern(SingleStringMatcher(next())); 629c42fe247SThomas Preud'homme return Matcher; 6302ec34544SRui Ueyama } 6312ec34544SRui Ueyama 6322a9aed0eSFangrui Song SortSectionPolicy ScriptParser::peekSortKind() { 6332a9aed0eSFangrui Song return StringSwitch<SortSectionPolicy>(peek()) 6342a9aed0eSFangrui Song .Cases("SORT", "SORT_BY_NAME", SortSectionPolicy::Name) 6352a9aed0eSFangrui Song .Case("SORT_BY_ALIGNMENT", SortSectionPolicy::Alignment) 6362a9aed0eSFangrui Song .Case("SORT_BY_INIT_PRIORITY", SortSectionPolicy::Priority) 6372a9aed0eSFangrui Song .Case("SORT_NONE", SortSectionPolicy::None) 6382a9aed0eSFangrui Song .Default(SortSectionPolicy::Default); 6392a9aed0eSFangrui Song } 6402a9aed0eSFangrui Song 6412ec34544SRui Ueyama SortSectionPolicy ScriptParser::readSortKind() { 6422a9aed0eSFangrui Song SortSectionPolicy ret = peekSortKind(); 6432a9aed0eSFangrui Song if (ret != SortSectionPolicy::Default) 6442a9aed0eSFangrui Song skip(); 6452a9aed0eSFangrui Song return ret; 6462ec34544SRui Ueyama } 6472ec34544SRui Ueyama 64803fc8d1eSRui Ueyama // Reads SECTIONS command contents in the following form: 64903fc8d1eSRui Ueyama // 65003fc8d1eSRui Ueyama // <contents> ::= <elem>* 65103fc8d1eSRui Ueyama // <elem> ::= <exclude>? <glob-pattern> 65203fc8d1eSRui Ueyama // <exclude> ::= "EXCLUDE_FILE" "(" <glob-pattern>+ ")" 65303fc8d1eSRui Ueyama // 65403fc8d1eSRui Ueyama // For example, 65503fc8d1eSRui Ueyama // 65603fc8d1eSRui Ueyama // *(.foo EXCLUDE_FILE (a.o) .bar EXCLUDE_FILE (b.o) .baz) 65703fc8d1eSRui Ueyama // 65803fc8d1eSRui Ueyama // is parsed as ".foo", ".bar" with "a.o", and ".baz" with "b.o". 65903fc8d1eSRui Ueyama // The semantics of that is section .foo in any file, section .bar in 66003fc8d1eSRui Ueyama // any file but a.o, and section .baz in any file but b.o. 6612ec34544SRui Ueyama std::vector<SectionPattern> ScriptParser::readInputSectionsList() { 6623837f427SRui Ueyama std::vector<SectionPattern> ret; 663b8a59c8aSBob Haarman while (!errorCount() && peek() != ")") { 6643837f427SRui Ueyama StringMatcher excludeFilePat; 6652ec34544SRui Ueyama if (consume("EXCLUDE_FILE")) { 6662ec34544SRui Ueyama expect("("); 6673837f427SRui Ueyama excludeFilePat = readFilePatterns(); 6682ec34544SRui Ueyama } 6692ec34544SRui Ueyama 670c42fe247SThomas Preud'homme StringMatcher SectionMatcher; 6712a9aed0eSFangrui Song // Break if the next token is ), EXCLUDE_FILE, or SORT*. 6722a9aed0eSFangrui Song while (!errorCount() && peek() != ")" && peek() != "EXCLUDE_FILE" && 6732a9aed0eSFangrui Song peekSortKind() == SortSectionPolicy::Default) 674c42fe247SThomas Preud'homme SectionMatcher.addPattern(unquote(next())); 6752ec34544SRui Ueyama 676c42fe247SThomas Preud'homme if (!SectionMatcher.empty()) 677c42fe247SThomas Preud'homme ret.push_back({std::move(excludeFilePat), std::move(SectionMatcher)}); 6782a9aed0eSFangrui Song else if (excludeFilePat.empty()) 6792a9aed0eSFangrui Song break; 6802ec34544SRui Ueyama else 6812ec34544SRui Ueyama setError("section pattern is expected"); 6822ec34544SRui Ueyama } 6833837f427SRui Ueyama return ret; 6842ec34544SRui Ueyama } 6852ec34544SRui Ueyama 6862ec34544SRui Ueyama // Reads contents of "SECTIONS" directive. That directive contains a 6872ec34544SRui Ueyama // list of glob patterns for input sections. The grammar is as follows. 6882ec34544SRui Ueyama // 6892ec34544SRui Ueyama // <patterns> ::= <section-list> 6902ec34544SRui Ueyama // | <sort> "(" <section-list> ")" 6912ec34544SRui Ueyama // | <sort> "(" <sort> "(" <section-list> ")" ")" 6922ec34544SRui Ueyama // 6932ec34544SRui Ueyama // <sort> ::= "SORT" | "SORT_BY_NAME" | "SORT_BY_ALIGNMENT" 6942ec34544SRui Ueyama // | "SORT_BY_INIT_PRIORITY" | "SORT_NONE" 6952ec34544SRui Ueyama // 6962ec34544SRui Ueyama // <section-list> is parsed by readInputSectionsList(). 6972ec34544SRui Ueyama InputSectionDescription * 698dbd0ad33SPeter Smith ScriptParser::readInputSectionRules(StringRef filePattern, uint64_t withFlags, 699dbd0ad33SPeter Smith uint64_t withoutFlags) { 700dbd0ad33SPeter Smith auto *cmd = 701dbd0ad33SPeter Smith make<InputSectionDescription>(filePattern, withFlags, withoutFlags); 7022ec34544SRui Ueyama expect("("); 7032ec34544SRui Ueyama 704b8a59c8aSBob Haarman while (!errorCount() && !consume(")")) { 7053837f427SRui Ueyama SortSectionPolicy outer = readSortKind(); 7063837f427SRui Ueyama SortSectionPolicy inner = SortSectionPolicy::Default; 7073837f427SRui Ueyama std::vector<SectionPattern> v; 7083837f427SRui Ueyama if (outer != SortSectionPolicy::Default) { 7092ec34544SRui Ueyama expect("("); 7103837f427SRui Ueyama inner = readSortKind(); 7113837f427SRui Ueyama if (inner != SortSectionPolicy::Default) { 7122ec34544SRui Ueyama expect("("); 7133837f427SRui Ueyama v = readInputSectionsList(); 7142ec34544SRui Ueyama expect(")"); 7152ec34544SRui Ueyama } else { 7163837f427SRui Ueyama v = readInputSectionsList(); 7172ec34544SRui Ueyama } 7182ec34544SRui Ueyama expect(")"); 7192ec34544SRui Ueyama } else { 7203837f427SRui Ueyama v = readInputSectionsList(); 7212ec34544SRui Ueyama } 7222ec34544SRui Ueyama 7233837f427SRui Ueyama for (SectionPattern &pat : v) { 7243837f427SRui Ueyama pat.sortInner = inner; 7253837f427SRui Ueyama pat.sortOuter = outer; 7262ec34544SRui Ueyama } 7272ec34544SRui Ueyama 7283837f427SRui Ueyama std::move(v.begin(), v.end(), std::back_inserter(cmd->sectionPatterns)); 7292ec34544SRui Ueyama } 7303837f427SRui Ueyama return cmd; 7312ec34544SRui Ueyama } 7322ec34544SRui Ueyama 7332ec34544SRui Ueyama InputSectionDescription * 7343837f427SRui Ueyama ScriptParser::readInputSectionDescription(StringRef tok) { 7352ec34544SRui Ueyama // Input section wildcard can be surrounded by KEEP. 7362ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep 737dbd0ad33SPeter Smith uint64_t withFlags = 0; 738dbd0ad33SPeter Smith uint64_t withoutFlags = 0; 7393837f427SRui Ueyama if (tok == "KEEP") { 7402ec34544SRui Ueyama expect("("); 741dbd0ad33SPeter Smith if (consume("INPUT_SECTION_FLAGS")) 742dbd0ad33SPeter Smith std::tie(withFlags, withoutFlags) = readInputSectionFlags(); 743dbd0ad33SPeter Smith InputSectionDescription *cmd = 744dbd0ad33SPeter Smith readInputSectionRules(next(), withFlags, withoutFlags); 7452ec34544SRui Ueyama expect(")"); 7463837f427SRui Ueyama script->keptSections.push_back(cmd); 7473837f427SRui Ueyama return cmd; 7482ec34544SRui Ueyama } 749dbd0ad33SPeter Smith if (tok == "INPUT_SECTION_FLAGS") { 750dbd0ad33SPeter Smith std::tie(withFlags, withoutFlags) = readInputSectionFlags(); 751dbd0ad33SPeter Smith tok = next(); 752dbd0ad33SPeter Smith } 753dbd0ad33SPeter Smith return readInputSectionRules(tok, withFlags, withoutFlags); 7542ec34544SRui Ueyama } 7552ec34544SRui Ueyama 7562ec34544SRui Ueyama void ScriptParser::readSort() { 7572ec34544SRui Ueyama expect("("); 7582ec34544SRui Ueyama expect("CONSTRUCTORS"); 7592ec34544SRui Ueyama expect(")"); 7602ec34544SRui Ueyama } 7612ec34544SRui Ueyama 762d30a78b3SGeorge Rimar Expr ScriptParser::readAssert() { 7632ec34544SRui Ueyama expect("("); 7643837f427SRui Ueyama Expr e = readExpr(); 7652ec34544SRui Ueyama expect(","); 7663837f427SRui Ueyama StringRef msg = unquote(next()); 7672ec34544SRui Ueyama expect(")"); 768b579c439SRui Ueyama 7692ec34544SRui Ueyama return [=] { 7703837f427SRui Ueyama if (!e().getValue()) 7712682bc3cSFangrui Song errorOrWarn(msg); 7723837f427SRui Ueyama return script->getDot(); 7732ec34544SRui Ueyama }; 7742ec34544SRui Ueyama } 7752ec34544SRui Ueyama 776a46d08ebSGeorge Rimar // Tries to read the special directive for an output section definition which 777a46d08ebSGeorge Rimar // can be one of following: "(NOLOAD)", "(COPY)", "(INFO)" or "(OVERLAY)". 778a46d08ebSGeorge Rimar // Tok1 and Tok2 are next 2 tokens peeked. See comment for readSectionAddressType below. 7793837f427SRui Ueyama bool ScriptParser::readSectionDirective(OutputSection *cmd, StringRef tok1, StringRef tok2) { 7803837f427SRui Ueyama if (tok1 != "(") 781a46d08ebSGeorge Rimar return false; 7823837f427SRui Ueyama if (tok2 != "NOLOAD" && tok2 != "COPY" && tok2 != "INFO" && tok2 != "OVERLAY") 783a46d08ebSGeorge Rimar return false; 784a46d08ebSGeorge Rimar 785a46d08ebSGeorge Rimar expect("("); 786a46d08ebSGeorge Rimar if (consume("NOLOAD")) { 7873837f427SRui Ueyama cmd->noload = true; 788fdc41aa2SMatt Schulte cmd->type = SHT_NOBITS; 789a46d08ebSGeorge Rimar } else { 790a46d08ebSGeorge Rimar skip(); // This is "COPY", "INFO" or "OVERLAY". 7913837f427SRui Ueyama cmd->nonAlloc = true; 792a46d08ebSGeorge Rimar } 793a46d08ebSGeorge Rimar expect(")"); 794a46d08ebSGeorge Rimar return true; 795a46d08ebSGeorge Rimar } 796a46d08ebSGeorge Rimar 7971c08e9f5SGeorge Rimar // Reads an expression and/or the special directive for an output 7981c08e9f5SGeorge Rimar // section definition. Directive is one of following: "(NOLOAD)", 7991c08e9f5SGeorge Rimar // "(COPY)", "(INFO)" or "(OVERLAY)". 8003271d370SRui Ueyama // 8013271d370SRui Ueyama // An output section name can be followed by an address expression 8021c08e9f5SGeorge Rimar // and/or directive. This grammar is not LL(1) because "(" can be 80397f4d158SGeorge Rimar // interpreted as either the beginning of some expression or beginning 8041c08e9f5SGeorge Rimar // of directive. 8053271d370SRui Ueyama // 806b579c439SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html 807fbb0463fSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Output-Section-Type.html 8083837f427SRui Ueyama void ScriptParser::readSectionAddressType(OutputSection *cmd) { 8093837f427SRui Ueyama if (readSectionDirective(cmd, peek(), peek2())) 8103271d370SRui Ueyama return; 8113271d370SRui Ueyama 8123837f427SRui Ueyama cmd->addrExpr = readExpr(); 8133837f427SRui Ueyama if (peek() == "(" && !readSectionDirective(cmd, "(", peek2())) 814a46d08ebSGeorge Rimar setError("unknown section directive: " + peek2()); 815fbb0463fSGeorge Rimar } 816fbb0463fSGeorge Rimar 8173837f427SRui Ueyama static Expr checkAlignment(Expr e, std::string &loc) { 818f22ec9ddSGeorge Rimar return [=] { 8193837f427SRui Ueyama uint64_t alignment = std::max((uint64_t)1, e().getValue()); 8203837f427SRui Ueyama if (!isPowerOf2_64(alignment)) { 8213837f427SRui Ueyama error(loc + ": alignment must be power of 2"); 822f22ec9ddSGeorge Rimar return (uint64_t)1; // Return a dummy value. 823f22ec9ddSGeorge Rimar } 8243837f427SRui Ueyama return alignment; 825f22ec9ddSGeorge Rimar }; 826f22ec9ddSGeorge Rimar } 827f22ec9ddSGeorge Rimar 828a582419aSGeorge Rimar OutputSection *ScriptParser::readOverlaySectionDescription() { 8293837f427SRui Ueyama OutputSection *cmd = 8303837f427SRui Ueyama script->createOutputSection(next(), getCurrentLocation()); 8313837f427SRui Ueyama cmd->inOverlay = true; 832a582419aSGeorge Rimar expect("{"); 833dbd0ad33SPeter Smith while (!errorCount() && !consume("}")) { 834dbd0ad33SPeter Smith uint64_t withFlags = 0; 835dbd0ad33SPeter Smith uint64_t withoutFlags = 0; 836dbd0ad33SPeter Smith if (consume("INPUT_SECTION_FLAGS")) 837dbd0ad33SPeter Smith std::tie(withFlags, withoutFlags) = readInputSectionFlags(); 838dbd0ad33SPeter Smith cmd->sectionCommands.push_back( 839dbd0ad33SPeter Smith readInputSectionRules(next(), withFlags, withoutFlags)); 840dbd0ad33SPeter Smith } 8413837f427SRui Ueyama return cmd; 842a582419aSGeorge Rimar } 843a582419aSGeorge Rimar 8443837f427SRui Ueyama OutputSection *ScriptParser::readOutputSectionDescription(StringRef outSec) { 8453837f427SRui Ueyama OutputSection *cmd = 8463837f427SRui Ueyama script->createOutputSection(outSec, getCurrentLocation()); 8473271d370SRui Ueyama 8483837f427SRui Ueyama size_t symbolsReferenced = script->referencedSymbols.size(); 849c4df670dSGeorge Rimar 8503271d370SRui Ueyama if (peek() != ":") 8513837f427SRui Ueyama readSectionAddressType(cmd); 8522ec34544SRui Ueyama expect(":"); 8532ec34544SRui Ueyama 8543837f427SRui Ueyama std::string location = getCurrentLocation(); 8552ec34544SRui Ueyama if (consume("AT")) 8563837f427SRui Ueyama cmd->lmaExpr = readParenExpr(); 8572ec34544SRui Ueyama if (consume("ALIGN")) 8583837f427SRui Ueyama cmd->alignExpr = checkAlignment(readParenExpr(), location); 8592ec34544SRui Ueyama if (consume("SUBALIGN")) 8603837f427SRui Ueyama cmd->subalignExpr = checkAlignment(readParenExpr(), location); 8612ec34544SRui Ueyama 8622ec34544SRui Ueyama // Parse constraints. 8632ec34544SRui Ueyama if (consume("ONLY_IF_RO")) 8643837f427SRui Ueyama cmd->constraint = ConstraintKind::ReadOnly; 8652ec34544SRui Ueyama if (consume("ONLY_IF_RW")) 8663837f427SRui Ueyama cmd->constraint = ConstraintKind::ReadWrite; 8672ec34544SRui Ueyama expect("{"); 8682ec34544SRui Ueyama 869b8a59c8aSBob Haarman while (!errorCount() && !consume("}")) { 8703837f427SRui Ueyama StringRef tok = next(); 8713837f427SRui Ueyama if (tok == ";") { 8722ec34544SRui Ueyama // Empty commands are allowed. Do nothing here. 8733837f427SRui Ueyama } else if (SymbolAssignment *assign = readAssignment(tok)) { 8743837f427SRui Ueyama cmd->sectionCommands.push_back(assign); 8753837f427SRui Ueyama } else if (ByteCommand *data = readByteCommand(tok)) { 8763837f427SRui Ueyama cmd->sectionCommands.push_back(data); 8773837f427SRui Ueyama } else if (tok == "CONSTRUCTORS") { 8782ec34544SRui Ueyama // CONSTRUCTORS is a keyword to make the linker recognize C++ ctors/dtors 8792ec34544SRui Ueyama // by name. This is for very old file formats such as ECOFF/XCOFF. 8802ec34544SRui Ueyama // For ELF, we should ignore. 8813837f427SRui Ueyama } else if (tok == "FILL") { 8820810f16fSGeorge Rimar // We handle the FILL command as an alias for =fillexp section attribute, 8830810f16fSGeorge Rimar // which is different from what GNU linkers do. 8840810f16fSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Output-Section-Data.html 885bb7d2b17SGeorgii Rymar if (peek() != "(") 886bb7d2b17SGeorgii Rymar setError("( expected, but got " + peek()); 8873837f427SRui Ueyama cmd->filler = readFill(); 8883837f427SRui Ueyama } else if (tok == "SORT") { 8892ec34544SRui Ueyama readSort(); 8903837f427SRui Ueyama } else if (tok == "INCLUDE") { 8912e9d40d5SRui Ueyama readInclude(); 8922ec34544SRui Ueyama } else if (peek() == "(") { 8933837f427SRui Ueyama cmd->sectionCommands.push_back(readInputSectionDescription(tok)); 8942ec34544SRui Ueyama } else { 895f49fe218SGeorge Rimar // We have a file name and no input sections description. It is not a 896f49fe218SGeorge Rimar // commonly used syntax, but still acceptable. In that case, all sections 897f49fe218SGeorge Rimar // from the file will be included. 898dbd0ad33SPeter Smith // FIXME: GNU ld permits INPUT_SECTION_FLAGS to be used here. We do not 899dbd0ad33SPeter Smith // handle this case here as it will already have been matched by the 900dbd0ad33SPeter Smith // case above. 9013837f427SRui Ueyama auto *isd = make<InputSectionDescription>(tok); 902c42fe247SThomas Preud'homme isd->sectionPatterns.push_back({{}, StringMatcher("*")}); 9033837f427SRui Ueyama cmd->sectionCommands.push_back(isd); 9042ec34544SRui Ueyama } 9052ec34544SRui Ueyama } 9062ec34544SRui Ueyama 9072ec34544SRui Ueyama if (consume(">")) 908adcd0268SBenjamin Kramer cmd->memoryRegionName = std::string(next()); 9092ec34544SRui Ueyama 9105d01a8beSGeorge Rimar if (consume("AT")) { 9115d01a8beSGeorge Rimar expect(">"); 912adcd0268SBenjamin Kramer cmd->lmaRegionName = std::string(next()); 9135d01a8beSGeorge Rimar } 9145d01a8beSGeorge Rimar 9153837f427SRui Ueyama if (cmd->lmaExpr && !cmd->lmaRegionName.empty()) 9165d01a8beSGeorge Rimar error("section can't have both LMA and a load region"); 9175d01a8beSGeorge Rimar 9183837f427SRui Ueyama cmd->phdrs = readOutputSectionPhdrs(); 9192ec34544SRui Ueyama 9200810f16fSGeorge Rimar if (peek() == "=" || peek().startswith("=")) { 9213837f427SRui Ueyama inExpr = true; 9220810f16fSGeorge Rimar consume("="); 9233837f427SRui Ueyama cmd->filler = readFill(); 9243837f427SRui Ueyama inExpr = false; 9250810f16fSGeorge Rimar } 9262ec34544SRui Ueyama 9272ec34544SRui Ueyama // Consume optional comma following output section command. 9282ec34544SRui Ueyama consume(","); 9292ec34544SRui Ueyama 9303837f427SRui Ueyama if (script->referencedSymbols.size() > symbolsReferenced) 9313837f427SRui Ueyama cmd->expressionsUseSymbols = true; 9323837f427SRui Ueyama return cmd; 9332ec34544SRui Ueyama } 9342ec34544SRui Ueyama 9350810f16fSGeorge Rimar // Reads a `=<fillexp>` expression and returns its value as a big-endian number. 9362ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html 9370810f16fSGeorge Rimar // We do not support using symbols in such expressions. 9382ec34544SRui Ueyama // 9398acbf1ccSRui Ueyama // When reading a hexstring, ld.bfd handles it as a blob of arbitrary 9408acbf1ccSRui Ueyama // size, while ld.gold always handles it as a 32-bit big-endian number. 9418acbf1ccSRui Ueyama // We are compatible with ld.gold because it's easier to implement. 942bb7d2b17SGeorgii Rymar // Also, we require that expressions with operators must be wrapped into 943bb7d2b17SGeorgii Rymar // round brackets. We did it to resolve the ambiguity when parsing scripts like: 944bb7d2b17SGeorgii Rymar // SECTIONS { .foo : { ... } =120+3 /DISCARD/ : { ... } } 9450810f16fSGeorge Rimar std::array<uint8_t, 4> ScriptParser::readFill() { 946bb7d2b17SGeorgii Rymar uint64_t value = readPrimary()().val; 9473837f427SRui Ueyama if (value > UINT32_MAX) 9480810f16fSGeorge Rimar setError("filler expression result does not fit 32-bit: 0x" + 9493837f427SRui Ueyama Twine::utohexstr(value)); 950b58079d4SRui Ueyama 9513837f427SRui Ueyama std::array<uint8_t, 4> buf; 9523837f427SRui Ueyama write32be(buf.data(), (uint32_t)value); 9533837f427SRui Ueyama return buf; 9542ec34544SRui Ueyama } 9552ec34544SRui Ueyama 9563837f427SRui Ueyama SymbolAssignment *ScriptParser::readProvideHidden(bool provide, bool hidden) { 9572ec34544SRui Ueyama expect("("); 9583837f427SRui Ueyama SymbolAssignment *cmd = readSymbolAssignment(next()); 9593837f427SRui Ueyama cmd->provide = provide; 9603837f427SRui Ueyama cmd->hidden = hidden; 9612ec34544SRui Ueyama expect(")"); 9623837f427SRui Ueyama return cmd; 9632ec34544SRui Ueyama } 9642ec34544SRui Ueyama 9653837f427SRui Ueyama SymbolAssignment *ScriptParser::readAssignment(StringRef tok) { 966d30a78b3SGeorge Rimar // Assert expression returns Dot, so this is equal to ".=." 9673837f427SRui Ueyama if (tok == "ASSERT") 968d30a78b3SGeorge Rimar return make<SymbolAssignment>(".", readAssert(), getCurrentLocation()); 969d30a78b3SGeorge Rimar 9703837f427SRui Ueyama size_t oldPos = pos; 9713837f427SRui Ueyama SymbolAssignment *cmd = nullptr; 972e88b76a9SGeorge Rimar if (peek() == "=" || peek() == "+=") 9733837f427SRui Ueyama cmd = readSymbolAssignment(tok); 9743837f427SRui Ueyama else if (tok == "PROVIDE") 9753837f427SRui Ueyama cmd = readProvideHidden(true, false); 9763837f427SRui Ueyama else if (tok == "HIDDEN") 9773837f427SRui Ueyama cmd = readProvideHidden(false, true); 9783837f427SRui Ueyama else if (tok == "PROVIDE_HIDDEN") 9793837f427SRui Ueyama cmd = readProvideHidden(true, true); 980e88b76a9SGeorge Rimar 9813837f427SRui Ueyama if (cmd) { 9823837f427SRui Ueyama cmd->commandString = 9833837f427SRui Ueyama tok.str() + " " + 9843837f427SRui Ueyama llvm::join(tokens.begin() + oldPos, tokens.begin() + pos, " "); 985e88b76a9SGeorge Rimar expect(";"); 9862ec34544SRui Ueyama } 9873837f427SRui Ueyama return cmd; 9882ec34544SRui Ueyama } 9892ec34544SRui Ueyama 9903837f427SRui Ueyama SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef name) { 9913837f427SRui Ueyama StringRef op = next(); 9923837f427SRui Ueyama assert(op == "=" || op == "+="); 9933837f427SRui Ueyama Expr e = readExpr(); 9943837f427SRui Ueyama if (op == "+=") { 9953837f427SRui Ueyama std::string loc = getCurrentLocation(); 9963837f427SRui Ueyama e = [=] { return add(script->getSymbolValue(name, loc), e()); }; 9972ec34544SRui Ueyama } 9983837f427SRui Ueyama return make<SymbolAssignment>(name, e, getCurrentLocation()); 9992ec34544SRui Ueyama } 10002ec34544SRui Ueyama 10012ec34544SRui Ueyama // This is an operator-precedence parser to parse a linker 10022ec34544SRui Ueyama // script expression. 10032ec34544SRui Ueyama Expr ScriptParser::readExpr() { 10042ec34544SRui Ueyama // Our lexer is context-aware. Set the in-expression bit so that 10052ec34544SRui Ueyama // they apply different tokenization rules. 10063837f427SRui Ueyama bool orig = inExpr; 10073837f427SRui Ueyama inExpr = true; 10083837f427SRui Ueyama Expr e = readExpr1(readPrimary(), 0); 10093837f427SRui Ueyama inExpr = orig; 10103837f427SRui Ueyama return e; 10112ec34544SRui Ueyama } 10122ec34544SRui Ueyama 10133837f427SRui Ueyama Expr ScriptParser::combine(StringRef op, Expr l, Expr r) { 10143837f427SRui Ueyama if (op == "+") 10153837f427SRui Ueyama return [=] { return add(l(), r()); }; 10163837f427SRui Ueyama if (op == "-") 10173837f427SRui Ueyama return [=] { return sub(l(), r()); }; 10183837f427SRui Ueyama if (op == "*") 10193837f427SRui Ueyama return [=] { return l().getValue() * r().getValue(); }; 10203837f427SRui Ueyama if (op == "/") { 10213837f427SRui Ueyama std::string loc = getCurrentLocation(); 10227b91e213SGeorge Rimar return [=]() -> uint64_t { 10233837f427SRui Ueyama if (uint64_t rv = r().getValue()) 10243837f427SRui Ueyama return l().getValue() / rv; 10253837f427SRui Ueyama error(loc + ": division by zero"); 1026067617f9SRui Ueyama return 0; 10277b91e213SGeorge Rimar }; 10287b91e213SGeorge Rimar } 10293837f427SRui Ueyama if (op == "%") { 10303837f427SRui Ueyama std::string loc = getCurrentLocation(); 10317b91e213SGeorge Rimar return [=]() -> uint64_t { 10323837f427SRui Ueyama if (uint64_t rv = r().getValue()) 10333837f427SRui Ueyama return l().getValue() % rv; 10343837f427SRui Ueyama error(loc + ": modulo by zero"); 1035067617f9SRui Ueyama return 0; 10367b91e213SGeorge Rimar }; 10377b91e213SGeorge Rimar } 10383837f427SRui Ueyama if (op == "<<") 10393837f427SRui Ueyama return [=] { return l().getValue() << r().getValue(); }; 10403837f427SRui Ueyama if (op == ">>") 10413837f427SRui Ueyama return [=] { return l().getValue() >> r().getValue(); }; 10423837f427SRui Ueyama if (op == "<") 10433837f427SRui Ueyama return [=] { return l().getValue() < r().getValue(); }; 10443837f427SRui Ueyama if (op == ">") 10453837f427SRui Ueyama return [=] { return l().getValue() > r().getValue(); }; 10463837f427SRui Ueyama if (op == ">=") 10473837f427SRui Ueyama return [=] { return l().getValue() >= r().getValue(); }; 10483837f427SRui Ueyama if (op == "<=") 10493837f427SRui Ueyama return [=] { return l().getValue() <= r().getValue(); }; 10503837f427SRui Ueyama if (op == "==") 10513837f427SRui Ueyama return [=] { return l().getValue() == r().getValue(); }; 10523837f427SRui Ueyama if (op == "!=") 10533837f427SRui Ueyama return [=] { return l().getValue() != r().getValue(); }; 10543837f427SRui Ueyama if (op == "||") 10553837f427SRui Ueyama return [=] { return l().getValue() || r().getValue(); }; 10563837f427SRui Ueyama if (op == "&&") 10573837f427SRui Ueyama return [=] { return l().getValue() && r().getValue(); }; 10583837f427SRui Ueyama if (op == "&") 10593837f427SRui Ueyama return [=] { return bitAnd(l(), r()); }; 10603837f427SRui Ueyama if (op == "|") 10613837f427SRui Ueyama return [=] { return bitOr(l(), r()); }; 10622ec34544SRui Ueyama llvm_unreachable("invalid operator"); 10632ec34544SRui Ueyama } 10642ec34544SRui Ueyama 10652ec34544SRui Ueyama // This is a part of the operator-precedence parser. This function 10662ec34544SRui Ueyama // assumes that the remaining token stream starts with an operator. 10673837f427SRui Ueyama Expr ScriptParser::readExpr1(Expr lhs, int minPrec) { 1068b8a59c8aSBob Haarman while (!atEOF() && !errorCount()) { 10692ec34544SRui Ueyama // Read an operator and an expression. 10702ec34544SRui Ueyama if (consume("?")) 10713837f427SRui Ueyama return readTernary(lhs); 10723837f427SRui Ueyama StringRef op1 = peek(); 10733837f427SRui Ueyama if (precedence(op1) < minPrec) 10742ec34544SRui Ueyama break; 10752ec34544SRui Ueyama skip(); 10763837f427SRui Ueyama Expr rhs = readPrimary(); 10772ec34544SRui Ueyama 10782ec34544SRui Ueyama // Evaluate the remaining part of the expression first if the 10792ec34544SRui Ueyama // next operator has greater precedence than the previous one. 10802ec34544SRui Ueyama // For example, if we have read "+" and "3", and if the next 10812ec34544SRui Ueyama // operator is "*", then we'll evaluate 3 * ... part first. 10822ec34544SRui Ueyama while (!atEOF()) { 10833837f427SRui Ueyama StringRef op2 = peek(); 10843837f427SRui Ueyama if (precedence(op2) <= precedence(op1)) 10852ec34544SRui Ueyama break; 10863837f427SRui Ueyama rhs = readExpr1(rhs, precedence(op2)); 10872ec34544SRui Ueyama } 10882ec34544SRui Ueyama 10893837f427SRui Ueyama lhs = combine(op1, lhs, rhs); 10902ec34544SRui Ueyama } 10913837f427SRui Ueyama return lhs; 10922ec34544SRui Ueyama } 10932ec34544SRui Ueyama 10945fb17128SGeorge Rimar Expr ScriptParser::getPageSize() { 10953837f427SRui Ueyama std::string location = getCurrentLocation(); 10965fb17128SGeorge Rimar return [=]() -> uint64_t { 10973837f427SRui Ueyama if (target) 10983837f427SRui Ueyama return config->commonPageSize; 10993837f427SRui Ueyama error(location + ": unable to calculate page size"); 11005fb17128SGeorge Rimar return 4096; // Return a dummy value. 11015fb17128SGeorge Rimar }; 11025fb17128SGeorge Rimar } 11035fb17128SGeorge Rimar 11045fb17128SGeorge Rimar Expr ScriptParser::readConstant() { 11053837f427SRui Ueyama StringRef s = readParenLiteral(); 11063837f427SRui Ueyama if (s == "COMMONPAGESIZE") 11075fb17128SGeorge Rimar return getPageSize(); 11083837f427SRui Ueyama if (s == "MAXPAGESIZE") 11093837f427SRui Ueyama return [] { return config->maxPageSize; }; 11103837f427SRui Ueyama setError("unknown constant: " + s); 1111b068b037SGeorge Rimar return [] { return 0; }; 11122ec34544SRui Ueyama } 11132ec34544SRui Ueyama 11145c65088fSRui Ueyama // Parses Tok as an integer. It recognizes hexadecimal (prefixed with 11155c65088fSRui Ueyama // "0x" or suffixed with "H") and decimal numbers. Decimal numbers may 11165c65088fSRui Ueyama // have "K" (Ki) or "M" (Mi) suffixes. 11173837f427SRui Ueyama static Optional<uint64_t> parseInt(StringRef tok) { 11182ec34544SRui Ueyama // Hexadecimal 11193837f427SRui Ueyama uint64_t val; 11203837f427SRui Ueyama if (tok.startswith_lower("0x")) { 11213837f427SRui Ueyama if (!to_integer(tok.substr(2), val, 16)) 11224092016bSRui Ueyama return None; 11233837f427SRui Ueyama return val; 11244092016bSRui Ueyama } 11253837f427SRui Ueyama if (tok.endswith_lower("H")) { 11263837f427SRui Ueyama if (!to_integer(tok.drop_back(), val, 16)) 11274092016bSRui Ueyama return None; 11283837f427SRui Ueyama return val; 11294092016bSRui Ueyama } 11302ec34544SRui Ueyama 11312ec34544SRui Ueyama // Decimal 11323837f427SRui Ueyama if (tok.endswith_lower("K")) { 11333837f427SRui Ueyama if (!to_integer(tok.drop_back(), val, 10)) 11345c65088fSRui Ueyama return None; 11353837f427SRui Ueyama return val * 1024; 11362ec34544SRui Ueyama } 11373837f427SRui Ueyama if (tok.endswith_lower("M")) { 11383837f427SRui Ueyama if (!to_integer(tok.drop_back(), val, 10)) 11395c65088fSRui Ueyama return None; 11403837f427SRui Ueyama return val * 1024 * 1024; 11415c65088fSRui Ueyama } 11423837f427SRui Ueyama if (!to_integer(tok, val, 10)) 11435c65088fSRui Ueyama return None; 11443837f427SRui Ueyama return val; 11452ec34544SRui Ueyama } 11462ec34544SRui Ueyama 11473837f427SRui Ueyama ByteCommand *ScriptParser::readByteCommand(StringRef tok) { 11483837f427SRui Ueyama int size = StringSwitch<int>(tok) 11492ec34544SRui Ueyama .Case("BYTE", 1) 11502ec34544SRui Ueyama .Case("SHORT", 2) 11512ec34544SRui Ueyama .Case("LONG", 4) 11522ec34544SRui Ueyama .Case("QUAD", 8) 11532ec34544SRui Ueyama .Default(-1); 11543837f427SRui Ueyama if (size == -1) 11552ec34544SRui Ueyama return nullptr; 115684bcabcbSGeorge Rimar 11573837f427SRui Ueyama size_t oldPos = pos; 11583837f427SRui Ueyama Expr e = readParenExpr(); 11593837f427SRui Ueyama std::string commandString = 11603837f427SRui Ueyama tok.str() + " " + 11613837f427SRui Ueyama llvm::join(tokens.begin() + oldPos, tokens.begin() + pos, " "); 11623837f427SRui Ueyama return make<ByteCommand>(e, size, commandString); 11632ec34544SRui Ueyama } 11642ec34544SRui Ueyama 1165dbd0ad33SPeter Smith static llvm::Optional<uint64_t> parseFlag(StringRef tok) { 1166dbd0ad33SPeter Smith if (llvm::Optional<uint64_t> asInt = parseInt(tok)) 1167dbd0ad33SPeter Smith return asInt; 1168dbd0ad33SPeter Smith #define CASE_ENT(enum) #enum, ELF::enum 1169dbd0ad33SPeter Smith return StringSwitch<llvm::Optional<uint64_t>>(tok) 1170dbd0ad33SPeter Smith .Case(CASE_ENT(SHF_WRITE)) 1171dbd0ad33SPeter Smith .Case(CASE_ENT(SHF_ALLOC)) 1172dbd0ad33SPeter Smith .Case(CASE_ENT(SHF_EXECINSTR)) 1173dbd0ad33SPeter Smith .Case(CASE_ENT(SHF_MERGE)) 1174dbd0ad33SPeter Smith .Case(CASE_ENT(SHF_STRINGS)) 1175dbd0ad33SPeter Smith .Case(CASE_ENT(SHF_INFO_LINK)) 1176dbd0ad33SPeter Smith .Case(CASE_ENT(SHF_LINK_ORDER)) 1177dbd0ad33SPeter Smith .Case(CASE_ENT(SHF_OS_NONCONFORMING)) 1178dbd0ad33SPeter Smith .Case(CASE_ENT(SHF_GROUP)) 1179dbd0ad33SPeter Smith .Case(CASE_ENT(SHF_TLS)) 1180dbd0ad33SPeter Smith .Case(CASE_ENT(SHF_COMPRESSED)) 1181dbd0ad33SPeter Smith .Case(CASE_ENT(SHF_EXCLUDE)) 1182dbd0ad33SPeter Smith .Case(CASE_ENT(SHF_ARM_PURECODE)) 1183dbd0ad33SPeter Smith .Default(None); 1184dbd0ad33SPeter Smith #undef CASE_ENT 1185dbd0ad33SPeter Smith } 1186dbd0ad33SPeter Smith 1187dbd0ad33SPeter Smith // Reads the '(' <flags> ')' list of section flags in 1188dbd0ad33SPeter Smith // INPUT_SECTION_FLAGS '(' <flags> ')' in the 1189dbd0ad33SPeter Smith // following form: 1190dbd0ad33SPeter Smith // <flags> ::= <flag> 1191dbd0ad33SPeter Smith // | <flags> & flag 1192dbd0ad33SPeter Smith // <flag> ::= Recognized Flag Name, or Integer value of flag. 1193dbd0ad33SPeter Smith // If the first character of <flag> is a ! then this means without flag, 1194dbd0ad33SPeter Smith // otherwise with flag. 1195dbd0ad33SPeter Smith // Example: SHF_EXECINSTR & !SHF_WRITE means with flag SHF_EXECINSTR and 1196dbd0ad33SPeter Smith // without flag SHF_WRITE. 1197dbd0ad33SPeter Smith std::pair<uint64_t, uint64_t> ScriptParser::readInputSectionFlags() { 1198dbd0ad33SPeter Smith uint64_t withFlags = 0; 1199dbd0ad33SPeter Smith uint64_t withoutFlags = 0; 1200dbd0ad33SPeter Smith expect("("); 1201dbd0ad33SPeter Smith while (!errorCount()) { 1202dbd0ad33SPeter Smith StringRef tok = unquote(next()); 1203dbd0ad33SPeter Smith bool without = tok.consume_front("!"); 1204dbd0ad33SPeter Smith if (llvm::Optional<uint64_t> flag = parseFlag(tok)) { 1205dbd0ad33SPeter Smith if (without) 1206dbd0ad33SPeter Smith withoutFlags |= *flag; 1207dbd0ad33SPeter Smith else 1208dbd0ad33SPeter Smith withFlags |= *flag; 1209dbd0ad33SPeter Smith } else { 1210dbd0ad33SPeter Smith setError("unrecognised flag: " + tok); 1211dbd0ad33SPeter Smith } 1212dbd0ad33SPeter Smith if (consume(")")) 1213dbd0ad33SPeter Smith break; 1214dbd0ad33SPeter Smith if (!consume("&")) { 1215dbd0ad33SPeter Smith next(); 1216dbd0ad33SPeter Smith setError("expected & or )"); 1217dbd0ad33SPeter Smith } 1218dbd0ad33SPeter Smith } 1219dbd0ad33SPeter Smith return std::make_pair(withFlags, withoutFlags); 1220dbd0ad33SPeter Smith } 1221dbd0ad33SPeter Smith 12222ec34544SRui Ueyama StringRef ScriptParser::readParenLiteral() { 12232ec34544SRui Ueyama expect("("); 12243837f427SRui Ueyama bool orig = inExpr; 12253837f427SRui Ueyama inExpr = false; 12263837f427SRui Ueyama StringRef tok = next(); 12273837f427SRui Ueyama inExpr = orig; 12282ec34544SRui Ueyama expect(")"); 12293837f427SRui Ueyama return tok; 12302ec34544SRui Ueyama } 12312ec34544SRui Ueyama 12323837f427SRui Ueyama static void checkIfExists(OutputSection *cmd, StringRef location) { 12333837f427SRui Ueyama if (cmd->location.empty() && script->errorOnMissingSection) 12343837f427SRui Ueyama error(location + ": undefined section " + cmd->name); 123505c4f67cSRafael Espindola } 123605c4f67cSRafael Espindola 12372ec34544SRui Ueyama Expr ScriptParser::readPrimary() { 12382ec34544SRui Ueyama if (peek() == "(") 12392ec34544SRui Ueyama return readParenExpr(); 12402ec34544SRui Ueyama 12415c65088fSRui Ueyama if (consume("~")) { 12423837f427SRui Ueyama Expr e = readPrimary(); 12433837f427SRui Ueyama return [=] { return ~e().getValue(); }; 12442ec34544SRui Ueyama } 12456f1d954eSHafiz Abid Qadeer if (consume("!")) { 12463837f427SRui Ueyama Expr e = readPrimary(); 12473837f427SRui Ueyama return [=] { return !e().getValue(); }; 12486f1d954eSHafiz Abid Qadeer } 12495c65088fSRui Ueyama if (consume("-")) { 12503837f427SRui Ueyama Expr e = readPrimary(); 12513837f427SRui Ueyama return [=] { return -e().getValue(); }; 12522ec34544SRui Ueyama } 12532ec34544SRui Ueyama 12543837f427SRui Ueyama StringRef tok = next(); 12553837f427SRui Ueyama std::string location = getCurrentLocation(); 12565c65088fSRui Ueyama 12572ec34544SRui Ueyama // Built-in functions are parsed here. 12582ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html. 12593837f427SRui Ueyama if (tok == "ABSOLUTE") { 12603837f427SRui Ueyama Expr inner = readParenExpr(); 12612ec34544SRui Ueyama return [=] { 12623837f427SRui Ueyama ExprValue i = inner(); 12633837f427SRui Ueyama i.forceAbsolute = true; 12643837f427SRui Ueyama return i; 12652ec34544SRui Ueyama }; 12662ec34544SRui Ueyama } 12673837f427SRui Ueyama if (tok == "ADDR") { 12683837f427SRui Ueyama StringRef name = readParenLiteral(); 12693837f427SRui Ueyama OutputSection *sec = script->getOrCreateOutputSection(name); 12703837f427SRui Ueyama sec->usedInExpression = true; 127141c7ab4aSGeorge Rimar return [=]() -> ExprValue { 12723837f427SRui Ueyama checkIfExists(sec, location); 12733837f427SRui Ueyama return {sec, false, 0, location}; 127441c7ab4aSGeorge Rimar }; 12752ec34544SRui Ueyama } 12763837f427SRui Ueyama if (tok == "ALIGN") { 12772ec34544SRui Ueyama expect("("); 12783837f427SRui Ueyama Expr e = readExpr(); 1279f22ec9ddSGeorge Rimar if (consume(")")) { 12803837f427SRui Ueyama e = checkAlignment(e, location); 12813837f427SRui Ueyama return [=] { return alignTo(script->getDot(), e().getValue()); }; 1282f22ec9ddSGeorge Rimar } 1283b579c439SRui Ueyama expect(","); 12843837f427SRui Ueyama Expr e2 = checkAlignment(readExpr(), location); 12852ec34544SRui Ueyama expect(")"); 12863c6de1a6SPetr Hosek return [=] { 12873837f427SRui Ueyama ExprValue v = e(); 12883837f427SRui Ueyama v.alignment = e2().getValue(); 12893837f427SRui Ueyama return v; 12903c6de1a6SPetr Hosek }; 12912ec34544SRui Ueyama } 12923837f427SRui Ueyama if (tok == "ALIGNOF") { 12933837f427SRui Ueyama StringRef name = readParenLiteral(); 12943837f427SRui Ueyama OutputSection *cmd = script->getOrCreateOutputSection(name); 1295617e2f98SRui Ueyama return [=] { 12963837f427SRui Ueyama checkIfExists(cmd, location); 12973837f427SRui Ueyama return cmd->alignment; 1298617e2f98SRui Ueyama }; 12992ec34544SRui Ueyama } 13003837f427SRui Ueyama if (tok == "ASSERT") 1301d30a78b3SGeorge Rimar return readAssert(); 13023837f427SRui Ueyama if (tok == "CONSTANT") 13035fb17128SGeorge Rimar return readConstant(); 13043837f427SRui Ueyama if (tok == "DATA_SEGMENT_ALIGN") { 13052ec34544SRui Ueyama expect("("); 13063837f427SRui Ueyama Expr e = readExpr(); 13072ec34544SRui Ueyama expect(","); 13082ec34544SRui Ueyama readExpr(); 13092ec34544SRui Ueyama expect(")"); 131060833f6eSGeorge Rimar return [=] { 13113837f427SRui Ueyama return alignTo(script->getDot(), std::max((uint64_t)1, e().getValue())); 131260833f6eSGeorge Rimar }; 13132ec34544SRui Ueyama } 13143837f427SRui Ueyama if (tok == "DATA_SEGMENT_END") { 13152ec34544SRui Ueyama expect("("); 13162ec34544SRui Ueyama expect("."); 13172ec34544SRui Ueyama expect(")"); 13183837f427SRui Ueyama return [] { return script->getDot(); }; 13192ec34544SRui Ueyama } 13203837f427SRui Ueyama if (tok == "DATA_SEGMENT_RELRO_END") { 13212ec34544SRui Ueyama // GNU linkers implements more complicated logic to handle 13222ec34544SRui Ueyama // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and 13232ec34544SRui Ueyama // just align to the next page boundary for simplicity. 13242ec34544SRui Ueyama expect("("); 13252ec34544SRui Ueyama readExpr(); 13262ec34544SRui Ueyama expect(","); 13272ec34544SRui Ueyama readExpr(); 13282ec34544SRui Ueyama expect(")"); 13293837f427SRui Ueyama Expr e = getPageSize(); 13303837f427SRui Ueyama return [=] { return alignTo(script->getDot(), e().getValue()); }; 13312ec34544SRui Ueyama } 13323837f427SRui Ueyama if (tok == "DEFINED") { 13333837f427SRui Ueyama StringRef name = readParenLiteral(); 13341f166edeSHafiz Abid Qadeer return [=] { 13351f166edeSHafiz Abid Qadeer Symbol *b = symtab->find(name); 13361f166edeSHafiz Abid Qadeer return (b && b->isDefined()) ? 1 : 0; 13371f166edeSHafiz Abid Qadeer }; 13382ec34544SRui Ueyama } 13393837f427SRui Ueyama if (tok == "LENGTH") { 13403837f427SRui Ueyama StringRef name = readParenLiteral(); 13413837f427SRui Ueyama if (script->memoryRegions.count(name) == 0) { 13423837f427SRui Ueyama setError("memory region not defined: " + name); 1343b068b037SGeorge Rimar return [] { return 0; }; 1344b068b037SGeorge Rimar } 134592b5b980SFangrui Song return script->memoryRegions[name]->length; 134691b95b61SRui Ueyama } 13473837f427SRui Ueyama if (tok == "LOADADDR") { 13483837f427SRui Ueyama StringRef name = readParenLiteral(); 13493837f427SRui Ueyama OutputSection *cmd = script->getOrCreateOutputSection(name); 13503837f427SRui Ueyama cmd->usedInExpression = true; 1351617e2f98SRui Ueyama return [=] { 13523837f427SRui Ueyama checkIfExists(cmd, location); 13533837f427SRui Ueyama return cmd->getLMA(); 1354617e2f98SRui Ueyama }; 13552ec34544SRui Ueyama } 1356fa1145a8SIsaac Richter if (tok == "LOG2CEIL") { 1357fa1145a8SIsaac Richter expect("("); 1358fa1145a8SIsaac Richter Expr a = readExpr(); 1359fa1145a8SIsaac Richter expect(")"); 1360fa1145a8SIsaac Richter return [=] { 1361fa1145a8SIsaac Richter // LOG2CEIL(0) is defined to be 0. 1362fa1145a8SIsaac Richter return llvm::Log2_64_Ceil(std::max(a().getValue(), UINT64_C(1))); 1363fa1145a8SIsaac Richter }; 1364fa1145a8SIsaac Richter } 13653837f427SRui Ueyama if (tok == "MAX" || tok == "MIN") { 1366fd11560fSGeorge Rimar expect("("); 13673837f427SRui Ueyama Expr a = readExpr(); 1368fd11560fSGeorge Rimar expect(","); 13693837f427SRui Ueyama Expr b = readExpr(); 1370fd11560fSGeorge Rimar expect(")"); 13713837f427SRui Ueyama if (tok == "MIN") 13723837f427SRui Ueyama return [=] { return std::min(a().getValue(), b().getValue()); }; 13733837f427SRui Ueyama return [=] { return std::max(a().getValue(), b().getValue()); }; 1374fd11560fSGeorge Rimar } 13753837f427SRui Ueyama if (tok == "ORIGIN") { 13763837f427SRui Ueyama StringRef name = readParenLiteral(); 13773837f427SRui Ueyama if (script->memoryRegions.count(name) == 0) { 13783837f427SRui Ueyama setError("memory region not defined: " + name); 1379b068b037SGeorge Rimar return [] { return 0; }; 1380b068b037SGeorge Rimar } 138192b5b980SFangrui Song return script->memoryRegions[name]->origin; 138291b95b61SRui Ueyama } 13833837f427SRui Ueyama if (tok == "SEGMENT_START") { 13842ec34544SRui Ueyama expect("("); 13852ec34544SRui Ueyama skip(); 13862ec34544SRui Ueyama expect(","); 13873837f427SRui Ueyama Expr e = readExpr(); 13882ec34544SRui Ueyama expect(")"); 13893837f427SRui Ueyama return [=] { return e(); }; 13902ec34544SRui Ueyama } 13913837f427SRui Ueyama if (tok == "SIZEOF") { 13923837f427SRui Ueyama StringRef name = readParenLiteral(); 13933837f427SRui Ueyama OutputSection *cmd = script->getOrCreateOutputSection(name); 139405c4f67cSRafael Espindola // Linker script does not create an output section if its content is empty. 139505c4f67cSRafael Espindola // We want to allow SIZEOF(.foo) where .foo is a section which happened to 139605c4f67cSRafael Espindola // be empty. 13973837f427SRui Ueyama return [=] { return cmd->size; }; 13982ec34544SRui Ueyama } 13993837f427SRui Ueyama if (tok == "SIZEOF_HEADERS") 140007837b8fSFangrui Song return [=] { return elf::getHeaderSize(); }; 14012ec34544SRui Ueyama 14024eb2eccbSRui Ueyama // Tok is the dot. 14033837f427SRui Ueyama if (tok == ".") 14043837f427SRui Ueyama return [=] { return script->getSymbolValue(tok, location); }; 14054eb2eccbSRui Ueyama 14062ec34544SRui Ueyama // Tok is a literal number. 14073837f427SRui Ueyama if (Optional<uint64_t> val = parseInt(tok)) 14083837f427SRui Ueyama return [=] { return *val; }; 14092ec34544SRui Ueyama 14102ec34544SRui Ueyama // Tok is a symbol name. 14113837f427SRui Ueyama if (!isValidCIdentifier(tok)) 14123837f427SRui Ueyama setError("malformed number: " + tok); 14133837f427SRui Ueyama script->referencedSymbols.push_back(tok); 14143837f427SRui Ueyama return [=] { return script->getSymbolValue(tok, location); }; 14152ec34544SRui Ueyama } 14162ec34544SRui Ueyama 14173837f427SRui Ueyama Expr ScriptParser::readTernary(Expr cond) { 14183837f427SRui Ueyama Expr l = readExpr(); 14192ec34544SRui Ueyama expect(":"); 14203837f427SRui Ueyama Expr r = readExpr(); 14213837f427SRui Ueyama return [=] { return cond().getValue() ? l() : r(); }; 14222ec34544SRui Ueyama } 14232ec34544SRui Ueyama 14242ec34544SRui Ueyama Expr ScriptParser::readParenExpr() { 14252ec34544SRui Ueyama expect("("); 14263837f427SRui Ueyama Expr e = readExpr(); 14272ec34544SRui Ueyama expect(")"); 14283837f427SRui Ueyama return e; 14292ec34544SRui Ueyama } 14302ec34544SRui Ueyama 14312ec34544SRui Ueyama std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() { 14323837f427SRui Ueyama std::vector<StringRef> phdrs; 1433b8a59c8aSBob Haarman while (!errorCount() && peek().startswith(":")) { 14343837f427SRui Ueyama StringRef tok = next(); 14353837f427SRui Ueyama phdrs.push_back((tok.size() == 1) ? next() : tok.substr(1)); 14362ec34544SRui Ueyama } 14373837f427SRui Ueyama return phdrs; 14382ec34544SRui Ueyama } 14392ec34544SRui Ueyama 14402ec34544SRui Ueyama // Read a program header type name. The next token must be a 14412ec34544SRui Ueyama // name of a program header type or a constant (e.g. "0x3"). 14422ec34544SRui Ueyama unsigned ScriptParser::readPhdrType() { 14433837f427SRui Ueyama StringRef tok = next(); 14443837f427SRui Ueyama if (Optional<uint64_t> val = parseInt(tok)) 14453837f427SRui Ueyama return *val; 14462ec34544SRui Ueyama 14473837f427SRui Ueyama unsigned ret = StringSwitch<unsigned>(tok) 14482ec34544SRui Ueyama .Case("PT_NULL", PT_NULL) 14492ec34544SRui Ueyama .Case("PT_LOAD", PT_LOAD) 14502ec34544SRui Ueyama .Case("PT_DYNAMIC", PT_DYNAMIC) 14512ec34544SRui Ueyama .Case("PT_INTERP", PT_INTERP) 14522ec34544SRui Ueyama .Case("PT_NOTE", PT_NOTE) 14532ec34544SRui Ueyama .Case("PT_SHLIB", PT_SHLIB) 14542ec34544SRui Ueyama .Case("PT_PHDR", PT_PHDR) 14552ec34544SRui Ueyama .Case("PT_TLS", PT_TLS) 14562ec34544SRui Ueyama .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME) 14572ec34544SRui Ueyama .Case("PT_GNU_STACK", PT_GNU_STACK) 14582ec34544SRui Ueyama .Case("PT_GNU_RELRO", PT_GNU_RELRO) 14592ec34544SRui Ueyama .Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE) 14602ec34544SRui Ueyama .Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED) 14612ec34544SRui Ueyama .Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA) 14622ec34544SRui Ueyama .Default(-1); 14632ec34544SRui Ueyama 14643837f427SRui Ueyama if (ret == (unsigned)-1) { 14653837f427SRui Ueyama setError("invalid program header type: " + tok); 14662ec34544SRui Ueyama return PT_NULL; 14672ec34544SRui Ueyama } 14683837f427SRui Ueyama return ret; 14692ec34544SRui Ueyama } 14702ec34544SRui Ueyama 14712ec34544SRui Ueyama // Reads an anonymous version declaration. 14722ec34544SRui Ueyama void ScriptParser::readAnonymousDeclaration() { 14733837f427SRui Ueyama std::vector<SymbolVersion> locals; 14743837f427SRui Ueyama std::vector<SymbolVersion> globals; 14753837f427SRui Ueyama std::tie(locals, globals) = readSymbols(); 1476e28a70daSFangrui Song for (const SymbolVersion &pat : locals) 1477e28a70daSFangrui Song config->versionDefinitions[VER_NDX_LOCAL].patterns.push_back(pat); 1478e28a70daSFangrui Song for (const SymbolVersion &pat : globals) 1479e28a70daSFangrui Song config->versionDefinitions[VER_NDX_GLOBAL].patterns.push_back(pat); 14802ec34544SRui Ueyama 14812ec34544SRui Ueyama expect(";"); 14822ec34544SRui Ueyama } 14832ec34544SRui Ueyama 14842ec34544SRui Ueyama // Reads a non-anonymous version definition, 14852ec34544SRui Ueyama // e.g. "VerStr { global: foo; bar; local: *; };". 14863837f427SRui Ueyama void ScriptParser::readVersionDeclaration(StringRef verStr) { 14872ec34544SRui Ueyama // Read a symbol list. 14883837f427SRui Ueyama std::vector<SymbolVersion> locals; 14893837f427SRui Ueyama std::vector<SymbolVersion> globals; 14903837f427SRui Ueyama std::tie(locals, globals) = readSymbols(); 1491e28a70daSFangrui Song for (const SymbolVersion &pat : locals) 1492e28a70daSFangrui Song config->versionDefinitions[VER_NDX_LOCAL].patterns.push_back(pat); 14932ec34544SRui Ueyama 14942ec34544SRui Ueyama // Create a new version definition and add that to the global symbols. 14953837f427SRui Ueyama VersionDefinition ver; 14963837f427SRui Ueyama ver.name = verStr; 1497e28a70daSFangrui Song ver.patterns = globals; 1498e28a70daSFangrui Song ver.id = config->versionDefinitions.size(); 14993837f427SRui Ueyama config->versionDefinitions.push_back(ver); 15002ec34544SRui Ueyama 15012ec34544SRui Ueyama // Each version may have a parent version. For example, "Ver2" 15022ec34544SRui Ueyama // defined as "Ver2 { global: foo; local: *; } Ver1;" has "Ver1" 15032ec34544SRui Ueyama // as a parent. This version hierarchy is, probably against your 15042ec34544SRui Ueyama // instinct, purely for hint; the runtime doesn't care about it 15052ec34544SRui Ueyama // at all. In LLD, we simply ignore it. 15065f380403SFangrui Song if (next() != ";") 15072ec34544SRui Ueyama expect(";"); 15082ec34544SRui Ueyama } 15092ec34544SRui Ueyama 151049279ca1SFangrui Song bool elf::hasWildcard(StringRef s) { 15113837f427SRui Ueyama return s.find_first_of("?*[") != StringRef::npos; 15121e77ad14SRui Ueyama } 15131e77ad14SRui Ueyama 15142ec34544SRui Ueyama // Reads a list of symbols, e.g. "{ global: foo; bar; local: *; };". 15152ec34544SRui Ueyama std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>> 15162ec34544SRui Ueyama ScriptParser::readSymbols() { 15173837f427SRui Ueyama std::vector<SymbolVersion> locals; 15183837f427SRui Ueyama std::vector<SymbolVersion> globals; 15193837f427SRui Ueyama std::vector<SymbolVersion> *v = &globals; 15202ec34544SRui Ueyama 1521b8a59c8aSBob Haarman while (!errorCount()) { 15222ec34544SRui Ueyama if (consume("}")) 15232ec34544SRui Ueyama break; 15242ec34544SRui Ueyama if (consumeLabel("local")) { 15253837f427SRui Ueyama v = &locals; 15262ec34544SRui Ueyama continue; 15272ec34544SRui Ueyama } 15282ec34544SRui Ueyama if (consumeLabel("global")) { 15293837f427SRui Ueyama v = &globals; 15302ec34544SRui Ueyama continue; 15312ec34544SRui Ueyama } 15322ec34544SRui Ueyama 15332ec34544SRui Ueyama if (consume("extern")) { 15343837f427SRui Ueyama std::vector<SymbolVersion> ext = readVersionExtern(); 15353837f427SRui Ueyama v->insert(v->end(), ext.begin(), ext.end()); 15362ec34544SRui Ueyama } else { 15373837f427SRui Ueyama StringRef tok = next(); 15383837f427SRui Ueyama v->push_back({unquote(tok), false, hasWildcard(tok)}); 15392ec34544SRui Ueyama } 15402ec34544SRui Ueyama expect(";"); 15412ec34544SRui Ueyama } 15423837f427SRui Ueyama return {locals, globals}; 15432ec34544SRui Ueyama } 15442ec34544SRui Ueyama 15452ec34544SRui Ueyama // Reads an "extern C++" directive, e.g., 15462ec34544SRui Ueyama // "extern "C++" { ns::*; "f(int, double)"; };" 154717324d8bSRui Ueyama // 154817324d8bSRui Ueyama // The last semicolon is optional. E.g. this is OK: 154917324d8bSRui Ueyama // "extern "C++" { ns::*; "f(int, double)" };" 15502ec34544SRui Ueyama std::vector<SymbolVersion> ScriptParser::readVersionExtern() { 15513837f427SRui Ueyama StringRef tok = next(); 15523837f427SRui Ueyama bool isCXX = tok == "\"C++\""; 15533837f427SRui Ueyama if (!isCXX && tok != "\"C\"") 15542ec34544SRui Ueyama setError("Unknown language"); 15552ec34544SRui Ueyama expect("{"); 15562ec34544SRui Ueyama 15573837f427SRui Ueyama std::vector<SymbolVersion> ret; 1558b8a59c8aSBob Haarman while (!errorCount() && peek() != "}") { 15593837f427SRui Ueyama StringRef tok = next(); 15603837f427SRui Ueyama ret.push_back( 15613837f427SRui Ueyama {unquote(tok), isCXX, !tok.startswith("\"") && hasWildcard(tok)}); 156217324d8bSRui Ueyama if (consume("}")) 15633837f427SRui Ueyama return ret; 15642ec34544SRui Ueyama expect(";"); 15652ec34544SRui Ueyama } 15662ec34544SRui Ueyama 15672ec34544SRui Ueyama expect("}"); 15683837f427SRui Ueyama return ret; 15692ec34544SRui Ueyama } 15702ec34544SRui Ueyama 157192b5b980SFangrui Song Expr ScriptParser::readMemoryAssignment(StringRef s1, StringRef s2, 15723837f427SRui Ueyama StringRef s3) { 15733837f427SRui Ueyama if (!consume(s1) && !consume(s2) && !consume(s3)) { 15743837f427SRui Ueyama setError("expected one of: " + s1 + ", " + s2 + ", or " + s3); 157592b5b980SFangrui Song return [] { return 0; }; 15762ec34544SRui Ueyama } 15772ec34544SRui Ueyama expect("="); 157892b5b980SFangrui Song return readExpr(); 15792ec34544SRui Ueyama } 15802ec34544SRui Ueyama 15812ec34544SRui Ueyama // Parse the MEMORY command as specified in: 15822ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/MEMORY.html 15832ec34544SRui Ueyama // 15842ec34544SRui Ueyama // MEMORY { name [(attr)] : ORIGIN = origin, LENGTH = len ... } 15852ec34544SRui Ueyama void ScriptParser::readMemory() { 15862ec34544SRui Ueyama expect("{"); 1587b8a59c8aSBob Haarman while (!errorCount() && !consume("}")) { 15883837f427SRui Ueyama StringRef tok = next(); 15893837f427SRui Ueyama if (tok == "INCLUDE") { 15902e9d40d5SRui Ueyama readInclude(); 15912e9d40d5SRui Ueyama continue; 15922e9d40d5SRui Ueyama } 15932ec34544SRui Ueyama 15943837f427SRui Ueyama uint32_t flags = 0; 15953837f427SRui Ueyama uint32_t negFlags = 0; 15962ec34544SRui Ueyama if (consume("(")) { 15973837f427SRui Ueyama std::tie(flags, negFlags) = readMemoryAttributes(); 15982ec34544SRui Ueyama expect(")"); 15992ec34544SRui Ueyama } 16002ec34544SRui Ueyama expect(":"); 16012ec34544SRui Ueyama 160292b5b980SFangrui Song Expr origin = readMemoryAssignment("ORIGIN", "org", "o"); 16032ec34544SRui Ueyama expect(","); 160492b5b980SFangrui Song Expr length = readMemoryAssignment("LENGTH", "len", "l"); 16052ec34544SRui Ueyama 16065f37541cSGeorge Rimar // Add the memory region to the region map. 16073837f427SRui Ueyama MemoryRegion *mr = make<MemoryRegion>(tok, origin, length, flags, negFlags); 16083837f427SRui Ueyama if (!script->memoryRegions.insert({tok, mr}).second) 16093837f427SRui Ueyama setError("region '" + tok + "' already defined"); 16102ec34544SRui Ueyama } 16112ec34544SRui Ueyama } 16122ec34544SRui Ueyama 16132ec34544SRui Ueyama // This function parses the attributes used to match against section 16142ec34544SRui Ueyama // flags when placing output sections in a memory region. These flags 16152ec34544SRui Ueyama // are only used when an explicit memory region name is not used. 16162ec34544SRui Ueyama std::pair<uint32_t, uint32_t> ScriptParser::readMemoryAttributes() { 16173837f427SRui Ueyama uint32_t flags = 0; 16183837f427SRui Ueyama uint32_t negFlags = 0; 16193837f427SRui Ueyama bool invert = false; 16202ec34544SRui Ueyama 16213837f427SRui Ueyama for (char c : next().lower()) { 16223837f427SRui Ueyama uint32_t flag = 0; 16233837f427SRui Ueyama if (c == '!') 16243837f427SRui Ueyama invert = !invert; 16253837f427SRui Ueyama else if (c == 'w') 16263837f427SRui Ueyama flag = SHF_WRITE; 16273837f427SRui Ueyama else if (c == 'x') 16283837f427SRui Ueyama flag = SHF_EXECINSTR; 16293837f427SRui Ueyama else if (c == 'a') 16303837f427SRui Ueyama flag = SHF_ALLOC; 16313837f427SRui Ueyama else if (c != 'r') 16322ec34544SRui Ueyama setError("invalid memory region attribute"); 16332ec34544SRui Ueyama 16343837f427SRui Ueyama if (invert) 16353837f427SRui Ueyama negFlags |= flag; 16362ec34544SRui Ueyama else 16373837f427SRui Ueyama flags |= flag; 16382ec34544SRui Ueyama } 16393837f427SRui Ueyama return {flags, negFlags}; 16402ec34544SRui Ueyama } 16412ec34544SRui Ueyama 164207837b8fSFangrui Song void elf::readLinkerScript(MemoryBufferRef mb) { 1643439341b9SJames Henderson llvm::TimeTraceScope timeScope("Read linker script", 1644439341b9SJames Henderson mb.getBufferIdentifier()); 16453837f427SRui Ueyama ScriptParser(mb).readLinkerScript(); 16462ec34544SRui Ueyama } 16472ec34544SRui Ueyama 164807837b8fSFangrui Song void elf::readVersionScript(MemoryBufferRef mb) { 1649439341b9SJames Henderson llvm::TimeTraceScope timeScope("Read version script", 1650439341b9SJames Henderson mb.getBufferIdentifier()); 16513837f427SRui Ueyama ScriptParser(mb).readVersionScript(); 16522ec34544SRui Ueyama } 16532ec34544SRui Ueyama 165407837b8fSFangrui Song void elf::readDynamicList(MemoryBufferRef mb) { 1655439341b9SJames Henderson llvm::TimeTraceScope timeScope("Read dynamic list", mb.getBufferIdentifier()); 165607837b8fSFangrui Song ScriptParser(mb).readDynamicList(); 16578c7e8cceSPetr Hosek } 1658bd8cfe65SFangrui Song 165907837b8fSFangrui Song void elf::readDefsym(StringRef name, MemoryBufferRef mb) { 1660439341b9SJames Henderson llvm::TimeTraceScope timeScope("Read defsym input", name); 166107837b8fSFangrui Song ScriptParser(mb).readDefsym(name); 166207837b8fSFangrui Song } 1663