12ec34544SRui Ueyama //===- ScriptParser.cpp ---------------------------------------------------===// 22ec34544SRui Ueyama // 3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 5*2946cd70SChandler 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 432ec34544SRui Ueyama static bool isUnderSysroot(StringRef Path); 442ec34544SRui Ueyama 4596b3fe02SRui Ueyama namespace { 4696b3fe02SRui Ueyama class ScriptParser final : ScriptLexer { 472ec34544SRui Ueyama public: 482ec34544SRui Ueyama ScriptParser(MemoryBufferRef MB) 492ec34544SRui Ueyama : ScriptLexer(MB), 502ec34544SRui Ueyama IsUnderSysroot(isUnderSysroot(MB.getBufferIdentifier())) {} 512ec34544SRui Ueyama 522ec34544SRui Ueyama void readLinkerScript(); 532ec34544SRui Ueyama void readVersionScript(); 542ec34544SRui Ueyama void readDynamicList(); 558c7e8cceSPetr Hosek void readDefsym(StringRef Name); 562ec34544SRui Ueyama 572ec34544SRui Ueyama private: 582ec34544SRui Ueyama void addFile(StringRef Path); 592ec34544SRui Ueyama 602ec34544SRui Ueyama void readAsNeeded(); 612ec34544SRui Ueyama void readEntry(); 622ec34544SRui Ueyama void readExtern(); 632ec34544SRui Ueyama void readGroup(); 642ec34544SRui Ueyama void readInclude(); 651d92aa73SRui Ueyama void readInput(); 662ec34544SRui Ueyama void readMemory(); 672ec34544SRui Ueyama void readOutput(); 682ec34544SRui Ueyama void readOutputArch(); 692ec34544SRui Ueyama void readOutputFormat(); 702ec34544SRui Ueyama void readPhdrs(); 715f37541cSGeorge Rimar void readRegionAlias(); 722ec34544SRui Ueyama void readSearchDir(); 732ec34544SRui Ueyama void readSections(); 74e262bb1aSRui Ueyama void readTarget(); 752ec34544SRui Ueyama void readVersion(); 762ec34544SRui Ueyama void readVersionScriptCommand(); 772ec34544SRui Ueyama 78d30a78b3SGeorge Rimar SymbolAssignment *readSymbolAssignment(StringRef Name); 79f0403c60SRui Ueyama ByteCommand *readByteCommand(StringRef Tok); 80b0486051SSimon Atanasyan std::array<uint8_t, 4> readFill(); 81b0486051SSimon Atanasyan std::array<uint8_t, 4> parseFill(StringRef Tok); 82a46d08ebSGeorge Rimar bool readSectionDirective(OutputSection *Cmd, StringRef Tok1, StringRef Tok2); 838c022ca7SRafael Espindola void readSectionAddressType(OutputSection *Cmd); 84a582419aSGeorge Rimar OutputSection *readOverlaySectionDescription(); 858c022ca7SRafael Espindola OutputSection *readOutputSectionDescription(StringRef OutSec); 86a582419aSGeorge Rimar std::vector<BaseCommand *> readOverlay(); 872ec34544SRui Ueyama std::vector<StringRef> readOutputSectionPhdrs(); 882ec34544SRui Ueyama InputSectionDescription *readInputSectionDescription(StringRef Tok); 892ec34544SRui Ueyama StringMatcher readFilePatterns(); 902ec34544SRui Ueyama std::vector<SectionPattern> readInputSectionsList(); 912ec34544SRui Ueyama InputSectionDescription *readInputSectionRules(StringRef FilePattern); 922ec34544SRui Ueyama unsigned readPhdrType(); 932ec34544SRui Ueyama SortSectionPolicy readSortKind(); 942ec34544SRui Ueyama SymbolAssignment *readProvideHidden(bool Provide, bool Hidden); 95d30a78b3SGeorge Rimar SymbolAssignment *readAssignment(StringRef Tok); 9669c61200SSimon Atanasyan std::tuple<ELFKind, uint16_t, bool> readBfdName(); 972ec34544SRui Ueyama void readSort(); 98d30a78b3SGeorge Rimar Expr readAssert(); 995fb17128SGeorge Rimar Expr readConstant(); 1005fb17128SGeorge Rimar Expr getPageSize(); 1012ec34544SRui Ueyama 1022ec34544SRui Ueyama uint64_t readMemoryAssignment(StringRef, StringRef, StringRef); 1032ec34544SRui Ueyama std::pair<uint32_t, uint32_t> readMemoryAttributes(); 1042ec34544SRui Ueyama 1057b91e213SGeorge Rimar Expr combine(StringRef Op, Expr L, Expr R); 1062ec34544SRui Ueyama Expr readExpr(); 1072ec34544SRui Ueyama Expr readExpr1(Expr Lhs, int MinPrec); 1082ec34544SRui Ueyama StringRef readParenLiteral(); 1092ec34544SRui Ueyama Expr readPrimary(); 1102ec34544SRui Ueyama Expr readTernary(Expr Cond); 1112ec34544SRui Ueyama Expr readParenExpr(); 1122ec34544SRui Ueyama 1132ec34544SRui Ueyama // For parsing version script. 1142ec34544SRui Ueyama std::vector<SymbolVersion> readVersionExtern(); 1152ec34544SRui Ueyama void readAnonymousDeclaration(); 1162ec34544SRui Ueyama void readVersionDeclaration(StringRef VerStr); 1172ec34544SRui Ueyama 1182ec34544SRui Ueyama std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>> 1192ec34544SRui Ueyama readSymbols(); 1202ec34544SRui Ueyama 121fd06b025SRui Ueyama // True if a script being read is in a subdirectory specified by -sysroot. 1222ec34544SRui Ueyama bool IsUnderSysroot; 1230440be4aSRui Ueyama 1240440be4aSRui Ueyama // A set to detect an INCLUDE() cycle. 1250440be4aSRui Ueyama StringSet<> Seen; 1262ec34544SRui Ueyama }; 12796b3fe02SRui Ueyama } // namespace 1282ec34544SRui Ueyama 1291e77ad14SRui Ueyama static StringRef unquote(StringRef S) { 1301e77ad14SRui Ueyama if (S.startswith("\"")) 1311e77ad14SRui Ueyama return S.substr(1, S.size() - 2); 1321e77ad14SRui Ueyama return S; 1331e77ad14SRui Ueyama } 1341e77ad14SRui Ueyama 1352ec34544SRui Ueyama static bool isUnderSysroot(StringRef Path) { 1362ec34544SRui Ueyama if (Config->Sysroot == "") 1372ec34544SRui Ueyama return false; 1382ec34544SRui Ueyama for (; !Path.empty(); Path = sys::path::parent_path(Path)) 1392ec34544SRui Ueyama if (sys::fs::equivalent(Config->Sysroot, Path)) 1402ec34544SRui Ueyama return true; 1412ec34544SRui Ueyama return false; 1422ec34544SRui Ueyama } 1432ec34544SRui Ueyama 1442ec34544SRui Ueyama // Some operations only support one non absolute value. Move the 1452ec34544SRui Ueyama // absolute one to the right hand side for convenience. 1462ec34544SRui Ueyama static void moveAbsRight(ExprValue &A, ExprValue &B) { 14723be5e8dSRafael Espindola if (A.Sec == nullptr || (A.ForceAbsolute && !B.isAbsolute())) 1482ec34544SRui Ueyama std::swap(A, B); 1492ec34544SRui Ueyama if (!B.isAbsolute()) 15041c7ab4aSGeorge Rimar error(A.Loc + ": at least one side of the expression must be absolute"); 1512ec34544SRui Ueyama } 1522ec34544SRui Ueyama 1532ec34544SRui Ueyama static ExprValue add(ExprValue A, ExprValue B) { 1542ec34544SRui Ueyama moveAbsRight(A, B); 155a6acd23cSRafael Espindola return {A.Sec, A.ForceAbsolute, A.getSectionOffset() + B.getValue(), A.Loc}; 1562ec34544SRui Ueyama } 1572ec34544SRui Ueyama 1582ec34544SRui Ueyama static ExprValue sub(ExprValue A, ExprValue B) { 15963a4a98eSRafael Espindola // The distance between two symbols in sections is absolute. 1609cbb6dd1SRafael Espindola if (!A.isAbsolute() && !B.isAbsolute()) 1619cbb6dd1SRafael Espindola return A.getValue() - B.getValue(); 1624fbe3518SRui Ueyama return {A.Sec, false, A.getSectionOffset() - B.getValue(), A.Loc}; 1632ec34544SRui Ueyama } 1642ec34544SRui Ueyama 1652ec34544SRui Ueyama static ExprValue bitAnd(ExprValue A, ExprValue B) { 1662ec34544SRui Ueyama moveAbsRight(A, B); 1672ec34544SRui Ueyama return {A.Sec, A.ForceAbsolute, 16841c7ab4aSGeorge Rimar (A.getValue() & B.getValue()) - A.getSecAddr(), A.Loc}; 1692ec34544SRui Ueyama } 1702ec34544SRui Ueyama 1712ec34544SRui Ueyama static ExprValue bitOr(ExprValue A, ExprValue B) { 1722ec34544SRui Ueyama moveAbsRight(A, B); 1732ec34544SRui Ueyama return {A.Sec, A.ForceAbsolute, 17441c7ab4aSGeorge Rimar (A.getValue() | B.getValue()) - A.getSecAddr(), A.Loc}; 1752ec34544SRui Ueyama } 1762ec34544SRui Ueyama 1772ec34544SRui Ueyama void ScriptParser::readDynamicList() { 1788016bdfdSRafael Espindola Config->HasDynamicList = true; 1792ec34544SRui Ueyama expect("{"); 180d72d97b3SRafael Espindola std::vector<SymbolVersion> Locals; 181d72d97b3SRafael Espindola std::vector<SymbolVersion> Globals; 182d72d97b3SRafael Espindola std::tie(Locals, Globals) = readSymbols(); 183d72d97b3SRafael Espindola expect(";"); 184d72d97b3SRafael Espindola 185d72d97b3SRafael Espindola if (!atEOF()) { 1862ec34544SRui Ueyama setError("EOF expected, but got " + next()); 187d72d97b3SRafael Espindola return; 188d72d97b3SRafael Espindola } 189d72d97b3SRafael Espindola if (!Locals.empty()) { 190d72d97b3SRafael Espindola setError("\"local:\" scope not supported in --dynamic-list"); 191d72d97b3SRafael Espindola return; 192d72d97b3SRafael Espindola } 193d72d97b3SRafael Espindola 194d72d97b3SRafael Espindola for (SymbolVersion V : Globals) 195d72d97b3SRafael Espindola Config->DynamicList.push_back(V); 1962ec34544SRui Ueyama } 1972ec34544SRui Ueyama 1982ec34544SRui Ueyama void ScriptParser::readVersionScript() { 1992ec34544SRui Ueyama readVersionScriptCommand(); 2002ec34544SRui Ueyama if (!atEOF()) 2012ec34544SRui Ueyama setError("EOF expected, but got " + next()); 2022ec34544SRui Ueyama } 2032ec34544SRui Ueyama 2042ec34544SRui Ueyama void ScriptParser::readVersionScriptCommand() { 2052ec34544SRui Ueyama if (consume("{")) { 2062ec34544SRui Ueyama readAnonymousDeclaration(); 2072ec34544SRui Ueyama return; 2082ec34544SRui Ueyama } 2092ec34544SRui Ueyama 210b8a59c8aSBob Haarman while (!atEOF() && !errorCount() && peek() != "}") { 2112ec34544SRui Ueyama StringRef VerStr = next(); 2122ec34544SRui Ueyama if (VerStr == "{") { 2132ec34544SRui Ueyama setError("anonymous version definition is used in " 2142ec34544SRui Ueyama "combination with other version definitions"); 2152ec34544SRui Ueyama return; 2162ec34544SRui Ueyama } 2172ec34544SRui Ueyama expect("{"); 2182ec34544SRui Ueyama readVersionDeclaration(VerStr); 2192ec34544SRui Ueyama } 2202ec34544SRui Ueyama } 2212ec34544SRui Ueyama 2222ec34544SRui Ueyama void ScriptParser::readVersion() { 2232ec34544SRui Ueyama expect("{"); 2242ec34544SRui Ueyama readVersionScriptCommand(); 2252ec34544SRui Ueyama expect("}"); 2262ec34544SRui Ueyama } 2272ec34544SRui Ueyama 2282ec34544SRui Ueyama void ScriptParser::readLinkerScript() { 2292ec34544SRui Ueyama while (!atEOF()) { 2302ec34544SRui Ueyama StringRef Tok = next(); 2312ec34544SRui Ueyama if (Tok == ";") 2322ec34544SRui Ueyama continue; 2332ec34544SRui Ueyama 234d30a78b3SGeorge Rimar if (Tok == "ENTRY") { 2352ec34544SRui Ueyama readEntry(); 2362ec34544SRui Ueyama } else if (Tok == "EXTERN") { 2372ec34544SRui Ueyama readExtern(); 2381d92aa73SRui Ueyama } else if (Tok == "GROUP") { 2392ec34544SRui Ueyama readGroup(); 2402ec34544SRui Ueyama } else if (Tok == "INCLUDE") { 2412ec34544SRui Ueyama readInclude(); 2421d92aa73SRui Ueyama } else if (Tok == "INPUT") { 2431d92aa73SRui Ueyama readInput(); 2442ec34544SRui Ueyama } else if (Tok == "MEMORY") { 2452ec34544SRui Ueyama readMemory(); 2462ec34544SRui Ueyama } else if (Tok == "OUTPUT") { 2472ec34544SRui Ueyama readOutput(); 2482ec34544SRui Ueyama } else if (Tok == "OUTPUT_ARCH") { 2492ec34544SRui Ueyama readOutputArch(); 2502ec34544SRui Ueyama } else if (Tok == "OUTPUT_FORMAT") { 2512ec34544SRui Ueyama readOutputFormat(); 2522ec34544SRui Ueyama } else if (Tok == "PHDRS") { 2532ec34544SRui Ueyama readPhdrs(); 2545f37541cSGeorge Rimar } else if (Tok == "REGION_ALIAS") { 2555f37541cSGeorge Rimar readRegionAlias(); 2562ec34544SRui Ueyama } else if (Tok == "SEARCH_DIR") { 2572ec34544SRui Ueyama readSearchDir(); 2582ec34544SRui Ueyama } else if (Tok == "SECTIONS") { 2592ec34544SRui Ueyama readSections(); 260e262bb1aSRui Ueyama } else if (Tok == "TARGET") { 261e262bb1aSRui Ueyama readTarget(); 2622ec34544SRui Ueyama } else if (Tok == "VERSION") { 2632ec34544SRui Ueyama readVersion(); 264d30a78b3SGeorge Rimar } else if (SymbolAssignment *Cmd = readAssignment(Tok)) { 2656b394caaSRui Ueyama Script->SectionCommands.push_back(Cmd); 2662ec34544SRui Ueyama } else { 2672ec34544SRui Ueyama setError("unknown directive: " + Tok); 2682ec34544SRui Ueyama } 2692ec34544SRui Ueyama } 2702ec34544SRui Ueyama } 2712ec34544SRui Ueyama 2728c7e8cceSPetr Hosek void ScriptParser::readDefsym(StringRef Name) { 273c1522816SGeorge Rimar if (errorCount()) 274c1522816SGeorge Rimar return; 2758c7e8cceSPetr Hosek Expr E = readExpr(); 2768c7e8cceSPetr Hosek if (!atEOF()) 2778c7e8cceSPetr Hosek setError("EOF expected, but got " + next()); 278e88b76a9SGeorge Rimar SymbolAssignment *Cmd = make<SymbolAssignment>(Name, E, getCurrentLocation()); 2798c7e8cceSPetr Hosek Script->SectionCommands.push_back(Cmd); 2808c7e8cceSPetr Hosek } 2818c7e8cceSPetr Hosek 2822ec34544SRui Ueyama void ScriptParser::addFile(StringRef S) { 2832ec34544SRui Ueyama if (IsUnderSysroot && S.startswith("/")) { 2842ec34544SRui Ueyama SmallString<128> PathData; 2852ec34544SRui Ueyama StringRef Path = (Config->Sysroot + S).toStringRef(PathData); 2862ec34544SRui Ueyama if (sys::fs::exists(Path)) { 287a76349bfSEvgeniy Stepanov Driver->addFile(Saver.save(Path), /*WithLOption=*/false); 2882ec34544SRui Ueyama return; 2892ec34544SRui Ueyama } 2902ec34544SRui Ueyama } 2912ec34544SRui Ueyama 292875ae82bSRui Ueyama if (S.startswith("/")) { 293a76349bfSEvgeniy Stepanov Driver->addFile(S, /*WithLOption=*/false); 2942ec34544SRui Ueyama } else if (S.startswith("=")) { 2952ec34544SRui Ueyama if (Config->Sysroot.empty()) 296a76349bfSEvgeniy Stepanov Driver->addFile(S.substr(1), /*WithLOption=*/false); 2972ec34544SRui Ueyama else 298a76349bfSEvgeniy Stepanov Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1)), 299a76349bfSEvgeniy Stepanov /*WithLOption=*/false); 3002ec34544SRui Ueyama } else if (S.startswith("-l")) { 3012ec34544SRui Ueyama Driver->addLibrary(S.substr(2)); 3022ec34544SRui Ueyama } else if (sys::fs::exists(S)) { 303a76349bfSEvgeniy Stepanov Driver->addFile(S, /*WithLOption=*/false); 3042ec34544SRui Ueyama } else { 3052ec34544SRui Ueyama if (Optional<std::string> Path = findFromSearchPaths(S)) 306a76349bfSEvgeniy Stepanov Driver->addFile(Saver.save(*Path), /*WithLOption=*/true); 3072ec34544SRui Ueyama else 3082ec34544SRui Ueyama setError("unable to find " + S); 3092ec34544SRui Ueyama } 3102ec34544SRui Ueyama } 3112ec34544SRui Ueyama 3122ec34544SRui Ueyama void ScriptParser::readAsNeeded() { 3132ec34544SRui Ueyama expect("("); 3142ec34544SRui Ueyama bool Orig = Config->AsNeeded; 3152ec34544SRui Ueyama Config->AsNeeded = true; 316b8a59c8aSBob Haarman while (!errorCount() && !consume(")")) 3172ec34544SRui Ueyama addFile(unquote(next())); 3182ec34544SRui Ueyama Config->AsNeeded = Orig; 3192ec34544SRui Ueyama } 3202ec34544SRui Ueyama 3212ec34544SRui Ueyama void ScriptParser::readEntry() { 3222ec34544SRui Ueyama // -e <symbol> takes predecence over ENTRY(<symbol>). 3232ec34544SRui Ueyama expect("("); 3242ec34544SRui Ueyama StringRef Tok = next(); 3252ec34544SRui Ueyama if (Config->Entry.empty()) 3262ec34544SRui Ueyama Config->Entry = Tok; 3272ec34544SRui Ueyama expect(")"); 3282ec34544SRui Ueyama } 3292ec34544SRui Ueyama 3302ec34544SRui Ueyama void ScriptParser::readExtern() { 3312ec34544SRui Ueyama expect("("); 332b8a59c8aSBob Haarman while (!errorCount() && !consume(")")) 3332ec34544SRui Ueyama Config->Undefined.push_back(next()); 3342ec34544SRui Ueyama } 3352ec34544SRui Ueyama 3362ec34544SRui Ueyama void ScriptParser::readGroup() { 3371d92aa73SRui Ueyama bool Orig = InputFile::IsInGroup; 3381d92aa73SRui Ueyama InputFile::IsInGroup = true; 3391d92aa73SRui Ueyama readInput(); 3401d92aa73SRui Ueyama InputFile::IsInGroup = Orig; 341b72daf00SFangrui Song if (!Orig) 342b72daf00SFangrui Song ++InputFile::NextGroupId; 3432ec34544SRui Ueyama } 3442ec34544SRui Ueyama 3452ec34544SRui Ueyama void ScriptParser::readInclude() { 3462ec34544SRui Ueyama StringRef Tok = unquote(next()); 3472ec34544SRui Ueyama 3480440be4aSRui Ueyama if (!Seen.insert(Tok).second) { 3490440be4aSRui Ueyama setError("there is a cycle in linker script INCLUDEs"); 3500440be4aSRui Ueyama return; 3510440be4aSRui Ueyama } 3520440be4aSRui Ueyama 353c60f85d0SFangrui Song if (Optional<std::string> Path = searchScript(Tok)) { 3542ec34544SRui Ueyama if (Optional<MemoryBufferRef> MB = readFile(*Path)) 3552ec34544SRui Ueyama tokenize(*MB); 3562ec34544SRui Ueyama return; 3572ec34544SRui Ueyama } 3581de78471SAlexander Richardson setError("cannot find linker script " + Tok); 3592ec34544SRui Ueyama } 3602ec34544SRui Ueyama 3611d92aa73SRui Ueyama void ScriptParser::readInput() { 3621d92aa73SRui Ueyama expect("("); 3631d92aa73SRui Ueyama while (!errorCount() && !consume(")")) { 3641d92aa73SRui Ueyama if (consume("AS_NEEDED")) 3651d92aa73SRui Ueyama readAsNeeded(); 3661d92aa73SRui Ueyama else 3671d92aa73SRui Ueyama addFile(unquote(next())); 3681d92aa73SRui Ueyama } 3691d92aa73SRui Ueyama } 3701d92aa73SRui Ueyama 3712ec34544SRui Ueyama void ScriptParser::readOutput() { 3722ec34544SRui Ueyama // -o <file> takes predecence over OUTPUT(<file>). 3732ec34544SRui Ueyama expect("("); 3742ec34544SRui Ueyama StringRef Tok = next(); 3752ec34544SRui Ueyama if (Config->OutputFile.empty()) 3762ec34544SRui Ueyama Config->OutputFile = unquote(Tok); 3772ec34544SRui Ueyama expect(")"); 3782ec34544SRui Ueyama } 3792ec34544SRui Ueyama 3802ec34544SRui Ueyama void ScriptParser::readOutputArch() { 3812ec34544SRui Ueyama // OUTPUT_ARCH is ignored for now. 3822ec34544SRui Ueyama expect("("); 383b8a59c8aSBob Haarman while (!errorCount() && !consume(")")) 3842ec34544SRui Ueyama skip(); 3852ec34544SRui Ueyama } 3862ec34544SRui Ueyama 38769c61200SSimon Atanasyan std::tuple<ELFKind, uint16_t, bool> ScriptParser::readBfdName() { 3884ec5d67eSGalina Kistanova StringRef S = unquote(next()); 389ea8cd00aSRui Ueyama if (S == "elf32-i386") 39000e82a6fSHaojian Wu return std::make_tuple(ELF32LEKind, EM_386, false); 391ea8cd00aSRui Ueyama if (S == "elf32-iamcu") 39200e82a6fSHaojian Wu return std::make_tuple(ELF32LEKind, EM_IAMCU, false); 393c8e9d2b5SShoaib Meenai if (S == "elf32-littlearm") 39400e82a6fSHaojian Wu return std::make_tuple(ELF32LEKind, EM_ARM, false); 395ea8cd00aSRui Ueyama if (S == "elf32-x86-64") 39600e82a6fSHaojian Wu return std::make_tuple(ELF32LEKind, EM_X86_64, false); 397ea8cd00aSRui Ueyama if (S == "elf64-littleaarch64") 39800e82a6fSHaojian Wu return std::make_tuple(ELF64LEKind, EM_AARCH64, false); 39992964e74SSean Fertile if (S == "elf64-powerpc") 40000e82a6fSHaojian Wu return std::make_tuple(ELF64BEKind, EM_PPC64, false); 40192964e74SSean Fertile if (S == "elf64-powerpcle") 40200e82a6fSHaojian Wu return std::make_tuple(ELF64LEKind, EM_PPC64, false); 403ea8cd00aSRui Ueyama if (S == "elf64-x86-64") 40400e82a6fSHaojian Wu return std::make_tuple(ELF64LEKind, EM_X86_64, false); 40569c61200SSimon Atanasyan if (S == "elf32-tradbigmips") 40600e82a6fSHaojian Wu return std::make_tuple(ELF32BEKind, EM_MIPS, false); 40769c61200SSimon Atanasyan if (S == "elf32-ntradbigmips") 408ac6e1fb8SHaojian Wu return std::make_tuple(ELF32BEKind, EM_MIPS, true); 40969c61200SSimon Atanasyan if (S == "elf32-tradlittlemips") 41000e82a6fSHaojian Wu return std::make_tuple(ELF32LEKind, EM_MIPS, false); 41169c61200SSimon Atanasyan if (S == "elf32-ntradlittlemips") 41200e82a6fSHaojian Wu return std::make_tuple(ELF32LEKind, EM_MIPS, true); 41369c61200SSimon Atanasyan if (S == "elf64-tradbigmips") 41400e82a6fSHaojian Wu return std::make_tuple(ELF64BEKind, EM_MIPS, false); 41569c61200SSimon Atanasyan if (S == "elf64-tradlittlemips") 41600e82a6fSHaojian Wu return std::make_tuple(ELF64LEKind, EM_MIPS, false); 417ea8cd00aSRui Ueyama 418ea8cd00aSRui Ueyama setError("unknown output format name: " + S); 41900e82a6fSHaojian Wu return std::make_tuple(ELFNoneKind, EM_NONE, false); 420ea8cd00aSRui Ueyama } 421ea8cd00aSRui Ueyama 422ea8cd00aSRui Ueyama // Parse OUTPUT_FORMAT(bfdname) or OUTPUT_FORMAT(bfdname, big, little). 423ea8cd00aSRui Ueyama // Currently we ignore big and little parameters. 4242ec34544SRui Ueyama void ScriptParser::readOutputFormat() { 4252ec34544SRui Ueyama expect("("); 426ea8cd00aSRui Ueyama 42769c61200SSimon Atanasyan std::tuple<ELFKind, uint16_t, bool> BfdTuple = readBfdName(); 42869c61200SSimon Atanasyan if (Config->EKind == ELFNoneKind) 42969c61200SSimon Atanasyan std::tie(Config->EKind, Config->EMachine, Config->MipsN32Abi) = BfdTuple; 430ea8cd00aSRui Ueyama 431b579c439SRui Ueyama if (consume(")")) 4322ec34544SRui Ueyama return; 433b579c439SRui Ueyama expect(","); 4342ec34544SRui Ueyama skip(); 4352ec34544SRui Ueyama expect(","); 4362ec34544SRui Ueyama skip(); 4372ec34544SRui Ueyama expect(")"); 4382ec34544SRui Ueyama } 4392ec34544SRui Ueyama 4402ec34544SRui Ueyama void ScriptParser::readPhdrs() { 4412ec34544SRui Ueyama expect("{"); 4422ec34544SRui Ueyama 443b8a59c8aSBob Haarman while (!errorCount() && !consume("}")) { 4440ae2c24cSRui Ueyama PhdrsCommand Cmd; 4450ae2c24cSRui Ueyama Cmd.Name = next(); 4460ae2c24cSRui Ueyama Cmd.Type = readPhdrType(); 447b579c439SRui Ueyama 448b8a59c8aSBob Haarman while (!errorCount() && !consume(";")) { 449b579c439SRui Ueyama if (consume("FILEHDR")) 4500ae2c24cSRui Ueyama Cmd.HasFilehdr = true; 451b579c439SRui Ueyama else if (consume("PHDRS")) 4520ae2c24cSRui Ueyama Cmd.HasPhdrs = true; 453b579c439SRui Ueyama else if (consume("AT")) 4540ae2c24cSRui Ueyama Cmd.LMAExpr = readParenExpr(); 455b579c439SRui Ueyama else if (consume("FLAGS")) 4560ae2c24cSRui Ueyama Cmd.Flags = readParenExpr()().getValue(); 457b579c439SRui Ueyama else 458b579c439SRui Ueyama setError("unexpected header attribute: " + next()); 459b579c439SRui Ueyama } 4600ae2c24cSRui Ueyama 461ac27de9dSRui Ueyama Script->PhdrsCommands.push_back(Cmd); 4622ec34544SRui Ueyama } 4632ec34544SRui Ueyama } 4642ec34544SRui Ueyama 4655f37541cSGeorge Rimar void ScriptParser::readRegionAlias() { 4665f37541cSGeorge Rimar expect("("); 4675f37541cSGeorge Rimar StringRef Alias = unquote(next()); 4685f37541cSGeorge Rimar expect(","); 4695f37541cSGeorge Rimar StringRef Name = next(); 4705f37541cSGeorge Rimar expect(")"); 4715f37541cSGeorge Rimar 472ac27de9dSRui Ueyama if (Script->MemoryRegions.count(Alias)) 4735f37541cSGeorge Rimar setError("redefinition of memory region '" + Alias + "'"); 474ac27de9dSRui Ueyama if (!Script->MemoryRegions.count(Name)) 4755f37541cSGeorge Rimar setError("memory region '" + Name + "' is not defined"); 4768c825db2SGeorge Rimar Script->MemoryRegions.insert({Alias, Script->MemoryRegions[Name]}); 4775f37541cSGeorge Rimar } 4785f37541cSGeorge Rimar 4792ec34544SRui Ueyama void ScriptParser::readSearchDir() { 4802ec34544SRui Ueyama expect("("); 4812ec34544SRui Ueyama StringRef Tok = next(); 4822ec34544SRui Ueyama if (!Config->Nostdlib) 4832ec34544SRui Ueyama Config->SearchPaths.push_back(unquote(Tok)); 4842ec34544SRui Ueyama expect(")"); 4852ec34544SRui Ueyama } 4862ec34544SRui Ueyama 487a582419aSGeorge Rimar // This reads an overlay description. Overlays are used to describe output 488a582419aSGeorge Rimar // sections that use the same virtual memory range and normally would trigger 489a582419aSGeorge Rimar // linker's sections sanity check failures. 490a582419aSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Overlay-Description.html#Overlay-Description 491a582419aSGeorge Rimar std::vector<BaseCommand *> ScriptParser::readOverlay() { 492a582419aSGeorge Rimar // VA and LMA expressions are optional, though for simplicity of 493a582419aSGeorge Rimar // implementation we assume they are not. That is what OVERLAY was designed 494a582419aSGeorge Rimar // for first of all: to allow sections with overlapping VAs at different LMAs. 495a582419aSGeorge Rimar Expr AddrExpr = readExpr(); 496a582419aSGeorge Rimar expect(":"); 497a582419aSGeorge Rimar expect("AT"); 498a582419aSGeorge Rimar Expr LMAExpr = readParenExpr(); 499a582419aSGeorge Rimar expect("{"); 500a582419aSGeorge Rimar 501a582419aSGeorge Rimar std::vector<BaseCommand *> V; 502a582419aSGeorge Rimar OutputSection *Prev = nullptr; 503a582419aSGeorge Rimar while (!errorCount() && !consume("}")) { 504a582419aSGeorge Rimar // VA is the same for all sections. The LMAs are consecutive in memory 505a582419aSGeorge Rimar // starting from the base load address specified. 506a582419aSGeorge Rimar OutputSection *OS = readOverlaySectionDescription(); 507a582419aSGeorge Rimar OS->AddrExpr = AddrExpr; 508a582419aSGeorge Rimar if (Prev) 509a582419aSGeorge Rimar OS->LMAExpr = [=] { return Prev->getLMA() + Prev->Size; }; 510a582419aSGeorge Rimar else 511a582419aSGeorge Rimar OS->LMAExpr = LMAExpr; 512a582419aSGeorge Rimar V.push_back(OS); 513a582419aSGeorge Rimar Prev = OS; 514a582419aSGeorge Rimar } 515a582419aSGeorge Rimar 516a582419aSGeorge Rimar // According to the specification, at the end of the overlay, the location 517a582419aSGeorge Rimar // counter should be equal to the overlay base address plus size of the 518a582419aSGeorge Rimar // largest section seen in the overlay. 519a582419aSGeorge Rimar // Here we want to create the Dot assignment command to achieve that. 520a582419aSGeorge Rimar Expr MoveDot = [=] { 521a582419aSGeorge Rimar uint64_t Max = 0; 522a582419aSGeorge Rimar for (BaseCommand *Cmd : V) 523a582419aSGeorge Rimar Max = std::max(Max, cast<OutputSection>(Cmd)->Size); 524a582419aSGeorge Rimar return AddrExpr().getValue() + Max; 525a582419aSGeorge Rimar }; 526a582419aSGeorge Rimar V.push_back(make<SymbolAssignment>(".", MoveDot, getCurrentLocation())); 527a582419aSGeorge Rimar return V; 528a582419aSGeorge Rimar } 529a582419aSGeorge Rimar 5302ec34544SRui Ueyama void ScriptParser::readSections() { 531a323e2a7SRui Ueyama Script->HasSectionsCommand = true; 532b579c439SRui Ueyama 5332ec34544SRui Ueyama // -no-rosegment is used to avoid placing read only non-executable sections in 5342ec34544SRui Ueyama // their own segment. We do the same if SECTIONS command is present in linker 5352ec34544SRui Ueyama // script. See comment for computeFlags(). 5362ec34544SRui Ueyama Config->SingleRoRx = true; 5372ec34544SRui Ueyama 5382ec34544SRui Ueyama expect("{"); 5399e2c8a9dSGeorge Rimar std::vector<BaseCommand *> V; 540b8a59c8aSBob Haarman while (!errorCount() && !consume("}")) { 5412ec34544SRui Ueyama StringRef Tok = next(); 542a582419aSGeorge Rimar if (Tok == "OVERLAY") { 543a582419aSGeorge Rimar for (BaseCommand *Cmd : readOverlay()) 544a582419aSGeorge Rimar V.push_back(Cmd); 545a582419aSGeorge Rimar continue; 5462e9d40d5SRui Ueyama } else if (Tok == "INCLUDE") { 5472e9d40d5SRui Ueyama readInclude(); 5482e9d40d5SRui Ueyama continue; 549a582419aSGeorge Rimar } 550a582419aSGeorge Rimar 551d30a78b3SGeorge Rimar if (BaseCommand *Cmd = readAssignment(Tok)) 5529e2c8a9dSGeorge Rimar V.push_back(Cmd); 553d30a78b3SGeorge Rimar else 554d30a78b3SGeorge Rimar V.push_back(readOutputSectionDescription(Tok)); 5552ec34544SRui Ueyama } 5569e2c8a9dSGeorge Rimar 5579e2c8a9dSGeorge Rimar if (!atEOF() && consume("INSERT")) { 558796684b4SGeorge Rimar std::vector<BaseCommand *> *Dest = nullptr; 559796684b4SGeorge Rimar if (consume("AFTER")) 560796684b4SGeorge Rimar Dest = &Script->InsertAfterCommands[next()]; 561796684b4SGeorge Rimar else if (consume("BEFORE")) 562796684b4SGeorge Rimar Dest = &Script->InsertBeforeCommands[next()]; 563796684b4SGeorge Rimar else 564796684b4SGeorge Rimar setError("expected AFTER/BEFORE, but got '" + next() + "'"); 565796684b4SGeorge Rimar if (Dest) 566796684b4SGeorge Rimar Dest->insert(Dest->end(), V.begin(), V.end()); 5679e2c8a9dSGeorge Rimar return; 5689e2c8a9dSGeorge Rimar } 5699e2c8a9dSGeorge Rimar 5709e2c8a9dSGeorge Rimar Script->SectionCommands.insert(Script->SectionCommands.end(), V.begin(), 5719e2c8a9dSGeorge Rimar V.end()); 5722ec34544SRui Ueyama } 5732ec34544SRui Ueyama 574e262bb1aSRui Ueyama void ScriptParser::readTarget() { 575e262bb1aSRui Ueyama // TARGET(foo) is an alias for "--format foo". Unlike GNU linkers, 576e262bb1aSRui Ueyama // we accept only a limited set of BFD names (i.e. "elf" or "binary") 577e262bb1aSRui Ueyama // for --format. We recognize only /^elf/ and "binary" in the linker 578e262bb1aSRui Ueyama // script as well. 579e262bb1aSRui Ueyama expect("("); 580e262bb1aSRui Ueyama StringRef Tok = next(); 581e262bb1aSRui Ueyama expect(")"); 582e262bb1aSRui Ueyama 583e262bb1aSRui Ueyama if (Tok.startswith("elf")) 584e262bb1aSRui Ueyama Config->FormatBinary = false; 585e262bb1aSRui Ueyama else if (Tok == "binary") 586e262bb1aSRui Ueyama Config->FormatBinary = true; 587e262bb1aSRui Ueyama else 588e262bb1aSRui Ueyama setError("unknown target: " + Tok); 589e262bb1aSRui Ueyama } 590e262bb1aSRui Ueyama 5912ec34544SRui Ueyama static int precedence(StringRef Op) { 5922ec34544SRui Ueyama return StringSwitch<int>(Op) 593a5005482SGeorge Rimar .Cases("*", "/", "%", 8) 594a5005482SGeorge Rimar .Cases("+", "-", 7) 595a5005482SGeorge Rimar .Cases("<<", ">>", 6) 596a5005482SGeorge Rimar .Cases("<", "<=", ">", ">=", "==", "!=", 5) 597a5005482SGeorge Rimar .Case("&", 4) 598a5005482SGeorge Rimar .Case("|", 3) 599a5005482SGeorge Rimar .Case("&&", 2) 600a5005482SGeorge Rimar .Case("||", 1) 6012ec34544SRui Ueyama .Default(-1); 6022ec34544SRui Ueyama } 6032ec34544SRui Ueyama 6042ec34544SRui Ueyama StringMatcher ScriptParser::readFilePatterns() { 6052ec34544SRui Ueyama std::vector<StringRef> V; 606b8a59c8aSBob Haarman while (!errorCount() && !consume(")")) 6072ec34544SRui Ueyama V.push_back(next()); 6082ec34544SRui Ueyama return StringMatcher(V); 6092ec34544SRui Ueyama } 6102ec34544SRui Ueyama 6112ec34544SRui Ueyama SortSectionPolicy ScriptParser::readSortKind() { 6122ec34544SRui Ueyama if (consume("SORT") || consume("SORT_BY_NAME")) 6132ec34544SRui Ueyama return SortSectionPolicy::Name; 6142ec34544SRui Ueyama if (consume("SORT_BY_ALIGNMENT")) 6152ec34544SRui Ueyama return SortSectionPolicy::Alignment; 6162ec34544SRui Ueyama if (consume("SORT_BY_INIT_PRIORITY")) 6172ec34544SRui Ueyama return SortSectionPolicy::Priority; 6182ec34544SRui Ueyama if (consume("SORT_NONE")) 6192ec34544SRui Ueyama return SortSectionPolicy::None; 6202ec34544SRui Ueyama return SortSectionPolicy::Default; 6212ec34544SRui Ueyama } 6222ec34544SRui Ueyama 62303fc8d1eSRui Ueyama // Reads SECTIONS command contents in the following form: 62403fc8d1eSRui Ueyama // 62503fc8d1eSRui Ueyama // <contents> ::= <elem>* 62603fc8d1eSRui Ueyama // <elem> ::= <exclude>? <glob-pattern> 62703fc8d1eSRui Ueyama // <exclude> ::= "EXCLUDE_FILE" "(" <glob-pattern>+ ")" 62803fc8d1eSRui Ueyama // 62903fc8d1eSRui Ueyama // For example, 63003fc8d1eSRui Ueyama // 63103fc8d1eSRui Ueyama // *(.foo EXCLUDE_FILE (a.o) .bar EXCLUDE_FILE (b.o) .baz) 63203fc8d1eSRui Ueyama // 63303fc8d1eSRui Ueyama // is parsed as ".foo", ".bar" with "a.o", and ".baz" with "b.o". 63403fc8d1eSRui Ueyama // The semantics of that is section .foo in any file, section .bar in 63503fc8d1eSRui Ueyama // any file but a.o, and section .baz in any file but b.o. 6362ec34544SRui Ueyama std::vector<SectionPattern> ScriptParser::readInputSectionsList() { 6372ec34544SRui Ueyama std::vector<SectionPattern> Ret; 638b8a59c8aSBob Haarman while (!errorCount() && peek() != ")") { 6392ec34544SRui Ueyama StringMatcher ExcludeFilePat; 6402ec34544SRui Ueyama if (consume("EXCLUDE_FILE")) { 6412ec34544SRui Ueyama expect("("); 6422ec34544SRui Ueyama ExcludeFilePat = readFilePatterns(); 6432ec34544SRui Ueyama } 6442ec34544SRui Ueyama 6452ec34544SRui Ueyama std::vector<StringRef> V; 646b8a59c8aSBob Haarman while (!errorCount() && peek() != ")" && peek() != "EXCLUDE_FILE") 6472ec34544SRui Ueyama V.push_back(next()); 6482ec34544SRui Ueyama 6492ec34544SRui Ueyama if (!V.empty()) 6502ec34544SRui Ueyama Ret.push_back({std::move(ExcludeFilePat), StringMatcher(V)}); 6512ec34544SRui Ueyama else 6522ec34544SRui Ueyama setError("section pattern is expected"); 6532ec34544SRui Ueyama } 6542ec34544SRui Ueyama return Ret; 6552ec34544SRui Ueyama } 6562ec34544SRui Ueyama 6572ec34544SRui Ueyama // Reads contents of "SECTIONS" directive. That directive contains a 6582ec34544SRui Ueyama // list of glob patterns for input sections. The grammar is as follows. 6592ec34544SRui Ueyama // 6602ec34544SRui Ueyama // <patterns> ::= <section-list> 6612ec34544SRui Ueyama // | <sort> "(" <section-list> ")" 6622ec34544SRui Ueyama // | <sort> "(" <sort> "(" <section-list> ")" ")" 6632ec34544SRui Ueyama // 6642ec34544SRui Ueyama // <sort> ::= "SORT" | "SORT_BY_NAME" | "SORT_BY_ALIGNMENT" 6652ec34544SRui Ueyama // | "SORT_BY_INIT_PRIORITY" | "SORT_NONE" 6662ec34544SRui Ueyama // 6672ec34544SRui Ueyama // <section-list> is parsed by readInputSectionsList(). 6682ec34544SRui Ueyama InputSectionDescription * 6692ec34544SRui Ueyama ScriptParser::readInputSectionRules(StringRef FilePattern) { 6702ec34544SRui Ueyama auto *Cmd = make<InputSectionDescription>(FilePattern); 6712ec34544SRui Ueyama expect("("); 6722ec34544SRui Ueyama 673b8a59c8aSBob Haarman while (!errorCount() && !consume(")")) { 6742ec34544SRui Ueyama SortSectionPolicy Outer = readSortKind(); 6752ec34544SRui Ueyama SortSectionPolicy Inner = SortSectionPolicy::Default; 6762ec34544SRui Ueyama std::vector<SectionPattern> V; 6772ec34544SRui Ueyama if (Outer != SortSectionPolicy::Default) { 6782ec34544SRui Ueyama expect("("); 6792ec34544SRui Ueyama Inner = readSortKind(); 6802ec34544SRui Ueyama if (Inner != SortSectionPolicy::Default) { 6812ec34544SRui Ueyama expect("("); 6822ec34544SRui Ueyama V = readInputSectionsList(); 6832ec34544SRui Ueyama expect(")"); 6842ec34544SRui Ueyama } else { 6852ec34544SRui Ueyama V = readInputSectionsList(); 6862ec34544SRui Ueyama } 6872ec34544SRui Ueyama expect(")"); 6882ec34544SRui Ueyama } else { 6892ec34544SRui Ueyama V = readInputSectionsList(); 6902ec34544SRui Ueyama } 6912ec34544SRui Ueyama 6922ec34544SRui Ueyama for (SectionPattern &Pat : V) { 6932ec34544SRui Ueyama Pat.SortInner = Inner; 6942ec34544SRui Ueyama Pat.SortOuter = Outer; 6952ec34544SRui Ueyama } 6962ec34544SRui Ueyama 6972ec34544SRui Ueyama std::move(V.begin(), V.end(), std::back_inserter(Cmd->SectionPatterns)); 6982ec34544SRui Ueyama } 6992ec34544SRui Ueyama return Cmd; 7002ec34544SRui Ueyama } 7012ec34544SRui Ueyama 7022ec34544SRui Ueyama InputSectionDescription * 7032ec34544SRui Ueyama ScriptParser::readInputSectionDescription(StringRef Tok) { 7042ec34544SRui Ueyama // Input section wildcard can be surrounded by KEEP. 7052ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep 7062ec34544SRui Ueyama if (Tok == "KEEP") { 7072ec34544SRui Ueyama expect("("); 7082ec34544SRui Ueyama StringRef FilePattern = next(); 7092ec34544SRui Ueyama InputSectionDescription *Cmd = readInputSectionRules(FilePattern); 7102ec34544SRui Ueyama expect(")"); 711ac27de9dSRui Ueyama Script->KeptSections.push_back(Cmd); 7122ec34544SRui Ueyama return Cmd; 7132ec34544SRui Ueyama } 7142ec34544SRui Ueyama return readInputSectionRules(Tok); 7152ec34544SRui Ueyama } 7162ec34544SRui Ueyama 7172ec34544SRui Ueyama void ScriptParser::readSort() { 7182ec34544SRui Ueyama expect("("); 7192ec34544SRui Ueyama expect("CONSTRUCTORS"); 7202ec34544SRui Ueyama expect(")"); 7212ec34544SRui Ueyama } 7222ec34544SRui Ueyama 723d30a78b3SGeorge Rimar Expr ScriptParser::readAssert() { 7242ec34544SRui Ueyama expect("("); 7252ec34544SRui Ueyama Expr E = readExpr(); 7262ec34544SRui Ueyama expect(","); 7272ec34544SRui Ueyama StringRef Msg = unquote(next()); 7282ec34544SRui Ueyama expect(")"); 729b579c439SRui Ueyama 7302ec34544SRui Ueyama return [=] { 7312ec34544SRui Ueyama if (!E().getValue()) 7322ec34544SRui Ueyama error(Msg); 7332ec34544SRui Ueyama return Script->getDot(); 7342ec34544SRui Ueyama }; 7352ec34544SRui Ueyama } 7362ec34544SRui Ueyama 7372ec34544SRui Ueyama // Reads a FILL(expr) command. We handle the FILL command as an 7382ec34544SRui Ueyama // alias for =fillexp section attribute, which is different from 7392ec34544SRui Ueyama // what GNU linkers do. 7402ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Data.html 741b0486051SSimon Atanasyan std::array<uint8_t, 4> ScriptParser::readFill() { 7422ec34544SRui Ueyama expect("("); 743b0486051SSimon Atanasyan std::array<uint8_t, 4> V = parseFill(next()); 7442ec34544SRui Ueyama expect(")"); 7452ec34544SRui Ueyama return V; 7462ec34544SRui Ueyama } 7472ec34544SRui Ueyama 748a46d08ebSGeorge Rimar // Tries to read the special directive for an output section definition which 749a46d08ebSGeorge Rimar // can be one of following: "(NOLOAD)", "(COPY)", "(INFO)" or "(OVERLAY)". 750a46d08ebSGeorge Rimar // Tok1 and Tok2 are next 2 tokens peeked. See comment for readSectionAddressType below. 751a46d08ebSGeorge Rimar bool ScriptParser::readSectionDirective(OutputSection *Cmd, StringRef Tok1, StringRef Tok2) { 752a46d08ebSGeorge Rimar if (Tok1 != "(") 753a46d08ebSGeorge Rimar return false; 754a46d08ebSGeorge Rimar if (Tok2 != "NOLOAD" && Tok2 != "COPY" && Tok2 != "INFO" && Tok2 != "OVERLAY") 755a46d08ebSGeorge Rimar return false; 756a46d08ebSGeorge Rimar 757a46d08ebSGeorge Rimar expect("("); 758a46d08ebSGeorge Rimar if (consume("NOLOAD")) { 759a46d08ebSGeorge Rimar Cmd->Noload = true; 760a46d08ebSGeorge Rimar } else { 761a46d08ebSGeorge Rimar skip(); // This is "COPY", "INFO" or "OVERLAY". 762a46d08ebSGeorge Rimar Cmd->NonAlloc = true; 763a46d08ebSGeorge Rimar } 764a46d08ebSGeorge Rimar expect(")"); 765a46d08ebSGeorge Rimar return true; 766a46d08ebSGeorge Rimar } 767a46d08ebSGeorge Rimar 7681c08e9f5SGeorge Rimar // Reads an expression and/or the special directive for an output 7691c08e9f5SGeorge Rimar // section definition. Directive is one of following: "(NOLOAD)", 7701c08e9f5SGeorge Rimar // "(COPY)", "(INFO)" or "(OVERLAY)". 7713271d370SRui Ueyama // 7723271d370SRui Ueyama // An output section name can be followed by an address expression 7731c08e9f5SGeorge Rimar // and/or directive. This grammar is not LL(1) because "(" can be 77497f4d158SGeorge Rimar // interpreted as either the beginning of some expression or beginning 7751c08e9f5SGeorge Rimar // of directive. 7763271d370SRui Ueyama // 777b579c439SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html 778fbb0463fSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Output-Section-Type.html 7798c022ca7SRafael Espindola void ScriptParser::readSectionAddressType(OutputSection *Cmd) { 780a46d08ebSGeorge Rimar if (readSectionDirective(Cmd, peek(), peek2())) 7813271d370SRui Ueyama return; 7823271d370SRui Ueyama 783a46d08ebSGeorge Rimar Cmd->AddrExpr = readExpr(); 784a46d08ebSGeorge Rimar if (peek() == "(" && !readSectionDirective(Cmd, "(", peek2())) 785a46d08ebSGeorge Rimar setError("unknown section directive: " + peek2()); 786fbb0463fSGeorge Rimar } 787fbb0463fSGeorge Rimar 788f22ec9ddSGeorge Rimar static Expr checkAlignment(Expr E, std::string &Loc) { 789f22ec9ddSGeorge Rimar return [=] { 790f22ec9ddSGeorge Rimar uint64_t Alignment = std::max((uint64_t)1, E().getValue()); 791f22ec9ddSGeorge Rimar if (!isPowerOf2_64(Alignment)) { 792f22ec9ddSGeorge Rimar error(Loc + ": alignment must be power of 2"); 793f22ec9ddSGeorge Rimar return (uint64_t)1; // Return a dummy value. 794f22ec9ddSGeorge Rimar } 795f22ec9ddSGeorge Rimar return Alignment; 796f22ec9ddSGeorge Rimar }; 797f22ec9ddSGeorge Rimar } 798f22ec9ddSGeorge Rimar 799a582419aSGeorge Rimar OutputSection *ScriptParser::readOverlaySectionDescription() { 800a582419aSGeorge Rimar OutputSection *Cmd = 801a582419aSGeorge Rimar Script->createOutputSection(next(), getCurrentLocation()); 802a582419aSGeorge Rimar Cmd->InOverlay = true; 803a582419aSGeorge Rimar expect("{"); 804a582419aSGeorge Rimar while (!errorCount() && !consume("}")) 805a582419aSGeorge Rimar Cmd->SectionCommands.push_back(readInputSectionRules(next())); 806a582419aSGeorge Rimar Cmd->Phdrs = readOutputSectionPhdrs(); 807a582419aSGeorge Rimar return Cmd; 808a582419aSGeorge Rimar } 809a582419aSGeorge Rimar 8108c022ca7SRafael Espindola OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) { 8118c022ca7SRafael Espindola OutputSection *Cmd = 8128c022ca7SRafael Espindola Script->createOutputSection(OutSec, getCurrentLocation()); 8133271d370SRui Ueyama 814c4df670dSGeorge Rimar size_t SymbolsReferenced = Script->ReferencedSymbols.size(); 815c4df670dSGeorge Rimar 8163271d370SRui Ueyama if (peek() != ":") 8173271d370SRui Ueyama readSectionAddressType(Cmd); 8182ec34544SRui Ueyama expect(":"); 8192ec34544SRui Ueyama 820f22ec9ddSGeorge Rimar std::string Location = getCurrentLocation(); 8212ec34544SRui Ueyama if (consume("AT")) 8222ec34544SRui Ueyama Cmd->LMAExpr = readParenExpr(); 8232ec34544SRui Ueyama if (consume("ALIGN")) 824f22ec9ddSGeorge Rimar Cmd->AlignExpr = checkAlignment(readParenExpr(), Location); 8252ec34544SRui Ueyama if (consume("SUBALIGN")) 826f22ec9ddSGeorge Rimar Cmd->SubalignExpr = checkAlignment(readParenExpr(), Location); 8272ec34544SRui Ueyama 8282ec34544SRui Ueyama // Parse constraints. 8292ec34544SRui Ueyama if (consume("ONLY_IF_RO")) 8302ec34544SRui Ueyama Cmd->Constraint = ConstraintKind::ReadOnly; 8312ec34544SRui Ueyama if (consume("ONLY_IF_RW")) 8322ec34544SRui Ueyama Cmd->Constraint = ConstraintKind::ReadWrite; 8332ec34544SRui Ueyama expect("{"); 8342ec34544SRui Ueyama 835b8a59c8aSBob Haarman while (!errorCount() && !consume("}")) { 8362ec34544SRui Ueyama StringRef Tok = next(); 8372ec34544SRui Ueyama if (Tok == ";") { 8382ec34544SRui Ueyama // Empty commands are allowed. Do nothing here. 839d30a78b3SGeorge Rimar } else if (SymbolAssignment *Assign = readAssignment(Tok)) { 8406b394caaSRui Ueyama Cmd->SectionCommands.push_back(Assign); 841f0403c60SRui Ueyama } else if (ByteCommand *Data = readByteCommand(Tok)) { 8426b394caaSRui Ueyama Cmd->SectionCommands.push_back(Data); 8432ec34544SRui Ueyama } else if (Tok == "CONSTRUCTORS") { 8442ec34544SRui Ueyama // CONSTRUCTORS is a keyword to make the linker recognize C++ ctors/dtors 8452ec34544SRui Ueyama // by name. This is for very old file formats such as ECOFF/XCOFF. 8462ec34544SRui Ueyama // For ELF, we should ignore. 8472ec34544SRui Ueyama } else if (Tok == "FILL") { 8482ec34544SRui Ueyama Cmd->Filler = readFill(); 8492ec34544SRui Ueyama } else if (Tok == "SORT") { 8502ec34544SRui Ueyama readSort(); 8512e9d40d5SRui Ueyama } else if (Tok == "INCLUDE") { 8522e9d40d5SRui Ueyama readInclude(); 8532ec34544SRui Ueyama } else if (peek() == "(") { 8546b394caaSRui Ueyama Cmd->SectionCommands.push_back(readInputSectionDescription(Tok)); 8552ec34544SRui Ueyama } else { 856f49fe218SGeorge Rimar // We have a file name and no input sections description. It is not a 857f49fe218SGeorge Rimar // commonly used syntax, but still acceptable. In that case, all sections 858f49fe218SGeorge Rimar // from the file will be included. 859e1fd3f94SGeorge Rimar auto *ISD = make<InputSectionDescription>(Tok); 860f49fe218SGeorge Rimar ISD->SectionPatterns.push_back({{}, StringMatcher({"*"})}); 861f49fe218SGeorge Rimar Cmd->SectionCommands.push_back(ISD); 8622ec34544SRui Ueyama } 8632ec34544SRui Ueyama } 8642ec34544SRui Ueyama 8652ec34544SRui Ueyama if (consume(">")) 8662ec34544SRui Ueyama Cmd->MemoryRegionName = next(); 8672ec34544SRui Ueyama 8685d01a8beSGeorge Rimar if (consume("AT")) { 8695d01a8beSGeorge Rimar expect(">"); 8705d01a8beSGeorge Rimar Cmd->LMARegionName = next(); 8715d01a8beSGeorge Rimar } 8725d01a8beSGeorge Rimar 8735d01a8beSGeorge Rimar if (Cmd->LMAExpr && !Cmd->LMARegionName.empty()) 8745d01a8beSGeorge Rimar error("section can't have both LMA and a load region"); 8755d01a8beSGeorge Rimar 8762ec34544SRui Ueyama Cmd->Phdrs = readOutputSectionPhdrs(); 8772ec34544SRui Ueyama 8782ec34544SRui Ueyama if (consume("=")) 8798acbf1ccSRui Ueyama Cmd->Filler = parseFill(next()); 8802ec34544SRui Ueyama else if (peek().startswith("=")) 8818acbf1ccSRui Ueyama Cmd->Filler = parseFill(next().drop_front()); 8822ec34544SRui Ueyama 8832ec34544SRui Ueyama // Consume optional comma following output section command. 8842ec34544SRui Ueyama consume(","); 8852ec34544SRui Ueyama 886c4df670dSGeorge Rimar if (Script->ReferencedSymbols.size() > SymbolsReferenced) 887c4df670dSGeorge Rimar Cmd->ExpressionsUseSymbols = true; 8882ec34544SRui Ueyama return Cmd; 8892ec34544SRui Ueyama } 8902ec34544SRui Ueyama 8918acbf1ccSRui Ueyama // Parses a given string as a octal/decimal/hexadecimal number and 8928acbf1ccSRui Ueyama // returns it as a big-endian number. Used for `=<fillexp>`. 8932ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html 8942ec34544SRui Ueyama // 8958acbf1ccSRui Ueyama // When reading a hexstring, ld.bfd handles it as a blob of arbitrary 8968acbf1ccSRui Ueyama // size, while ld.gold always handles it as a 32-bit big-endian number. 8978acbf1ccSRui Ueyama // We are compatible with ld.gold because it's easier to implement. 898b0486051SSimon Atanasyan std::array<uint8_t, 4> ScriptParser::parseFill(StringRef Tok) { 899b58079d4SRui Ueyama uint32_t V = 0; 900ab94768cSGeorge Rimar if (!to_integer(Tok, V)) 9012ec34544SRui Ueyama setError("invalid filler expression: " + Tok); 902b58079d4SRui Ueyama 903b0486051SSimon Atanasyan std::array<uint8_t, 4> Buf; 904b0486051SSimon Atanasyan write32be(Buf.data(), V); 905b58079d4SRui Ueyama return Buf; 9062ec34544SRui Ueyama } 9072ec34544SRui Ueyama 9082ec34544SRui Ueyama SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) { 9092ec34544SRui Ueyama expect("("); 910d30a78b3SGeorge Rimar SymbolAssignment *Cmd = readSymbolAssignment(next()); 9112ec34544SRui Ueyama Cmd->Provide = Provide; 9122ec34544SRui Ueyama Cmd->Hidden = Hidden; 9132ec34544SRui Ueyama expect(")"); 9142ec34544SRui Ueyama return Cmd; 9152ec34544SRui Ueyama } 9162ec34544SRui Ueyama 917d30a78b3SGeorge Rimar SymbolAssignment *ScriptParser::readAssignment(StringRef Tok) { 918d30a78b3SGeorge Rimar // Assert expression returns Dot, so this is equal to ".=." 919d30a78b3SGeorge Rimar if (Tok == "ASSERT") 920d30a78b3SGeorge Rimar return make<SymbolAssignment>(".", readAssert(), getCurrentLocation()); 921d30a78b3SGeorge Rimar 922e88b76a9SGeorge Rimar size_t OldPos = Pos; 9232ec34544SRui Ueyama SymbolAssignment *Cmd = nullptr; 924e88b76a9SGeorge Rimar if (peek() == "=" || peek() == "+=") 925d30a78b3SGeorge Rimar Cmd = readSymbolAssignment(Tok); 926e88b76a9SGeorge Rimar else if (Tok == "PROVIDE") 9272ec34544SRui Ueyama Cmd = readProvideHidden(true, false); 928e88b76a9SGeorge Rimar else if (Tok == "HIDDEN") 9292ec34544SRui Ueyama Cmd = readProvideHidden(false, true); 930e88b76a9SGeorge Rimar else if (Tok == "PROVIDE_HIDDEN") 9312ec34544SRui Ueyama Cmd = readProvideHidden(true, true); 932e88b76a9SGeorge Rimar 933e88b76a9SGeorge Rimar if (Cmd) { 934e88b76a9SGeorge Rimar Cmd->CommandString = 935e88b76a9SGeorge Rimar Tok.str() + " " + 936e88b76a9SGeorge Rimar llvm::join(Tokens.begin() + OldPos, Tokens.begin() + Pos, " "); 937e88b76a9SGeorge Rimar expect(";"); 9382ec34544SRui Ueyama } 9392ec34544SRui Ueyama return Cmd; 9402ec34544SRui Ueyama } 9412ec34544SRui Ueyama 942d30a78b3SGeorge Rimar SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef Name) { 9432ec34544SRui Ueyama StringRef Op = next(); 9442ec34544SRui Ueyama assert(Op == "=" || Op == "+="); 9452ec34544SRui Ueyama Expr E = readExpr(); 9462ec34544SRui Ueyama if (Op == "+=") { 9472ec34544SRui Ueyama std::string Loc = getCurrentLocation(); 948722221f5SRui Ueyama E = [=] { return add(Script->getSymbolValue(Name, Loc), E()); }; 9492ec34544SRui Ueyama } 950e88b76a9SGeorge Rimar return make<SymbolAssignment>(Name, E, getCurrentLocation()); 9512ec34544SRui Ueyama } 9522ec34544SRui Ueyama 9532ec34544SRui Ueyama // This is an operator-precedence parser to parse a linker 9542ec34544SRui Ueyama // script expression. 9552ec34544SRui Ueyama Expr ScriptParser::readExpr() { 9562ec34544SRui Ueyama // Our lexer is context-aware. Set the in-expression bit so that 9572ec34544SRui Ueyama // they apply different tokenization rules. 9582ec34544SRui Ueyama bool Orig = InExpr; 9592ec34544SRui Ueyama InExpr = true; 9602ec34544SRui Ueyama Expr E = readExpr1(readPrimary(), 0); 9612ec34544SRui Ueyama InExpr = Orig; 9622ec34544SRui Ueyama return E; 9632ec34544SRui Ueyama } 9642ec34544SRui Ueyama 9657b91e213SGeorge Rimar Expr ScriptParser::combine(StringRef Op, Expr L, Expr R) { 9662ec34544SRui Ueyama if (Op == "+") 9672ec34544SRui Ueyama return [=] { return add(L(), R()); }; 9682ec34544SRui Ueyama if (Op == "-") 9692ec34544SRui Ueyama return [=] { return sub(L(), R()); }; 970b579c439SRui Ueyama if (Op == "*") 9711d20222aSRui Ueyama return [=] { return L().getValue() * R().getValue(); }; 9727b91e213SGeorge Rimar if (Op == "/") { 9737b91e213SGeorge Rimar std::string Loc = getCurrentLocation(); 9747b91e213SGeorge Rimar return [=]() -> uint64_t { 9757b91e213SGeorge Rimar if (uint64_t RV = R().getValue()) 9767b91e213SGeorge Rimar return L().getValue() / RV; 9777b91e213SGeorge Rimar error(Loc + ": division by zero"); 978067617f9SRui Ueyama return 0; 9797b91e213SGeorge Rimar }; 9807b91e213SGeorge Rimar } 9817b91e213SGeorge Rimar if (Op == "%") { 9827b91e213SGeorge Rimar std::string Loc = getCurrentLocation(); 9837b91e213SGeorge Rimar return [=]() -> uint64_t { 9847b91e213SGeorge Rimar if (uint64_t RV = R().getValue()) 9857b91e213SGeorge Rimar return L().getValue() % RV; 9867b91e213SGeorge Rimar error(Loc + ": modulo by zero"); 987067617f9SRui Ueyama return 0; 9887b91e213SGeorge Rimar }; 9897b91e213SGeorge Rimar } 9902ec34544SRui Ueyama if (Op == "<<") 9917e915511SRui Ueyama return [=] { return L().getValue() << R().getValue(); }; 9922ec34544SRui Ueyama if (Op == ">>") 9937e915511SRui Ueyama return [=] { return L().getValue() >> R().getValue(); }; 9942ec34544SRui Ueyama if (Op == "<") 9952ec34544SRui Ueyama return [=] { return L().getValue() < R().getValue(); }; 9962ec34544SRui Ueyama if (Op == ">") 9972ec34544SRui Ueyama return [=] { return L().getValue() > R().getValue(); }; 9982ec34544SRui Ueyama if (Op == ">=") 9992ec34544SRui Ueyama return [=] { return L().getValue() >= R().getValue(); }; 10002ec34544SRui Ueyama if (Op == "<=") 10012ec34544SRui Ueyama return [=] { return L().getValue() <= R().getValue(); }; 10022ec34544SRui Ueyama if (Op == "==") 10032ec34544SRui Ueyama return [=] { return L().getValue() == R().getValue(); }; 10042ec34544SRui Ueyama if (Op == "!=") 10052ec34544SRui Ueyama return [=] { return L().getValue() != R().getValue(); }; 1006a5005482SGeorge Rimar if (Op == "||") 1007a5005482SGeorge Rimar return [=] { return L().getValue() || R().getValue(); }; 1008a5005482SGeorge Rimar if (Op == "&&") 1009a5005482SGeorge Rimar return [=] { return L().getValue() && R().getValue(); }; 10102ec34544SRui Ueyama if (Op == "&") 10112ec34544SRui Ueyama return [=] { return bitAnd(L(), R()); }; 10122ec34544SRui Ueyama if (Op == "|") 10132ec34544SRui Ueyama return [=] { return bitOr(L(), R()); }; 10142ec34544SRui Ueyama llvm_unreachable("invalid operator"); 10152ec34544SRui Ueyama } 10162ec34544SRui Ueyama 10172ec34544SRui Ueyama // This is a part of the operator-precedence parser. This function 10182ec34544SRui Ueyama // assumes that the remaining token stream starts with an operator. 10192ec34544SRui Ueyama Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) { 1020b8a59c8aSBob Haarman while (!atEOF() && !errorCount()) { 10212ec34544SRui Ueyama // Read an operator and an expression. 10222ec34544SRui Ueyama if (consume("?")) 10232ec34544SRui Ueyama return readTernary(Lhs); 10242ec34544SRui Ueyama StringRef Op1 = peek(); 10252ec34544SRui Ueyama if (precedence(Op1) < MinPrec) 10262ec34544SRui Ueyama break; 10272ec34544SRui Ueyama skip(); 10282ec34544SRui Ueyama Expr Rhs = readPrimary(); 10292ec34544SRui Ueyama 10302ec34544SRui Ueyama // Evaluate the remaining part of the expression first if the 10312ec34544SRui Ueyama // next operator has greater precedence than the previous one. 10322ec34544SRui Ueyama // For example, if we have read "+" and "3", and if the next 10332ec34544SRui Ueyama // operator is "*", then we'll evaluate 3 * ... part first. 10342ec34544SRui Ueyama while (!atEOF()) { 10352ec34544SRui Ueyama StringRef Op2 = peek(); 10362ec34544SRui Ueyama if (precedence(Op2) <= precedence(Op1)) 10372ec34544SRui Ueyama break; 10382ec34544SRui Ueyama Rhs = readExpr1(Rhs, precedence(Op2)); 10392ec34544SRui Ueyama } 10402ec34544SRui Ueyama 10412ec34544SRui Ueyama Lhs = combine(Op1, Lhs, Rhs); 10422ec34544SRui Ueyama } 10432ec34544SRui Ueyama return Lhs; 10442ec34544SRui Ueyama } 10452ec34544SRui Ueyama 10465fb17128SGeorge Rimar Expr ScriptParser::getPageSize() { 10475fb17128SGeorge Rimar std::string Location = getCurrentLocation(); 10485fb17128SGeorge Rimar return [=]() -> uint64_t { 10495fb17128SGeorge Rimar if (Target) 10502ec34544SRui Ueyama return Target->PageSize; 10515fb17128SGeorge Rimar error(Location + ": unable to calculate page size"); 10525fb17128SGeorge Rimar return 4096; // Return a dummy value. 10535fb17128SGeorge Rimar }; 10545fb17128SGeorge Rimar } 10555fb17128SGeorge Rimar 10565fb17128SGeorge Rimar Expr ScriptParser::readConstant() { 10575fb17128SGeorge Rimar StringRef S = readParenLiteral(); 10585fb17128SGeorge Rimar if (S == "COMMONPAGESIZE") 10595fb17128SGeorge Rimar return getPageSize(); 10602ec34544SRui Ueyama if (S == "MAXPAGESIZE") 10615fb17128SGeorge Rimar return [] { return Config->MaxPageSize; }; 10625fb17128SGeorge Rimar setError("unknown constant: " + S); 1063b068b037SGeorge Rimar return [] { return 0; }; 10642ec34544SRui Ueyama } 10652ec34544SRui Ueyama 10665c65088fSRui Ueyama // Parses Tok as an integer. It recognizes hexadecimal (prefixed with 10675c65088fSRui Ueyama // "0x" or suffixed with "H") and decimal numbers. Decimal numbers may 10685c65088fSRui Ueyama // have "K" (Ki) or "M" (Mi) suffixes. 10695c65088fSRui Ueyama static Optional<uint64_t> parseInt(StringRef Tok) { 10702ec34544SRui Ueyama // Hexadecimal 10715c65088fSRui Ueyama uint64_t Val; 10724092016bSRui Ueyama if (Tok.startswith_lower("0x")) { 10734092016bSRui Ueyama if (!to_integer(Tok.substr(2), Val, 16)) 10744092016bSRui Ueyama return None; 10755c65088fSRui Ueyama return Val; 10764092016bSRui Ueyama } 10774092016bSRui Ueyama if (Tok.endswith_lower("H")) { 10784092016bSRui Ueyama if (!to_integer(Tok.drop_back(), Val, 16)) 10794092016bSRui Ueyama return None; 10805c65088fSRui Ueyama return Val; 10814092016bSRui Ueyama } 10822ec34544SRui Ueyama 10832ec34544SRui Ueyama // Decimal 10842ec34544SRui Ueyama if (Tok.endswith_lower("K")) { 1085ab94768cSGeorge Rimar if (!to_integer(Tok.drop_back(), Val, 10)) 10865c65088fSRui Ueyama return None; 10875c65088fSRui Ueyama return Val * 1024; 10882ec34544SRui Ueyama } 10895c65088fSRui Ueyama if (Tok.endswith_lower("M")) { 1090ab94768cSGeorge Rimar if (!to_integer(Tok.drop_back(), Val, 10)) 10915c65088fSRui Ueyama return None; 10925c65088fSRui Ueyama return Val * 1024 * 1024; 10935c65088fSRui Ueyama } 1094ab94768cSGeorge Rimar if (!to_integer(Tok, Val, 10)) 10955c65088fSRui Ueyama return None; 10965c65088fSRui Ueyama return Val; 10972ec34544SRui Ueyama } 10982ec34544SRui Ueyama 1099f0403c60SRui Ueyama ByteCommand *ScriptParser::readByteCommand(StringRef Tok) { 1100b579c439SRui Ueyama int Size = StringSwitch<int>(Tok) 11012ec34544SRui Ueyama .Case("BYTE", 1) 11022ec34544SRui Ueyama .Case("SHORT", 2) 11032ec34544SRui Ueyama .Case("LONG", 4) 11042ec34544SRui Ueyama .Case("QUAD", 8) 11052ec34544SRui Ueyama .Default(-1); 11062ec34544SRui Ueyama if (Size == -1) 11072ec34544SRui Ueyama return nullptr; 110884bcabcbSGeorge Rimar 110984bcabcbSGeorge Rimar size_t OldPos = Pos; 111084bcabcbSGeorge Rimar Expr E = readParenExpr(); 111184bcabcbSGeorge Rimar std::string CommandString = 111284bcabcbSGeorge Rimar Tok.str() + " " + 111384bcabcbSGeorge Rimar llvm::join(Tokens.begin() + OldPos, Tokens.begin() + Pos, " "); 111484bcabcbSGeorge Rimar return make<ByteCommand>(E, Size, CommandString); 11152ec34544SRui Ueyama } 11162ec34544SRui Ueyama 11172ec34544SRui Ueyama StringRef ScriptParser::readParenLiteral() { 11182ec34544SRui Ueyama expect("("); 11195e9c7762SRafael Espindola bool Orig = InExpr; 11205e9c7762SRafael Espindola InExpr = false; 11212ec34544SRui Ueyama StringRef Tok = next(); 11225e9c7762SRafael Espindola InExpr = Orig; 11232ec34544SRui Ueyama expect(")"); 11242ec34544SRui Ueyama return Tok; 11252ec34544SRui Ueyama } 11262ec34544SRui Ueyama 1127617e2f98SRui Ueyama static void checkIfExists(OutputSection *Cmd, StringRef Location) { 112805c4f67cSRafael Espindola if (Cmd->Location.empty() && Script->ErrorOnMissingSection) 112905c4f67cSRafael Espindola error(Location + ": undefined section " + Cmd->Name); 113005c4f67cSRafael Espindola } 113105c4f67cSRafael Espindola 11322ec34544SRui Ueyama Expr ScriptParser::readPrimary() { 11332ec34544SRui Ueyama if (peek() == "(") 11342ec34544SRui Ueyama return readParenExpr(); 11352ec34544SRui Ueyama 11365c65088fSRui Ueyama if (consume("~")) { 11372ec34544SRui Ueyama Expr E = readPrimary(); 1138b2fb84a1SRui Ueyama return [=] { return ~E().getValue(); }; 11392ec34544SRui Ueyama } 11406f1d954eSHafiz Abid Qadeer if (consume("!")) { 11416f1d954eSHafiz Abid Qadeer Expr E = readPrimary(); 11426f1d954eSHafiz Abid Qadeer return [=] { return !E().getValue(); }; 11436f1d954eSHafiz Abid Qadeer } 11445c65088fSRui Ueyama if (consume("-")) { 11452ec34544SRui Ueyama Expr E = readPrimary(); 1146b2fb84a1SRui Ueyama return [=] { return -E().getValue(); }; 11472ec34544SRui Ueyama } 11482ec34544SRui Ueyama 11495c65088fSRui Ueyama StringRef Tok = next(); 11505c65088fSRui Ueyama std::string Location = getCurrentLocation(); 11515c65088fSRui Ueyama 11522ec34544SRui Ueyama // Built-in functions are parsed here. 11532ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html. 11542ec34544SRui Ueyama if (Tok == "ABSOLUTE") { 11552ec34544SRui Ueyama Expr Inner = readParenExpr(); 11562ec34544SRui Ueyama return [=] { 11572ec34544SRui Ueyama ExprValue I = Inner(); 11582ec34544SRui Ueyama I.ForceAbsolute = true; 11592ec34544SRui Ueyama return I; 11602ec34544SRui Ueyama }; 11612ec34544SRui Ueyama } 11622ec34544SRui Ueyama if (Tok == "ADDR") { 11632ec34544SRui Ueyama StringRef Name = readParenLiteral(); 11644fbe3518SRui Ueyama OutputSection *Sec = Script->getOrCreateOutputSection(Name); 116541c7ab4aSGeorge Rimar return [=]() -> ExprValue { 11664fbe3518SRui Ueyama checkIfExists(Sec, Location); 11674fbe3518SRui Ueyama return {Sec, false, 0, Location}; 116841c7ab4aSGeorge Rimar }; 11692ec34544SRui Ueyama } 11702ec34544SRui Ueyama if (Tok == "ALIGN") { 11712ec34544SRui Ueyama expect("("); 11722ec34544SRui Ueyama Expr E = readExpr(); 1173f22ec9ddSGeorge Rimar if (consume(")")) { 1174f22ec9ddSGeorge Rimar E = checkAlignment(E, Location); 1175f22ec9ddSGeorge Rimar return [=] { return alignTo(Script->getDot(), E().getValue()); }; 1176f22ec9ddSGeorge Rimar } 1177b579c439SRui Ueyama expect(","); 1178f22ec9ddSGeorge Rimar Expr E2 = checkAlignment(readExpr(), Location); 11792ec34544SRui Ueyama expect(")"); 11803c6de1a6SPetr Hosek return [=] { 11813c6de1a6SPetr Hosek ExprValue V = E(); 1182f22ec9ddSGeorge Rimar V.Alignment = E2().getValue(); 11833c6de1a6SPetr Hosek return V; 11843c6de1a6SPetr Hosek }; 11852ec34544SRui Ueyama } 11862ec34544SRui Ueyama if (Tok == "ALIGNOF") { 11872ec34544SRui Ueyama StringRef Name = readParenLiteral(); 11888c022ca7SRafael Espindola OutputSection *Cmd = Script->getOrCreateOutputSection(Name); 1189617e2f98SRui Ueyama return [=] { 1190617e2f98SRui Ueyama checkIfExists(Cmd, Location); 1191617e2f98SRui Ueyama return Cmd->Alignment; 1192617e2f98SRui Ueyama }; 11932ec34544SRui Ueyama } 11942ec34544SRui Ueyama if (Tok == "ASSERT") 1195d30a78b3SGeorge Rimar return readAssert(); 11965fb17128SGeorge Rimar if (Tok == "CONSTANT") 11975fb17128SGeorge Rimar return readConstant(); 11982ec34544SRui Ueyama if (Tok == "DATA_SEGMENT_ALIGN") { 11992ec34544SRui Ueyama expect("("); 12002ec34544SRui Ueyama Expr E = readExpr(); 12012ec34544SRui Ueyama expect(","); 12022ec34544SRui Ueyama readExpr(); 12032ec34544SRui Ueyama expect(")"); 120460833f6eSGeorge Rimar return [=] { 120560833f6eSGeorge Rimar return alignTo(Script->getDot(), std::max((uint64_t)1, E().getValue())); 120660833f6eSGeorge Rimar }; 12072ec34544SRui Ueyama } 12082ec34544SRui Ueyama if (Tok == "DATA_SEGMENT_END") { 12092ec34544SRui Ueyama expect("("); 12102ec34544SRui Ueyama expect("."); 12112ec34544SRui Ueyama expect(")"); 12122ec34544SRui Ueyama return [] { return Script->getDot(); }; 12132ec34544SRui Ueyama } 12142ec34544SRui Ueyama if (Tok == "DATA_SEGMENT_RELRO_END") { 12152ec34544SRui Ueyama // GNU linkers implements more complicated logic to handle 12162ec34544SRui Ueyama // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and 12172ec34544SRui Ueyama // just align to the next page boundary for simplicity. 12182ec34544SRui Ueyama expect("("); 12192ec34544SRui Ueyama readExpr(); 12202ec34544SRui Ueyama expect(","); 12212ec34544SRui Ueyama readExpr(); 12222ec34544SRui Ueyama expect(")"); 12235fb17128SGeorge Rimar Expr E = getPageSize(); 12245fb17128SGeorge Rimar return [=] { return alignTo(Script->getDot(), E().getValue()); }; 12252ec34544SRui Ueyama } 12262ec34544SRui Ueyama if (Tok == "DEFINED") { 12272ec34544SRui Ueyama StringRef Name = readParenLiteral(); 12289b18f50fSRui Ueyama return [=] { return Symtab->find(Name) ? 1 : 0; }; 12292ec34544SRui Ueyama } 123091b95b61SRui Ueyama if (Tok == "LENGTH") { 123191b95b61SRui Ueyama StringRef Name = readParenLiteral(); 1232b068b037SGeorge Rimar if (Script->MemoryRegions.count(Name) == 0) { 123391b95b61SRui Ueyama setError("memory region not defined: " + Name); 1234b068b037SGeorge Rimar return [] { return 0; }; 1235b068b037SGeorge Rimar } 1236ac27de9dSRui Ueyama return [=] { return Script->MemoryRegions[Name]->Length; }; 123791b95b61SRui Ueyama } 12382ec34544SRui Ueyama if (Tok == "LOADADDR") { 12392ec34544SRui Ueyama StringRef Name = readParenLiteral(); 12408c022ca7SRafael Espindola OutputSection *Cmd = Script->getOrCreateOutputSection(Name); 1241617e2f98SRui Ueyama return [=] { 1242617e2f98SRui Ueyama checkIfExists(Cmd, Location); 1243617e2f98SRui Ueyama return Cmd->getLMA(); 1244617e2f98SRui Ueyama }; 12452ec34544SRui Ueyama } 1246fd11560fSGeorge Rimar if (Tok == "MAX" || Tok == "MIN") { 1247fd11560fSGeorge Rimar expect("("); 1248fd11560fSGeorge Rimar Expr A = readExpr(); 1249fd11560fSGeorge Rimar expect(","); 1250fd11560fSGeorge Rimar Expr B = readExpr(); 1251fd11560fSGeorge Rimar expect(")"); 1252fd11560fSGeorge Rimar if (Tok == "MIN") 1253fd11560fSGeorge Rimar return [=] { return std::min(A().getValue(), B().getValue()); }; 1254fd11560fSGeorge Rimar return [=] { return std::max(A().getValue(), B().getValue()); }; 1255fd11560fSGeorge Rimar } 125691b95b61SRui Ueyama if (Tok == "ORIGIN") { 125791b95b61SRui Ueyama StringRef Name = readParenLiteral(); 1258b068b037SGeorge Rimar if (Script->MemoryRegions.count(Name) == 0) { 125991b95b61SRui Ueyama setError("memory region not defined: " + Name); 1260b068b037SGeorge Rimar return [] { return 0; }; 1261b068b037SGeorge Rimar } 1262ac27de9dSRui Ueyama return [=] { return Script->MemoryRegions[Name]->Origin; }; 126391b95b61SRui Ueyama } 12642ec34544SRui Ueyama if (Tok == "SEGMENT_START") { 12652ec34544SRui Ueyama expect("("); 12662ec34544SRui Ueyama skip(); 12672ec34544SRui Ueyama expect(","); 12682ec34544SRui Ueyama Expr E = readExpr(); 12692ec34544SRui Ueyama expect(")"); 12702ec34544SRui Ueyama return [=] { return E(); }; 12712ec34544SRui Ueyama } 12722ec34544SRui Ueyama if (Tok == "SIZEOF") { 12732ec34544SRui Ueyama StringRef Name = readParenLiteral(); 12748c022ca7SRafael Espindola OutputSection *Cmd = Script->getOrCreateOutputSection(Name); 127505c4f67cSRafael Espindola // Linker script does not create an output section if its content is empty. 127605c4f67cSRafael Espindola // We want to allow SIZEOF(.foo) where .foo is a section which happened to 127705c4f67cSRafael Espindola // be empty. 12788c022ca7SRafael Espindola return [=] { return Cmd->Size; }; 12792ec34544SRui Ueyama } 12802ec34544SRui Ueyama if (Tok == "SIZEOF_HEADERS") 12812ec34544SRui Ueyama return [=] { return elf::getHeaderSize(); }; 12822ec34544SRui Ueyama 12834eb2eccbSRui Ueyama // Tok is the dot. 12844eb2eccbSRui Ueyama if (Tok == ".") 1285722221f5SRui Ueyama return [=] { return Script->getSymbolValue(Tok, Location); }; 12864eb2eccbSRui Ueyama 12872ec34544SRui Ueyama // Tok is a literal number. 12885c65088fSRui Ueyama if (Optional<uint64_t> Val = parseInt(Tok)) 12895c65088fSRui Ueyama return [=] { return *Val; }; 12902ec34544SRui Ueyama 12912ec34544SRui Ueyama // Tok is a symbol name. 12922ec34544SRui Ueyama if (!isValidCIdentifier(Tok)) 12932ec34544SRui Ueyama setError("malformed number: " + Tok); 1294ac27de9dSRui Ueyama Script->ReferencedSymbols.push_back(Tok); 1295722221f5SRui Ueyama return [=] { return Script->getSymbolValue(Tok, Location); }; 12962ec34544SRui Ueyama } 12972ec34544SRui Ueyama 12982ec34544SRui Ueyama Expr ScriptParser::readTernary(Expr Cond) { 12992ec34544SRui Ueyama Expr L = readExpr(); 13002ec34544SRui Ueyama expect(":"); 13012ec34544SRui Ueyama Expr R = readExpr(); 13022ec34544SRui Ueyama return [=] { return Cond().getValue() ? L() : R(); }; 13032ec34544SRui Ueyama } 13042ec34544SRui Ueyama 13052ec34544SRui Ueyama Expr ScriptParser::readParenExpr() { 13062ec34544SRui Ueyama expect("("); 13072ec34544SRui Ueyama Expr E = readExpr(); 13082ec34544SRui Ueyama expect(")"); 13092ec34544SRui Ueyama return E; 13102ec34544SRui Ueyama } 13112ec34544SRui Ueyama 13122ec34544SRui Ueyama std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() { 13132ec34544SRui Ueyama std::vector<StringRef> Phdrs; 1314b8a59c8aSBob Haarman while (!errorCount() && peek().startswith(":")) { 13152ec34544SRui Ueyama StringRef Tok = next(); 13162ec34544SRui Ueyama Phdrs.push_back((Tok.size() == 1) ? next() : Tok.substr(1)); 13172ec34544SRui Ueyama } 13182ec34544SRui Ueyama return Phdrs; 13192ec34544SRui Ueyama } 13202ec34544SRui Ueyama 13212ec34544SRui Ueyama // Read a program header type name. The next token must be a 13222ec34544SRui Ueyama // name of a program header type or a constant (e.g. "0x3"). 13232ec34544SRui Ueyama unsigned ScriptParser::readPhdrType() { 13242ec34544SRui Ueyama StringRef Tok = next(); 13255c65088fSRui Ueyama if (Optional<uint64_t> Val = parseInt(Tok)) 13265c65088fSRui Ueyama return *Val; 13272ec34544SRui Ueyama 13282ec34544SRui Ueyama unsigned Ret = StringSwitch<unsigned>(Tok) 13292ec34544SRui Ueyama .Case("PT_NULL", PT_NULL) 13302ec34544SRui Ueyama .Case("PT_LOAD", PT_LOAD) 13312ec34544SRui Ueyama .Case("PT_DYNAMIC", PT_DYNAMIC) 13322ec34544SRui Ueyama .Case("PT_INTERP", PT_INTERP) 13332ec34544SRui Ueyama .Case("PT_NOTE", PT_NOTE) 13342ec34544SRui Ueyama .Case("PT_SHLIB", PT_SHLIB) 13352ec34544SRui Ueyama .Case("PT_PHDR", PT_PHDR) 13362ec34544SRui Ueyama .Case("PT_TLS", PT_TLS) 13372ec34544SRui Ueyama .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME) 13382ec34544SRui Ueyama .Case("PT_GNU_STACK", PT_GNU_STACK) 13392ec34544SRui Ueyama .Case("PT_GNU_RELRO", PT_GNU_RELRO) 13402ec34544SRui Ueyama .Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE) 13412ec34544SRui Ueyama .Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED) 13422ec34544SRui Ueyama .Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA) 13432ec34544SRui Ueyama .Default(-1); 13442ec34544SRui Ueyama 13452ec34544SRui Ueyama if (Ret == (unsigned)-1) { 13462ec34544SRui Ueyama setError("invalid program header type: " + Tok); 13472ec34544SRui Ueyama return PT_NULL; 13482ec34544SRui Ueyama } 13492ec34544SRui Ueyama return Ret; 13502ec34544SRui Ueyama } 13512ec34544SRui Ueyama 13522ec34544SRui Ueyama // Reads an anonymous version declaration. 13532ec34544SRui Ueyama void ScriptParser::readAnonymousDeclaration() { 13542ec34544SRui Ueyama std::vector<SymbolVersion> Locals; 13552ec34544SRui Ueyama std::vector<SymbolVersion> Globals; 13562ec34544SRui Ueyama std::tie(Locals, Globals) = readSymbols(); 13572ec34544SRui Ueyama 13582ec34544SRui Ueyama for (SymbolVersion V : Locals) { 13592ec34544SRui Ueyama if (V.Name == "*") 13602ec34544SRui Ueyama Config->DefaultSymbolVersion = VER_NDX_LOCAL; 13612ec34544SRui Ueyama else 13622ec34544SRui Ueyama Config->VersionScriptLocals.push_back(V); 13632ec34544SRui Ueyama } 13642ec34544SRui Ueyama 13652ec34544SRui Ueyama for (SymbolVersion V : Globals) 13662ec34544SRui Ueyama Config->VersionScriptGlobals.push_back(V); 13672ec34544SRui Ueyama 13682ec34544SRui Ueyama expect(";"); 13692ec34544SRui Ueyama } 13702ec34544SRui Ueyama 13712ec34544SRui Ueyama // Reads a non-anonymous version definition, 13722ec34544SRui Ueyama // e.g. "VerStr { global: foo; bar; local: *; };". 13732ec34544SRui Ueyama void ScriptParser::readVersionDeclaration(StringRef VerStr) { 13742ec34544SRui Ueyama // Read a symbol list. 13752ec34544SRui Ueyama std::vector<SymbolVersion> Locals; 13762ec34544SRui Ueyama std::vector<SymbolVersion> Globals; 13772ec34544SRui Ueyama std::tie(Locals, Globals) = readSymbols(); 13782ec34544SRui Ueyama 13792ec34544SRui Ueyama for (SymbolVersion V : Locals) { 13802ec34544SRui Ueyama if (V.Name == "*") 13812ec34544SRui Ueyama Config->DefaultSymbolVersion = VER_NDX_LOCAL; 13822ec34544SRui Ueyama else 13832ec34544SRui Ueyama Config->VersionScriptLocals.push_back(V); 13842ec34544SRui Ueyama } 13852ec34544SRui Ueyama 13862ec34544SRui Ueyama // Create a new version definition and add that to the global symbols. 13872ec34544SRui Ueyama VersionDefinition Ver; 13882ec34544SRui Ueyama Ver.Name = VerStr; 13892ec34544SRui Ueyama Ver.Globals = Globals; 13902ec34544SRui Ueyama 13912ec34544SRui Ueyama // User-defined version number starts from 2 because 0 and 1 are 13922ec34544SRui Ueyama // reserved for VER_NDX_LOCAL and VER_NDX_GLOBAL, respectively. 13932ec34544SRui Ueyama Ver.Id = Config->VersionDefinitions.size() + 2; 13942ec34544SRui Ueyama Config->VersionDefinitions.push_back(Ver); 13952ec34544SRui Ueyama 13962ec34544SRui Ueyama // Each version may have a parent version. For example, "Ver2" 13972ec34544SRui Ueyama // defined as "Ver2 { global: foo; local: *; } Ver1;" has "Ver1" 13982ec34544SRui Ueyama // as a parent. This version hierarchy is, probably against your 13992ec34544SRui Ueyama // instinct, purely for hint; the runtime doesn't care about it 14002ec34544SRui Ueyama // at all. In LLD, we simply ignore it. 14012ec34544SRui Ueyama if (peek() != ";") 14022ec34544SRui Ueyama skip(); 14032ec34544SRui Ueyama expect(";"); 14042ec34544SRui Ueyama } 14052ec34544SRui Ueyama 14061e77ad14SRui Ueyama static bool hasWildcard(StringRef S) { 14071e77ad14SRui Ueyama return S.find_first_of("?*[") != StringRef::npos; 14081e77ad14SRui Ueyama } 14091e77ad14SRui Ueyama 14102ec34544SRui Ueyama // Reads a list of symbols, e.g. "{ global: foo; bar; local: *; };". 14112ec34544SRui Ueyama std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>> 14122ec34544SRui Ueyama ScriptParser::readSymbols() { 14132ec34544SRui Ueyama std::vector<SymbolVersion> Locals; 14142ec34544SRui Ueyama std::vector<SymbolVersion> Globals; 14152ec34544SRui Ueyama std::vector<SymbolVersion> *V = &Globals; 14162ec34544SRui Ueyama 1417b8a59c8aSBob Haarman while (!errorCount()) { 14182ec34544SRui Ueyama if (consume("}")) 14192ec34544SRui Ueyama break; 14202ec34544SRui Ueyama if (consumeLabel("local")) { 14212ec34544SRui Ueyama V = &Locals; 14222ec34544SRui Ueyama continue; 14232ec34544SRui Ueyama } 14242ec34544SRui Ueyama if (consumeLabel("global")) { 14252ec34544SRui Ueyama V = &Globals; 14262ec34544SRui Ueyama continue; 14272ec34544SRui Ueyama } 14282ec34544SRui Ueyama 14292ec34544SRui Ueyama if (consume("extern")) { 14302ec34544SRui Ueyama std::vector<SymbolVersion> Ext = readVersionExtern(); 14312ec34544SRui Ueyama V->insert(V->end(), Ext.begin(), Ext.end()); 14322ec34544SRui Ueyama } else { 14332ec34544SRui Ueyama StringRef Tok = next(); 14342ec34544SRui Ueyama V->push_back({unquote(Tok), false, hasWildcard(Tok)}); 14352ec34544SRui Ueyama } 14362ec34544SRui Ueyama expect(";"); 14372ec34544SRui Ueyama } 14382ec34544SRui Ueyama return {Locals, Globals}; 14392ec34544SRui Ueyama } 14402ec34544SRui Ueyama 14412ec34544SRui Ueyama // Reads an "extern C++" directive, e.g., 14422ec34544SRui Ueyama // "extern "C++" { ns::*; "f(int, double)"; };" 144317324d8bSRui Ueyama // 144417324d8bSRui Ueyama // The last semicolon is optional. E.g. this is OK: 144517324d8bSRui Ueyama // "extern "C++" { ns::*; "f(int, double)" };" 14462ec34544SRui Ueyama std::vector<SymbolVersion> ScriptParser::readVersionExtern() { 14472ec34544SRui Ueyama StringRef Tok = next(); 14482ec34544SRui Ueyama bool IsCXX = Tok == "\"C++\""; 14492ec34544SRui Ueyama if (!IsCXX && Tok != "\"C\"") 14502ec34544SRui Ueyama setError("Unknown language"); 14512ec34544SRui Ueyama expect("{"); 14522ec34544SRui Ueyama 14532ec34544SRui Ueyama std::vector<SymbolVersion> Ret; 1454b8a59c8aSBob Haarman while (!errorCount() && peek() != "}") { 14552ec34544SRui Ueyama StringRef Tok = next(); 14562ec34544SRui Ueyama bool HasWildcard = !Tok.startswith("\"") && hasWildcard(Tok); 14572ec34544SRui Ueyama Ret.push_back({unquote(Tok), IsCXX, HasWildcard}); 145817324d8bSRui Ueyama if (consume("}")) 145917324d8bSRui Ueyama return Ret; 14602ec34544SRui Ueyama expect(";"); 14612ec34544SRui Ueyama } 14622ec34544SRui Ueyama 14632ec34544SRui Ueyama expect("}"); 14642ec34544SRui Ueyama return Ret; 14652ec34544SRui Ueyama } 14662ec34544SRui Ueyama 14672ec34544SRui Ueyama uint64_t ScriptParser::readMemoryAssignment(StringRef S1, StringRef S2, 14682ec34544SRui Ueyama StringRef S3) { 1469b579c439SRui Ueyama if (!consume(S1) && !consume(S2) && !consume(S3)) { 14702ec34544SRui Ueyama setError("expected one of: " + S1 + ", " + S2 + ", or " + S3); 14712ec34544SRui Ueyama return 0; 14722ec34544SRui Ueyama } 14732ec34544SRui Ueyama expect("="); 1474040af7deSRui Ueyama return readExpr()().getValue(); 14752ec34544SRui Ueyama } 14762ec34544SRui Ueyama 14772ec34544SRui Ueyama // Parse the MEMORY command as specified in: 14782ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/MEMORY.html 14792ec34544SRui Ueyama // 14802ec34544SRui Ueyama // MEMORY { name [(attr)] : ORIGIN = origin, LENGTH = len ... } 14812ec34544SRui Ueyama void ScriptParser::readMemory() { 14822ec34544SRui Ueyama expect("{"); 1483b8a59c8aSBob Haarman while (!errorCount() && !consume("}")) { 14842e9d40d5SRui Ueyama StringRef Tok = next(); 14852e9d40d5SRui Ueyama if (Tok == "INCLUDE") { 14862e9d40d5SRui Ueyama readInclude(); 14872e9d40d5SRui Ueyama continue; 14882e9d40d5SRui Ueyama } 14892ec34544SRui Ueyama 14902ec34544SRui Ueyama uint32_t Flags = 0; 14912ec34544SRui Ueyama uint32_t NegFlags = 0; 14922ec34544SRui Ueyama if (consume("(")) { 14932ec34544SRui Ueyama std::tie(Flags, NegFlags) = readMemoryAttributes(); 14942ec34544SRui Ueyama expect(")"); 14952ec34544SRui Ueyama } 14962ec34544SRui Ueyama expect(":"); 14972ec34544SRui Ueyama 14982ec34544SRui Ueyama uint64_t Origin = readMemoryAssignment("ORIGIN", "org", "o"); 14992ec34544SRui Ueyama expect(","); 15002ec34544SRui Ueyama uint64_t Length = readMemoryAssignment("LENGTH", "len", "l"); 15012ec34544SRui Ueyama 15025f37541cSGeorge Rimar // Add the memory region to the region map. 15032e9d40d5SRui Ueyama MemoryRegion *MR = make<MemoryRegion>(Tok, Origin, Length, Flags, NegFlags); 15042e9d40d5SRui Ueyama if (!Script->MemoryRegions.insert({Tok, MR}).second) 15052e9d40d5SRui Ueyama setError("region '" + Tok + "' already defined"); 15062ec34544SRui Ueyama } 15072ec34544SRui Ueyama } 15082ec34544SRui Ueyama 15092ec34544SRui Ueyama // This function parses the attributes used to match against section 15102ec34544SRui Ueyama // flags when placing output sections in a memory region. These flags 15112ec34544SRui Ueyama // are only used when an explicit memory region name is not used. 15122ec34544SRui Ueyama std::pair<uint32_t, uint32_t> ScriptParser::readMemoryAttributes() { 15132ec34544SRui Ueyama uint32_t Flags = 0; 15142ec34544SRui Ueyama uint32_t NegFlags = 0; 15152ec34544SRui Ueyama bool Invert = false; 15162ec34544SRui Ueyama 15172ec34544SRui Ueyama for (char C : next().lower()) { 15182ec34544SRui Ueyama uint32_t Flag = 0; 15192ec34544SRui Ueyama if (C == '!') 15202ec34544SRui Ueyama Invert = !Invert; 15212ec34544SRui Ueyama else if (C == 'w') 15222ec34544SRui Ueyama Flag = SHF_WRITE; 15232ec34544SRui Ueyama else if (C == 'x') 15242ec34544SRui Ueyama Flag = SHF_EXECINSTR; 15252ec34544SRui Ueyama else if (C == 'a') 15262ec34544SRui Ueyama Flag = SHF_ALLOC; 15272ec34544SRui Ueyama else if (C != 'r') 15282ec34544SRui Ueyama setError("invalid memory region attribute"); 15292ec34544SRui Ueyama 15302ec34544SRui Ueyama if (Invert) 15312ec34544SRui Ueyama NegFlags |= Flag; 15322ec34544SRui Ueyama else 15332ec34544SRui Ueyama Flags |= Flag; 15342ec34544SRui Ueyama } 15352ec34544SRui Ueyama return {Flags, NegFlags}; 15362ec34544SRui Ueyama } 15372ec34544SRui Ueyama 15382ec34544SRui Ueyama void elf::readLinkerScript(MemoryBufferRef MB) { 15392ec34544SRui Ueyama ScriptParser(MB).readLinkerScript(); 15402ec34544SRui Ueyama } 15412ec34544SRui Ueyama 15422ec34544SRui Ueyama void elf::readVersionScript(MemoryBufferRef MB) { 15432ec34544SRui Ueyama ScriptParser(MB).readVersionScript(); 15442ec34544SRui Ueyama } 15452ec34544SRui Ueyama 15462ec34544SRui Ueyama void elf::readDynamicList(MemoryBufferRef MB) { 15472ec34544SRui Ueyama ScriptParser(MB).readDynamicList(); 15482ec34544SRui Ueyama } 15498c7e8cceSPetr Hosek 15508c7e8cceSPetr Hosek void elf::readDefsym(StringRef Name, MemoryBufferRef MB) { 15518c7e8cceSPetr Hosek ScriptParser(MB).readDefsym(Name); 15528c7e8cceSPetr Hosek } 1553