12ec34544SRui Ueyama //===- ScriptParser.cpp ---------------------------------------------------===// 22ec34544SRui Ueyama // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 62ec34544SRui Ueyama // 72ec34544SRui Ueyama //===----------------------------------------------------------------------===// 805f6b852SRui Ueyama // 905f6b852SRui Ueyama // This file contains a recursive-descendent parser for linker scripts. 1005f6b852SRui Ueyama // Parsed results are stored to Config and Script global objects. 1105f6b852SRui Ueyama // 1205f6b852SRui Ueyama //===----------------------------------------------------------------------===// 132ec34544SRui Ueyama 142ec34544SRui Ueyama #include "ScriptParser.h" 152ec34544SRui Ueyama #include "Config.h" 162ec34544SRui Ueyama #include "Driver.h" 172ec34544SRui Ueyama #include "InputSection.h" 182ec34544SRui Ueyama #include "LinkerScript.h" 192ec34544SRui Ueyama #include "OutputSections.h" 202ec34544SRui Ueyama #include "ScriptLexer.h" 212ec34544SRui Ueyama #include "Symbols.h" 222ec34544SRui Ueyama #include "Target.h" 232017d52bSRui Ueyama #include "lld/Common/Memory.h" 242ec34544SRui Ueyama #include "llvm/ADT/SmallString.h" 252ec34544SRui Ueyama #include "llvm/ADT/StringRef.h" 260440be4aSRui Ueyama #include "llvm/ADT/StringSet.h" 272ec34544SRui Ueyama #include "llvm/ADT/StringSwitch.h" 28264b5d9eSZachary Turner #include "llvm/BinaryFormat/ELF.h" 292ec34544SRui Ueyama #include "llvm/Support/Casting.h" 302ec34544SRui Ueyama #include "llvm/Support/ErrorHandling.h" 312ec34544SRui Ueyama #include "llvm/Support/FileSystem.h" 322ec34544SRui Ueyama #include "llvm/Support/Path.h" 332ec34544SRui Ueyama #include <cassert> 342ec34544SRui Ueyama #include <limits> 352ec34544SRui Ueyama #include <vector> 362ec34544SRui Ueyama 372ec34544SRui Ueyama using namespace llvm; 382ec34544SRui Ueyama using namespace llvm::ELF; 39b58079d4SRui Ueyama using namespace llvm::support::endian; 402ec34544SRui Ueyama using namespace lld; 412ec34544SRui Ueyama using namespace lld::elf; 422ec34544SRui Ueyama 4396b3fe02SRui Ueyama namespace { 4496b3fe02SRui Ueyama class ScriptParser final : ScriptLexer { 452ec34544SRui Ueyama public: 463837f427SRui Ueyama ScriptParser(MemoryBufferRef mb) : ScriptLexer(mb) { 4711ae59f0SRui Ueyama // Initialize IsUnderSysroot 483837f427SRui Ueyama if (config->sysroot == "") 4911ae59f0SRui Ueyama return; 503837f427SRui Ueyama StringRef path = mb.getBufferIdentifier(); 513837f427SRui Ueyama for (; !path.empty(); path = sys::path::parent_path(path)) { 523837f427SRui Ueyama if (!sys::fs::equivalent(config->sysroot, path)) 5311ae59f0SRui Ueyama continue; 543837f427SRui Ueyama isUnderSysroot = true; 5511ae59f0SRui Ueyama return; 5611ae59f0SRui Ueyama } 5711ae59f0SRui Ueyama } 582ec34544SRui Ueyama 592ec34544SRui Ueyama void readLinkerScript(); 602ec34544SRui Ueyama void readVersionScript(); 612ec34544SRui Ueyama void readDynamicList(); 623837f427SRui Ueyama void readDefsym(StringRef name); 632ec34544SRui Ueyama 642ec34544SRui Ueyama private: 653837f427SRui Ueyama void addFile(StringRef path); 662ec34544SRui Ueyama 672ec34544SRui Ueyama void readAsNeeded(); 682ec34544SRui Ueyama void readEntry(); 692ec34544SRui Ueyama void readExtern(); 702ec34544SRui Ueyama void readGroup(); 712ec34544SRui Ueyama void readInclude(); 721d92aa73SRui Ueyama void readInput(); 732ec34544SRui Ueyama void readMemory(); 742ec34544SRui Ueyama void readOutput(); 752ec34544SRui Ueyama void readOutputArch(); 762ec34544SRui Ueyama void readOutputFormat(); 772ec34544SRui Ueyama void readPhdrs(); 785f37541cSGeorge Rimar void readRegionAlias(); 792ec34544SRui Ueyama void readSearchDir(); 802ec34544SRui Ueyama void readSections(); 81e262bb1aSRui Ueyama void readTarget(); 822ec34544SRui Ueyama void readVersion(); 832ec34544SRui Ueyama void readVersionScriptCommand(); 842ec34544SRui Ueyama 853837f427SRui Ueyama SymbolAssignment *readSymbolAssignment(StringRef name); 863837f427SRui Ueyama ByteCommand *readByteCommand(StringRef tok); 87b0486051SSimon Atanasyan std::array<uint8_t, 4> readFill(); 883837f427SRui Ueyama bool readSectionDirective(OutputSection *cmd, StringRef tok1, StringRef tok2); 893837f427SRui Ueyama void readSectionAddressType(OutputSection *cmd); 90a582419aSGeorge Rimar OutputSection *readOverlaySectionDescription(); 913837f427SRui Ueyama OutputSection *readOutputSectionDescription(StringRef outSec); 92a582419aSGeorge Rimar std::vector<BaseCommand *> readOverlay(); 932ec34544SRui Ueyama std::vector<StringRef> readOutputSectionPhdrs(); 943837f427SRui Ueyama InputSectionDescription *readInputSectionDescription(StringRef tok); 952ec34544SRui Ueyama StringMatcher readFilePatterns(); 962ec34544SRui Ueyama std::vector<SectionPattern> readInputSectionsList(); 973837f427SRui Ueyama InputSectionDescription *readInputSectionRules(StringRef filePattern); 982ec34544SRui Ueyama unsigned readPhdrType(); 992ec34544SRui Ueyama SortSectionPolicy readSortKind(); 1003837f427SRui Ueyama SymbolAssignment *readProvideHidden(bool provide, bool hidden); 1013837f427SRui Ueyama SymbolAssignment *readAssignment(StringRef tok); 1022ec34544SRui Ueyama void readSort(); 103d30a78b3SGeorge Rimar Expr readAssert(); 1045fb17128SGeorge Rimar Expr readConstant(); 1055fb17128SGeorge Rimar Expr getPageSize(); 1062ec34544SRui Ueyama 1072ec34544SRui Ueyama uint64_t readMemoryAssignment(StringRef, StringRef, StringRef); 1082ec34544SRui Ueyama std::pair<uint32_t, uint32_t> readMemoryAttributes(); 1092ec34544SRui Ueyama 1103837f427SRui Ueyama Expr combine(StringRef op, Expr l, Expr r); 1112ec34544SRui Ueyama Expr readExpr(); 1123837f427SRui Ueyama Expr readExpr1(Expr lhs, int minPrec); 1132ec34544SRui Ueyama StringRef readParenLiteral(); 1142ec34544SRui Ueyama Expr readPrimary(); 1153837f427SRui Ueyama Expr readTernary(Expr cond); 1162ec34544SRui Ueyama Expr readParenExpr(); 1172ec34544SRui Ueyama 1182ec34544SRui Ueyama // For parsing version script. 1192ec34544SRui Ueyama std::vector<SymbolVersion> readVersionExtern(); 1202ec34544SRui Ueyama void readAnonymousDeclaration(); 1213837f427SRui Ueyama void readVersionDeclaration(StringRef verStr); 1222ec34544SRui Ueyama 1232ec34544SRui Ueyama std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>> 1242ec34544SRui Ueyama readSymbols(); 1252ec34544SRui Ueyama 126fd06b025SRui Ueyama // True if a script being read is in a subdirectory specified by -sysroot. 1273837f427SRui Ueyama bool isUnderSysroot = false; 1280440be4aSRui Ueyama 1290440be4aSRui Ueyama // A set to detect an INCLUDE() cycle. 1303837f427SRui Ueyama StringSet<> seen; 1312ec34544SRui Ueyama }; 13296b3fe02SRui Ueyama } // namespace 1332ec34544SRui Ueyama 1343837f427SRui Ueyama static StringRef unquote(StringRef s) { 1353837f427SRui Ueyama if (s.startswith("\"")) 1363837f427SRui Ueyama return s.substr(1, s.size() - 2); 1373837f427SRui Ueyama return s; 1381e77ad14SRui Ueyama } 1391e77ad14SRui Ueyama 1402ec34544SRui Ueyama // Some operations only support one non absolute value. Move the 1412ec34544SRui Ueyama // absolute one to the right hand side for convenience. 1423837f427SRui Ueyama static void moveAbsRight(ExprValue &a, ExprValue &b) { 1433837f427SRui Ueyama if (a.sec == nullptr || (a.forceAbsolute && !b.isAbsolute())) 1443837f427SRui Ueyama std::swap(a, b); 1453837f427SRui Ueyama if (!b.isAbsolute()) 1463837f427SRui Ueyama error(a.loc + ": at least one side of the expression must be absolute"); 1472ec34544SRui Ueyama } 1482ec34544SRui Ueyama 1493837f427SRui Ueyama static ExprValue add(ExprValue a, ExprValue b) { 1503837f427SRui Ueyama moveAbsRight(a, b); 1513837f427SRui Ueyama return {a.sec, a.forceAbsolute, a.getSectionOffset() + b.getValue(), a.loc}; 1522ec34544SRui Ueyama } 1532ec34544SRui Ueyama 1543837f427SRui Ueyama static ExprValue sub(ExprValue a, ExprValue b) { 15563a4a98eSRafael Espindola // The distance between two symbols in sections is absolute. 1563837f427SRui Ueyama if (!a.isAbsolute() && !b.isAbsolute()) 1573837f427SRui Ueyama return a.getValue() - b.getValue(); 1583837f427SRui Ueyama return {a.sec, false, a.getSectionOffset() - b.getValue(), a.loc}; 1592ec34544SRui Ueyama } 1602ec34544SRui Ueyama 1613837f427SRui Ueyama static ExprValue bitAnd(ExprValue a, ExprValue b) { 1623837f427SRui Ueyama moveAbsRight(a, b); 1633837f427SRui Ueyama return {a.sec, a.forceAbsolute, 1643837f427SRui Ueyama (a.getValue() & b.getValue()) - a.getSecAddr(), a.loc}; 1652ec34544SRui Ueyama } 1662ec34544SRui Ueyama 1673837f427SRui Ueyama static ExprValue bitOr(ExprValue a, ExprValue b) { 1683837f427SRui Ueyama moveAbsRight(a, b); 1693837f427SRui Ueyama return {a.sec, a.forceAbsolute, 1703837f427SRui Ueyama (a.getValue() | b.getValue()) - a.getSecAddr(), a.loc}; 1712ec34544SRui Ueyama } 1722ec34544SRui Ueyama 1732ec34544SRui Ueyama void ScriptParser::readDynamicList() { 1743837f427SRui Ueyama config->hasDynamicList = true; 1752ec34544SRui Ueyama expect("{"); 1763837f427SRui Ueyama std::vector<SymbolVersion> locals; 1773837f427SRui Ueyama std::vector<SymbolVersion> globals; 1783837f427SRui Ueyama std::tie(locals, globals) = readSymbols(); 179d72d97b3SRafael Espindola expect(";"); 180d72d97b3SRafael Espindola 181d72d97b3SRafael Espindola if (!atEOF()) { 1822ec34544SRui Ueyama setError("EOF expected, but got " + next()); 183d72d97b3SRafael Espindola return; 184d72d97b3SRafael Espindola } 1853837f427SRui Ueyama if (!locals.empty()) { 186d72d97b3SRafael Espindola setError("\"local:\" scope not supported in --dynamic-list"); 187d72d97b3SRafael Espindola return; 188d72d97b3SRafael Espindola } 189d72d97b3SRafael Espindola 1903837f427SRui Ueyama for (SymbolVersion v : globals) 1913837f427SRui Ueyama config->dynamicList.push_back(v); 1922ec34544SRui Ueyama } 1932ec34544SRui Ueyama 1942ec34544SRui Ueyama void ScriptParser::readVersionScript() { 1952ec34544SRui Ueyama readVersionScriptCommand(); 1962ec34544SRui Ueyama if (!atEOF()) 1972ec34544SRui Ueyama setError("EOF expected, but got " + next()); 1982ec34544SRui Ueyama } 1992ec34544SRui Ueyama 2002ec34544SRui Ueyama void ScriptParser::readVersionScriptCommand() { 2012ec34544SRui Ueyama if (consume("{")) { 2022ec34544SRui Ueyama readAnonymousDeclaration(); 2032ec34544SRui Ueyama return; 2042ec34544SRui Ueyama } 2052ec34544SRui Ueyama 206b8a59c8aSBob Haarman while (!atEOF() && !errorCount() && peek() != "}") { 2073837f427SRui Ueyama StringRef verStr = next(); 2083837f427SRui Ueyama if (verStr == "{") { 2092ec34544SRui Ueyama setError("anonymous version definition is used in " 2102ec34544SRui Ueyama "combination with other version definitions"); 2112ec34544SRui Ueyama return; 2122ec34544SRui Ueyama } 2132ec34544SRui Ueyama expect("{"); 2143837f427SRui Ueyama readVersionDeclaration(verStr); 2152ec34544SRui Ueyama } 2162ec34544SRui Ueyama } 2172ec34544SRui Ueyama 2182ec34544SRui Ueyama void ScriptParser::readVersion() { 2192ec34544SRui Ueyama expect("{"); 2202ec34544SRui Ueyama readVersionScriptCommand(); 2212ec34544SRui Ueyama expect("}"); 2222ec34544SRui Ueyama } 2232ec34544SRui Ueyama 2242ec34544SRui Ueyama void ScriptParser::readLinkerScript() { 2252ec34544SRui Ueyama while (!atEOF()) { 2263837f427SRui Ueyama StringRef tok = next(); 2273837f427SRui Ueyama if (tok == ";") 2282ec34544SRui Ueyama continue; 2292ec34544SRui Ueyama 2303837f427SRui Ueyama if (tok == "ENTRY") { 2312ec34544SRui Ueyama readEntry(); 2323837f427SRui Ueyama } else if (tok == "EXTERN") { 2332ec34544SRui Ueyama readExtern(); 2343837f427SRui Ueyama } else if (tok == "GROUP") { 2352ec34544SRui Ueyama readGroup(); 2363837f427SRui Ueyama } else if (tok == "INCLUDE") { 2372ec34544SRui Ueyama readInclude(); 2383837f427SRui Ueyama } else if (tok == "INPUT") { 2391d92aa73SRui Ueyama readInput(); 2403837f427SRui Ueyama } else if (tok == "MEMORY") { 2412ec34544SRui Ueyama readMemory(); 2423837f427SRui Ueyama } else if (tok == "OUTPUT") { 2432ec34544SRui Ueyama readOutput(); 2443837f427SRui Ueyama } else if (tok == "OUTPUT_ARCH") { 2452ec34544SRui Ueyama readOutputArch(); 2463837f427SRui Ueyama } else if (tok == "OUTPUT_FORMAT") { 2472ec34544SRui Ueyama readOutputFormat(); 2483837f427SRui Ueyama } else if (tok == "PHDRS") { 2492ec34544SRui Ueyama readPhdrs(); 2503837f427SRui Ueyama } else if (tok == "REGION_ALIAS") { 2515f37541cSGeorge Rimar readRegionAlias(); 2523837f427SRui Ueyama } else if (tok == "SEARCH_DIR") { 2532ec34544SRui Ueyama readSearchDir(); 2543837f427SRui Ueyama } else if (tok == "SECTIONS") { 2552ec34544SRui Ueyama readSections(); 2563837f427SRui Ueyama } else if (tok == "TARGET") { 257e262bb1aSRui Ueyama readTarget(); 2583837f427SRui Ueyama } else if (tok == "VERSION") { 2592ec34544SRui Ueyama readVersion(); 2603837f427SRui Ueyama } else if (SymbolAssignment *cmd = readAssignment(tok)) { 2613837f427SRui Ueyama script->sectionCommands.push_back(cmd); 2622ec34544SRui Ueyama } else { 2633837f427SRui Ueyama setError("unknown directive: " + tok); 2642ec34544SRui Ueyama } 2652ec34544SRui Ueyama } 2662ec34544SRui Ueyama } 2672ec34544SRui Ueyama 2683837f427SRui Ueyama void ScriptParser::readDefsym(StringRef name) { 269c1522816SGeorge Rimar if (errorCount()) 270c1522816SGeorge Rimar return; 2713837f427SRui Ueyama Expr e = readExpr(); 2728c7e8cceSPetr Hosek if (!atEOF()) 2738c7e8cceSPetr Hosek setError("EOF expected, but got " + next()); 2743837f427SRui Ueyama SymbolAssignment *cmd = make<SymbolAssignment>(name, e, getCurrentLocation()); 2753837f427SRui Ueyama script->sectionCommands.push_back(cmd); 2768c7e8cceSPetr Hosek } 2778c7e8cceSPetr Hosek 2783837f427SRui Ueyama void ScriptParser::addFile(StringRef s) { 2793837f427SRui Ueyama if (isUnderSysroot && s.startswith("/")) { 2803837f427SRui Ueyama SmallString<128> pathData; 2813837f427SRui Ueyama StringRef path = (config->sysroot + s).toStringRef(pathData); 2823837f427SRui Ueyama if (sys::fs::exists(path)) { 283*136d27abSRui Ueyama driver->addFile(saver.save(path), /*WithLOption=*/false); 2842ec34544SRui Ueyama return; 2852ec34544SRui Ueyama } 2862ec34544SRui Ueyama } 2872ec34544SRui Ueyama 2883837f427SRui Ueyama if (s.startswith("/")) { 2893837f427SRui Ueyama driver->addFile(s, /*WithLOption=*/false); 2903837f427SRui Ueyama } else if (s.startswith("=")) { 2913837f427SRui Ueyama if (config->sysroot.empty()) 2923837f427SRui Ueyama driver->addFile(s.substr(1), /*WithLOption=*/false); 2932ec34544SRui Ueyama else 294*136d27abSRui Ueyama driver->addFile(saver.save(config->sysroot + "/" + s.substr(1)), 295a76349bfSEvgeniy Stepanov /*WithLOption=*/false); 2963837f427SRui Ueyama } else if (s.startswith("-l")) { 2973837f427SRui Ueyama driver->addLibrary(s.substr(2)); 2983837f427SRui Ueyama } else if (sys::fs::exists(s)) { 2993837f427SRui Ueyama driver->addFile(s, /*WithLOption=*/false); 3002ec34544SRui Ueyama } else { 3013837f427SRui Ueyama if (Optional<std::string> path = findFromSearchPaths(s)) 302*136d27abSRui Ueyama driver->addFile(saver.save(*path), /*WithLOption=*/true); 3032ec34544SRui Ueyama else 3043837f427SRui Ueyama setError("unable to find " + s); 3052ec34544SRui Ueyama } 3062ec34544SRui Ueyama } 3072ec34544SRui Ueyama 3082ec34544SRui Ueyama void ScriptParser::readAsNeeded() { 3092ec34544SRui Ueyama expect("("); 3103837f427SRui Ueyama bool orig = config->asNeeded; 3113837f427SRui Ueyama config->asNeeded = true; 312b8a59c8aSBob Haarman while (!errorCount() && !consume(")")) 3132ec34544SRui Ueyama addFile(unquote(next())); 3143837f427SRui Ueyama config->asNeeded = orig; 3152ec34544SRui Ueyama } 3162ec34544SRui Ueyama 3172ec34544SRui Ueyama void ScriptParser::readEntry() { 3182ec34544SRui Ueyama // -e <symbol> takes predecence over ENTRY(<symbol>). 3192ec34544SRui Ueyama expect("("); 3203837f427SRui Ueyama StringRef tok = next(); 3213837f427SRui Ueyama if (config->entry.empty()) 3223837f427SRui Ueyama config->entry = tok; 3232ec34544SRui Ueyama expect(")"); 3242ec34544SRui Ueyama } 3252ec34544SRui Ueyama 3262ec34544SRui Ueyama void ScriptParser::readExtern() { 3272ec34544SRui Ueyama expect("("); 328b8a59c8aSBob Haarman while (!errorCount() && !consume(")")) 3293837f427SRui Ueyama config->undefined.push_back(unquote(next())); 3302ec34544SRui Ueyama } 3312ec34544SRui Ueyama 3322ec34544SRui Ueyama void ScriptParser::readGroup() { 3333837f427SRui Ueyama bool orig = InputFile::isInGroup; 3343837f427SRui Ueyama InputFile::isInGroup = true; 3351d92aa73SRui Ueyama readInput(); 3363837f427SRui Ueyama InputFile::isInGroup = orig; 3373837f427SRui Ueyama if (!orig) 3383837f427SRui Ueyama ++InputFile::nextGroupId; 3392ec34544SRui Ueyama } 3402ec34544SRui Ueyama 3412ec34544SRui Ueyama void ScriptParser::readInclude() { 3423837f427SRui Ueyama StringRef tok = unquote(next()); 3432ec34544SRui Ueyama 3443837f427SRui Ueyama if (!seen.insert(tok).second) { 3450440be4aSRui Ueyama setError("there is a cycle in linker script INCLUDEs"); 3460440be4aSRui Ueyama return; 3470440be4aSRui Ueyama } 3480440be4aSRui Ueyama 3493837f427SRui Ueyama if (Optional<std::string> path = searchScript(tok)) { 3503837f427SRui Ueyama if (Optional<MemoryBufferRef> mb = readFile(*path)) 3513837f427SRui Ueyama tokenize(*mb); 3522ec34544SRui Ueyama return; 3532ec34544SRui Ueyama } 3543837f427SRui Ueyama setError("cannot find linker script " + tok); 3552ec34544SRui Ueyama } 3562ec34544SRui Ueyama 3571d92aa73SRui Ueyama void ScriptParser::readInput() { 3581d92aa73SRui Ueyama expect("("); 3591d92aa73SRui Ueyama while (!errorCount() && !consume(")")) { 3601d92aa73SRui Ueyama if (consume("AS_NEEDED")) 3611d92aa73SRui Ueyama readAsNeeded(); 3621d92aa73SRui Ueyama else 3631d92aa73SRui Ueyama addFile(unquote(next())); 3641d92aa73SRui Ueyama } 3651d92aa73SRui Ueyama } 3661d92aa73SRui Ueyama 3672ec34544SRui Ueyama void ScriptParser::readOutput() { 3682ec34544SRui Ueyama // -o <file> takes predecence over OUTPUT(<file>). 3692ec34544SRui Ueyama expect("("); 3703837f427SRui Ueyama StringRef tok = next(); 3713837f427SRui Ueyama if (config->outputFile.empty()) 3723837f427SRui Ueyama config->outputFile = unquote(tok); 3732ec34544SRui Ueyama expect(")"); 3742ec34544SRui Ueyama } 3752ec34544SRui Ueyama 3762ec34544SRui Ueyama void ScriptParser::readOutputArch() { 3772ec34544SRui Ueyama // OUTPUT_ARCH is ignored for now. 3782ec34544SRui Ueyama expect("("); 379b8a59c8aSBob Haarman while (!errorCount() && !consume(")")) 3802ec34544SRui Ueyama skip(); 3812ec34544SRui Ueyama } 3822ec34544SRui Ueyama 3833837f427SRui Ueyama static std::pair<ELFKind, uint16_t> parseBfdName(StringRef s) { 3843837f427SRui Ueyama return StringSwitch<std::pair<ELFKind, uint16_t>>(s) 3854f8c8228SRui Ueyama .Case("elf32-i386", {ELF32LEKind, EM_386}) 3864f8c8228SRui Ueyama .Case("elf32-iamcu", {ELF32LEKind, EM_IAMCU}) 3874f8c8228SRui Ueyama .Case("elf32-littlearm", {ELF32LEKind, EM_ARM}) 3884f8c8228SRui Ueyama .Case("elf32-x86-64", {ELF32LEKind, EM_X86_64}) 38919b134ccSDimitry Andric .Case("elf64-aarch64", {ELF64LEKind, EM_AARCH64}) 3904f8c8228SRui Ueyama .Case("elf64-littleaarch64", {ELF64LEKind, EM_AARCH64}) 3914134143cSRui Ueyama .Case("elf32-powerpc", {ELF32BEKind, EM_PPC}) 3924f8c8228SRui Ueyama .Case("elf64-powerpc", {ELF64BEKind, EM_PPC64}) 3934f8c8228SRui Ueyama .Case("elf64-powerpcle", {ELF64LEKind, EM_PPC64}) 3944f8c8228SRui Ueyama .Case("elf64-x86-64", {ELF64LEKind, EM_X86_64}) 3954134143cSRui Ueyama .Cases("elf32-tradbigmips", "elf32-bigmips", {ELF32BEKind, EM_MIPS}) 3964f8c8228SRui Ueyama .Case("elf32-ntradbigmips", {ELF32BEKind, EM_MIPS}) 3974f8c8228SRui Ueyama .Case("elf32-tradlittlemips", {ELF32LEKind, EM_MIPS}) 3984f8c8228SRui Ueyama .Case("elf32-ntradlittlemips", {ELF32LEKind, EM_MIPS}) 3994f8c8228SRui Ueyama .Case("elf64-tradbigmips", {ELF64BEKind, EM_MIPS}) 4004f8c8228SRui Ueyama .Case("elf64-tradlittlemips", {ELF64LEKind, EM_MIPS}) 40144d908d7SFangrui Song .Case("elf32-littleriscv", {ELF32LEKind, EM_RISCV}) 40244d908d7SFangrui Song .Case("elf64-littleriscv", {ELF64LEKind, EM_RISCV}) 4034f8c8228SRui Ueyama .Default({ELFNoneKind, EM_NONE}); 404ea8cd00aSRui Ueyama } 405ea8cd00aSRui Ueyama 406ea8cd00aSRui Ueyama // Parse OUTPUT_FORMAT(bfdname) or OUTPUT_FORMAT(bfdname, big, little). 407ea8cd00aSRui Ueyama // Currently we ignore big and little parameters. 4082ec34544SRui Ueyama void ScriptParser::readOutputFormat() { 4092ec34544SRui Ueyama expect("("); 410ea8cd00aSRui Ueyama 4113837f427SRui Ueyama StringRef name = unquote(next()); 4123837f427SRui Ueyama StringRef s = name; 4133837f427SRui Ueyama if (s.consume_back("-freebsd")) 4143837f427SRui Ueyama config->osabi = ELFOSABI_FREEBSD; 4154f8c8228SRui Ueyama 4163837f427SRui Ueyama std::tie(config->ekind, config->emachine) = parseBfdName(s); 4173837f427SRui Ueyama if (config->emachine == EM_NONE) 4183837f427SRui Ueyama setError("unknown output format name: " + name); 4193837f427SRui Ueyama if (s == "elf32-ntradlittlemips" || s == "elf32-ntradbigmips") 4203837f427SRui Ueyama config->mipsN32Abi = true; 421ea8cd00aSRui Ueyama 422b579c439SRui Ueyama if (consume(")")) 4232ec34544SRui Ueyama return; 424b579c439SRui Ueyama expect(","); 4252ec34544SRui Ueyama skip(); 4262ec34544SRui Ueyama expect(","); 4272ec34544SRui Ueyama skip(); 4282ec34544SRui Ueyama expect(")"); 4292ec34544SRui Ueyama } 4302ec34544SRui Ueyama 4312ec34544SRui Ueyama void ScriptParser::readPhdrs() { 4322ec34544SRui Ueyama expect("{"); 4332ec34544SRui Ueyama 434b8a59c8aSBob Haarman while (!errorCount() && !consume("}")) { 4353837f427SRui Ueyama PhdrsCommand cmd; 4363837f427SRui Ueyama cmd.name = next(); 4373837f427SRui Ueyama cmd.type = readPhdrType(); 438b579c439SRui Ueyama 439b8a59c8aSBob Haarman while (!errorCount() && !consume(";")) { 440b579c439SRui Ueyama if (consume("FILEHDR")) 4413837f427SRui Ueyama cmd.hasFilehdr = true; 442b579c439SRui Ueyama else if (consume("PHDRS")) 4433837f427SRui Ueyama cmd.hasPhdrs = true; 444b579c439SRui Ueyama else if (consume("AT")) 4453837f427SRui Ueyama cmd.lmaExpr = readParenExpr(); 446b579c439SRui Ueyama else if (consume("FLAGS")) 4473837f427SRui Ueyama cmd.flags = readParenExpr()().getValue(); 448b579c439SRui Ueyama else 449b579c439SRui Ueyama setError("unexpected header attribute: " + next()); 450b579c439SRui Ueyama } 4510ae2c24cSRui Ueyama 4523837f427SRui Ueyama script->phdrsCommands.push_back(cmd); 4532ec34544SRui Ueyama } 4542ec34544SRui Ueyama } 4552ec34544SRui Ueyama 4565f37541cSGeorge Rimar void ScriptParser::readRegionAlias() { 4575f37541cSGeorge Rimar expect("("); 4583837f427SRui Ueyama StringRef alias = unquote(next()); 4595f37541cSGeorge Rimar expect(","); 4603837f427SRui Ueyama StringRef name = next(); 4615f37541cSGeorge Rimar expect(")"); 4625f37541cSGeorge Rimar 4633837f427SRui Ueyama if (script->memoryRegions.count(alias)) 4643837f427SRui Ueyama setError("redefinition of memory region '" + alias + "'"); 4653837f427SRui Ueyama if (!script->memoryRegions.count(name)) 4663837f427SRui Ueyama setError("memory region '" + name + "' is not defined"); 4673837f427SRui Ueyama script->memoryRegions.insert({alias, script->memoryRegions[name]}); 4685f37541cSGeorge Rimar } 4695f37541cSGeorge Rimar 4702ec34544SRui Ueyama void ScriptParser::readSearchDir() { 4712ec34544SRui Ueyama expect("("); 4723837f427SRui Ueyama StringRef tok = next(); 4733837f427SRui Ueyama if (!config->nostdlib) 4743837f427SRui Ueyama config->searchPaths.push_back(unquote(tok)); 4752ec34544SRui Ueyama expect(")"); 4762ec34544SRui Ueyama } 4772ec34544SRui Ueyama 478a582419aSGeorge Rimar // This reads an overlay description. Overlays are used to describe output 479a582419aSGeorge Rimar // sections that use the same virtual memory range and normally would trigger 480a582419aSGeorge Rimar // linker's sections sanity check failures. 481a582419aSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Overlay-Description.html#Overlay-Description 482a582419aSGeorge Rimar std::vector<BaseCommand *> ScriptParser::readOverlay() { 483a582419aSGeorge Rimar // VA and LMA expressions are optional, though for simplicity of 484a582419aSGeorge Rimar // implementation we assume they are not. That is what OVERLAY was designed 485a582419aSGeorge Rimar // for first of all: to allow sections with overlapping VAs at different LMAs. 4863837f427SRui Ueyama Expr addrExpr = readExpr(); 487a582419aSGeorge Rimar expect(":"); 488a582419aSGeorge Rimar expect("AT"); 4893837f427SRui Ueyama Expr lmaExpr = readParenExpr(); 490a582419aSGeorge Rimar expect("{"); 491a582419aSGeorge Rimar 4923837f427SRui Ueyama std::vector<BaseCommand *> v; 4933837f427SRui Ueyama OutputSection *prev = nullptr; 494a582419aSGeorge Rimar while (!errorCount() && !consume("}")) { 495a582419aSGeorge Rimar // VA is the same for all sections. The LMAs are consecutive in memory 496a582419aSGeorge Rimar // starting from the base load address specified. 4973837f427SRui Ueyama OutputSection *os = readOverlaySectionDescription(); 4983837f427SRui Ueyama os->addrExpr = addrExpr; 4993837f427SRui Ueyama if (prev) 5003837f427SRui Ueyama os->lmaExpr = [=] { return prev->getLMA() + prev->size; }; 501a582419aSGeorge Rimar else 5023837f427SRui Ueyama os->lmaExpr = lmaExpr; 5033837f427SRui Ueyama v.push_back(os); 5043837f427SRui Ueyama prev = os; 505a582419aSGeorge Rimar } 506a582419aSGeorge Rimar 507a582419aSGeorge Rimar // According to the specification, at the end of the overlay, the location 508a582419aSGeorge Rimar // counter should be equal to the overlay base address plus size of the 509a582419aSGeorge Rimar // largest section seen in the overlay. 510a582419aSGeorge Rimar // Here we want to create the Dot assignment command to achieve that. 5113837f427SRui Ueyama Expr moveDot = [=] { 5123837f427SRui Ueyama uint64_t max = 0; 5133837f427SRui Ueyama for (BaseCommand *cmd : v) 5143837f427SRui Ueyama max = std::max(max, cast<OutputSection>(cmd)->size); 5153837f427SRui Ueyama return addrExpr().getValue() + max; 516a582419aSGeorge Rimar }; 5173837f427SRui Ueyama v.push_back(make<SymbolAssignment>(".", moveDot, getCurrentLocation())); 5183837f427SRui Ueyama return v; 519a582419aSGeorge Rimar } 520a582419aSGeorge Rimar 5212ec34544SRui Ueyama void ScriptParser::readSections() { 5223837f427SRui Ueyama script->hasSectionsCommand = true; 523b579c439SRui Ueyama 5242ec34544SRui Ueyama // -no-rosegment is used to avoid placing read only non-executable sections in 5252ec34544SRui Ueyama // their own segment. We do the same if SECTIONS command is present in linker 5262ec34544SRui Ueyama // script. See comment for computeFlags(). 5273837f427SRui Ueyama config->singleRoRx = true; 5282ec34544SRui Ueyama 5292ec34544SRui Ueyama expect("{"); 5303837f427SRui Ueyama std::vector<BaseCommand *> v; 531b8a59c8aSBob Haarman while (!errorCount() && !consume("}")) { 5323837f427SRui Ueyama StringRef tok = next(); 5333837f427SRui Ueyama if (tok == "OVERLAY") { 5343837f427SRui Ueyama for (BaseCommand *cmd : readOverlay()) 5353837f427SRui Ueyama v.push_back(cmd); 536a582419aSGeorge Rimar continue; 5373837f427SRui Ueyama } else if (tok == "INCLUDE") { 5382e9d40d5SRui Ueyama readInclude(); 5392e9d40d5SRui Ueyama continue; 540a582419aSGeorge Rimar } 541a582419aSGeorge Rimar 5423837f427SRui Ueyama if (BaseCommand *cmd = readAssignment(tok)) 5433837f427SRui Ueyama v.push_back(cmd); 544d30a78b3SGeorge Rimar else 5453837f427SRui Ueyama v.push_back(readOutputSectionDescription(tok)); 5462ec34544SRui Ueyama } 5479e2c8a9dSGeorge Rimar 5489e2c8a9dSGeorge Rimar if (!atEOF() && consume("INSERT")) { 5493837f427SRui Ueyama std::vector<BaseCommand *> *dest = nullptr; 550796684b4SGeorge Rimar if (consume("AFTER")) 5513837f427SRui Ueyama dest = &script->insertAfterCommands[next()]; 552796684b4SGeorge Rimar else if (consume("BEFORE")) 5533837f427SRui Ueyama dest = &script->insertBeforeCommands[next()]; 554796684b4SGeorge Rimar else 555796684b4SGeorge Rimar setError("expected AFTER/BEFORE, but got '" + next() + "'"); 5563837f427SRui Ueyama if (dest) 5573837f427SRui Ueyama dest->insert(dest->end(), v.begin(), v.end()); 5589e2c8a9dSGeorge Rimar return; 5599e2c8a9dSGeorge Rimar } 5609e2c8a9dSGeorge Rimar 5613837f427SRui Ueyama script->sectionCommands.insert(script->sectionCommands.end(), v.begin(), 5623837f427SRui Ueyama v.end()); 5632ec34544SRui Ueyama } 5642ec34544SRui Ueyama 565e262bb1aSRui Ueyama void ScriptParser::readTarget() { 566e262bb1aSRui Ueyama // TARGET(foo) is an alias for "--format foo". Unlike GNU linkers, 567e262bb1aSRui Ueyama // we accept only a limited set of BFD names (i.e. "elf" or "binary") 568e262bb1aSRui Ueyama // for --format. We recognize only /^elf/ and "binary" in the linker 569e262bb1aSRui Ueyama // script as well. 570e262bb1aSRui Ueyama expect("("); 5713837f427SRui Ueyama StringRef tok = next(); 572e262bb1aSRui Ueyama expect(")"); 573e262bb1aSRui Ueyama 5743837f427SRui Ueyama if (tok.startswith("elf")) 5753837f427SRui Ueyama config->formatBinary = false; 5763837f427SRui Ueyama else if (tok == "binary") 5773837f427SRui Ueyama config->formatBinary = true; 578e262bb1aSRui Ueyama else 5793837f427SRui Ueyama setError("unknown target: " + tok); 580e262bb1aSRui Ueyama } 581e262bb1aSRui Ueyama 5823837f427SRui Ueyama static int precedence(StringRef op) { 5833837f427SRui Ueyama return StringSwitch<int>(op) 584a5005482SGeorge Rimar .Cases("*", "/", "%", 8) 585a5005482SGeorge Rimar .Cases("+", "-", 7) 586a5005482SGeorge Rimar .Cases("<<", ">>", 6) 587a5005482SGeorge Rimar .Cases("<", "<=", ">", ">=", "==", "!=", 5) 588a5005482SGeorge Rimar .Case("&", 4) 589a5005482SGeorge Rimar .Case("|", 3) 590a5005482SGeorge Rimar .Case("&&", 2) 591a5005482SGeorge Rimar .Case("||", 1) 5922ec34544SRui Ueyama .Default(-1); 5932ec34544SRui Ueyama } 5942ec34544SRui Ueyama 5952ec34544SRui Ueyama StringMatcher ScriptParser::readFilePatterns() { 5963837f427SRui Ueyama std::vector<StringRef> v; 597b8a59c8aSBob Haarman while (!errorCount() && !consume(")")) 5983837f427SRui Ueyama v.push_back(next()); 5993837f427SRui Ueyama return StringMatcher(v); 6002ec34544SRui Ueyama } 6012ec34544SRui Ueyama 6022ec34544SRui Ueyama SortSectionPolicy ScriptParser::readSortKind() { 6032ec34544SRui Ueyama if (consume("SORT") || consume("SORT_BY_NAME")) 6042ec34544SRui Ueyama return SortSectionPolicy::Name; 6052ec34544SRui Ueyama if (consume("SORT_BY_ALIGNMENT")) 6062ec34544SRui Ueyama return SortSectionPolicy::Alignment; 6072ec34544SRui Ueyama if (consume("SORT_BY_INIT_PRIORITY")) 6082ec34544SRui Ueyama return SortSectionPolicy::Priority; 6092ec34544SRui Ueyama if (consume("SORT_NONE")) 6102ec34544SRui Ueyama return SortSectionPolicy::None; 6112ec34544SRui Ueyama return SortSectionPolicy::Default; 6122ec34544SRui Ueyama } 6132ec34544SRui Ueyama 61403fc8d1eSRui Ueyama // Reads SECTIONS command contents in the following form: 61503fc8d1eSRui Ueyama // 61603fc8d1eSRui Ueyama // <contents> ::= <elem>* 61703fc8d1eSRui Ueyama // <elem> ::= <exclude>? <glob-pattern> 61803fc8d1eSRui Ueyama // <exclude> ::= "EXCLUDE_FILE" "(" <glob-pattern>+ ")" 61903fc8d1eSRui Ueyama // 62003fc8d1eSRui Ueyama // For example, 62103fc8d1eSRui Ueyama // 62203fc8d1eSRui Ueyama // *(.foo EXCLUDE_FILE (a.o) .bar EXCLUDE_FILE (b.o) .baz) 62303fc8d1eSRui Ueyama // 62403fc8d1eSRui Ueyama // is parsed as ".foo", ".bar" with "a.o", and ".baz" with "b.o". 62503fc8d1eSRui Ueyama // The semantics of that is section .foo in any file, section .bar in 62603fc8d1eSRui Ueyama // any file but a.o, and section .baz in any file but b.o. 6272ec34544SRui Ueyama std::vector<SectionPattern> ScriptParser::readInputSectionsList() { 6283837f427SRui Ueyama std::vector<SectionPattern> ret; 629b8a59c8aSBob Haarman while (!errorCount() && peek() != ")") { 6303837f427SRui Ueyama StringMatcher excludeFilePat; 6312ec34544SRui Ueyama if (consume("EXCLUDE_FILE")) { 6322ec34544SRui Ueyama expect("("); 6333837f427SRui Ueyama excludeFilePat = readFilePatterns(); 6342ec34544SRui Ueyama } 6352ec34544SRui Ueyama 6363837f427SRui Ueyama std::vector<StringRef> v; 637b8a59c8aSBob Haarman while (!errorCount() && peek() != ")" && peek() != "EXCLUDE_FILE") 6383837f427SRui Ueyama v.push_back(unquote(next())); 6392ec34544SRui Ueyama 6403837f427SRui Ueyama if (!v.empty()) 6413837f427SRui Ueyama ret.push_back({std::move(excludeFilePat), StringMatcher(v)}); 6422ec34544SRui Ueyama else 6432ec34544SRui Ueyama setError("section pattern is expected"); 6442ec34544SRui Ueyama } 6453837f427SRui Ueyama return ret; 6462ec34544SRui Ueyama } 6472ec34544SRui Ueyama 6482ec34544SRui Ueyama // Reads contents of "SECTIONS" directive. That directive contains a 6492ec34544SRui Ueyama // list of glob patterns for input sections. The grammar is as follows. 6502ec34544SRui Ueyama // 6512ec34544SRui Ueyama // <patterns> ::= <section-list> 6522ec34544SRui Ueyama // | <sort> "(" <section-list> ")" 6532ec34544SRui Ueyama // | <sort> "(" <sort> "(" <section-list> ")" ")" 6542ec34544SRui Ueyama // 6552ec34544SRui Ueyama // <sort> ::= "SORT" | "SORT_BY_NAME" | "SORT_BY_ALIGNMENT" 6562ec34544SRui Ueyama // | "SORT_BY_INIT_PRIORITY" | "SORT_NONE" 6572ec34544SRui Ueyama // 6582ec34544SRui Ueyama // <section-list> is parsed by readInputSectionsList(). 6592ec34544SRui Ueyama InputSectionDescription * 6603837f427SRui Ueyama ScriptParser::readInputSectionRules(StringRef filePattern) { 6613837f427SRui Ueyama auto *cmd = make<InputSectionDescription>(filePattern); 6622ec34544SRui Ueyama expect("("); 6632ec34544SRui Ueyama 664b8a59c8aSBob Haarman while (!errorCount() && !consume(")")) { 6653837f427SRui Ueyama SortSectionPolicy outer = readSortKind(); 6663837f427SRui Ueyama SortSectionPolicy inner = SortSectionPolicy::Default; 6673837f427SRui Ueyama std::vector<SectionPattern> v; 6683837f427SRui Ueyama if (outer != SortSectionPolicy::Default) { 6692ec34544SRui Ueyama expect("("); 6703837f427SRui Ueyama inner = readSortKind(); 6713837f427SRui Ueyama if (inner != SortSectionPolicy::Default) { 6722ec34544SRui Ueyama expect("("); 6733837f427SRui Ueyama v = readInputSectionsList(); 6742ec34544SRui Ueyama expect(")"); 6752ec34544SRui Ueyama } else { 6763837f427SRui Ueyama v = readInputSectionsList(); 6772ec34544SRui Ueyama } 6782ec34544SRui Ueyama expect(")"); 6792ec34544SRui Ueyama } else { 6803837f427SRui Ueyama v = readInputSectionsList(); 6812ec34544SRui Ueyama } 6822ec34544SRui Ueyama 6833837f427SRui Ueyama for (SectionPattern &pat : v) { 6843837f427SRui Ueyama pat.sortInner = inner; 6853837f427SRui Ueyama pat.sortOuter = outer; 6862ec34544SRui Ueyama } 6872ec34544SRui Ueyama 6883837f427SRui Ueyama std::move(v.begin(), v.end(), std::back_inserter(cmd->sectionPatterns)); 6892ec34544SRui Ueyama } 6903837f427SRui Ueyama return cmd; 6912ec34544SRui Ueyama } 6922ec34544SRui Ueyama 6932ec34544SRui Ueyama InputSectionDescription * 6943837f427SRui Ueyama ScriptParser::readInputSectionDescription(StringRef tok) { 6952ec34544SRui Ueyama // Input section wildcard can be surrounded by KEEP. 6962ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep 6973837f427SRui Ueyama if (tok == "KEEP") { 6982ec34544SRui Ueyama expect("("); 6993837f427SRui Ueyama StringRef filePattern = next(); 7003837f427SRui Ueyama InputSectionDescription *cmd = readInputSectionRules(filePattern); 7012ec34544SRui Ueyama expect(")"); 7023837f427SRui Ueyama script->keptSections.push_back(cmd); 7033837f427SRui Ueyama return cmd; 7042ec34544SRui Ueyama } 7053837f427SRui Ueyama return readInputSectionRules(tok); 7062ec34544SRui Ueyama } 7072ec34544SRui Ueyama 7082ec34544SRui Ueyama void ScriptParser::readSort() { 7092ec34544SRui Ueyama expect("("); 7102ec34544SRui Ueyama expect("CONSTRUCTORS"); 7112ec34544SRui Ueyama expect(")"); 7122ec34544SRui Ueyama } 7132ec34544SRui Ueyama 714d30a78b3SGeorge Rimar Expr ScriptParser::readAssert() { 7152ec34544SRui Ueyama expect("("); 7163837f427SRui Ueyama Expr e = readExpr(); 7172ec34544SRui Ueyama expect(","); 7183837f427SRui Ueyama StringRef msg = unquote(next()); 7192ec34544SRui Ueyama expect(")"); 720b579c439SRui Ueyama 7212ec34544SRui Ueyama return [=] { 7223837f427SRui Ueyama if (!e().getValue()) 7233837f427SRui Ueyama error(msg); 7243837f427SRui Ueyama return script->getDot(); 7252ec34544SRui Ueyama }; 7262ec34544SRui Ueyama } 7272ec34544SRui Ueyama 728a46d08ebSGeorge Rimar // Tries to read the special directive for an output section definition which 729a46d08ebSGeorge Rimar // can be one of following: "(NOLOAD)", "(COPY)", "(INFO)" or "(OVERLAY)". 730a46d08ebSGeorge Rimar // Tok1 and Tok2 are next 2 tokens peeked. See comment for readSectionAddressType below. 7313837f427SRui Ueyama bool ScriptParser::readSectionDirective(OutputSection *cmd, StringRef tok1, StringRef tok2) { 7323837f427SRui Ueyama if (tok1 != "(") 733a46d08ebSGeorge Rimar return false; 7343837f427SRui Ueyama if (tok2 != "NOLOAD" && tok2 != "COPY" && tok2 != "INFO" && tok2 != "OVERLAY") 735a46d08ebSGeorge Rimar return false; 736a46d08ebSGeorge Rimar 737a46d08ebSGeorge Rimar expect("("); 738a46d08ebSGeorge Rimar if (consume("NOLOAD")) { 7393837f427SRui Ueyama cmd->noload = true; 740a46d08ebSGeorge Rimar } else { 741a46d08ebSGeorge Rimar skip(); // This is "COPY", "INFO" or "OVERLAY". 7423837f427SRui Ueyama cmd->nonAlloc = true; 743a46d08ebSGeorge Rimar } 744a46d08ebSGeorge Rimar expect(")"); 745a46d08ebSGeorge Rimar return true; 746a46d08ebSGeorge Rimar } 747a46d08ebSGeorge Rimar 7481c08e9f5SGeorge Rimar // Reads an expression and/or the special directive for an output 7491c08e9f5SGeorge Rimar // section definition. Directive is one of following: "(NOLOAD)", 7501c08e9f5SGeorge Rimar // "(COPY)", "(INFO)" or "(OVERLAY)". 7513271d370SRui Ueyama // 7523271d370SRui Ueyama // An output section name can be followed by an address expression 7531c08e9f5SGeorge Rimar // and/or directive. This grammar is not LL(1) because "(" can be 75497f4d158SGeorge Rimar // interpreted as either the beginning of some expression or beginning 7551c08e9f5SGeorge Rimar // of directive. 7563271d370SRui Ueyama // 757b579c439SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html 758fbb0463fSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Output-Section-Type.html 7593837f427SRui Ueyama void ScriptParser::readSectionAddressType(OutputSection *cmd) { 7603837f427SRui Ueyama if (readSectionDirective(cmd, peek(), peek2())) 7613271d370SRui Ueyama return; 7623271d370SRui Ueyama 7633837f427SRui Ueyama cmd->addrExpr = readExpr(); 7643837f427SRui Ueyama if (peek() == "(" && !readSectionDirective(cmd, "(", peek2())) 765a46d08ebSGeorge Rimar setError("unknown section directive: " + peek2()); 766fbb0463fSGeorge Rimar } 767fbb0463fSGeorge Rimar 7683837f427SRui Ueyama static Expr checkAlignment(Expr e, std::string &loc) { 769f22ec9ddSGeorge Rimar return [=] { 7703837f427SRui Ueyama uint64_t alignment = std::max((uint64_t)1, e().getValue()); 7713837f427SRui Ueyama if (!isPowerOf2_64(alignment)) { 7723837f427SRui Ueyama error(loc + ": alignment must be power of 2"); 773f22ec9ddSGeorge Rimar return (uint64_t)1; // Return a dummy value. 774f22ec9ddSGeorge Rimar } 7753837f427SRui Ueyama return alignment; 776f22ec9ddSGeorge Rimar }; 777f22ec9ddSGeorge Rimar } 778f22ec9ddSGeorge Rimar 779a582419aSGeorge Rimar OutputSection *ScriptParser::readOverlaySectionDescription() { 7803837f427SRui Ueyama OutputSection *cmd = 7813837f427SRui Ueyama script->createOutputSection(next(), getCurrentLocation()); 7823837f427SRui Ueyama cmd->inOverlay = true; 783a582419aSGeorge Rimar expect("{"); 784a582419aSGeorge Rimar while (!errorCount() && !consume("}")) 7853837f427SRui Ueyama cmd->sectionCommands.push_back(readInputSectionRules(next())); 7863837f427SRui Ueyama cmd->phdrs = readOutputSectionPhdrs(); 7873837f427SRui Ueyama return cmd; 788a582419aSGeorge Rimar } 789a582419aSGeorge Rimar 7903837f427SRui Ueyama OutputSection *ScriptParser::readOutputSectionDescription(StringRef outSec) { 7913837f427SRui Ueyama OutputSection *cmd = 7923837f427SRui Ueyama script->createOutputSection(outSec, getCurrentLocation()); 7933271d370SRui Ueyama 7943837f427SRui Ueyama size_t symbolsReferenced = script->referencedSymbols.size(); 795c4df670dSGeorge Rimar 7963271d370SRui Ueyama if (peek() != ":") 7973837f427SRui Ueyama readSectionAddressType(cmd); 7982ec34544SRui Ueyama expect(":"); 7992ec34544SRui Ueyama 8003837f427SRui Ueyama std::string location = getCurrentLocation(); 8012ec34544SRui Ueyama if (consume("AT")) 8023837f427SRui Ueyama cmd->lmaExpr = readParenExpr(); 8032ec34544SRui Ueyama if (consume("ALIGN")) 8043837f427SRui Ueyama cmd->alignExpr = checkAlignment(readParenExpr(), location); 8052ec34544SRui Ueyama if (consume("SUBALIGN")) 8063837f427SRui Ueyama cmd->subalignExpr = checkAlignment(readParenExpr(), location); 8072ec34544SRui Ueyama 8082ec34544SRui Ueyama // Parse constraints. 8092ec34544SRui Ueyama if (consume("ONLY_IF_RO")) 8103837f427SRui Ueyama cmd->constraint = ConstraintKind::ReadOnly; 8112ec34544SRui Ueyama if (consume("ONLY_IF_RW")) 8123837f427SRui Ueyama cmd->constraint = ConstraintKind::ReadWrite; 8132ec34544SRui Ueyama expect("{"); 8142ec34544SRui Ueyama 815b8a59c8aSBob Haarman while (!errorCount() && !consume("}")) { 8163837f427SRui Ueyama StringRef tok = next(); 8173837f427SRui Ueyama if (tok == ";") { 8182ec34544SRui Ueyama // Empty commands are allowed. Do nothing here. 8193837f427SRui Ueyama } else if (SymbolAssignment *assign = readAssignment(tok)) { 8203837f427SRui Ueyama cmd->sectionCommands.push_back(assign); 8213837f427SRui Ueyama } else if (ByteCommand *data = readByteCommand(tok)) { 8223837f427SRui Ueyama cmd->sectionCommands.push_back(data); 8233837f427SRui Ueyama } else if (tok == "CONSTRUCTORS") { 8242ec34544SRui Ueyama // CONSTRUCTORS is a keyword to make the linker recognize C++ ctors/dtors 8252ec34544SRui Ueyama // by name. This is for very old file formats such as ECOFF/XCOFF. 8262ec34544SRui Ueyama // For ELF, we should ignore. 8273837f427SRui Ueyama } else if (tok == "FILL") { 8280810f16fSGeorge Rimar // We handle the FILL command as an alias for =fillexp section attribute, 8290810f16fSGeorge Rimar // which is different from what GNU linkers do. 8300810f16fSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Output-Section-Data.html 831c44a23f8SGeorge Rimar expect("("); 8323837f427SRui Ueyama cmd->filler = readFill(); 833c44a23f8SGeorge Rimar expect(")"); 8343837f427SRui Ueyama } else if (tok == "SORT") { 8352ec34544SRui Ueyama readSort(); 8363837f427SRui Ueyama } else if (tok == "INCLUDE") { 8372e9d40d5SRui Ueyama readInclude(); 8382ec34544SRui Ueyama } else if (peek() == "(") { 8393837f427SRui Ueyama cmd->sectionCommands.push_back(readInputSectionDescription(tok)); 8402ec34544SRui Ueyama } else { 841f49fe218SGeorge Rimar // We have a file name and no input sections description. It is not a 842f49fe218SGeorge Rimar // commonly used syntax, but still acceptable. In that case, all sections 843f49fe218SGeorge Rimar // from the file will be included. 8443837f427SRui Ueyama auto *isd = make<InputSectionDescription>(tok); 8453837f427SRui Ueyama isd->sectionPatterns.push_back({{}, StringMatcher({"*"})}); 8463837f427SRui Ueyama cmd->sectionCommands.push_back(isd); 8472ec34544SRui Ueyama } 8482ec34544SRui Ueyama } 8492ec34544SRui Ueyama 8502ec34544SRui Ueyama if (consume(">")) 8513837f427SRui Ueyama cmd->memoryRegionName = next(); 8522ec34544SRui Ueyama 8535d01a8beSGeorge Rimar if (consume("AT")) { 8545d01a8beSGeorge Rimar expect(">"); 8553837f427SRui Ueyama cmd->lmaRegionName = next(); 8565d01a8beSGeorge Rimar } 8575d01a8beSGeorge Rimar 8583837f427SRui Ueyama if (cmd->lmaExpr && !cmd->lmaRegionName.empty()) 8595d01a8beSGeorge Rimar error("section can't have both LMA and a load region"); 8605d01a8beSGeorge Rimar 8613837f427SRui Ueyama cmd->phdrs = readOutputSectionPhdrs(); 8622ec34544SRui Ueyama 8630810f16fSGeorge Rimar if (peek() == "=" || peek().startswith("=")) { 8643837f427SRui Ueyama inExpr = true; 8650810f16fSGeorge Rimar consume("="); 8663837f427SRui Ueyama cmd->filler = readFill(); 8673837f427SRui Ueyama inExpr = false; 8680810f16fSGeorge Rimar } 8692ec34544SRui Ueyama 8702ec34544SRui Ueyama // Consume optional comma following output section command. 8712ec34544SRui Ueyama consume(","); 8722ec34544SRui Ueyama 8733837f427SRui Ueyama if (script->referencedSymbols.size() > symbolsReferenced) 8743837f427SRui Ueyama cmd->expressionsUseSymbols = true; 8753837f427SRui Ueyama return cmd; 8762ec34544SRui Ueyama } 8772ec34544SRui Ueyama 8780810f16fSGeorge Rimar // Reads a `=<fillexp>` expression and returns its value as a big-endian number. 8792ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html 8800810f16fSGeorge Rimar // We do not support using symbols in such expressions. 8812ec34544SRui Ueyama // 8828acbf1ccSRui Ueyama // When reading a hexstring, ld.bfd handles it as a blob of arbitrary 8838acbf1ccSRui Ueyama // size, while ld.gold always handles it as a 32-bit big-endian number. 8848acbf1ccSRui Ueyama // We are compatible with ld.gold because it's easier to implement. 8850810f16fSGeorge Rimar std::array<uint8_t, 4> ScriptParser::readFill() { 8863837f427SRui Ueyama uint64_t value = readExpr()().val; 8873837f427SRui Ueyama if (value > UINT32_MAX) 8880810f16fSGeorge Rimar setError("filler expression result does not fit 32-bit: 0x" + 8893837f427SRui Ueyama Twine::utohexstr(value)); 890b58079d4SRui Ueyama 8913837f427SRui Ueyama std::array<uint8_t, 4> buf; 8923837f427SRui Ueyama write32be(buf.data(), (uint32_t)value); 8933837f427SRui Ueyama return buf; 8942ec34544SRui Ueyama } 8952ec34544SRui Ueyama 8963837f427SRui Ueyama SymbolAssignment *ScriptParser::readProvideHidden(bool provide, bool hidden) { 8972ec34544SRui Ueyama expect("("); 8983837f427SRui Ueyama SymbolAssignment *cmd = readSymbolAssignment(next()); 8993837f427SRui Ueyama cmd->provide = provide; 9003837f427SRui Ueyama cmd->hidden = hidden; 9012ec34544SRui Ueyama expect(")"); 9023837f427SRui Ueyama return cmd; 9032ec34544SRui Ueyama } 9042ec34544SRui Ueyama 9053837f427SRui Ueyama SymbolAssignment *ScriptParser::readAssignment(StringRef tok) { 906d30a78b3SGeorge Rimar // Assert expression returns Dot, so this is equal to ".=." 9073837f427SRui Ueyama if (tok == "ASSERT") 908d30a78b3SGeorge Rimar return make<SymbolAssignment>(".", readAssert(), getCurrentLocation()); 909d30a78b3SGeorge Rimar 9103837f427SRui Ueyama size_t oldPos = pos; 9113837f427SRui Ueyama SymbolAssignment *cmd = nullptr; 912e88b76a9SGeorge Rimar if (peek() == "=" || peek() == "+=") 9133837f427SRui Ueyama cmd = readSymbolAssignment(tok); 9143837f427SRui Ueyama else if (tok == "PROVIDE") 9153837f427SRui Ueyama cmd = readProvideHidden(true, false); 9163837f427SRui Ueyama else if (tok == "HIDDEN") 9173837f427SRui Ueyama cmd = readProvideHidden(false, true); 9183837f427SRui Ueyama else if (tok == "PROVIDE_HIDDEN") 9193837f427SRui Ueyama cmd = readProvideHidden(true, true); 920e88b76a9SGeorge Rimar 9213837f427SRui Ueyama if (cmd) { 9223837f427SRui Ueyama cmd->commandString = 9233837f427SRui Ueyama tok.str() + " " + 9243837f427SRui Ueyama llvm::join(tokens.begin() + oldPos, tokens.begin() + pos, " "); 925e88b76a9SGeorge Rimar expect(";"); 9262ec34544SRui Ueyama } 9273837f427SRui Ueyama return cmd; 9282ec34544SRui Ueyama } 9292ec34544SRui Ueyama 9303837f427SRui Ueyama SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef name) { 9313837f427SRui Ueyama StringRef op = next(); 9323837f427SRui Ueyama assert(op == "=" || op == "+="); 9333837f427SRui Ueyama Expr e = readExpr(); 9343837f427SRui Ueyama if (op == "+=") { 9353837f427SRui Ueyama std::string loc = getCurrentLocation(); 9363837f427SRui Ueyama e = [=] { return add(script->getSymbolValue(name, loc), e()); }; 9372ec34544SRui Ueyama } 9383837f427SRui Ueyama return make<SymbolAssignment>(name, e, getCurrentLocation()); 9392ec34544SRui Ueyama } 9402ec34544SRui Ueyama 9412ec34544SRui Ueyama // This is an operator-precedence parser to parse a linker 9422ec34544SRui Ueyama // script expression. 9432ec34544SRui Ueyama Expr ScriptParser::readExpr() { 9442ec34544SRui Ueyama // Our lexer is context-aware. Set the in-expression bit so that 9452ec34544SRui Ueyama // they apply different tokenization rules. 9463837f427SRui Ueyama bool orig = inExpr; 9473837f427SRui Ueyama inExpr = true; 9483837f427SRui Ueyama Expr e = readExpr1(readPrimary(), 0); 9493837f427SRui Ueyama inExpr = orig; 9503837f427SRui Ueyama return e; 9512ec34544SRui Ueyama } 9522ec34544SRui Ueyama 9533837f427SRui Ueyama Expr ScriptParser::combine(StringRef op, Expr l, Expr r) { 9543837f427SRui Ueyama if (op == "+") 9553837f427SRui Ueyama return [=] { return add(l(), r()); }; 9563837f427SRui Ueyama if (op == "-") 9573837f427SRui Ueyama return [=] { return sub(l(), r()); }; 9583837f427SRui Ueyama if (op == "*") 9593837f427SRui Ueyama return [=] { return l().getValue() * r().getValue(); }; 9603837f427SRui Ueyama if (op == "/") { 9613837f427SRui Ueyama std::string loc = getCurrentLocation(); 9627b91e213SGeorge Rimar return [=]() -> uint64_t { 9633837f427SRui Ueyama if (uint64_t rv = r().getValue()) 9643837f427SRui Ueyama return l().getValue() / rv; 9653837f427SRui Ueyama error(loc + ": division by zero"); 966067617f9SRui Ueyama return 0; 9677b91e213SGeorge Rimar }; 9687b91e213SGeorge Rimar } 9693837f427SRui Ueyama if (op == "%") { 9703837f427SRui Ueyama std::string loc = getCurrentLocation(); 9717b91e213SGeorge Rimar return [=]() -> uint64_t { 9723837f427SRui Ueyama if (uint64_t rv = r().getValue()) 9733837f427SRui Ueyama return l().getValue() % rv; 9743837f427SRui Ueyama error(loc + ": modulo by zero"); 975067617f9SRui Ueyama return 0; 9767b91e213SGeorge Rimar }; 9777b91e213SGeorge Rimar } 9783837f427SRui Ueyama if (op == "<<") 9793837f427SRui Ueyama return [=] { return l().getValue() << r().getValue(); }; 9803837f427SRui Ueyama if (op == ">>") 9813837f427SRui Ueyama return [=] { return l().getValue() >> r().getValue(); }; 9823837f427SRui Ueyama if (op == "<") 9833837f427SRui Ueyama return [=] { return l().getValue() < r().getValue(); }; 9843837f427SRui Ueyama if (op == ">") 9853837f427SRui Ueyama return [=] { return l().getValue() > r().getValue(); }; 9863837f427SRui Ueyama if (op == ">=") 9873837f427SRui Ueyama return [=] { return l().getValue() >= r().getValue(); }; 9883837f427SRui Ueyama if (op == "<=") 9893837f427SRui Ueyama return [=] { return l().getValue() <= r().getValue(); }; 9903837f427SRui Ueyama if (op == "==") 9913837f427SRui Ueyama return [=] { return l().getValue() == r().getValue(); }; 9923837f427SRui Ueyama if (op == "!=") 9933837f427SRui Ueyama return [=] { return l().getValue() != r().getValue(); }; 9943837f427SRui Ueyama if (op == "||") 9953837f427SRui Ueyama return [=] { return l().getValue() || r().getValue(); }; 9963837f427SRui Ueyama if (op == "&&") 9973837f427SRui Ueyama return [=] { return l().getValue() && r().getValue(); }; 9983837f427SRui Ueyama if (op == "&") 9993837f427SRui Ueyama return [=] { return bitAnd(l(), r()); }; 10003837f427SRui Ueyama if (op == "|") 10013837f427SRui Ueyama return [=] { return bitOr(l(), r()); }; 10022ec34544SRui Ueyama llvm_unreachable("invalid operator"); 10032ec34544SRui Ueyama } 10042ec34544SRui Ueyama 10052ec34544SRui Ueyama // This is a part of the operator-precedence parser. This function 10062ec34544SRui Ueyama // assumes that the remaining token stream starts with an operator. 10073837f427SRui Ueyama Expr ScriptParser::readExpr1(Expr lhs, int minPrec) { 1008b8a59c8aSBob Haarman while (!atEOF() && !errorCount()) { 10092ec34544SRui Ueyama // Read an operator and an expression. 10102ec34544SRui Ueyama if (consume("?")) 10113837f427SRui Ueyama return readTernary(lhs); 10123837f427SRui Ueyama StringRef op1 = peek(); 10133837f427SRui Ueyama if (precedence(op1) < minPrec) 10142ec34544SRui Ueyama break; 10152ec34544SRui Ueyama skip(); 10163837f427SRui Ueyama Expr rhs = readPrimary(); 10172ec34544SRui Ueyama 10182ec34544SRui Ueyama // Evaluate the remaining part of the expression first if the 10192ec34544SRui Ueyama // next operator has greater precedence than the previous one. 10202ec34544SRui Ueyama // For example, if we have read "+" and "3", and if the next 10212ec34544SRui Ueyama // operator is "*", then we'll evaluate 3 * ... part first. 10222ec34544SRui Ueyama while (!atEOF()) { 10233837f427SRui Ueyama StringRef op2 = peek(); 10243837f427SRui Ueyama if (precedence(op2) <= precedence(op1)) 10252ec34544SRui Ueyama break; 10263837f427SRui Ueyama rhs = readExpr1(rhs, precedence(op2)); 10272ec34544SRui Ueyama } 10282ec34544SRui Ueyama 10293837f427SRui Ueyama lhs = combine(op1, lhs, rhs); 10302ec34544SRui Ueyama } 10313837f427SRui Ueyama return lhs; 10322ec34544SRui Ueyama } 10332ec34544SRui Ueyama 10345fb17128SGeorge Rimar Expr ScriptParser::getPageSize() { 10353837f427SRui Ueyama std::string location = getCurrentLocation(); 10365fb17128SGeorge Rimar return [=]() -> uint64_t { 10373837f427SRui Ueyama if (target) 10383837f427SRui Ueyama return config->commonPageSize; 10393837f427SRui Ueyama error(location + ": unable to calculate page size"); 10405fb17128SGeorge Rimar return 4096; // Return a dummy value. 10415fb17128SGeorge Rimar }; 10425fb17128SGeorge Rimar } 10435fb17128SGeorge Rimar 10445fb17128SGeorge Rimar Expr ScriptParser::readConstant() { 10453837f427SRui Ueyama StringRef s = readParenLiteral(); 10463837f427SRui Ueyama if (s == "COMMONPAGESIZE") 10475fb17128SGeorge Rimar return getPageSize(); 10483837f427SRui Ueyama if (s == "MAXPAGESIZE") 10493837f427SRui Ueyama return [] { return config->maxPageSize; }; 10503837f427SRui Ueyama setError("unknown constant: " + s); 1051b068b037SGeorge Rimar return [] { return 0; }; 10522ec34544SRui Ueyama } 10532ec34544SRui Ueyama 10545c65088fSRui Ueyama // Parses Tok as an integer. It recognizes hexadecimal (prefixed with 10555c65088fSRui Ueyama // "0x" or suffixed with "H") and decimal numbers. Decimal numbers may 10565c65088fSRui Ueyama // have "K" (Ki) or "M" (Mi) suffixes. 10573837f427SRui Ueyama static Optional<uint64_t> parseInt(StringRef tok) { 10582ec34544SRui Ueyama // Hexadecimal 10593837f427SRui Ueyama uint64_t val; 10603837f427SRui Ueyama if (tok.startswith_lower("0x")) { 10613837f427SRui Ueyama if (!to_integer(tok.substr(2), val, 16)) 10624092016bSRui Ueyama return None; 10633837f427SRui Ueyama return val; 10644092016bSRui Ueyama } 10653837f427SRui Ueyama if (tok.endswith_lower("H")) { 10663837f427SRui Ueyama if (!to_integer(tok.drop_back(), val, 16)) 10674092016bSRui Ueyama return None; 10683837f427SRui Ueyama return val; 10694092016bSRui Ueyama } 10702ec34544SRui Ueyama 10712ec34544SRui Ueyama // Decimal 10723837f427SRui Ueyama if (tok.endswith_lower("K")) { 10733837f427SRui Ueyama if (!to_integer(tok.drop_back(), val, 10)) 10745c65088fSRui Ueyama return None; 10753837f427SRui Ueyama return val * 1024; 10762ec34544SRui Ueyama } 10773837f427SRui Ueyama if (tok.endswith_lower("M")) { 10783837f427SRui Ueyama if (!to_integer(tok.drop_back(), val, 10)) 10795c65088fSRui Ueyama return None; 10803837f427SRui Ueyama return val * 1024 * 1024; 10815c65088fSRui Ueyama } 10823837f427SRui Ueyama if (!to_integer(tok, val, 10)) 10835c65088fSRui Ueyama return None; 10843837f427SRui Ueyama return val; 10852ec34544SRui Ueyama } 10862ec34544SRui Ueyama 10873837f427SRui Ueyama ByteCommand *ScriptParser::readByteCommand(StringRef tok) { 10883837f427SRui Ueyama int size = StringSwitch<int>(tok) 10892ec34544SRui Ueyama .Case("BYTE", 1) 10902ec34544SRui Ueyama .Case("SHORT", 2) 10912ec34544SRui Ueyama .Case("LONG", 4) 10922ec34544SRui Ueyama .Case("QUAD", 8) 10932ec34544SRui Ueyama .Default(-1); 10943837f427SRui Ueyama if (size == -1) 10952ec34544SRui Ueyama return nullptr; 109684bcabcbSGeorge Rimar 10973837f427SRui Ueyama size_t oldPos = pos; 10983837f427SRui Ueyama Expr e = readParenExpr(); 10993837f427SRui Ueyama std::string commandString = 11003837f427SRui Ueyama tok.str() + " " + 11013837f427SRui Ueyama llvm::join(tokens.begin() + oldPos, tokens.begin() + pos, " "); 11023837f427SRui Ueyama return make<ByteCommand>(e, size, commandString); 11032ec34544SRui Ueyama } 11042ec34544SRui Ueyama 11052ec34544SRui Ueyama StringRef ScriptParser::readParenLiteral() { 11062ec34544SRui Ueyama expect("("); 11073837f427SRui Ueyama bool orig = inExpr; 11083837f427SRui Ueyama inExpr = false; 11093837f427SRui Ueyama StringRef tok = next(); 11103837f427SRui Ueyama inExpr = orig; 11112ec34544SRui Ueyama expect(")"); 11123837f427SRui Ueyama return tok; 11132ec34544SRui Ueyama } 11142ec34544SRui Ueyama 11153837f427SRui Ueyama static void checkIfExists(OutputSection *cmd, StringRef location) { 11163837f427SRui Ueyama if (cmd->location.empty() && script->errorOnMissingSection) 11173837f427SRui Ueyama error(location + ": undefined section " + cmd->name); 111805c4f67cSRafael Espindola } 111905c4f67cSRafael Espindola 11202ec34544SRui Ueyama Expr ScriptParser::readPrimary() { 11212ec34544SRui Ueyama if (peek() == "(") 11222ec34544SRui Ueyama return readParenExpr(); 11232ec34544SRui Ueyama 11245c65088fSRui Ueyama if (consume("~")) { 11253837f427SRui Ueyama Expr e = readPrimary(); 11263837f427SRui Ueyama return [=] { return ~e().getValue(); }; 11272ec34544SRui Ueyama } 11286f1d954eSHafiz Abid Qadeer if (consume("!")) { 11293837f427SRui Ueyama Expr e = readPrimary(); 11303837f427SRui Ueyama return [=] { return !e().getValue(); }; 11316f1d954eSHafiz Abid Qadeer } 11325c65088fSRui Ueyama if (consume("-")) { 11333837f427SRui Ueyama Expr e = readPrimary(); 11343837f427SRui Ueyama return [=] { return -e().getValue(); }; 11352ec34544SRui Ueyama } 11362ec34544SRui Ueyama 11373837f427SRui Ueyama StringRef tok = next(); 11383837f427SRui Ueyama std::string location = getCurrentLocation(); 11395c65088fSRui Ueyama 11402ec34544SRui Ueyama // Built-in functions are parsed here. 11412ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html. 11423837f427SRui Ueyama if (tok == "ABSOLUTE") { 11433837f427SRui Ueyama Expr inner = readParenExpr(); 11442ec34544SRui Ueyama return [=] { 11453837f427SRui Ueyama ExprValue i = inner(); 11463837f427SRui Ueyama i.forceAbsolute = true; 11473837f427SRui Ueyama return i; 11482ec34544SRui Ueyama }; 11492ec34544SRui Ueyama } 11503837f427SRui Ueyama if (tok == "ADDR") { 11513837f427SRui Ueyama StringRef name = readParenLiteral(); 11523837f427SRui Ueyama OutputSection *sec = script->getOrCreateOutputSection(name); 11533837f427SRui Ueyama sec->usedInExpression = true; 115441c7ab4aSGeorge Rimar return [=]() -> ExprValue { 11553837f427SRui Ueyama checkIfExists(sec, location); 11563837f427SRui Ueyama return {sec, false, 0, location}; 115741c7ab4aSGeorge Rimar }; 11582ec34544SRui Ueyama } 11593837f427SRui Ueyama if (tok == "ALIGN") { 11602ec34544SRui Ueyama expect("("); 11613837f427SRui Ueyama Expr e = readExpr(); 1162f22ec9ddSGeorge Rimar if (consume(")")) { 11633837f427SRui Ueyama e = checkAlignment(e, location); 11643837f427SRui Ueyama return [=] { return alignTo(script->getDot(), e().getValue()); }; 1165f22ec9ddSGeorge Rimar } 1166b579c439SRui Ueyama expect(","); 11673837f427SRui Ueyama Expr e2 = checkAlignment(readExpr(), location); 11682ec34544SRui Ueyama expect(")"); 11693c6de1a6SPetr Hosek return [=] { 11703837f427SRui Ueyama ExprValue v = e(); 11713837f427SRui Ueyama v.alignment = e2().getValue(); 11723837f427SRui Ueyama return v; 11733c6de1a6SPetr Hosek }; 11742ec34544SRui Ueyama } 11753837f427SRui Ueyama if (tok == "ALIGNOF") { 11763837f427SRui Ueyama StringRef name = readParenLiteral(); 11773837f427SRui Ueyama OutputSection *cmd = script->getOrCreateOutputSection(name); 1178617e2f98SRui Ueyama return [=] { 11793837f427SRui Ueyama checkIfExists(cmd, location); 11803837f427SRui Ueyama return cmd->alignment; 1181617e2f98SRui Ueyama }; 11822ec34544SRui Ueyama } 11833837f427SRui Ueyama if (tok == "ASSERT") 1184d30a78b3SGeorge Rimar return readAssert(); 11853837f427SRui Ueyama if (tok == "CONSTANT") 11865fb17128SGeorge Rimar return readConstant(); 11873837f427SRui Ueyama if (tok == "DATA_SEGMENT_ALIGN") { 11882ec34544SRui Ueyama expect("("); 11893837f427SRui Ueyama Expr e = readExpr(); 11902ec34544SRui Ueyama expect(","); 11912ec34544SRui Ueyama readExpr(); 11922ec34544SRui Ueyama expect(")"); 119360833f6eSGeorge Rimar return [=] { 11943837f427SRui Ueyama return alignTo(script->getDot(), std::max((uint64_t)1, e().getValue())); 119560833f6eSGeorge Rimar }; 11962ec34544SRui Ueyama } 11973837f427SRui Ueyama if (tok == "DATA_SEGMENT_END") { 11982ec34544SRui Ueyama expect("("); 11992ec34544SRui Ueyama expect("."); 12002ec34544SRui Ueyama expect(")"); 12013837f427SRui Ueyama return [] { return script->getDot(); }; 12022ec34544SRui Ueyama } 12033837f427SRui Ueyama if (tok == "DATA_SEGMENT_RELRO_END") { 12042ec34544SRui Ueyama // GNU linkers implements more complicated logic to handle 12052ec34544SRui Ueyama // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and 12062ec34544SRui Ueyama // just align to the next page boundary for simplicity. 12072ec34544SRui Ueyama expect("("); 12082ec34544SRui Ueyama readExpr(); 12092ec34544SRui Ueyama expect(","); 12102ec34544SRui Ueyama readExpr(); 12112ec34544SRui Ueyama expect(")"); 12123837f427SRui Ueyama Expr e = getPageSize(); 12133837f427SRui Ueyama return [=] { return alignTo(script->getDot(), e().getValue()); }; 12142ec34544SRui Ueyama } 12153837f427SRui Ueyama if (tok == "DEFINED") { 12163837f427SRui Ueyama StringRef name = readParenLiteral(); 12173837f427SRui Ueyama return [=] { return symtab->find(name) ? 1 : 0; }; 12182ec34544SRui Ueyama } 12193837f427SRui Ueyama if (tok == "LENGTH") { 12203837f427SRui Ueyama StringRef name = readParenLiteral(); 12213837f427SRui Ueyama if (script->memoryRegions.count(name) == 0) { 12223837f427SRui Ueyama setError("memory region not defined: " + name); 1223b068b037SGeorge Rimar return [] { return 0; }; 1224b068b037SGeorge Rimar } 12253837f427SRui Ueyama return [=] { return script->memoryRegions[name]->length; }; 122691b95b61SRui Ueyama } 12273837f427SRui Ueyama if (tok == "LOADADDR") { 12283837f427SRui Ueyama StringRef name = readParenLiteral(); 12293837f427SRui Ueyama OutputSection *cmd = script->getOrCreateOutputSection(name); 12303837f427SRui Ueyama cmd->usedInExpression = true; 1231617e2f98SRui Ueyama return [=] { 12323837f427SRui Ueyama checkIfExists(cmd, location); 12333837f427SRui Ueyama return cmd->getLMA(); 1234617e2f98SRui Ueyama }; 12352ec34544SRui Ueyama } 12363837f427SRui Ueyama if (tok == "MAX" || tok == "MIN") { 1237fd11560fSGeorge Rimar expect("("); 12383837f427SRui Ueyama Expr a = readExpr(); 1239fd11560fSGeorge Rimar expect(","); 12403837f427SRui Ueyama Expr b = readExpr(); 1241fd11560fSGeorge Rimar expect(")"); 12423837f427SRui Ueyama if (tok == "MIN") 12433837f427SRui Ueyama return [=] { return std::min(a().getValue(), b().getValue()); }; 12443837f427SRui Ueyama return [=] { return std::max(a().getValue(), b().getValue()); }; 1245fd11560fSGeorge Rimar } 12463837f427SRui Ueyama if (tok == "ORIGIN") { 12473837f427SRui Ueyama StringRef name = readParenLiteral(); 12483837f427SRui Ueyama if (script->memoryRegions.count(name) == 0) { 12493837f427SRui Ueyama setError("memory region not defined: " + name); 1250b068b037SGeorge Rimar return [] { return 0; }; 1251b068b037SGeorge Rimar } 12523837f427SRui Ueyama return [=] { return script->memoryRegions[name]->origin; }; 125391b95b61SRui Ueyama } 12543837f427SRui Ueyama if (tok == "SEGMENT_START") { 12552ec34544SRui Ueyama expect("("); 12562ec34544SRui Ueyama skip(); 12572ec34544SRui Ueyama expect(","); 12583837f427SRui Ueyama Expr e = readExpr(); 12592ec34544SRui Ueyama expect(")"); 12603837f427SRui Ueyama return [=] { return e(); }; 12612ec34544SRui Ueyama } 12623837f427SRui Ueyama if (tok == "SIZEOF") { 12633837f427SRui Ueyama StringRef name = readParenLiteral(); 12643837f427SRui Ueyama OutputSection *cmd = script->getOrCreateOutputSection(name); 126505c4f67cSRafael Espindola // Linker script does not create an output section if its content is empty. 126605c4f67cSRafael Espindola // We want to allow SIZEOF(.foo) where .foo is a section which happened to 126705c4f67cSRafael Espindola // be empty. 12683837f427SRui Ueyama return [=] { return cmd->size; }; 12692ec34544SRui Ueyama } 12703837f427SRui Ueyama if (tok == "SIZEOF_HEADERS") 12712ec34544SRui Ueyama return [=] { return elf::getHeaderSize(); }; 12722ec34544SRui Ueyama 12734eb2eccbSRui Ueyama // Tok is the dot. 12743837f427SRui Ueyama if (tok == ".") 12753837f427SRui Ueyama return [=] { return script->getSymbolValue(tok, location); }; 12764eb2eccbSRui Ueyama 12772ec34544SRui Ueyama // Tok is a literal number. 12783837f427SRui Ueyama if (Optional<uint64_t> val = parseInt(tok)) 12793837f427SRui Ueyama return [=] { return *val; }; 12802ec34544SRui Ueyama 12812ec34544SRui Ueyama // Tok is a symbol name. 12823837f427SRui Ueyama if (!isValidCIdentifier(tok)) 12833837f427SRui Ueyama setError("malformed number: " + tok); 12843837f427SRui Ueyama script->referencedSymbols.push_back(tok); 12853837f427SRui Ueyama return [=] { return script->getSymbolValue(tok, location); }; 12862ec34544SRui Ueyama } 12872ec34544SRui Ueyama 12883837f427SRui Ueyama Expr ScriptParser::readTernary(Expr cond) { 12893837f427SRui Ueyama Expr l = readExpr(); 12902ec34544SRui Ueyama expect(":"); 12913837f427SRui Ueyama Expr r = readExpr(); 12923837f427SRui Ueyama return [=] { return cond().getValue() ? l() : r(); }; 12932ec34544SRui Ueyama } 12942ec34544SRui Ueyama 12952ec34544SRui Ueyama Expr ScriptParser::readParenExpr() { 12962ec34544SRui Ueyama expect("("); 12973837f427SRui Ueyama Expr e = readExpr(); 12982ec34544SRui Ueyama expect(")"); 12993837f427SRui Ueyama return e; 13002ec34544SRui Ueyama } 13012ec34544SRui Ueyama 13022ec34544SRui Ueyama std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() { 13033837f427SRui Ueyama std::vector<StringRef> phdrs; 1304b8a59c8aSBob Haarman while (!errorCount() && peek().startswith(":")) { 13053837f427SRui Ueyama StringRef tok = next(); 13063837f427SRui Ueyama phdrs.push_back((tok.size() == 1) ? next() : tok.substr(1)); 13072ec34544SRui Ueyama } 13083837f427SRui Ueyama return phdrs; 13092ec34544SRui Ueyama } 13102ec34544SRui Ueyama 13112ec34544SRui Ueyama // Read a program header type name. The next token must be a 13122ec34544SRui Ueyama // name of a program header type or a constant (e.g. "0x3"). 13132ec34544SRui Ueyama unsigned ScriptParser::readPhdrType() { 13143837f427SRui Ueyama StringRef tok = next(); 13153837f427SRui Ueyama if (Optional<uint64_t> val = parseInt(tok)) 13163837f427SRui Ueyama return *val; 13172ec34544SRui Ueyama 13183837f427SRui Ueyama unsigned ret = StringSwitch<unsigned>(tok) 13192ec34544SRui Ueyama .Case("PT_NULL", PT_NULL) 13202ec34544SRui Ueyama .Case("PT_LOAD", PT_LOAD) 13212ec34544SRui Ueyama .Case("PT_DYNAMIC", PT_DYNAMIC) 13222ec34544SRui Ueyama .Case("PT_INTERP", PT_INTERP) 13232ec34544SRui Ueyama .Case("PT_NOTE", PT_NOTE) 13242ec34544SRui Ueyama .Case("PT_SHLIB", PT_SHLIB) 13252ec34544SRui Ueyama .Case("PT_PHDR", PT_PHDR) 13262ec34544SRui Ueyama .Case("PT_TLS", PT_TLS) 13272ec34544SRui Ueyama .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME) 13282ec34544SRui Ueyama .Case("PT_GNU_STACK", PT_GNU_STACK) 13292ec34544SRui Ueyama .Case("PT_GNU_RELRO", PT_GNU_RELRO) 13302ec34544SRui Ueyama .Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE) 13312ec34544SRui Ueyama .Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED) 13322ec34544SRui Ueyama .Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA) 13332ec34544SRui Ueyama .Default(-1); 13342ec34544SRui Ueyama 13353837f427SRui Ueyama if (ret == (unsigned)-1) { 13363837f427SRui Ueyama setError("invalid program header type: " + tok); 13372ec34544SRui Ueyama return PT_NULL; 13382ec34544SRui Ueyama } 13393837f427SRui Ueyama return ret; 13402ec34544SRui Ueyama } 13412ec34544SRui Ueyama 13422ec34544SRui Ueyama // Reads an anonymous version declaration. 13432ec34544SRui Ueyama void ScriptParser::readAnonymousDeclaration() { 13443837f427SRui Ueyama std::vector<SymbolVersion> locals; 13453837f427SRui Ueyama std::vector<SymbolVersion> globals; 13463837f427SRui Ueyama std::tie(locals, globals) = readSymbols(); 13472ec34544SRui Ueyama 13483837f427SRui Ueyama for (SymbolVersion v : locals) { 13493837f427SRui Ueyama if (v.name == "*") 13503837f427SRui Ueyama config->defaultSymbolVersion = VER_NDX_LOCAL; 13512ec34544SRui Ueyama else 13523837f427SRui Ueyama config->versionScriptLocals.push_back(v); 13532ec34544SRui Ueyama } 13542ec34544SRui Ueyama 13553837f427SRui Ueyama for (SymbolVersion v : globals) 13563837f427SRui Ueyama config->versionScriptGlobals.push_back(v); 13572ec34544SRui Ueyama 13582ec34544SRui Ueyama expect(";"); 13592ec34544SRui Ueyama } 13602ec34544SRui Ueyama 13612ec34544SRui Ueyama // Reads a non-anonymous version definition, 13622ec34544SRui Ueyama // e.g. "VerStr { global: foo; bar; local: *; };". 13633837f427SRui Ueyama void ScriptParser::readVersionDeclaration(StringRef verStr) { 13642ec34544SRui Ueyama // Read a symbol list. 13653837f427SRui Ueyama std::vector<SymbolVersion> locals; 13663837f427SRui Ueyama std::vector<SymbolVersion> globals; 13673837f427SRui Ueyama std::tie(locals, globals) = readSymbols(); 13682ec34544SRui Ueyama 13693837f427SRui Ueyama for (SymbolVersion v : locals) { 13703837f427SRui Ueyama if (v.name == "*") 13713837f427SRui Ueyama config->defaultSymbolVersion = VER_NDX_LOCAL; 13722ec34544SRui Ueyama else 13733837f427SRui Ueyama config->versionScriptLocals.push_back(v); 13742ec34544SRui Ueyama } 13752ec34544SRui Ueyama 13762ec34544SRui Ueyama // Create a new version definition and add that to the global symbols. 13773837f427SRui Ueyama VersionDefinition ver; 13783837f427SRui Ueyama ver.name = verStr; 13793837f427SRui Ueyama ver.globals = globals; 13802ec34544SRui Ueyama 13812ec34544SRui Ueyama // User-defined version number starts from 2 because 0 and 1 are 13822ec34544SRui Ueyama // reserved for VER_NDX_LOCAL and VER_NDX_GLOBAL, respectively. 13833837f427SRui Ueyama ver.id = config->versionDefinitions.size() + 2; 13843837f427SRui Ueyama config->versionDefinitions.push_back(ver); 13852ec34544SRui Ueyama 13862ec34544SRui Ueyama // Each version may have a parent version. For example, "Ver2" 13872ec34544SRui Ueyama // defined as "Ver2 { global: foo; local: *; } Ver1;" has "Ver1" 13882ec34544SRui Ueyama // as a parent. This version hierarchy is, probably against your 13892ec34544SRui Ueyama // instinct, purely for hint; the runtime doesn't care about it 13902ec34544SRui Ueyama // at all. In LLD, we simply ignore it. 13912ec34544SRui Ueyama if (peek() != ";") 13922ec34544SRui Ueyama skip(); 13932ec34544SRui Ueyama expect(";"); 13942ec34544SRui Ueyama } 13952ec34544SRui Ueyama 13963837f427SRui Ueyama static bool hasWildcard(StringRef s) { 13973837f427SRui Ueyama return s.find_first_of("?*[") != StringRef::npos; 13981e77ad14SRui Ueyama } 13991e77ad14SRui Ueyama 14002ec34544SRui Ueyama // Reads a list of symbols, e.g. "{ global: foo; bar; local: *; };". 14012ec34544SRui Ueyama std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>> 14022ec34544SRui Ueyama ScriptParser::readSymbols() { 14033837f427SRui Ueyama std::vector<SymbolVersion> locals; 14043837f427SRui Ueyama std::vector<SymbolVersion> globals; 14053837f427SRui Ueyama std::vector<SymbolVersion> *v = &globals; 14062ec34544SRui Ueyama 1407b8a59c8aSBob Haarman while (!errorCount()) { 14082ec34544SRui Ueyama if (consume("}")) 14092ec34544SRui Ueyama break; 14102ec34544SRui Ueyama if (consumeLabel("local")) { 14113837f427SRui Ueyama v = &locals; 14122ec34544SRui Ueyama continue; 14132ec34544SRui Ueyama } 14142ec34544SRui Ueyama if (consumeLabel("global")) { 14153837f427SRui Ueyama v = &globals; 14162ec34544SRui Ueyama continue; 14172ec34544SRui Ueyama } 14182ec34544SRui Ueyama 14192ec34544SRui Ueyama if (consume("extern")) { 14203837f427SRui Ueyama std::vector<SymbolVersion> ext = readVersionExtern(); 14213837f427SRui Ueyama v->insert(v->end(), ext.begin(), ext.end()); 14222ec34544SRui Ueyama } else { 14233837f427SRui Ueyama StringRef tok = next(); 14243837f427SRui Ueyama v->push_back({unquote(tok), false, hasWildcard(tok)}); 14252ec34544SRui Ueyama } 14262ec34544SRui Ueyama expect(";"); 14272ec34544SRui Ueyama } 14283837f427SRui Ueyama return {locals, globals}; 14292ec34544SRui Ueyama } 14302ec34544SRui Ueyama 14312ec34544SRui Ueyama // Reads an "extern C++" directive, e.g., 14322ec34544SRui Ueyama // "extern "C++" { ns::*; "f(int, double)"; };" 143317324d8bSRui Ueyama // 143417324d8bSRui Ueyama // The last semicolon is optional. E.g. this is OK: 143517324d8bSRui Ueyama // "extern "C++" { ns::*; "f(int, double)" };" 14362ec34544SRui Ueyama std::vector<SymbolVersion> ScriptParser::readVersionExtern() { 14373837f427SRui Ueyama StringRef tok = next(); 14383837f427SRui Ueyama bool isCXX = tok == "\"C++\""; 14393837f427SRui Ueyama if (!isCXX && tok != "\"C\"") 14402ec34544SRui Ueyama setError("Unknown language"); 14412ec34544SRui Ueyama expect("{"); 14422ec34544SRui Ueyama 14433837f427SRui Ueyama std::vector<SymbolVersion> ret; 1444b8a59c8aSBob Haarman while (!errorCount() && peek() != "}") { 14453837f427SRui Ueyama StringRef tok = next(); 14463837f427SRui Ueyama ret.push_back( 14473837f427SRui Ueyama {unquote(tok), isCXX, !tok.startswith("\"") && hasWildcard(tok)}); 144817324d8bSRui Ueyama if (consume("}")) 14493837f427SRui Ueyama return ret; 14502ec34544SRui Ueyama expect(";"); 14512ec34544SRui Ueyama } 14522ec34544SRui Ueyama 14532ec34544SRui Ueyama expect("}"); 14543837f427SRui Ueyama return ret; 14552ec34544SRui Ueyama } 14562ec34544SRui Ueyama 14573837f427SRui Ueyama uint64_t ScriptParser::readMemoryAssignment(StringRef s1, StringRef s2, 14583837f427SRui Ueyama StringRef s3) { 14593837f427SRui Ueyama if (!consume(s1) && !consume(s2) && !consume(s3)) { 14603837f427SRui Ueyama setError("expected one of: " + s1 + ", " + s2 + ", or " + s3); 14612ec34544SRui Ueyama return 0; 14622ec34544SRui Ueyama } 14632ec34544SRui Ueyama expect("="); 1464040af7deSRui Ueyama return readExpr()().getValue(); 14652ec34544SRui Ueyama } 14662ec34544SRui Ueyama 14672ec34544SRui Ueyama // Parse the MEMORY command as specified in: 14682ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/MEMORY.html 14692ec34544SRui Ueyama // 14702ec34544SRui Ueyama // MEMORY { name [(attr)] : ORIGIN = origin, LENGTH = len ... } 14712ec34544SRui Ueyama void ScriptParser::readMemory() { 14722ec34544SRui Ueyama expect("{"); 1473b8a59c8aSBob Haarman while (!errorCount() && !consume("}")) { 14743837f427SRui Ueyama StringRef tok = next(); 14753837f427SRui Ueyama if (tok == "INCLUDE") { 14762e9d40d5SRui Ueyama readInclude(); 14772e9d40d5SRui Ueyama continue; 14782e9d40d5SRui Ueyama } 14792ec34544SRui Ueyama 14803837f427SRui Ueyama uint32_t flags = 0; 14813837f427SRui Ueyama uint32_t negFlags = 0; 14822ec34544SRui Ueyama if (consume("(")) { 14833837f427SRui Ueyama std::tie(flags, negFlags) = readMemoryAttributes(); 14842ec34544SRui Ueyama expect(")"); 14852ec34544SRui Ueyama } 14862ec34544SRui Ueyama expect(":"); 14872ec34544SRui Ueyama 14883837f427SRui Ueyama uint64_t origin = readMemoryAssignment("ORIGIN", "org", "o"); 14892ec34544SRui Ueyama expect(","); 14903837f427SRui Ueyama uint64_t length = readMemoryAssignment("LENGTH", "len", "l"); 14912ec34544SRui Ueyama 14925f37541cSGeorge Rimar // Add the memory region to the region map. 14933837f427SRui Ueyama MemoryRegion *mr = make<MemoryRegion>(tok, origin, length, flags, negFlags); 14943837f427SRui Ueyama if (!script->memoryRegions.insert({tok, mr}).second) 14953837f427SRui Ueyama setError("region '" + tok + "' already defined"); 14962ec34544SRui Ueyama } 14972ec34544SRui Ueyama } 14982ec34544SRui Ueyama 14992ec34544SRui Ueyama // This function parses the attributes used to match against section 15002ec34544SRui Ueyama // flags when placing output sections in a memory region. These flags 15012ec34544SRui Ueyama // are only used when an explicit memory region name is not used. 15022ec34544SRui Ueyama std::pair<uint32_t, uint32_t> ScriptParser::readMemoryAttributes() { 15033837f427SRui Ueyama uint32_t flags = 0; 15043837f427SRui Ueyama uint32_t negFlags = 0; 15053837f427SRui Ueyama bool invert = false; 15062ec34544SRui Ueyama 15073837f427SRui Ueyama for (char c : next().lower()) { 15083837f427SRui Ueyama uint32_t flag = 0; 15093837f427SRui Ueyama if (c == '!') 15103837f427SRui Ueyama invert = !invert; 15113837f427SRui Ueyama else if (c == 'w') 15123837f427SRui Ueyama flag = SHF_WRITE; 15133837f427SRui Ueyama else if (c == 'x') 15143837f427SRui Ueyama flag = SHF_EXECINSTR; 15153837f427SRui Ueyama else if (c == 'a') 15163837f427SRui Ueyama flag = SHF_ALLOC; 15173837f427SRui Ueyama else if (c != 'r') 15182ec34544SRui Ueyama setError("invalid memory region attribute"); 15192ec34544SRui Ueyama 15203837f427SRui Ueyama if (invert) 15213837f427SRui Ueyama negFlags |= flag; 15222ec34544SRui Ueyama else 15233837f427SRui Ueyama flags |= flag; 15242ec34544SRui Ueyama } 15253837f427SRui Ueyama return {flags, negFlags}; 15262ec34544SRui Ueyama } 15272ec34544SRui Ueyama 15283837f427SRui Ueyama void elf::readLinkerScript(MemoryBufferRef mb) { 15293837f427SRui Ueyama ScriptParser(mb).readLinkerScript(); 15302ec34544SRui Ueyama } 15312ec34544SRui Ueyama 15323837f427SRui Ueyama void elf::readVersionScript(MemoryBufferRef mb) { 15333837f427SRui Ueyama ScriptParser(mb).readVersionScript(); 15342ec34544SRui Ueyama } 15352ec34544SRui Ueyama 15363837f427SRui Ueyama void elf::readDynamicList(MemoryBufferRef mb) { 15373837f427SRui Ueyama ScriptParser(mb).readDynamicList(); 15382ec34544SRui Ueyama } 15398c7e8cceSPetr Hosek 15403837f427SRui Ueyama void elf::readDefsym(StringRef name, MemoryBufferRef mb) { 15413837f427SRui Ueyama ScriptParser(mb).readDefsym(name); 15428c7e8cceSPetr Hosek } 1543