12ec34544SRui Ueyama //===- ScriptParser.cpp ---------------------------------------------------===// 22ec34544SRui Ueyama // 32ec34544SRui Ueyama // The LLVM Linker 42ec34544SRui Ueyama // 52ec34544SRui Ueyama // This file is distributed under the University of Illinois Open Source 62ec34544SRui Ueyama // License. See LICENSE.TXT for details. 72ec34544SRui Ueyama // 82ec34544SRui Ueyama //===----------------------------------------------------------------------===// 905f6b852SRui Ueyama // 1005f6b852SRui Ueyama // This file contains a recursive-descendent parser for linker scripts. 1105f6b852SRui Ueyama // Parsed results are stored to Config and Script global objects. 1205f6b852SRui Ueyama // 1305f6b852SRui Ueyama //===----------------------------------------------------------------------===// 142ec34544SRui Ueyama 152ec34544SRui Ueyama #include "ScriptParser.h" 162ec34544SRui Ueyama #include "Config.h" 172ec34544SRui Ueyama #include "Driver.h" 182ec34544SRui Ueyama #include "InputSection.h" 192ec34544SRui Ueyama #include "LinkerScript.h" 202ec34544SRui Ueyama #include "OutputSections.h" 212ec34544SRui Ueyama #include "ScriptLexer.h" 222ec34544SRui Ueyama #include "Symbols.h" 232ec34544SRui Ueyama #include "Target.h" 242017d52bSRui Ueyama #include "lld/Common/Memory.h" 252ec34544SRui Ueyama #include "llvm/ADT/SmallString.h" 262ec34544SRui Ueyama #include "llvm/ADT/StringRef.h" 270440be4aSRui Ueyama #include "llvm/ADT/StringSet.h" 282ec34544SRui Ueyama #include "llvm/ADT/StringSwitch.h" 29264b5d9eSZachary Turner #include "llvm/BinaryFormat/ELF.h" 302ec34544SRui Ueyama #include "llvm/Support/Casting.h" 312ec34544SRui Ueyama #include "llvm/Support/ErrorHandling.h" 322ec34544SRui Ueyama #include "llvm/Support/FileSystem.h" 332ec34544SRui Ueyama #include "llvm/Support/Path.h" 342ec34544SRui Ueyama #include <cassert> 352ec34544SRui Ueyama #include <limits> 362ec34544SRui Ueyama #include <vector> 372ec34544SRui Ueyama 382ec34544SRui Ueyama using namespace llvm; 392ec34544SRui Ueyama using namespace llvm::ELF; 40b58079d4SRui Ueyama using namespace llvm::support::endian; 412ec34544SRui Ueyama using namespace lld; 422ec34544SRui Ueyama using namespace lld::elf; 432ec34544SRui Ueyama 442ec34544SRui Ueyama static bool isUnderSysroot(StringRef Path); 452ec34544SRui Ueyama 4696b3fe02SRui Ueyama namespace { 4796b3fe02SRui Ueyama class ScriptParser final : ScriptLexer { 482ec34544SRui Ueyama public: 492ec34544SRui Ueyama ScriptParser(MemoryBufferRef MB) 502ec34544SRui Ueyama : ScriptLexer(MB), 512ec34544SRui Ueyama IsUnderSysroot(isUnderSysroot(MB.getBufferIdentifier())) {} 522ec34544SRui Ueyama 532ec34544SRui Ueyama void readLinkerScript(); 542ec34544SRui Ueyama void readVersionScript(); 552ec34544SRui Ueyama void readDynamicList(); 568c7e8cceSPetr Hosek void readDefsym(StringRef Name); 572ec34544SRui Ueyama 582ec34544SRui Ueyama private: 592ec34544SRui Ueyama void addFile(StringRef Path); 602ec34544SRui Ueyama 612ec34544SRui Ueyama void readAsNeeded(); 622ec34544SRui Ueyama void readEntry(); 632ec34544SRui Ueyama void readExtern(); 642ec34544SRui Ueyama void readGroup(); 652ec34544SRui Ueyama void readInclude(); 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(); 742ec34544SRui Ueyama void readVersion(); 752ec34544SRui Ueyama void readVersionScriptCommand(); 762ec34544SRui Ueyama 772ec34544SRui Ueyama SymbolAssignment *readAssignment(StringRef Name); 78f0403c60SRui Ueyama ByteCommand *readByteCommand(StringRef Tok); 792ec34544SRui Ueyama uint32_t readFill(); 808acbf1ccSRui Ueyama uint32_t parseFill(StringRef Tok); 818c022ca7SRafael Espindola void readSectionAddressType(OutputSection *Cmd); 828c022ca7SRafael Espindola OutputSection *readOutputSectionDescription(StringRef OutSec); 832ec34544SRui Ueyama std::vector<StringRef> readOutputSectionPhdrs(); 842ec34544SRui Ueyama InputSectionDescription *readInputSectionDescription(StringRef Tok); 852ec34544SRui Ueyama StringMatcher readFilePatterns(); 862ec34544SRui Ueyama std::vector<SectionPattern> readInputSectionsList(); 872ec34544SRui Ueyama InputSectionDescription *readInputSectionRules(StringRef FilePattern); 882ec34544SRui Ueyama unsigned readPhdrType(); 892ec34544SRui Ueyama SortSectionPolicy readSortKind(); 902ec34544SRui Ueyama SymbolAssignment *readProvideHidden(bool Provide, bool Hidden); 912ec34544SRui Ueyama SymbolAssignment *readProvideOrAssignment(StringRef Tok); 922ec34544SRui Ueyama void readSort(); 9323af89ccSRui Ueyama AssertCommand *readAssert(); 9423af89ccSRui Ueyama Expr readAssertExpr(); 955fb17128SGeorge Rimar Expr readConstant(); 965fb17128SGeorge Rimar Expr getPageSize(); 972ec34544SRui Ueyama 982ec34544SRui Ueyama uint64_t readMemoryAssignment(StringRef, StringRef, StringRef); 992ec34544SRui Ueyama std::pair<uint32_t, uint32_t> readMemoryAttributes(); 1002ec34544SRui Ueyama 1017b91e213SGeorge Rimar Expr combine(StringRef Op, Expr L, Expr R); 1022ec34544SRui Ueyama Expr readExpr(); 1032ec34544SRui Ueyama Expr readExpr1(Expr Lhs, int MinPrec); 1042ec34544SRui Ueyama StringRef readParenLiteral(); 1052ec34544SRui Ueyama Expr readPrimary(); 1062ec34544SRui Ueyama Expr readTernary(Expr Cond); 1072ec34544SRui Ueyama Expr readParenExpr(); 1082ec34544SRui Ueyama 1092ec34544SRui Ueyama // For parsing version script. 1102ec34544SRui Ueyama std::vector<SymbolVersion> readVersionExtern(); 1112ec34544SRui Ueyama void readAnonymousDeclaration(); 1122ec34544SRui Ueyama void readVersionDeclaration(StringRef VerStr); 1132ec34544SRui Ueyama 1142ec34544SRui Ueyama std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>> 1152ec34544SRui Ueyama readSymbols(); 1162ec34544SRui Ueyama 117fd06b025SRui Ueyama // True if a script being read is in a subdirectory specified by -sysroot. 1182ec34544SRui Ueyama bool IsUnderSysroot; 1190440be4aSRui Ueyama 1200440be4aSRui Ueyama // A set to detect an INCLUDE() cycle. 1210440be4aSRui Ueyama StringSet<> Seen; 1222ec34544SRui Ueyama }; 12396b3fe02SRui Ueyama } // namespace 1242ec34544SRui Ueyama 1251e77ad14SRui Ueyama static StringRef unquote(StringRef S) { 1261e77ad14SRui Ueyama if (S.startswith("\"")) 1271e77ad14SRui Ueyama return S.substr(1, S.size() - 2); 1281e77ad14SRui Ueyama return S; 1291e77ad14SRui Ueyama } 1301e77ad14SRui Ueyama 1312ec34544SRui Ueyama static bool isUnderSysroot(StringRef Path) { 1322ec34544SRui Ueyama if (Config->Sysroot == "") 1332ec34544SRui Ueyama return false; 1342ec34544SRui Ueyama for (; !Path.empty(); Path = sys::path::parent_path(Path)) 1352ec34544SRui Ueyama if (sys::fs::equivalent(Config->Sysroot, Path)) 1362ec34544SRui Ueyama return true; 1372ec34544SRui Ueyama return false; 1382ec34544SRui Ueyama } 1392ec34544SRui Ueyama 1402ec34544SRui Ueyama // Some operations only support one non absolute value. Move the 1412ec34544SRui Ueyama // absolute one to the right hand side for convenience. 1422ec34544SRui Ueyama static void moveAbsRight(ExprValue &A, ExprValue &B) { 14323be5e8dSRafael Espindola if (A.Sec == nullptr || (A.ForceAbsolute && !B.isAbsolute())) 1442ec34544SRui Ueyama std::swap(A, B); 1452ec34544SRui Ueyama if (!B.isAbsolute()) 14641c7ab4aSGeorge Rimar error(A.Loc + ": at least one side of the expression must be absolute"); 1472ec34544SRui Ueyama } 1482ec34544SRui Ueyama 1492ec34544SRui Ueyama static ExprValue add(ExprValue A, ExprValue B) { 1502ec34544SRui Ueyama moveAbsRight(A, B); 151a6acd23cSRafael Espindola return {A.Sec, A.ForceAbsolute, A.getSectionOffset() + B.getValue(), A.Loc}; 1522ec34544SRui Ueyama } 1532ec34544SRui Ueyama 1542ec34544SRui Ueyama static ExprValue sub(ExprValue A, ExprValue B) { 15563a4a98eSRafael Espindola // The distance between two symbols in sections is absolute. 1569cbb6dd1SRafael Espindola if (!A.isAbsolute() && !B.isAbsolute()) 1579cbb6dd1SRafael Espindola return A.getValue() - B.getValue(); 1584fbe3518SRui Ueyama return {A.Sec, false, A.getSectionOffset() - B.getValue(), A.Loc}; 1592ec34544SRui Ueyama } 1602ec34544SRui Ueyama 1612ec34544SRui Ueyama static ExprValue bitAnd(ExprValue A, ExprValue B) { 1622ec34544SRui Ueyama moveAbsRight(A, B); 1632ec34544SRui Ueyama return {A.Sec, A.ForceAbsolute, 16441c7ab4aSGeorge Rimar (A.getValue() & B.getValue()) - A.getSecAddr(), A.Loc}; 1652ec34544SRui Ueyama } 1662ec34544SRui Ueyama 1672ec34544SRui Ueyama static ExprValue bitOr(ExprValue A, ExprValue B) { 1682ec34544SRui Ueyama moveAbsRight(A, B); 1692ec34544SRui Ueyama return {A.Sec, A.ForceAbsolute, 17041c7ab4aSGeorge Rimar (A.getValue() | B.getValue()) - A.getSecAddr(), A.Loc}; 1712ec34544SRui Ueyama } 1722ec34544SRui Ueyama 1732ec34544SRui Ueyama void ScriptParser::readDynamicList() { 1748016bdfdSRafael Espindola Config->HasDynamicList = true; 1752ec34544SRui Ueyama expect("{"); 176d72d97b3SRafael Espindola std::vector<SymbolVersion> Locals; 177d72d97b3SRafael Espindola std::vector<SymbolVersion> Globals; 178d72d97b3SRafael Espindola 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 } 185d72d97b3SRafael Espindola if (!Locals.empty()) { 186d72d97b3SRafael Espindola setError("\"local:\" scope not supported in --dynamic-list"); 187d72d97b3SRafael Espindola return; 188d72d97b3SRafael Espindola } 189d72d97b3SRafael Espindola 190d72d97b3SRafael Espindola for (SymbolVersion V : Globals) 191d72d97b3SRafael Espindola 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() != "}") { 2072ec34544SRui Ueyama StringRef VerStr = next(); 2082ec34544SRui 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("{"); 2142ec34544SRui 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()) { 2262ec34544SRui Ueyama StringRef Tok = next(); 2272ec34544SRui Ueyama if (Tok == ";") 2282ec34544SRui Ueyama continue; 2292ec34544SRui Ueyama 2302ec34544SRui Ueyama if (Tok == "ASSERT") { 2316b394caaSRui Ueyama Script->SectionCommands.push_back(readAssert()); 2322ec34544SRui Ueyama } else if (Tok == "ENTRY") { 2332ec34544SRui Ueyama readEntry(); 2342ec34544SRui Ueyama } else if (Tok == "EXTERN") { 2352ec34544SRui Ueyama readExtern(); 2362ec34544SRui Ueyama } else if (Tok == "GROUP" || Tok == "INPUT") { 2372ec34544SRui Ueyama readGroup(); 2382ec34544SRui Ueyama } else if (Tok == "INCLUDE") { 2392ec34544SRui Ueyama readInclude(); 2402ec34544SRui Ueyama } else if (Tok == "MEMORY") { 2412ec34544SRui Ueyama readMemory(); 2422ec34544SRui Ueyama } else if (Tok == "OUTPUT") { 2432ec34544SRui Ueyama readOutput(); 2442ec34544SRui Ueyama } else if (Tok == "OUTPUT_ARCH") { 2452ec34544SRui Ueyama readOutputArch(); 2462ec34544SRui Ueyama } else if (Tok == "OUTPUT_FORMAT") { 2472ec34544SRui Ueyama readOutputFormat(); 2482ec34544SRui Ueyama } else if (Tok == "PHDRS") { 2492ec34544SRui Ueyama readPhdrs(); 2505f37541cSGeorge Rimar } else if (Tok == "REGION_ALIAS") { 2515f37541cSGeorge Rimar readRegionAlias(); 2522ec34544SRui Ueyama } else if (Tok == "SEARCH_DIR") { 2532ec34544SRui Ueyama readSearchDir(); 2542ec34544SRui Ueyama } else if (Tok == "SECTIONS") { 2552ec34544SRui Ueyama readSections(); 2562ec34544SRui Ueyama } else if (Tok == "VERSION") { 2572ec34544SRui Ueyama readVersion(); 2582ec34544SRui Ueyama } else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok)) { 2596b394caaSRui Ueyama Script->SectionCommands.push_back(Cmd); 2602ec34544SRui Ueyama } else { 2612ec34544SRui Ueyama setError("unknown directive: " + Tok); 2622ec34544SRui Ueyama } 2632ec34544SRui Ueyama } 2642ec34544SRui Ueyama } 2652ec34544SRui Ueyama 2668c7e8cceSPetr Hosek void ScriptParser::readDefsym(StringRef Name) { 2678c7e8cceSPetr Hosek Expr E = readExpr(); 2688c7e8cceSPetr Hosek if (!atEOF()) 2698c7e8cceSPetr Hosek setError("EOF expected, but got " + next()); 2708c7e8cceSPetr Hosek SymbolAssignment *Cmd = make<SymbolAssignment>(Name, E, getCurrentLocation()); 2718c7e8cceSPetr Hosek Script->SectionCommands.push_back(Cmd); 2728c7e8cceSPetr Hosek } 2738c7e8cceSPetr Hosek 2742ec34544SRui Ueyama void ScriptParser::addFile(StringRef S) { 2752ec34544SRui Ueyama if (IsUnderSysroot && S.startswith("/")) { 2762ec34544SRui Ueyama SmallString<128> PathData; 2772ec34544SRui Ueyama StringRef Path = (Config->Sysroot + S).toStringRef(PathData); 2782ec34544SRui Ueyama if (sys::fs::exists(Path)) { 279a76349bfSEvgeniy Stepanov Driver->addFile(Saver.save(Path), /*WithLOption=*/false); 2802ec34544SRui Ueyama return; 2812ec34544SRui Ueyama } 2822ec34544SRui Ueyama } 2832ec34544SRui Ueyama 284875ae82bSRui Ueyama if (S.startswith("/")) { 285a76349bfSEvgeniy Stepanov Driver->addFile(S, /*WithLOption=*/false); 2862ec34544SRui Ueyama } else if (S.startswith("=")) { 2872ec34544SRui Ueyama if (Config->Sysroot.empty()) 288a76349bfSEvgeniy Stepanov Driver->addFile(S.substr(1), /*WithLOption=*/false); 2892ec34544SRui Ueyama else 290a76349bfSEvgeniy Stepanov Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1)), 291a76349bfSEvgeniy Stepanov /*WithLOption=*/false); 2922ec34544SRui Ueyama } else if (S.startswith("-l")) { 2932ec34544SRui Ueyama Driver->addLibrary(S.substr(2)); 2942ec34544SRui Ueyama } else if (sys::fs::exists(S)) { 295a76349bfSEvgeniy Stepanov Driver->addFile(S, /*WithLOption=*/false); 2962ec34544SRui Ueyama } else { 2972ec34544SRui Ueyama if (Optional<std::string> Path = findFromSearchPaths(S)) 298a76349bfSEvgeniy Stepanov Driver->addFile(Saver.save(*Path), /*WithLOption=*/true); 2992ec34544SRui Ueyama else 3002ec34544SRui Ueyama setError("unable to find " + S); 3012ec34544SRui Ueyama } 3022ec34544SRui Ueyama } 3032ec34544SRui Ueyama 3042ec34544SRui Ueyama void ScriptParser::readAsNeeded() { 3052ec34544SRui Ueyama expect("("); 3062ec34544SRui Ueyama bool Orig = Config->AsNeeded; 3072ec34544SRui Ueyama Config->AsNeeded = true; 308b8a59c8aSBob Haarman while (!errorCount() && !consume(")")) 3092ec34544SRui Ueyama addFile(unquote(next())); 3102ec34544SRui Ueyama Config->AsNeeded = Orig; 3112ec34544SRui Ueyama } 3122ec34544SRui Ueyama 3132ec34544SRui Ueyama void ScriptParser::readEntry() { 3142ec34544SRui Ueyama // -e <symbol> takes predecence over ENTRY(<symbol>). 3152ec34544SRui Ueyama expect("("); 3162ec34544SRui Ueyama StringRef Tok = next(); 3172ec34544SRui Ueyama if (Config->Entry.empty()) 3182ec34544SRui Ueyama Config->Entry = Tok; 3192ec34544SRui Ueyama expect(")"); 3202ec34544SRui Ueyama } 3212ec34544SRui Ueyama 3222ec34544SRui Ueyama void ScriptParser::readExtern() { 3232ec34544SRui Ueyama expect("("); 324b8a59c8aSBob Haarman while (!errorCount() && !consume(")")) 3252ec34544SRui Ueyama Config->Undefined.push_back(next()); 3262ec34544SRui Ueyama } 3272ec34544SRui Ueyama 3282ec34544SRui Ueyama void ScriptParser::readGroup() { 3292ec34544SRui Ueyama expect("("); 330b8a59c8aSBob Haarman while (!errorCount() && !consume(")")) { 331b579c439SRui Ueyama if (consume("AS_NEEDED")) 3322ec34544SRui Ueyama readAsNeeded(); 3332ec34544SRui Ueyama else 334b579c439SRui Ueyama addFile(unquote(next())); 3352ec34544SRui Ueyama } 3362ec34544SRui Ueyama } 3372ec34544SRui Ueyama 3382ec34544SRui Ueyama void ScriptParser::readInclude() { 3392ec34544SRui Ueyama StringRef Tok = unquote(next()); 3402ec34544SRui Ueyama 3410440be4aSRui Ueyama if (!Seen.insert(Tok).second) { 3420440be4aSRui Ueyama setError("there is a cycle in linker script INCLUDEs"); 3430440be4aSRui Ueyama return; 3440440be4aSRui Ueyama } 3450440be4aSRui Ueyama 3461de78471SAlexander Richardson if (Optional<std::string> Path = searchLinkerScript(Tok)) { 3472ec34544SRui Ueyama if (Optional<MemoryBufferRef> MB = readFile(*Path)) 3482ec34544SRui Ueyama tokenize(*MB); 3492ec34544SRui Ueyama return; 3502ec34544SRui Ueyama } 3511de78471SAlexander Richardson setError("cannot find linker script " + Tok); 3522ec34544SRui Ueyama } 3532ec34544SRui Ueyama 3542ec34544SRui Ueyama void ScriptParser::readOutput() { 3552ec34544SRui Ueyama // -o <file> takes predecence over OUTPUT(<file>). 3562ec34544SRui Ueyama expect("("); 3572ec34544SRui Ueyama StringRef Tok = next(); 3582ec34544SRui Ueyama if (Config->OutputFile.empty()) 3592ec34544SRui Ueyama Config->OutputFile = unquote(Tok); 3602ec34544SRui Ueyama expect(")"); 3612ec34544SRui Ueyama } 3622ec34544SRui Ueyama 3632ec34544SRui Ueyama void ScriptParser::readOutputArch() { 3642ec34544SRui Ueyama // OUTPUT_ARCH is ignored for now. 3652ec34544SRui Ueyama expect("("); 366b8a59c8aSBob Haarman while (!errorCount() && !consume(")")) 3672ec34544SRui Ueyama skip(); 3682ec34544SRui Ueyama } 3692ec34544SRui Ueyama 3702ec34544SRui Ueyama void ScriptParser::readOutputFormat() { 3712ec34544SRui Ueyama // Error checking only for now. 3722ec34544SRui Ueyama expect("("); 3732ec34544SRui Ueyama skip(); 374b579c439SRui Ueyama if (consume(")")) 3752ec34544SRui Ueyama return; 376b579c439SRui Ueyama expect(","); 3772ec34544SRui Ueyama skip(); 3782ec34544SRui Ueyama expect(","); 3792ec34544SRui Ueyama skip(); 3802ec34544SRui Ueyama expect(")"); 3812ec34544SRui Ueyama } 3822ec34544SRui Ueyama 3832ec34544SRui Ueyama void ScriptParser::readPhdrs() { 3842ec34544SRui Ueyama expect("{"); 3852ec34544SRui Ueyama 386b8a59c8aSBob Haarman while (!errorCount() && !consume("}")) { 3870ae2c24cSRui Ueyama PhdrsCommand Cmd; 3880ae2c24cSRui Ueyama Cmd.Name = next(); 3890ae2c24cSRui Ueyama Cmd.Type = readPhdrType(); 390b579c439SRui Ueyama 391b8a59c8aSBob Haarman while (!errorCount() && !consume(";")) { 392b579c439SRui Ueyama if (consume("FILEHDR")) 3930ae2c24cSRui Ueyama Cmd.HasFilehdr = true; 394b579c439SRui Ueyama else if (consume("PHDRS")) 3950ae2c24cSRui Ueyama Cmd.HasPhdrs = true; 396b579c439SRui Ueyama else if (consume("AT")) 3970ae2c24cSRui Ueyama Cmd.LMAExpr = readParenExpr(); 398b579c439SRui Ueyama else if (consume("FLAGS")) 3990ae2c24cSRui Ueyama Cmd.Flags = readParenExpr()().getValue(); 400b579c439SRui Ueyama else 401b579c439SRui Ueyama setError("unexpected header attribute: " + next()); 402b579c439SRui Ueyama } 4030ae2c24cSRui Ueyama 404ac27de9dSRui Ueyama Script->PhdrsCommands.push_back(Cmd); 4052ec34544SRui Ueyama } 4062ec34544SRui Ueyama } 4072ec34544SRui Ueyama 4085f37541cSGeorge Rimar void ScriptParser::readRegionAlias() { 4095f37541cSGeorge Rimar expect("("); 4105f37541cSGeorge Rimar StringRef Alias = unquote(next()); 4115f37541cSGeorge Rimar expect(","); 4125f37541cSGeorge Rimar StringRef Name = next(); 4135f37541cSGeorge Rimar expect(")"); 4145f37541cSGeorge Rimar 415ac27de9dSRui Ueyama if (Script->MemoryRegions.count(Alias)) 4165f37541cSGeorge Rimar setError("redefinition of memory region '" + Alias + "'"); 417ac27de9dSRui Ueyama if (!Script->MemoryRegions.count(Name)) 4185f37541cSGeorge Rimar setError("memory region '" + Name + "' is not defined"); 4198c825db2SGeorge Rimar Script->MemoryRegions.insert({Alias, Script->MemoryRegions[Name]}); 4205f37541cSGeorge Rimar } 4215f37541cSGeorge Rimar 4222ec34544SRui Ueyama void ScriptParser::readSearchDir() { 4232ec34544SRui Ueyama expect("("); 4242ec34544SRui Ueyama StringRef Tok = next(); 4252ec34544SRui Ueyama if (!Config->Nostdlib) 4262ec34544SRui Ueyama Config->SearchPaths.push_back(unquote(Tok)); 4272ec34544SRui Ueyama expect(")"); 4282ec34544SRui Ueyama } 4292ec34544SRui Ueyama 4302ec34544SRui Ueyama void ScriptParser::readSections() { 431a323e2a7SRui Ueyama Script->HasSectionsCommand = true; 432b579c439SRui Ueyama 4332ec34544SRui Ueyama // -no-rosegment is used to avoid placing read only non-executable sections in 4342ec34544SRui Ueyama // their own segment. We do the same if SECTIONS command is present in linker 4352ec34544SRui Ueyama // script. See comment for computeFlags(). 4362ec34544SRui Ueyama Config->SingleRoRx = true; 4372ec34544SRui Ueyama 4382ec34544SRui Ueyama expect("{"); 439*9e2c8a9dSGeorge Rimar std::vector<BaseCommand *> V; 440b8a59c8aSBob Haarman while (!errorCount() && !consume("}")) { 4412ec34544SRui Ueyama StringRef Tok = next(); 4422ec34544SRui Ueyama BaseCommand *Cmd = readProvideOrAssignment(Tok); 4432ec34544SRui Ueyama if (!Cmd) { 4442ec34544SRui Ueyama if (Tok == "ASSERT") 44523af89ccSRui Ueyama Cmd = readAssert(); 4462ec34544SRui Ueyama else 4472ec34544SRui Ueyama Cmd = readOutputSectionDescription(Tok); 4482ec34544SRui Ueyama } 449*9e2c8a9dSGeorge Rimar V.push_back(Cmd); 4502ec34544SRui Ueyama } 451*9e2c8a9dSGeorge Rimar 452*9e2c8a9dSGeorge Rimar if (!atEOF() && consume("INSERT")) { 453*9e2c8a9dSGeorge Rimar consume("AFTER"); 454*9e2c8a9dSGeorge Rimar std::vector<BaseCommand *> &Dest = Script->InsertAfterCommands[next()]; 455*9e2c8a9dSGeorge Rimar Dest.insert(Dest.end(), V.begin(), V.end()); 456*9e2c8a9dSGeorge Rimar return; 457*9e2c8a9dSGeorge Rimar } 458*9e2c8a9dSGeorge Rimar 459*9e2c8a9dSGeorge Rimar Script->SectionCommands.insert(Script->SectionCommands.end(), V.begin(), 460*9e2c8a9dSGeorge Rimar V.end()); 4612ec34544SRui Ueyama } 4622ec34544SRui Ueyama 4632ec34544SRui Ueyama static int precedence(StringRef Op) { 4642ec34544SRui Ueyama return StringSwitch<int>(Op) 46539ba31ffSRui Ueyama .Cases("*", "/", "%", 5) 4662ec34544SRui Ueyama .Cases("+", "-", 4) 4672ec34544SRui Ueyama .Cases("<<", ">>", 3) 4682ec34544SRui Ueyama .Cases("<", "<=", ">", ">=", "==", "!=", 2) 4692ec34544SRui Ueyama .Cases("&", "|", 1) 4702ec34544SRui Ueyama .Default(-1); 4712ec34544SRui Ueyama } 4722ec34544SRui Ueyama 4732ec34544SRui Ueyama StringMatcher ScriptParser::readFilePatterns() { 4742ec34544SRui Ueyama std::vector<StringRef> V; 475b8a59c8aSBob Haarman while (!errorCount() && !consume(")")) 4762ec34544SRui Ueyama V.push_back(next()); 4772ec34544SRui Ueyama return StringMatcher(V); 4782ec34544SRui Ueyama } 4792ec34544SRui Ueyama 4802ec34544SRui Ueyama SortSectionPolicy ScriptParser::readSortKind() { 4812ec34544SRui Ueyama if (consume("SORT") || consume("SORT_BY_NAME")) 4822ec34544SRui Ueyama return SortSectionPolicy::Name; 4832ec34544SRui Ueyama if (consume("SORT_BY_ALIGNMENT")) 4842ec34544SRui Ueyama return SortSectionPolicy::Alignment; 4852ec34544SRui Ueyama if (consume("SORT_BY_INIT_PRIORITY")) 4862ec34544SRui Ueyama return SortSectionPolicy::Priority; 4872ec34544SRui Ueyama if (consume("SORT_NONE")) 4882ec34544SRui Ueyama return SortSectionPolicy::None; 4892ec34544SRui Ueyama return SortSectionPolicy::Default; 4902ec34544SRui Ueyama } 4912ec34544SRui Ueyama 49203fc8d1eSRui Ueyama // Reads SECTIONS command contents in the following form: 49303fc8d1eSRui Ueyama // 49403fc8d1eSRui Ueyama // <contents> ::= <elem>* 49503fc8d1eSRui Ueyama // <elem> ::= <exclude>? <glob-pattern> 49603fc8d1eSRui Ueyama // <exclude> ::= "EXCLUDE_FILE" "(" <glob-pattern>+ ")" 49703fc8d1eSRui Ueyama // 49803fc8d1eSRui Ueyama // For example, 49903fc8d1eSRui Ueyama // 50003fc8d1eSRui Ueyama // *(.foo EXCLUDE_FILE (a.o) .bar EXCLUDE_FILE (b.o) .baz) 50103fc8d1eSRui Ueyama // 50203fc8d1eSRui Ueyama // is parsed as ".foo", ".bar" with "a.o", and ".baz" with "b.o". 50303fc8d1eSRui Ueyama // The semantics of that is section .foo in any file, section .bar in 50403fc8d1eSRui Ueyama // any file but a.o, and section .baz in any file but b.o. 5052ec34544SRui Ueyama std::vector<SectionPattern> ScriptParser::readInputSectionsList() { 5062ec34544SRui Ueyama std::vector<SectionPattern> Ret; 507b8a59c8aSBob Haarman while (!errorCount() && peek() != ")") { 5082ec34544SRui Ueyama StringMatcher ExcludeFilePat; 5092ec34544SRui Ueyama if (consume("EXCLUDE_FILE")) { 5102ec34544SRui Ueyama expect("("); 5112ec34544SRui Ueyama ExcludeFilePat = readFilePatterns(); 5122ec34544SRui Ueyama } 5132ec34544SRui Ueyama 5142ec34544SRui Ueyama std::vector<StringRef> V; 515b8a59c8aSBob Haarman while (!errorCount() && peek() != ")" && peek() != "EXCLUDE_FILE") 5162ec34544SRui Ueyama V.push_back(next()); 5172ec34544SRui Ueyama 5182ec34544SRui Ueyama if (!V.empty()) 5192ec34544SRui Ueyama Ret.push_back({std::move(ExcludeFilePat), StringMatcher(V)}); 5202ec34544SRui Ueyama else 5212ec34544SRui Ueyama setError("section pattern is expected"); 5222ec34544SRui Ueyama } 5232ec34544SRui Ueyama return Ret; 5242ec34544SRui Ueyama } 5252ec34544SRui Ueyama 5262ec34544SRui Ueyama // Reads contents of "SECTIONS" directive. That directive contains a 5272ec34544SRui Ueyama // list of glob patterns for input sections. The grammar is as follows. 5282ec34544SRui Ueyama // 5292ec34544SRui Ueyama // <patterns> ::= <section-list> 5302ec34544SRui Ueyama // | <sort> "(" <section-list> ")" 5312ec34544SRui Ueyama // | <sort> "(" <sort> "(" <section-list> ")" ")" 5322ec34544SRui Ueyama // 5332ec34544SRui Ueyama // <sort> ::= "SORT" | "SORT_BY_NAME" | "SORT_BY_ALIGNMENT" 5342ec34544SRui Ueyama // | "SORT_BY_INIT_PRIORITY" | "SORT_NONE" 5352ec34544SRui Ueyama // 5362ec34544SRui Ueyama // <section-list> is parsed by readInputSectionsList(). 5372ec34544SRui Ueyama InputSectionDescription * 5382ec34544SRui Ueyama ScriptParser::readInputSectionRules(StringRef FilePattern) { 5392ec34544SRui Ueyama auto *Cmd = make<InputSectionDescription>(FilePattern); 5402ec34544SRui Ueyama expect("("); 5412ec34544SRui Ueyama 542b8a59c8aSBob Haarman while (!errorCount() && !consume(")")) { 5432ec34544SRui Ueyama SortSectionPolicy Outer = readSortKind(); 5442ec34544SRui Ueyama SortSectionPolicy Inner = SortSectionPolicy::Default; 5452ec34544SRui Ueyama std::vector<SectionPattern> V; 5462ec34544SRui Ueyama if (Outer != SortSectionPolicy::Default) { 5472ec34544SRui Ueyama expect("("); 5482ec34544SRui Ueyama Inner = readSortKind(); 5492ec34544SRui Ueyama if (Inner != SortSectionPolicy::Default) { 5502ec34544SRui Ueyama expect("("); 5512ec34544SRui Ueyama V = readInputSectionsList(); 5522ec34544SRui Ueyama expect(")"); 5532ec34544SRui Ueyama } else { 5542ec34544SRui Ueyama V = readInputSectionsList(); 5552ec34544SRui Ueyama } 5562ec34544SRui Ueyama expect(")"); 5572ec34544SRui Ueyama } else { 5582ec34544SRui Ueyama V = readInputSectionsList(); 5592ec34544SRui Ueyama } 5602ec34544SRui Ueyama 5612ec34544SRui Ueyama for (SectionPattern &Pat : V) { 5622ec34544SRui Ueyama Pat.SortInner = Inner; 5632ec34544SRui Ueyama Pat.SortOuter = Outer; 5642ec34544SRui Ueyama } 5652ec34544SRui Ueyama 5662ec34544SRui Ueyama std::move(V.begin(), V.end(), std::back_inserter(Cmd->SectionPatterns)); 5672ec34544SRui Ueyama } 5682ec34544SRui Ueyama return Cmd; 5692ec34544SRui Ueyama } 5702ec34544SRui Ueyama 5712ec34544SRui Ueyama InputSectionDescription * 5722ec34544SRui Ueyama ScriptParser::readInputSectionDescription(StringRef Tok) { 5732ec34544SRui Ueyama // Input section wildcard can be surrounded by KEEP. 5742ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep 5752ec34544SRui Ueyama if (Tok == "KEEP") { 5762ec34544SRui Ueyama expect("("); 5772ec34544SRui Ueyama StringRef FilePattern = next(); 5782ec34544SRui Ueyama InputSectionDescription *Cmd = readInputSectionRules(FilePattern); 5792ec34544SRui Ueyama expect(")"); 580ac27de9dSRui Ueyama Script->KeptSections.push_back(Cmd); 5812ec34544SRui Ueyama return Cmd; 5822ec34544SRui Ueyama } 5832ec34544SRui Ueyama return readInputSectionRules(Tok); 5842ec34544SRui Ueyama } 5852ec34544SRui Ueyama 5862ec34544SRui Ueyama void ScriptParser::readSort() { 5872ec34544SRui Ueyama expect("("); 5882ec34544SRui Ueyama expect("CONSTRUCTORS"); 5892ec34544SRui Ueyama expect(")"); 5902ec34544SRui Ueyama } 5912ec34544SRui Ueyama 59223af89ccSRui Ueyama AssertCommand *ScriptParser::readAssert() { 59323af89ccSRui Ueyama return make<AssertCommand>(readAssertExpr()); 59423af89ccSRui Ueyama } 59523af89ccSRui Ueyama 59623af89ccSRui Ueyama Expr ScriptParser::readAssertExpr() { 5972ec34544SRui Ueyama expect("("); 5982ec34544SRui Ueyama Expr E = readExpr(); 5992ec34544SRui Ueyama expect(","); 6002ec34544SRui Ueyama StringRef Msg = unquote(next()); 6012ec34544SRui Ueyama expect(")"); 602b579c439SRui Ueyama 6032ec34544SRui Ueyama return [=] { 6042ec34544SRui Ueyama if (!E().getValue()) 6052ec34544SRui Ueyama error(Msg); 6062ec34544SRui Ueyama return Script->getDot(); 6072ec34544SRui Ueyama }; 6082ec34544SRui Ueyama } 6092ec34544SRui Ueyama 6102ec34544SRui Ueyama // Reads a FILL(expr) command. We handle the FILL command as an 6112ec34544SRui Ueyama // alias for =fillexp section attribute, which is different from 6122ec34544SRui Ueyama // what GNU linkers do. 6132ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Data.html 6142ec34544SRui Ueyama uint32_t ScriptParser::readFill() { 6152ec34544SRui Ueyama expect("("); 6168acbf1ccSRui Ueyama uint32_t V = parseFill(next()); 6172ec34544SRui Ueyama expect(")"); 6182ec34544SRui Ueyama return V; 6192ec34544SRui Ueyama } 6202ec34544SRui Ueyama 6211c08e9f5SGeorge Rimar // Reads an expression and/or the special directive for an output 6221c08e9f5SGeorge Rimar // section definition. Directive is one of following: "(NOLOAD)", 6231c08e9f5SGeorge Rimar // "(COPY)", "(INFO)" or "(OVERLAY)". 6243271d370SRui Ueyama // 6253271d370SRui Ueyama // An output section name can be followed by an address expression 6261c08e9f5SGeorge Rimar // and/or directive. This grammar is not LL(1) because "(" can be 62797f4d158SGeorge Rimar // interpreted as either the beginning of some expression or beginning 6281c08e9f5SGeorge Rimar // of directive. 6293271d370SRui Ueyama // 630b579c439SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html 631fbb0463fSGeorge Rimar // https://sourceware.org/binutils/docs/ld/Output-Section-Type.html 6328c022ca7SRafael Espindola void ScriptParser::readSectionAddressType(OutputSection *Cmd) { 6333271d370SRui Ueyama if (consume("(")) { 6343271d370SRui Ueyama if (consume("NOLOAD")) { 6353271d370SRui Ueyama expect(")"); 6363271d370SRui Ueyama Cmd->Noload = true; 6373271d370SRui Ueyama return; 6383271d370SRui Ueyama } 6391c08e9f5SGeorge Rimar if (consume("COPY") || consume("INFO") || consume("OVERLAY")) { 6401c08e9f5SGeorge Rimar expect(")"); 6411c08e9f5SGeorge Rimar Cmd->NonAlloc = true; 6421c08e9f5SGeorge Rimar return; 6431c08e9f5SGeorge Rimar } 6443271d370SRui Ueyama Cmd->AddrExpr = readExpr(); 6453271d370SRui Ueyama expect(")"); 6463271d370SRui Ueyama } else { 6473271d370SRui Ueyama Cmd->AddrExpr = readExpr(); 6483271d370SRui Ueyama } 6493271d370SRui Ueyama 650fbb0463fSGeorge Rimar if (consume("(")) { 651fbb0463fSGeorge Rimar expect("NOLOAD"); 652fbb0463fSGeorge Rimar expect(")"); 653fbb0463fSGeorge Rimar Cmd->Noload = true; 654fbb0463fSGeorge Rimar } 655fbb0463fSGeorge Rimar } 656fbb0463fSGeorge Rimar 657f22ec9ddSGeorge Rimar static Expr checkAlignment(Expr E, std::string &Loc) { 658f22ec9ddSGeorge Rimar return [=] { 659f22ec9ddSGeorge Rimar uint64_t Alignment = std::max((uint64_t)1, E().getValue()); 660f22ec9ddSGeorge Rimar if (!isPowerOf2_64(Alignment)) { 661f22ec9ddSGeorge Rimar error(Loc + ": alignment must be power of 2"); 662f22ec9ddSGeorge Rimar return (uint64_t)1; // Return a dummy value. 663f22ec9ddSGeorge Rimar } 664f22ec9ddSGeorge Rimar return Alignment; 665f22ec9ddSGeorge Rimar }; 666f22ec9ddSGeorge Rimar } 667f22ec9ddSGeorge Rimar 6688c022ca7SRafael Espindola OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) { 6698c022ca7SRafael Espindola OutputSection *Cmd = 6708c022ca7SRafael Espindola Script->createOutputSection(OutSec, getCurrentLocation()); 6713271d370SRui Ueyama 672c4df670dSGeorge Rimar size_t SymbolsReferenced = Script->ReferencedSymbols.size(); 673c4df670dSGeorge Rimar 6743271d370SRui Ueyama if (peek() != ":") 6753271d370SRui Ueyama readSectionAddressType(Cmd); 6762ec34544SRui Ueyama expect(":"); 6772ec34544SRui Ueyama 678f22ec9ddSGeorge Rimar std::string Location = getCurrentLocation(); 6792ec34544SRui Ueyama if (consume("AT")) 6802ec34544SRui Ueyama Cmd->LMAExpr = readParenExpr(); 6812ec34544SRui Ueyama if (consume("ALIGN")) 682f22ec9ddSGeorge Rimar Cmd->AlignExpr = checkAlignment(readParenExpr(), Location); 6832ec34544SRui Ueyama if (consume("SUBALIGN")) 684f22ec9ddSGeorge Rimar Cmd->SubalignExpr = checkAlignment(readParenExpr(), Location); 6852ec34544SRui Ueyama 6862ec34544SRui Ueyama // Parse constraints. 6872ec34544SRui Ueyama if (consume("ONLY_IF_RO")) 6882ec34544SRui Ueyama Cmd->Constraint = ConstraintKind::ReadOnly; 6892ec34544SRui Ueyama if (consume("ONLY_IF_RW")) 6902ec34544SRui Ueyama Cmd->Constraint = ConstraintKind::ReadWrite; 6912ec34544SRui Ueyama expect("{"); 6922ec34544SRui Ueyama 693b8a59c8aSBob Haarman while (!errorCount() && !consume("}")) { 6942ec34544SRui Ueyama StringRef Tok = next(); 6952ec34544SRui Ueyama if (Tok == ";") { 6962ec34544SRui Ueyama // Empty commands are allowed. Do nothing here. 697b579c439SRui Ueyama } else if (SymbolAssignment *Assign = readProvideOrAssignment(Tok)) { 6986b394caaSRui Ueyama Cmd->SectionCommands.push_back(Assign); 699f0403c60SRui Ueyama } else if (ByteCommand *Data = readByteCommand(Tok)) { 7006b394caaSRui Ueyama Cmd->SectionCommands.push_back(Data); 7012ec34544SRui Ueyama } else if (Tok == "ASSERT") { 7026b394caaSRui Ueyama Cmd->SectionCommands.push_back(readAssert()); 7032ec34544SRui Ueyama expect(";"); 7042ec34544SRui Ueyama } else if (Tok == "CONSTRUCTORS") { 7052ec34544SRui Ueyama // CONSTRUCTORS is a keyword to make the linker recognize C++ ctors/dtors 7062ec34544SRui Ueyama // by name. This is for very old file formats such as ECOFF/XCOFF. 7072ec34544SRui Ueyama // For ELF, we should ignore. 7082ec34544SRui Ueyama } else if (Tok == "FILL") { 7092ec34544SRui Ueyama Cmd->Filler = readFill(); 7102ec34544SRui Ueyama } else if (Tok == "SORT") { 7112ec34544SRui Ueyama readSort(); 7122ec34544SRui Ueyama } else if (peek() == "(") { 7136b394caaSRui Ueyama Cmd->SectionCommands.push_back(readInputSectionDescription(Tok)); 7142ec34544SRui Ueyama } else { 7152ec34544SRui Ueyama setError("unknown command " + Tok); 7162ec34544SRui Ueyama } 7172ec34544SRui Ueyama } 7182ec34544SRui Ueyama 7192ec34544SRui Ueyama if (consume(">")) 7202ec34544SRui Ueyama Cmd->MemoryRegionName = next(); 7212ec34544SRui Ueyama 7225d01a8beSGeorge Rimar if (consume("AT")) { 7235d01a8beSGeorge Rimar expect(">"); 7245d01a8beSGeorge Rimar Cmd->LMARegionName = next(); 7255d01a8beSGeorge Rimar } 7265d01a8beSGeorge Rimar 7275d01a8beSGeorge Rimar if (Cmd->LMAExpr && !Cmd->LMARegionName.empty()) 7285d01a8beSGeorge Rimar error("section can't have both LMA and a load region"); 7295d01a8beSGeorge Rimar 7302ec34544SRui Ueyama Cmd->Phdrs = readOutputSectionPhdrs(); 7312ec34544SRui Ueyama 7322ec34544SRui Ueyama if (consume("=")) 7338acbf1ccSRui Ueyama Cmd->Filler = parseFill(next()); 7342ec34544SRui Ueyama else if (peek().startswith("=")) 7358acbf1ccSRui Ueyama Cmd->Filler = parseFill(next().drop_front()); 7362ec34544SRui Ueyama 7372ec34544SRui Ueyama // Consume optional comma following output section command. 7382ec34544SRui Ueyama consume(","); 7392ec34544SRui Ueyama 740c4df670dSGeorge Rimar if (Script->ReferencedSymbols.size() > SymbolsReferenced) 741c4df670dSGeorge Rimar Cmd->ExpressionsUseSymbols = true; 7422ec34544SRui Ueyama return Cmd; 7432ec34544SRui Ueyama } 7442ec34544SRui Ueyama 7458acbf1ccSRui Ueyama // Parses a given string as a octal/decimal/hexadecimal number and 7468acbf1ccSRui Ueyama // returns it as a big-endian number. Used for `=<fillexp>`. 7472ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html 7482ec34544SRui Ueyama // 7498acbf1ccSRui Ueyama // When reading a hexstring, ld.bfd handles it as a blob of arbitrary 7508acbf1ccSRui Ueyama // size, while ld.gold always handles it as a 32-bit big-endian number. 7518acbf1ccSRui Ueyama // We are compatible with ld.gold because it's easier to implement. 7528acbf1ccSRui Ueyama uint32_t ScriptParser::parseFill(StringRef Tok) { 753b58079d4SRui Ueyama uint32_t V = 0; 754ab94768cSGeorge Rimar if (!to_integer(Tok, V)) 7552ec34544SRui Ueyama setError("invalid filler expression: " + Tok); 756b58079d4SRui Ueyama 757b58079d4SRui Ueyama uint32_t Buf; 758b58079d4SRui Ueyama write32be(&Buf, V); 759b58079d4SRui Ueyama return Buf; 7602ec34544SRui Ueyama } 7612ec34544SRui Ueyama 7622ec34544SRui Ueyama SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) { 7632ec34544SRui Ueyama expect("("); 7642ec34544SRui Ueyama SymbolAssignment *Cmd = readAssignment(next()); 7652ec34544SRui Ueyama Cmd->Provide = Provide; 7662ec34544SRui Ueyama Cmd->Hidden = Hidden; 7672ec34544SRui Ueyama expect(")"); 7682ec34544SRui Ueyama expect(";"); 7692ec34544SRui Ueyama return Cmd; 7702ec34544SRui Ueyama } 7712ec34544SRui Ueyama 7722ec34544SRui Ueyama SymbolAssignment *ScriptParser::readProvideOrAssignment(StringRef Tok) { 7732ec34544SRui Ueyama SymbolAssignment *Cmd = nullptr; 7742ec34544SRui Ueyama if (peek() == "=" || peek() == "+=") { 7752ec34544SRui Ueyama Cmd = readAssignment(Tok); 7762ec34544SRui Ueyama expect(";"); 7772ec34544SRui Ueyama } else if (Tok == "PROVIDE") { 7782ec34544SRui Ueyama Cmd = readProvideHidden(true, false); 7792ec34544SRui Ueyama } else if (Tok == "HIDDEN") { 7802ec34544SRui Ueyama Cmd = readProvideHidden(false, true); 7812ec34544SRui Ueyama } else if (Tok == "PROVIDE_HIDDEN") { 7822ec34544SRui Ueyama Cmd = readProvideHidden(true, true); 7832ec34544SRui Ueyama } 7842ec34544SRui Ueyama return Cmd; 7852ec34544SRui Ueyama } 7862ec34544SRui Ueyama 7872ec34544SRui Ueyama SymbolAssignment *ScriptParser::readAssignment(StringRef Name) { 7882ec34544SRui Ueyama StringRef Op = next(); 7892ec34544SRui Ueyama assert(Op == "=" || Op == "+="); 7902ec34544SRui Ueyama Expr E = readExpr(); 7912ec34544SRui Ueyama if (Op == "+=") { 7922ec34544SRui Ueyama std::string Loc = getCurrentLocation(); 793722221f5SRui Ueyama E = [=] { return add(Script->getSymbolValue(Name, Loc), E()); }; 7942ec34544SRui Ueyama } 7952ec34544SRui Ueyama return make<SymbolAssignment>(Name, E, getCurrentLocation()); 7962ec34544SRui Ueyama } 7972ec34544SRui Ueyama 7982ec34544SRui Ueyama // This is an operator-precedence parser to parse a linker 7992ec34544SRui Ueyama // script expression. 8002ec34544SRui Ueyama Expr ScriptParser::readExpr() { 8012ec34544SRui Ueyama // Our lexer is context-aware. Set the in-expression bit so that 8022ec34544SRui Ueyama // they apply different tokenization rules. 8032ec34544SRui Ueyama bool Orig = InExpr; 8042ec34544SRui Ueyama InExpr = true; 8052ec34544SRui Ueyama Expr E = readExpr1(readPrimary(), 0); 8062ec34544SRui Ueyama InExpr = Orig; 8072ec34544SRui Ueyama return E; 8082ec34544SRui Ueyama } 8092ec34544SRui Ueyama 8107b91e213SGeorge Rimar Expr ScriptParser::combine(StringRef Op, Expr L, Expr R) { 8112ec34544SRui Ueyama if (Op == "+") 8122ec34544SRui Ueyama return [=] { return add(L(), R()); }; 8132ec34544SRui Ueyama if (Op == "-") 8142ec34544SRui Ueyama return [=] { return sub(L(), R()); }; 815b579c439SRui Ueyama if (Op == "*") 8161d20222aSRui Ueyama return [=] { return L().getValue() * R().getValue(); }; 8177b91e213SGeorge Rimar if (Op == "/") { 8187b91e213SGeorge Rimar std::string Loc = getCurrentLocation(); 8197b91e213SGeorge Rimar return [=]() -> uint64_t { 8207b91e213SGeorge Rimar if (uint64_t RV = R().getValue()) 8217b91e213SGeorge Rimar return L().getValue() / RV; 8227b91e213SGeorge Rimar error(Loc + ": division by zero"); 823067617f9SRui Ueyama return 0; 8247b91e213SGeorge Rimar }; 8257b91e213SGeorge Rimar } 8267b91e213SGeorge Rimar if (Op == "%") { 8277b91e213SGeorge Rimar std::string Loc = getCurrentLocation(); 8287b91e213SGeorge Rimar return [=]() -> uint64_t { 8297b91e213SGeorge Rimar if (uint64_t RV = R().getValue()) 8307b91e213SGeorge Rimar return L().getValue() % RV; 8317b91e213SGeorge Rimar error(Loc + ": modulo by zero"); 832067617f9SRui Ueyama return 0; 8337b91e213SGeorge Rimar }; 8347b91e213SGeorge Rimar } 8352ec34544SRui Ueyama if (Op == "<<") 8367e915511SRui Ueyama return [=] { return L().getValue() << R().getValue(); }; 8372ec34544SRui Ueyama if (Op == ">>") 8387e915511SRui Ueyama return [=] { return L().getValue() >> R().getValue(); }; 8392ec34544SRui Ueyama if (Op == "<") 8402ec34544SRui Ueyama return [=] { return L().getValue() < R().getValue(); }; 8412ec34544SRui Ueyama if (Op == ">") 8422ec34544SRui Ueyama return [=] { return L().getValue() > R().getValue(); }; 8432ec34544SRui Ueyama if (Op == ">=") 8442ec34544SRui Ueyama return [=] { return L().getValue() >= R().getValue(); }; 8452ec34544SRui Ueyama if (Op == "<=") 8462ec34544SRui Ueyama return [=] { return L().getValue() <= R().getValue(); }; 8472ec34544SRui Ueyama if (Op == "==") 8482ec34544SRui Ueyama return [=] { return L().getValue() == R().getValue(); }; 8492ec34544SRui Ueyama if (Op == "!=") 8502ec34544SRui Ueyama return [=] { return L().getValue() != R().getValue(); }; 8512ec34544SRui Ueyama if (Op == "&") 8522ec34544SRui Ueyama return [=] { return bitAnd(L(), R()); }; 8532ec34544SRui Ueyama if (Op == "|") 8542ec34544SRui Ueyama return [=] { return bitOr(L(), R()); }; 8552ec34544SRui Ueyama llvm_unreachable("invalid operator"); 8562ec34544SRui Ueyama } 8572ec34544SRui Ueyama 8582ec34544SRui Ueyama // This is a part of the operator-precedence parser. This function 8592ec34544SRui Ueyama // assumes that the remaining token stream starts with an operator. 8602ec34544SRui Ueyama Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) { 861b8a59c8aSBob Haarman while (!atEOF() && !errorCount()) { 8622ec34544SRui Ueyama // Read an operator and an expression. 8632ec34544SRui Ueyama if (consume("?")) 8642ec34544SRui Ueyama return readTernary(Lhs); 8652ec34544SRui Ueyama StringRef Op1 = peek(); 8662ec34544SRui Ueyama if (precedence(Op1) < MinPrec) 8672ec34544SRui Ueyama break; 8682ec34544SRui Ueyama skip(); 8692ec34544SRui Ueyama Expr Rhs = readPrimary(); 8702ec34544SRui Ueyama 8712ec34544SRui Ueyama // Evaluate the remaining part of the expression first if the 8722ec34544SRui Ueyama // next operator has greater precedence than the previous one. 8732ec34544SRui Ueyama // For example, if we have read "+" and "3", and if the next 8742ec34544SRui Ueyama // operator is "*", then we'll evaluate 3 * ... part first. 8752ec34544SRui Ueyama while (!atEOF()) { 8762ec34544SRui Ueyama StringRef Op2 = peek(); 8772ec34544SRui Ueyama if (precedence(Op2) <= precedence(Op1)) 8782ec34544SRui Ueyama break; 8792ec34544SRui Ueyama Rhs = readExpr1(Rhs, precedence(Op2)); 8802ec34544SRui Ueyama } 8812ec34544SRui Ueyama 8822ec34544SRui Ueyama Lhs = combine(Op1, Lhs, Rhs); 8832ec34544SRui Ueyama } 8842ec34544SRui Ueyama return Lhs; 8852ec34544SRui Ueyama } 8862ec34544SRui Ueyama 8875fb17128SGeorge Rimar Expr ScriptParser::getPageSize() { 8885fb17128SGeorge Rimar std::string Location = getCurrentLocation(); 8895fb17128SGeorge Rimar return [=]() -> uint64_t { 8905fb17128SGeorge Rimar if (Target) 8912ec34544SRui Ueyama return Target->PageSize; 8925fb17128SGeorge Rimar error(Location + ": unable to calculate page size"); 8935fb17128SGeorge Rimar return 4096; // Return a dummy value. 8945fb17128SGeorge Rimar }; 8955fb17128SGeorge Rimar } 8965fb17128SGeorge Rimar 8975fb17128SGeorge Rimar Expr ScriptParser::readConstant() { 8985fb17128SGeorge Rimar StringRef S = readParenLiteral(); 8995fb17128SGeorge Rimar if (S == "COMMONPAGESIZE") 9005fb17128SGeorge Rimar return getPageSize(); 9012ec34544SRui Ueyama if (S == "MAXPAGESIZE") 9025fb17128SGeorge Rimar return [] { return Config->MaxPageSize; }; 9035fb17128SGeorge Rimar setError("unknown constant: " + S); 904b068b037SGeorge Rimar return [] { return 0; }; 9052ec34544SRui Ueyama } 9062ec34544SRui Ueyama 9075c65088fSRui Ueyama // Parses Tok as an integer. It recognizes hexadecimal (prefixed with 9085c65088fSRui Ueyama // "0x" or suffixed with "H") and decimal numbers. Decimal numbers may 9095c65088fSRui Ueyama // have "K" (Ki) or "M" (Mi) suffixes. 9105c65088fSRui Ueyama static Optional<uint64_t> parseInt(StringRef Tok) { 9112ec34544SRui Ueyama // Hexadecimal 9125c65088fSRui Ueyama uint64_t Val; 9134092016bSRui Ueyama if (Tok.startswith_lower("0x")) { 9144092016bSRui Ueyama if (!to_integer(Tok.substr(2), Val, 16)) 9154092016bSRui Ueyama return None; 9165c65088fSRui Ueyama return Val; 9174092016bSRui Ueyama } 9184092016bSRui Ueyama if (Tok.endswith_lower("H")) { 9194092016bSRui Ueyama if (!to_integer(Tok.drop_back(), Val, 16)) 9204092016bSRui Ueyama return None; 9215c65088fSRui Ueyama return Val; 9224092016bSRui Ueyama } 9232ec34544SRui Ueyama 9242ec34544SRui Ueyama // Decimal 9252ec34544SRui Ueyama if (Tok.endswith_lower("K")) { 926ab94768cSGeorge Rimar if (!to_integer(Tok.drop_back(), Val, 10)) 9275c65088fSRui Ueyama return None; 9285c65088fSRui Ueyama return Val * 1024; 9292ec34544SRui Ueyama } 9305c65088fSRui Ueyama if (Tok.endswith_lower("M")) { 931ab94768cSGeorge Rimar if (!to_integer(Tok.drop_back(), Val, 10)) 9325c65088fSRui Ueyama return None; 9335c65088fSRui Ueyama return Val * 1024 * 1024; 9345c65088fSRui Ueyama } 935ab94768cSGeorge Rimar if (!to_integer(Tok, Val, 10)) 9365c65088fSRui Ueyama return None; 9375c65088fSRui Ueyama return Val; 9382ec34544SRui Ueyama } 9392ec34544SRui Ueyama 940f0403c60SRui Ueyama ByteCommand *ScriptParser::readByteCommand(StringRef Tok) { 941b579c439SRui Ueyama int Size = StringSwitch<int>(Tok) 9422ec34544SRui Ueyama .Case("BYTE", 1) 9432ec34544SRui Ueyama .Case("SHORT", 2) 9442ec34544SRui Ueyama .Case("LONG", 4) 9452ec34544SRui Ueyama .Case("QUAD", 8) 9462ec34544SRui Ueyama .Default(-1); 9472ec34544SRui Ueyama if (Size == -1) 9482ec34544SRui Ueyama return nullptr; 949f0403c60SRui Ueyama return make<ByteCommand>(readParenExpr(), Size); 9502ec34544SRui Ueyama } 9512ec34544SRui Ueyama 9522ec34544SRui Ueyama StringRef ScriptParser::readParenLiteral() { 9532ec34544SRui Ueyama expect("("); 9545e9c7762SRafael Espindola bool Orig = InExpr; 9555e9c7762SRafael Espindola InExpr = false; 9562ec34544SRui Ueyama StringRef Tok = next(); 9575e9c7762SRafael Espindola InExpr = Orig; 9582ec34544SRui Ueyama expect(")"); 9592ec34544SRui Ueyama return Tok; 9602ec34544SRui Ueyama } 9612ec34544SRui Ueyama 962617e2f98SRui Ueyama static void checkIfExists(OutputSection *Cmd, StringRef Location) { 96305c4f67cSRafael Espindola if (Cmd->Location.empty() && Script->ErrorOnMissingSection) 96405c4f67cSRafael Espindola error(Location + ": undefined section " + Cmd->Name); 96505c4f67cSRafael Espindola } 96605c4f67cSRafael Espindola 9672ec34544SRui Ueyama Expr ScriptParser::readPrimary() { 9682ec34544SRui Ueyama if (peek() == "(") 9692ec34544SRui Ueyama return readParenExpr(); 9702ec34544SRui Ueyama 9715c65088fSRui Ueyama if (consume("~")) { 9722ec34544SRui Ueyama Expr E = readPrimary(); 973b2fb84a1SRui Ueyama return [=] { return ~E().getValue(); }; 9742ec34544SRui Ueyama } 9756f1d954eSHafiz Abid Qadeer if (consume("!")) { 9766f1d954eSHafiz Abid Qadeer Expr E = readPrimary(); 9776f1d954eSHafiz Abid Qadeer return [=] { return !E().getValue(); }; 9786f1d954eSHafiz Abid Qadeer } 9795c65088fSRui Ueyama if (consume("-")) { 9802ec34544SRui Ueyama Expr E = readPrimary(); 981b2fb84a1SRui Ueyama return [=] { return -E().getValue(); }; 9822ec34544SRui Ueyama } 9832ec34544SRui Ueyama 9845c65088fSRui Ueyama StringRef Tok = next(); 9855c65088fSRui Ueyama std::string Location = getCurrentLocation(); 9865c65088fSRui Ueyama 9872ec34544SRui Ueyama // Built-in functions are parsed here. 9882ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html. 9892ec34544SRui Ueyama if (Tok == "ABSOLUTE") { 9902ec34544SRui Ueyama Expr Inner = readParenExpr(); 9912ec34544SRui Ueyama return [=] { 9922ec34544SRui Ueyama ExprValue I = Inner(); 9932ec34544SRui Ueyama I.ForceAbsolute = true; 9942ec34544SRui Ueyama return I; 9952ec34544SRui Ueyama }; 9962ec34544SRui Ueyama } 9972ec34544SRui Ueyama if (Tok == "ADDR") { 9982ec34544SRui Ueyama StringRef Name = readParenLiteral(); 9994fbe3518SRui Ueyama OutputSection *Sec = Script->getOrCreateOutputSection(Name); 100041c7ab4aSGeorge Rimar return [=]() -> ExprValue { 10014fbe3518SRui Ueyama checkIfExists(Sec, Location); 10024fbe3518SRui Ueyama return {Sec, false, 0, Location}; 100341c7ab4aSGeorge Rimar }; 10042ec34544SRui Ueyama } 10052ec34544SRui Ueyama if (Tok == "ALIGN") { 10062ec34544SRui Ueyama expect("("); 10072ec34544SRui Ueyama Expr E = readExpr(); 1008f22ec9ddSGeorge Rimar if (consume(")")) { 1009f22ec9ddSGeorge Rimar E = checkAlignment(E, Location); 1010f22ec9ddSGeorge Rimar return [=] { return alignTo(Script->getDot(), E().getValue()); }; 1011f22ec9ddSGeorge Rimar } 1012b579c439SRui Ueyama expect(","); 1013f22ec9ddSGeorge Rimar Expr E2 = checkAlignment(readExpr(), Location); 10142ec34544SRui Ueyama expect(")"); 10153c6de1a6SPetr Hosek return [=] { 10163c6de1a6SPetr Hosek ExprValue V = E(); 1017f22ec9ddSGeorge Rimar V.Alignment = E2().getValue(); 10183c6de1a6SPetr Hosek return V; 10193c6de1a6SPetr Hosek }; 10202ec34544SRui Ueyama } 10212ec34544SRui Ueyama if (Tok == "ALIGNOF") { 10222ec34544SRui Ueyama StringRef Name = readParenLiteral(); 10238c022ca7SRafael Espindola OutputSection *Cmd = Script->getOrCreateOutputSection(Name); 1024617e2f98SRui Ueyama return [=] { 1025617e2f98SRui Ueyama checkIfExists(Cmd, Location); 1026617e2f98SRui Ueyama return Cmd->Alignment; 1027617e2f98SRui Ueyama }; 10282ec34544SRui Ueyama } 10292ec34544SRui Ueyama if (Tok == "ASSERT") 103023af89ccSRui Ueyama return readAssertExpr(); 10315fb17128SGeorge Rimar if (Tok == "CONSTANT") 10325fb17128SGeorge Rimar return readConstant(); 10332ec34544SRui Ueyama if (Tok == "DATA_SEGMENT_ALIGN") { 10342ec34544SRui Ueyama expect("("); 10352ec34544SRui Ueyama Expr E = readExpr(); 10362ec34544SRui Ueyama expect(","); 10372ec34544SRui Ueyama readExpr(); 10382ec34544SRui Ueyama expect(")"); 103960833f6eSGeorge Rimar return [=] { 104060833f6eSGeorge Rimar return alignTo(Script->getDot(), std::max((uint64_t)1, E().getValue())); 104160833f6eSGeorge Rimar }; 10422ec34544SRui Ueyama } 10432ec34544SRui Ueyama if (Tok == "DATA_SEGMENT_END") { 10442ec34544SRui Ueyama expect("("); 10452ec34544SRui Ueyama expect("."); 10462ec34544SRui Ueyama expect(")"); 10472ec34544SRui Ueyama return [] { return Script->getDot(); }; 10482ec34544SRui Ueyama } 10492ec34544SRui Ueyama if (Tok == "DATA_SEGMENT_RELRO_END") { 10502ec34544SRui Ueyama // GNU linkers implements more complicated logic to handle 10512ec34544SRui Ueyama // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and 10522ec34544SRui Ueyama // just align to the next page boundary for simplicity. 10532ec34544SRui Ueyama expect("("); 10542ec34544SRui Ueyama readExpr(); 10552ec34544SRui Ueyama expect(","); 10562ec34544SRui Ueyama readExpr(); 10572ec34544SRui Ueyama expect(")"); 10585fb17128SGeorge Rimar Expr E = getPageSize(); 10595fb17128SGeorge Rimar return [=] { return alignTo(Script->getDot(), E().getValue()); }; 10602ec34544SRui Ueyama } 10612ec34544SRui Ueyama if (Tok == "DEFINED") { 10622ec34544SRui Ueyama StringRef Name = readParenLiteral(); 10639b18f50fSRui Ueyama return [=] { return Symtab->find(Name) ? 1 : 0; }; 10642ec34544SRui Ueyama } 106591b95b61SRui Ueyama if (Tok == "LENGTH") { 106691b95b61SRui Ueyama StringRef Name = readParenLiteral(); 1067b068b037SGeorge Rimar if (Script->MemoryRegions.count(Name) == 0) { 106891b95b61SRui Ueyama setError("memory region not defined: " + Name); 1069b068b037SGeorge Rimar return [] { return 0; }; 1070b068b037SGeorge Rimar } 1071ac27de9dSRui Ueyama return [=] { return Script->MemoryRegions[Name]->Length; }; 107291b95b61SRui Ueyama } 10732ec34544SRui Ueyama if (Tok == "LOADADDR") { 10742ec34544SRui Ueyama StringRef Name = readParenLiteral(); 10758c022ca7SRafael Espindola OutputSection *Cmd = Script->getOrCreateOutputSection(Name); 1076617e2f98SRui Ueyama return [=] { 1077617e2f98SRui Ueyama checkIfExists(Cmd, Location); 1078617e2f98SRui Ueyama return Cmd->getLMA(); 1079617e2f98SRui Ueyama }; 10802ec34544SRui Ueyama } 108191b95b61SRui Ueyama if (Tok == "ORIGIN") { 108291b95b61SRui Ueyama StringRef Name = readParenLiteral(); 1083b068b037SGeorge Rimar if (Script->MemoryRegions.count(Name) == 0) { 108491b95b61SRui Ueyama setError("memory region not defined: " + Name); 1085b068b037SGeorge Rimar return [] { return 0; }; 1086b068b037SGeorge Rimar } 1087ac27de9dSRui Ueyama return [=] { return Script->MemoryRegions[Name]->Origin; }; 108891b95b61SRui Ueyama } 10892ec34544SRui Ueyama if (Tok == "SEGMENT_START") { 10902ec34544SRui Ueyama expect("("); 10912ec34544SRui Ueyama skip(); 10922ec34544SRui Ueyama expect(","); 10932ec34544SRui Ueyama Expr E = readExpr(); 10942ec34544SRui Ueyama expect(")"); 10952ec34544SRui Ueyama return [=] { return E(); }; 10962ec34544SRui Ueyama } 10972ec34544SRui Ueyama if (Tok == "SIZEOF") { 10982ec34544SRui Ueyama StringRef Name = readParenLiteral(); 10998c022ca7SRafael Espindola OutputSection *Cmd = Script->getOrCreateOutputSection(Name); 110005c4f67cSRafael Espindola // Linker script does not create an output section if its content is empty. 110105c4f67cSRafael Espindola // We want to allow SIZEOF(.foo) where .foo is a section which happened to 110205c4f67cSRafael Espindola // be empty. 11038c022ca7SRafael Espindola return [=] { return Cmd->Size; }; 11042ec34544SRui Ueyama } 11052ec34544SRui Ueyama if (Tok == "SIZEOF_HEADERS") 11062ec34544SRui Ueyama return [=] { return elf::getHeaderSize(); }; 11072ec34544SRui Ueyama 11084eb2eccbSRui Ueyama // Tok is the dot. 11094eb2eccbSRui Ueyama if (Tok == ".") 1110722221f5SRui Ueyama return [=] { return Script->getSymbolValue(Tok, Location); }; 11114eb2eccbSRui Ueyama 11122ec34544SRui Ueyama // Tok is a literal number. 11135c65088fSRui Ueyama if (Optional<uint64_t> Val = parseInt(Tok)) 11145c65088fSRui Ueyama return [=] { return *Val; }; 11152ec34544SRui Ueyama 11162ec34544SRui Ueyama // Tok is a symbol name. 11172ec34544SRui Ueyama if (!isValidCIdentifier(Tok)) 11182ec34544SRui Ueyama setError("malformed number: " + Tok); 1119ac27de9dSRui Ueyama Script->ReferencedSymbols.push_back(Tok); 1120722221f5SRui Ueyama return [=] { return Script->getSymbolValue(Tok, Location); }; 11212ec34544SRui Ueyama } 11222ec34544SRui Ueyama 11232ec34544SRui Ueyama Expr ScriptParser::readTernary(Expr Cond) { 11242ec34544SRui Ueyama Expr L = readExpr(); 11252ec34544SRui Ueyama expect(":"); 11262ec34544SRui Ueyama Expr R = readExpr(); 11272ec34544SRui Ueyama return [=] { return Cond().getValue() ? L() : R(); }; 11282ec34544SRui Ueyama } 11292ec34544SRui Ueyama 11302ec34544SRui Ueyama Expr ScriptParser::readParenExpr() { 11312ec34544SRui Ueyama expect("("); 11322ec34544SRui Ueyama Expr E = readExpr(); 11332ec34544SRui Ueyama expect(")"); 11342ec34544SRui Ueyama return E; 11352ec34544SRui Ueyama } 11362ec34544SRui Ueyama 11372ec34544SRui Ueyama std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() { 11382ec34544SRui Ueyama std::vector<StringRef> Phdrs; 1139b8a59c8aSBob Haarman while (!errorCount() && peek().startswith(":")) { 11402ec34544SRui Ueyama StringRef Tok = next(); 11412ec34544SRui Ueyama Phdrs.push_back((Tok.size() == 1) ? next() : Tok.substr(1)); 11422ec34544SRui Ueyama } 11432ec34544SRui Ueyama return Phdrs; 11442ec34544SRui Ueyama } 11452ec34544SRui Ueyama 11462ec34544SRui Ueyama // Read a program header type name. The next token must be a 11472ec34544SRui Ueyama // name of a program header type or a constant (e.g. "0x3"). 11482ec34544SRui Ueyama unsigned ScriptParser::readPhdrType() { 11492ec34544SRui Ueyama StringRef Tok = next(); 11505c65088fSRui Ueyama if (Optional<uint64_t> Val = parseInt(Tok)) 11515c65088fSRui Ueyama return *Val; 11522ec34544SRui Ueyama 11532ec34544SRui Ueyama unsigned Ret = StringSwitch<unsigned>(Tok) 11542ec34544SRui Ueyama .Case("PT_NULL", PT_NULL) 11552ec34544SRui Ueyama .Case("PT_LOAD", PT_LOAD) 11562ec34544SRui Ueyama .Case("PT_DYNAMIC", PT_DYNAMIC) 11572ec34544SRui Ueyama .Case("PT_INTERP", PT_INTERP) 11582ec34544SRui Ueyama .Case("PT_NOTE", PT_NOTE) 11592ec34544SRui Ueyama .Case("PT_SHLIB", PT_SHLIB) 11602ec34544SRui Ueyama .Case("PT_PHDR", PT_PHDR) 11612ec34544SRui Ueyama .Case("PT_TLS", PT_TLS) 11622ec34544SRui Ueyama .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME) 11632ec34544SRui Ueyama .Case("PT_GNU_STACK", PT_GNU_STACK) 11642ec34544SRui Ueyama .Case("PT_GNU_RELRO", PT_GNU_RELRO) 11652ec34544SRui Ueyama .Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE) 11662ec34544SRui Ueyama .Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED) 11672ec34544SRui Ueyama .Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA) 11682ec34544SRui Ueyama .Default(-1); 11692ec34544SRui Ueyama 11702ec34544SRui Ueyama if (Ret == (unsigned)-1) { 11712ec34544SRui Ueyama setError("invalid program header type: " + Tok); 11722ec34544SRui Ueyama return PT_NULL; 11732ec34544SRui Ueyama } 11742ec34544SRui Ueyama return Ret; 11752ec34544SRui Ueyama } 11762ec34544SRui Ueyama 11772ec34544SRui Ueyama // Reads an anonymous version declaration. 11782ec34544SRui Ueyama void ScriptParser::readAnonymousDeclaration() { 11792ec34544SRui Ueyama std::vector<SymbolVersion> Locals; 11802ec34544SRui Ueyama std::vector<SymbolVersion> Globals; 11812ec34544SRui Ueyama std::tie(Locals, Globals) = readSymbols(); 11822ec34544SRui Ueyama 11832ec34544SRui Ueyama for (SymbolVersion V : Locals) { 11842ec34544SRui Ueyama if (V.Name == "*") 11852ec34544SRui Ueyama Config->DefaultSymbolVersion = VER_NDX_LOCAL; 11862ec34544SRui Ueyama else 11872ec34544SRui Ueyama Config->VersionScriptLocals.push_back(V); 11882ec34544SRui Ueyama } 11892ec34544SRui Ueyama 11902ec34544SRui Ueyama for (SymbolVersion V : Globals) 11912ec34544SRui Ueyama Config->VersionScriptGlobals.push_back(V); 11922ec34544SRui Ueyama 11932ec34544SRui Ueyama expect(";"); 11942ec34544SRui Ueyama } 11952ec34544SRui Ueyama 11962ec34544SRui Ueyama // Reads a non-anonymous version definition, 11972ec34544SRui Ueyama // e.g. "VerStr { global: foo; bar; local: *; };". 11982ec34544SRui Ueyama void ScriptParser::readVersionDeclaration(StringRef VerStr) { 11992ec34544SRui Ueyama // Read a symbol list. 12002ec34544SRui Ueyama std::vector<SymbolVersion> Locals; 12012ec34544SRui Ueyama std::vector<SymbolVersion> Globals; 12022ec34544SRui Ueyama std::tie(Locals, Globals) = readSymbols(); 12032ec34544SRui Ueyama 12042ec34544SRui Ueyama for (SymbolVersion V : Locals) { 12052ec34544SRui Ueyama if (V.Name == "*") 12062ec34544SRui Ueyama Config->DefaultSymbolVersion = VER_NDX_LOCAL; 12072ec34544SRui Ueyama else 12082ec34544SRui Ueyama Config->VersionScriptLocals.push_back(V); 12092ec34544SRui Ueyama } 12102ec34544SRui Ueyama 12112ec34544SRui Ueyama // Create a new version definition and add that to the global symbols. 12122ec34544SRui Ueyama VersionDefinition Ver; 12132ec34544SRui Ueyama Ver.Name = VerStr; 12142ec34544SRui Ueyama Ver.Globals = Globals; 12152ec34544SRui Ueyama 12162ec34544SRui Ueyama // User-defined version number starts from 2 because 0 and 1 are 12172ec34544SRui Ueyama // reserved for VER_NDX_LOCAL and VER_NDX_GLOBAL, respectively. 12182ec34544SRui Ueyama Ver.Id = Config->VersionDefinitions.size() + 2; 12192ec34544SRui Ueyama Config->VersionDefinitions.push_back(Ver); 12202ec34544SRui Ueyama 12212ec34544SRui Ueyama // Each version may have a parent version. For example, "Ver2" 12222ec34544SRui Ueyama // defined as "Ver2 { global: foo; local: *; } Ver1;" has "Ver1" 12232ec34544SRui Ueyama // as a parent. This version hierarchy is, probably against your 12242ec34544SRui Ueyama // instinct, purely for hint; the runtime doesn't care about it 12252ec34544SRui Ueyama // at all. In LLD, we simply ignore it. 12262ec34544SRui Ueyama if (peek() != ";") 12272ec34544SRui Ueyama skip(); 12282ec34544SRui Ueyama expect(";"); 12292ec34544SRui Ueyama } 12302ec34544SRui Ueyama 12311e77ad14SRui Ueyama static bool hasWildcard(StringRef S) { 12321e77ad14SRui Ueyama return S.find_first_of("?*[") != StringRef::npos; 12331e77ad14SRui Ueyama } 12341e77ad14SRui Ueyama 12352ec34544SRui Ueyama // Reads a list of symbols, e.g. "{ global: foo; bar; local: *; };". 12362ec34544SRui Ueyama std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>> 12372ec34544SRui Ueyama ScriptParser::readSymbols() { 12382ec34544SRui Ueyama std::vector<SymbolVersion> Locals; 12392ec34544SRui Ueyama std::vector<SymbolVersion> Globals; 12402ec34544SRui Ueyama std::vector<SymbolVersion> *V = &Globals; 12412ec34544SRui Ueyama 1242b8a59c8aSBob Haarman while (!errorCount()) { 12432ec34544SRui Ueyama if (consume("}")) 12442ec34544SRui Ueyama break; 12452ec34544SRui Ueyama if (consumeLabel("local")) { 12462ec34544SRui Ueyama V = &Locals; 12472ec34544SRui Ueyama continue; 12482ec34544SRui Ueyama } 12492ec34544SRui Ueyama if (consumeLabel("global")) { 12502ec34544SRui Ueyama V = &Globals; 12512ec34544SRui Ueyama continue; 12522ec34544SRui Ueyama } 12532ec34544SRui Ueyama 12542ec34544SRui Ueyama if (consume("extern")) { 12552ec34544SRui Ueyama std::vector<SymbolVersion> Ext = readVersionExtern(); 12562ec34544SRui Ueyama V->insert(V->end(), Ext.begin(), Ext.end()); 12572ec34544SRui Ueyama } else { 12582ec34544SRui Ueyama StringRef Tok = next(); 12592ec34544SRui Ueyama V->push_back({unquote(Tok), false, hasWildcard(Tok)}); 12602ec34544SRui Ueyama } 12612ec34544SRui Ueyama expect(";"); 12622ec34544SRui Ueyama } 12632ec34544SRui Ueyama return {Locals, Globals}; 12642ec34544SRui Ueyama } 12652ec34544SRui Ueyama 12662ec34544SRui Ueyama // Reads an "extern C++" directive, e.g., 12672ec34544SRui Ueyama // "extern "C++" { ns::*; "f(int, double)"; };" 126817324d8bSRui Ueyama // 126917324d8bSRui Ueyama // The last semicolon is optional. E.g. this is OK: 127017324d8bSRui Ueyama // "extern "C++" { ns::*; "f(int, double)" };" 12712ec34544SRui Ueyama std::vector<SymbolVersion> ScriptParser::readVersionExtern() { 12722ec34544SRui Ueyama StringRef Tok = next(); 12732ec34544SRui Ueyama bool IsCXX = Tok == "\"C++\""; 12742ec34544SRui Ueyama if (!IsCXX && Tok != "\"C\"") 12752ec34544SRui Ueyama setError("Unknown language"); 12762ec34544SRui Ueyama expect("{"); 12772ec34544SRui Ueyama 12782ec34544SRui Ueyama std::vector<SymbolVersion> Ret; 1279b8a59c8aSBob Haarman while (!errorCount() && peek() != "}") { 12802ec34544SRui Ueyama StringRef Tok = next(); 12812ec34544SRui Ueyama bool HasWildcard = !Tok.startswith("\"") && hasWildcard(Tok); 12822ec34544SRui Ueyama Ret.push_back({unquote(Tok), IsCXX, HasWildcard}); 128317324d8bSRui Ueyama if (consume("}")) 128417324d8bSRui Ueyama return Ret; 12852ec34544SRui Ueyama expect(";"); 12862ec34544SRui Ueyama } 12872ec34544SRui Ueyama 12882ec34544SRui Ueyama expect("}"); 12892ec34544SRui Ueyama return Ret; 12902ec34544SRui Ueyama } 12912ec34544SRui Ueyama 12922ec34544SRui Ueyama uint64_t ScriptParser::readMemoryAssignment(StringRef S1, StringRef S2, 12932ec34544SRui Ueyama StringRef S3) { 1294b579c439SRui Ueyama if (!consume(S1) && !consume(S2) && !consume(S3)) { 12952ec34544SRui Ueyama setError("expected one of: " + S1 + ", " + S2 + ", or " + S3); 12962ec34544SRui Ueyama return 0; 12972ec34544SRui Ueyama } 12982ec34544SRui Ueyama expect("="); 1299040af7deSRui Ueyama return readExpr()().getValue(); 13002ec34544SRui Ueyama } 13012ec34544SRui Ueyama 13022ec34544SRui Ueyama // Parse the MEMORY command as specified in: 13032ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/MEMORY.html 13042ec34544SRui Ueyama // 13052ec34544SRui Ueyama // MEMORY { name [(attr)] : ORIGIN = origin, LENGTH = len ... } 13062ec34544SRui Ueyama void ScriptParser::readMemory() { 13072ec34544SRui Ueyama expect("{"); 1308b8a59c8aSBob Haarman while (!errorCount() && !consume("}")) { 13092ec34544SRui Ueyama StringRef Name = next(); 13102ec34544SRui Ueyama 13112ec34544SRui Ueyama uint32_t Flags = 0; 13122ec34544SRui Ueyama uint32_t NegFlags = 0; 13132ec34544SRui Ueyama if (consume("(")) { 13142ec34544SRui Ueyama std::tie(Flags, NegFlags) = readMemoryAttributes(); 13152ec34544SRui Ueyama expect(")"); 13162ec34544SRui Ueyama } 13172ec34544SRui Ueyama expect(":"); 13182ec34544SRui Ueyama 13192ec34544SRui Ueyama uint64_t Origin = readMemoryAssignment("ORIGIN", "org", "o"); 13202ec34544SRui Ueyama expect(","); 13212ec34544SRui Ueyama uint64_t Length = readMemoryAssignment("LENGTH", "len", "l"); 13222ec34544SRui Ueyama 13235f37541cSGeorge Rimar // Add the memory region to the region map. 1324ac27de9dSRui Ueyama if (Script->MemoryRegions.count(Name)) 13252ec34544SRui Ueyama setError("region '" + Name + "' already defined"); 1326490f0a4dSRafael Espindola MemoryRegion *MR = 1327490f0a4dSRafael Espindola make<MemoryRegion>(Name, Origin, Length, Flags, NegFlags); 1328ac27de9dSRui Ueyama Script->MemoryRegions[Name] = MR; 13292ec34544SRui Ueyama } 13302ec34544SRui Ueyama } 13312ec34544SRui Ueyama 13322ec34544SRui Ueyama // This function parses the attributes used to match against section 13332ec34544SRui Ueyama // flags when placing output sections in a memory region. These flags 13342ec34544SRui Ueyama // are only used when an explicit memory region name is not used. 13352ec34544SRui Ueyama std::pair<uint32_t, uint32_t> ScriptParser::readMemoryAttributes() { 13362ec34544SRui Ueyama uint32_t Flags = 0; 13372ec34544SRui Ueyama uint32_t NegFlags = 0; 13382ec34544SRui Ueyama bool Invert = false; 13392ec34544SRui Ueyama 13402ec34544SRui Ueyama for (char C : next().lower()) { 13412ec34544SRui Ueyama uint32_t Flag = 0; 13422ec34544SRui Ueyama if (C == '!') 13432ec34544SRui Ueyama Invert = !Invert; 13442ec34544SRui Ueyama else if (C == 'w') 13452ec34544SRui Ueyama Flag = SHF_WRITE; 13462ec34544SRui Ueyama else if (C == 'x') 13472ec34544SRui Ueyama Flag = SHF_EXECINSTR; 13482ec34544SRui Ueyama else if (C == 'a') 13492ec34544SRui Ueyama Flag = SHF_ALLOC; 13502ec34544SRui Ueyama else if (C != 'r') 13512ec34544SRui Ueyama setError("invalid memory region attribute"); 13522ec34544SRui Ueyama 13532ec34544SRui Ueyama if (Invert) 13542ec34544SRui Ueyama NegFlags |= Flag; 13552ec34544SRui Ueyama else 13562ec34544SRui Ueyama Flags |= Flag; 13572ec34544SRui Ueyama } 13582ec34544SRui Ueyama return {Flags, NegFlags}; 13592ec34544SRui Ueyama } 13602ec34544SRui Ueyama 13612ec34544SRui Ueyama void elf::readLinkerScript(MemoryBufferRef MB) { 13622ec34544SRui Ueyama ScriptParser(MB).readLinkerScript(); 13632ec34544SRui Ueyama } 13642ec34544SRui Ueyama 13652ec34544SRui Ueyama void elf::readVersionScript(MemoryBufferRef MB) { 13662ec34544SRui Ueyama ScriptParser(MB).readVersionScript(); 13672ec34544SRui Ueyama } 13682ec34544SRui Ueyama 13692ec34544SRui Ueyama void elf::readDynamicList(MemoryBufferRef MB) { 13702ec34544SRui Ueyama ScriptParser(MB).readDynamicList(); 13712ec34544SRui Ueyama } 13728c7e8cceSPetr Hosek 13738c7e8cceSPetr Hosek void elf::readDefsym(StringRef Name, MemoryBufferRef MB) { 13748c7e8cceSPetr Hosek ScriptParser(MB).readDefsym(Name); 13758c7e8cceSPetr Hosek } 1376