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 //===----------------------------------------------------------------------===// 92ec34544SRui Ueyama 102ec34544SRui Ueyama #include "ScriptParser.h" 112ec34544SRui Ueyama #include "Config.h" 122ec34544SRui Ueyama #include "Driver.h" 132ec34544SRui Ueyama #include "InputSection.h" 142ec34544SRui Ueyama #include "LinkerScript.h" 152ec34544SRui Ueyama #include "Memory.h" 162ec34544SRui Ueyama #include "OutputSections.h" 172ec34544SRui Ueyama #include "ScriptLexer.h" 182ec34544SRui Ueyama #include "Symbols.h" 192ec34544SRui Ueyama #include "Target.h" 202ec34544SRui Ueyama #include "llvm/ADT/SmallString.h" 212ec34544SRui Ueyama #include "llvm/ADT/StringRef.h" 222ec34544SRui Ueyama #include "llvm/ADT/StringSwitch.h" 232ec34544SRui Ueyama #include "llvm/Support/Casting.h" 242ec34544SRui Ueyama #include "llvm/Support/ELF.h" 252ec34544SRui Ueyama #include "llvm/Support/ErrorHandling.h" 262ec34544SRui Ueyama #include "llvm/Support/FileSystem.h" 272ec34544SRui Ueyama #include "llvm/Support/Path.h" 282ec34544SRui Ueyama #include <cassert> 292ec34544SRui Ueyama #include <limits> 302ec34544SRui Ueyama #include <vector> 312ec34544SRui Ueyama 322ec34544SRui Ueyama using namespace llvm; 332ec34544SRui Ueyama using namespace llvm::ELF; 342ec34544SRui Ueyama using namespace lld; 352ec34544SRui Ueyama using namespace lld::elf; 362ec34544SRui Ueyama 372ec34544SRui Ueyama static bool isUnderSysroot(StringRef Path); 382ec34544SRui Ueyama 3996b3fe02SRui Ueyama namespace { 4096b3fe02SRui Ueyama class ScriptParser final : ScriptLexer { 412ec34544SRui Ueyama public: 422ec34544SRui Ueyama ScriptParser(MemoryBufferRef MB) 432ec34544SRui Ueyama : ScriptLexer(MB), 442ec34544SRui Ueyama IsUnderSysroot(isUnderSysroot(MB.getBufferIdentifier())) {} 452ec34544SRui Ueyama 462ec34544SRui Ueyama void readLinkerScript(); 472ec34544SRui Ueyama void readVersionScript(); 482ec34544SRui Ueyama void readDynamicList(); 492ec34544SRui Ueyama 502ec34544SRui Ueyama private: 512ec34544SRui Ueyama void addFile(StringRef Path); 522ec34544SRui Ueyama 532ec34544SRui Ueyama void readAsNeeded(); 542ec34544SRui Ueyama void readEntry(); 552ec34544SRui Ueyama void readExtern(); 562ec34544SRui Ueyama void readGroup(); 572ec34544SRui Ueyama void readInclude(); 582ec34544SRui Ueyama void readMemory(); 592ec34544SRui Ueyama void readOutput(); 602ec34544SRui Ueyama void readOutputArch(); 612ec34544SRui Ueyama void readOutputFormat(); 622ec34544SRui Ueyama void readPhdrs(); 632ec34544SRui Ueyama void readSearchDir(); 642ec34544SRui Ueyama void readSections(); 652ec34544SRui Ueyama void readVersion(); 662ec34544SRui Ueyama void readVersionScriptCommand(); 672ec34544SRui Ueyama 682ec34544SRui Ueyama SymbolAssignment *readAssignment(StringRef Name); 692ec34544SRui Ueyama BytesDataCommand *readBytesDataCommand(StringRef Tok); 702ec34544SRui Ueyama uint32_t readFill(); 712ec34544SRui Ueyama OutputSectionCommand *readOutputSectionDescription(StringRef OutSec); 722ec34544SRui Ueyama uint32_t readOutputSectionFiller(StringRef Tok); 732ec34544SRui Ueyama std::vector<StringRef> readOutputSectionPhdrs(); 742ec34544SRui Ueyama InputSectionDescription *readInputSectionDescription(StringRef Tok); 752ec34544SRui Ueyama StringMatcher readFilePatterns(); 762ec34544SRui Ueyama std::vector<SectionPattern> readInputSectionsList(); 772ec34544SRui Ueyama InputSectionDescription *readInputSectionRules(StringRef FilePattern); 782ec34544SRui Ueyama unsigned readPhdrType(); 792ec34544SRui Ueyama SortSectionPolicy readSortKind(); 802ec34544SRui Ueyama SymbolAssignment *readProvideHidden(bool Provide, bool Hidden); 812ec34544SRui Ueyama SymbolAssignment *readProvideOrAssignment(StringRef Tok); 822ec34544SRui Ueyama void readSort(); 832ec34544SRui Ueyama Expr readAssert(); 842ec34544SRui Ueyama 852ec34544SRui Ueyama uint64_t readMemoryAssignment(StringRef, StringRef, StringRef); 862ec34544SRui Ueyama std::pair<uint32_t, uint32_t> readMemoryAttributes(); 872ec34544SRui Ueyama 882ec34544SRui Ueyama Expr readExpr(); 892ec34544SRui Ueyama Expr readExpr1(Expr Lhs, int MinPrec); 902ec34544SRui Ueyama StringRef readParenLiteral(); 912ec34544SRui Ueyama Expr readPrimary(); 922ec34544SRui Ueyama Expr readTernary(Expr Cond); 932ec34544SRui Ueyama Expr readParenExpr(); 942ec34544SRui Ueyama 952ec34544SRui Ueyama // For parsing version script. 962ec34544SRui Ueyama std::vector<SymbolVersion> readVersionExtern(); 972ec34544SRui Ueyama void readAnonymousDeclaration(); 982ec34544SRui Ueyama void readVersionDeclaration(StringRef VerStr); 992ec34544SRui Ueyama 1002ec34544SRui Ueyama std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>> 1012ec34544SRui Ueyama readSymbols(); 1022ec34544SRui Ueyama 1032ec34544SRui Ueyama bool IsUnderSysroot; 1042ec34544SRui Ueyama }; 10596b3fe02SRui Ueyama } // namespace 1062ec34544SRui Ueyama 1072ec34544SRui Ueyama static bool isUnderSysroot(StringRef Path) { 1082ec34544SRui Ueyama if (Config->Sysroot == "") 1092ec34544SRui Ueyama return false; 1102ec34544SRui Ueyama for (; !Path.empty(); Path = sys::path::parent_path(Path)) 1112ec34544SRui Ueyama if (sys::fs::equivalent(Config->Sysroot, Path)) 1122ec34544SRui Ueyama return true; 1132ec34544SRui Ueyama return false; 1142ec34544SRui Ueyama } 1152ec34544SRui Ueyama 1162ec34544SRui Ueyama // Some operations only support one non absolute value. Move the 1172ec34544SRui Ueyama // absolute one to the right hand side for convenience. 1182ec34544SRui Ueyama static void moveAbsRight(ExprValue &A, ExprValue &B) { 1192ec34544SRui Ueyama if (A.isAbsolute()) 1202ec34544SRui Ueyama std::swap(A, B); 1212ec34544SRui Ueyama if (!B.isAbsolute()) 1222ec34544SRui Ueyama error("At least one side of the expression must be absolute"); 1232ec34544SRui Ueyama } 1242ec34544SRui Ueyama 1252ec34544SRui Ueyama static ExprValue add(ExprValue A, ExprValue B) { 1262ec34544SRui Ueyama moveAbsRight(A, B); 1272ec34544SRui Ueyama return {A.Sec, A.ForceAbsolute, A.Val + B.getValue()}; 1282ec34544SRui Ueyama } 1292ec34544SRui Ueyama 1302ec34544SRui Ueyama static ExprValue sub(ExprValue A, ExprValue B) { 1312ec34544SRui Ueyama return {A.Sec, A.Val - B.getValue()}; 1322ec34544SRui Ueyama } 1332ec34544SRui Ueyama 1342ec34544SRui Ueyama static ExprValue mul(ExprValue A, ExprValue B) { 1352ec34544SRui Ueyama return A.getValue() * B.getValue(); 1362ec34544SRui Ueyama } 1372ec34544SRui Ueyama 1382ec34544SRui Ueyama static ExprValue div(ExprValue A, ExprValue B) { 1392ec34544SRui Ueyama if (uint64_t BV = B.getValue()) 1402ec34544SRui Ueyama return A.getValue() / BV; 1412ec34544SRui Ueyama error("division by zero"); 1422ec34544SRui Ueyama return 0; 1432ec34544SRui Ueyama } 1442ec34544SRui Ueyama 1452ec34544SRui Ueyama static ExprValue bitAnd(ExprValue A, ExprValue B) { 1462ec34544SRui Ueyama moveAbsRight(A, B); 1472ec34544SRui Ueyama return {A.Sec, A.ForceAbsolute, 1482ec34544SRui Ueyama (A.getValue() & B.getValue()) - A.getSecAddr()}; 1492ec34544SRui Ueyama } 1502ec34544SRui Ueyama 1512ec34544SRui Ueyama static ExprValue bitOr(ExprValue A, ExprValue B) { 1522ec34544SRui Ueyama moveAbsRight(A, B); 1532ec34544SRui Ueyama return {A.Sec, A.ForceAbsolute, 1542ec34544SRui Ueyama (A.getValue() | B.getValue()) - A.getSecAddr()}; 1552ec34544SRui Ueyama } 1562ec34544SRui Ueyama 1572ec34544SRui Ueyama static ExprValue bitNot(ExprValue A) { return ~A.getValue(); } 1582ec34544SRui Ueyama static ExprValue minus(ExprValue A) { return -A.getValue(); } 1592ec34544SRui Ueyama 1602ec34544SRui Ueyama void ScriptParser::readDynamicList() { 1612ec34544SRui Ueyama expect("{"); 1622ec34544SRui Ueyama readAnonymousDeclaration(); 1632ec34544SRui Ueyama if (!atEOF()) 1642ec34544SRui Ueyama setError("EOF expected, but got " + next()); 1652ec34544SRui Ueyama } 1662ec34544SRui Ueyama 1672ec34544SRui Ueyama void ScriptParser::readVersionScript() { 1682ec34544SRui Ueyama readVersionScriptCommand(); 1692ec34544SRui Ueyama if (!atEOF()) 1702ec34544SRui Ueyama setError("EOF expected, but got " + next()); 1712ec34544SRui Ueyama } 1722ec34544SRui Ueyama 1732ec34544SRui Ueyama void ScriptParser::readVersionScriptCommand() { 1742ec34544SRui Ueyama if (consume("{")) { 1752ec34544SRui Ueyama readAnonymousDeclaration(); 1762ec34544SRui Ueyama return; 1772ec34544SRui Ueyama } 1782ec34544SRui Ueyama 1792ec34544SRui Ueyama while (!atEOF() && !Error && peek() != "}") { 1802ec34544SRui Ueyama StringRef VerStr = next(); 1812ec34544SRui Ueyama if (VerStr == "{") { 1822ec34544SRui Ueyama setError("anonymous version definition is used in " 1832ec34544SRui Ueyama "combination with other version definitions"); 1842ec34544SRui Ueyama return; 1852ec34544SRui Ueyama } 1862ec34544SRui Ueyama expect("{"); 1872ec34544SRui Ueyama readVersionDeclaration(VerStr); 1882ec34544SRui Ueyama } 1892ec34544SRui Ueyama } 1902ec34544SRui Ueyama 1912ec34544SRui Ueyama void ScriptParser::readVersion() { 1922ec34544SRui Ueyama expect("{"); 1932ec34544SRui Ueyama readVersionScriptCommand(); 1942ec34544SRui Ueyama expect("}"); 1952ec34544SRui Ueyama } 1962ec34544SRui Ueyama 1972ec34544SRui Ueyama void ScriptParser::readLinkerScript() { 1982ec34544SRui Ueyama while (!atEOF()) { 1992ec34544SRui Ueyama StringRef Tok = next(); 2002ec34544SRui Ueyama if (Tok == ";") 2012ec34544SRui Ueyama continue; 2022ec34544SRui Ueyama 2032ec34544SRui Ueyama if (Tok == "ASSERT") { 2042ec34544SRui Ueyama Script->Opt.Commands.push_back(make<AssertCommand>(readAssert())); 2052ec34544SRui Ueyama } else if (Tok == "ENTRY") { 2062ec34544SRui Ueyama readEntry(); 2072ec34544SRui Ueyama } else if (Tok == "EXTERN") { 2082ec34544SRui Ueyama readExtern(); 2092ec34544SRui Ueyama } else if (Tok == "GROUP" || Tok == "INPUT") { 2102ec34544SRui Ueyama readGroup(); 2112ec34544SRui Ueyama } else if (Tok == "INCLUDE") { 2122ec34544SRui Ueyama readInclude(); 2132ec34544SRui Ueyama } else if (Tok == "MEMORY") { 2142ec34544SRui Ueyama readMemory(); 2152ec34544SRui Ueyama } else if (Tok == "OUTPUT") { 2162ec34544SRui Ueyama readOutput(); 2172ec34544SRui Ueyama } else if (Tok == "OUTPUT_ARCH") { 2182ec34544SRui Ueyama readOutputArch(); 2192ec34544SRui Ueyama } else if (Tok == "OUTPUT_FORMAT") { 2202ec34544SRui Ueyama readOutputFormat(); 2212ec34544SRui Ueyama } else if (Tok == "PHDRS") { 2222ec34544SRui Ueyama readPhdrs(); 2232ec34544SRui Ueyama } else if (Tok == "SEARCH_DIR") { 2242ec34544SRui Ueyama readSearchDir(); 2252ec34544SRui Ueyama } else if (Tok == "SECTIONS") { 2262ec34544SRui Ueyama readSections(); 2272ec34544SRui Ueyama } else if (Tok == "VERSION") { 2282ec34544SRui Ueyama readVersion(); 2292ec34544SRui Ueyama } else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok)) { 2302ec34544SRui Ueyama Script->Opt.Commands.push_back(Cmd); 2312ec34544SRui Ueyama } else { 2322ec34544SRui Ueyama setError("unknown directive: " + Tok); 2332ec34544SRui Ueyama } 2342ec34544SRui Ueyama } 2352ec34544SRui Ueyama } 2362ec34544SRui Ueyama 2372ec34544SRui Ueyama void ScriptParser::addFile(StringRef S) { 2382ec34544SRui Ueyama if (IsUnderSysroot && S.startswith("/")) { 2392ec34544SRui Ueyama SmallString<128> PathData; 2402ec34544SRui Ueyama StringRef Path = (Config->Sysroot + S).toStringRef(PathData); 2412ec34544SRui Ueyama if (sys::fs::exists(Path)) { 2422ec34544SRui Ueyama Driver->addFile(Saver.save(Path)); 2432ec34544SRui Ueyama return; 2442ec34544SRui Ueyama } 2452ec34544SRui Ueyama } 2462ec34544SRui Ueyama 2472ec34544SRui Ueyama if (sys::path::is_absolute(S)) { 2482ec34544SRui Ueyama Driver->addFile(S); 2492ec34544SRui Ueyama } else if (S.startswith("=")) { 2502ec34544SRui Ueyama if (Config->Sysroot.empty()) 2512ec34544SRui Ueyama Driver->addFile(S.substr(1)); 2522ec34544SRui Ueyama else 2532ec34544SRui Ueyama Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1))); 2542ec34544SRui Ueyama } else if (S.startswith("-l")) { 2552ec34544SRui Ueyama Driver->addLibrary(S.substr(2)); 2562ec34544SRui Ueyama } else if (sys::fs::exists(S)) { 2572ec34544SRui Ueyama Driver->addFile(S); 2582ec34544SRui Ueyama } else { 2592ec34544SRui Ueyama if (Optional<std::string> Path = findFromSearchPaths(S)) 2602ec34544SRui Ueyama Driver->addFile(Saver.save(*Path)); 2612ec34544SRui Ueyama else 2622ec34544SRui Ueyama setError("unable to find " + S); 2632ec34544SRui Ueyama } 2642ec34544SRui Ueyama } 2652ec34544SRui Ueyama 2662ec34544SRui Ueyama void ScriptParser::readAsNeeded() { 2672ec34544SRui Ueyama expect("("); 2682ec34544SRui Ueyama bool Orig = Config->AsNeeded; 2692ec34544SRui Ueyama Config->AsNeeded = true; 2702ec34544SRui Ueyama while (!Error && !consume(")")) 2712ec34544SRui Ueyama addFile(unquote(next())); 2722ec34544SRui Ueyama Config->AsNeeded = Orig; 2732ec34544SRui Ueyama } 2742ec34544SRui Ueyama 2752ec34544SRui Ueyama void ScriptParser::readEntry() { 2762ec34544SRui Ueyama // -e <symbol> takes predecence over ENTRY(<symbol>). 2772ec34544SRui Ueyama expect("("); 2782ec34544SRui Ueyama StringRef Tok = next(); 2792ec34544SRui Ueyama if (Config->Entry.empty()) 2802ec34544SRui Ueyama Config->Entry = Tok; 2812ec34544SRui Ueyama expect(")"); 2822ec34544SRui Ueyama } 2832ec34544SRui Ueyama 2842ec34544SRui Ueyama void ScriptParser::readExtern() { 2852ec34544SRui Ueyama expect("("); 2862ec34544SRui Ueyama while (!Error && !consume(")")) 2872ec34544SRui Ueyama Config->Undefined.push_back(next()); 2882ec34544SRui Ueyama } 2892ec34544SRui Ueyama 2902ec34544SRui Ueyama void ScriptParser::readGroup() { 2912ec34544SRui Ueyama expect("("); 2922ec34544SRui Ueyama while (!Error && !consume(")")) { 2932ec34544SRui Ueyama StringRef Tok = next(); 2942ec34544SRui Ueyama if (Tok == "AS_NEEDED") 2952ec34544SRui Ueyama readAsNeeded(); 2962ec34544SRui Ueyama else 2972ec34544SRui Ueyama addFile(unquote(Tok)); 2982ec34544SRui Ueyama } 2992ec34544SRui Ueyama } 3002ec34544SRui Ueyama 3012ec34544SRui Ueyama void ScriptParser::readInclude() { 3022ec34544SRui Ueyama StringRef Tok = unquote(next()); 3032ec34544SRui Ueyama 3042ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/File-Commands.html: 3052ec34544SRui Ueyama // The file will be searched for in the current directory, and in any 3062ec34544SRui Ueyama // directory specified with the -L option. 3072ec34544SRui Ueyama if (sys::fs::exists(Tok)) { 3082ec34544SRui Ueyama if (Optional<MemoryBufferRef> MB = readFile(Tok)) 3092ec34544SRui Ueyama tokenize(*MB); 3102ec34544SRui Ueyama return; 3112ec34544SRui Ueyama } 3122ec34544SRui Ueyama if (Optional<std::string> Path = findFromSearchPaths(Tok)) { 3132ec34544SRui Ueyama if (Optional<MemoryBufferRef> MB = readFile(*Path)) 3142ec34544SRui Ueyama tokenize(*MB); 3152ec34544SRui Ueyama return; 3162ec34544SRui Ueyama } 3172ec34544SRui Ueyama setError("cannot open " + Tok); 3182ec34544SRui Ueyama } 3192ec34544SRui Ueyama 3202ec34544SRui Ueyama void ScriptParser::readOutput() { 3212ec34544SRui Ueyama // -o <file> takes predecence over OUTPUT(<file>). 3222ec34544SRui Ueyama expect("("); 3232ec34544SRui Ueyama StringRef Tok = next(); 3242ec34544SRui Ueyama if (Config->OutputFile.empty()) 3252ec34544SRui Ueyama Config->OutputFile = unquote(Tok); 3262ec34544SRui Ueyama expect(")"); 3272ec34544SRui Ueyama } 3282ec34544SRui Ueyama 3292ec34544SRui Ueyama void ScriptParser::readOutputArch() { 3302ec34544SRui Ueyama // OUTPUT_ARCH is ignored for now. 3312ec34544SRui Ueyama expect("("); 3322ec34544SRui Ueyama while (!Error && !consume(")")) 3332ec34544SRui Ueyama skip(); 3342ec34544SRui Ueyama } 3352ec34544SRui Ueyama 3362ec34544SRui Ueyama void ScriptParser::readOutputFormat() { 3372ec34544SRui Ueyama // Error checking only for now. 3382ec34544SRui Ueyama expect("("); 3392ec34544SRui Ueyama skip(); 3402ec34544SRui Ueyama StringRef Tok = next(); 3412ec34544SRui Ueyama if (Tok == ")") 3422ec34544SRui Ueyama return; 3432ec34544SRui Ueyama if (Tok != ",") { 3442ec34544SRui Ueyama setError("unexpected token: " + Tok); 3452ec34544SRui Ueyama return; 3462ec34544SRui Ueyama } 3472ec34544SRui Ueyama skip(); 3482ec34544SRui Ueyama expect(","); 3492ec34544SRui Ueyama skip(); 3502ec34544SRui Ueyama expect(")"); 3512ec34544SRui Ueyama } 3522ec34544SRui Ueyama 3532ec34544SRui Ueyama void ScriptParser::readPhdrs() { 3542ec34544SRui Ueyama expect("{"); 3552ec34544SRui Ueyama while (!Error && !consume("}")) { 3562ec34544SRui Ueyama StringRef Tok = next(); 3572ec34544SRui Ueyama Script->Opt.PhdrsCommands.push_back( 3582ec34544SRui Ueyama {Tok, PT_NULL, false, false, UINT_MAX, nullptr}); 3592ec34544SRui Ueyama PhdrsCommand &PhdrCmd = Script->Opt.PhdrsCommands.back(); 3602ec34544SRui Ueyama 3612ec34544SRui Ueyama PhdrCmd.Type = readPhdrType(); 3622ec34544SRui Ueyama do { 3632ec34544SRui Ueyama Tok = next(); 3642ec34544SRui Ueyama if (Tok == ";") 3652ec34544SRui Ueyama break; 3662ec34544SRui Ueyama if (Tok == "FILEHDR") 3672ec34544SRui Ueyama PhdrCmd.HasFilehdr = true; 3682ec34544SRui Ueyama else if (Tok == "PHDRS") 3692ec34544SRui Ueyama PhdrCmd.HasPhdrs = true; 3702ec34544SRui Ueyama else if (Tok == "AT") 3712ec34544SRui Ueyama PhdrCmd.LMAExpr = readParenExpr(); 3722ec34544SRui Ueyama else if (Tok == "FLAGS") { 3732ec34544SRui Ueyama expect("("); 3742ec34544SRui Ueyama // Passing 0 for the value of dot is a bit of a hack. It means that 3752ec34544SRui Ueyama // we accept expressions like ".|1". 3762ec34544SRui Ueyama PhdrCmd.Flags = readExpr()().getValue(); 3772ec34544SRui Ueyama expect(")"); 3782ec34544SRui Ueyama } else 3792ec34544SRui Ueyama setError("unexpected header attribute: " + Tok); 3802ec34544SRui Ueyama } while (!Error); 3812ec34544SRui Ueyama } 3822ec34544SRui Ueyama } 3832ec34544SRui Ueyama 3842ec34544SRui Ueyama void ScriptParser::readSearchDir() { 3852ec34544SRui Ueyama expect("("); 3862ec34544SRui Ueyama StringRef Tok = next(); 3872ec34544SRui Ueyama if (!Config->Nostdlib) 3882ec34544SRui Ueyama Config->SearchPaths.push_back(unquote(Tok)); 3892ec34544SRui Ueyama expect(")"); 3902ec34544SRui Ueyama } 3912ec34544SRui Ueyama 3922ec34544SRui Ueyama void ScriptParser::readSections() { 3932ec34544SRui Ueyama Script->Opt.HasSections = true; 3942ec34544SRui Ueyama // -no-rosegment is used to avoid placing read only non-executable sections in 3952ec34544SRui Ueyama // their own segment. We do the same if SECTIONS command is present in linker 3962ec34544SRui Ueyama // script. See comment for computeFlags(). 3972ec34544SRui Ueyama Config->SingleRoRx = true; 3982ec34544SRui Ueyama 3992ec34544SRui Ueyama expect("{"); 4002ec34544SRui Ueyama while (!Error && !consume("}")) { 4012ec34544SRui Ueyama StringRef Tok = next(); 4022ec34544SRui Ueyama BaseCommand *Cmd = readProvideOrAssignment(Tok); 4032ec34544SRui Ueyama if (!Cmd) { 4042ec34544SRui Ueyama if (Tok == "ASSERT") 4052ec34544SRui Ueyama Cmd = make<AssertCommand>(readAssert()); 4062ec34544SRui Ueyama else 4072ec34544SRui Ueyama Cmd = readOutputSectionDescription(Tok); 4082ec34544SRui Ueyama } 4092ec34544SRui Ueyama Script->Opt.Commands.push_back(Cmd); 4102ec34544SRui Ueyama } 4112ec34544SRui Ueyama } 4122ec34544SRui Ueyama 4132ec34544SRui Ueyama static int precedence(StringRef Op) { 4142ec34544SRui Ueyama return StringSwitch<int>(Op) 4152ec34544SRui Ueyama .Cases("*", "/", 5) 4162ec34544SRui Ueyama .Cases("+", "-", 4) 4172ec34544SRui Ueyama .Cases("<<", ">>", 3) 4182ec34544SRui Ueyama .Cases("<", "<=", ">", ">=", "==", "!=", 2) 4192ec34544SRui Ueyama .Cases("&", "|", 1) 4202ec34544SRui Ueyama .Default(-1); 4212ec34544SRui Ueyama } 4222ec34544SRui Ueyama 4232ec34544SRui Ueyama StringMatcher ScriptParser::readFilePatterns() { 4242ec34544SRui Ueyama std::vector<StringRef> V; 4252ec34544SRui Ueyama while (!Error && !consume(")")) 4262ec34544SRui Ueyama V.push_back(next()); 4272ec34544SRui Ueyama return StringMatcher(V); 4282ec34544SRui Ueyama } 4292ec34544SRui Ueyama 4302ec34544SRui Ueyama SortSectionPolicy ScriptParser::readSortKind() { 4312ec34544SRui Ueyama if (consume("SORT") || consume("SORT_BY_NAME")) 4322ec34544SRui Ueyama return SortSectionPolicy::Name; 4332ec34544SRui Ueyama if (consume("SORT_BY_ALIGNMENT")) 4342ec34544SRui Ueyama return SortSectionPolicy::Alignment; 4352ec34544SRui Ueyama if (consume("SORT_BY_INIT_PRIORITY")) 4362ec34544SRui Ueyama return SortSectionPolicy::Priority; 4372ec34544SRui Ueyama if (consume("SORT_NONE")) 4382ec34544SRui Ueyama return SortSectionPolicy::None; 4392ec34544SRui Ueyama return SortSectionPolicy::Default; 4402ec34544SRui Ueyama } 4412ec34544SRui Ueyama 4422ec34544SRui Ueyama // Method reads a list of sequence of excluded files and section globs given in 4432ec34544SRui Ueyama // a following form: ((EXCLUDE_FILE(file_pattern+))? section_pattern+)+ 4442ec34544SRui Ueyama // Example: *(.foo.1 EXCLUDE_FILE (*a.o) .foo.2 EXCLUDE_FILE (*b.o) .foo.3) 4452ec34544SRui Ueyama // The semantics of that is next: 4462ec34544SRui Ueyama // * Include .foo.1 from every file. 4472ec34544SRui Ueyama // * Include .foo.2 from every file but a.o 4482ec34544SRui Ueyama // * Include .foo.3 from every file but b.o 4492ec34544SRui Ueyama std::vector<SectionPattern> ScriptParser::readInputSectionsList() { 4502ec34544SRui Ueyama std::vector<SectionPattern> Ret; 4512ec34544SRui Ueyama while (!Error && peek() != ")") { 4522ec34544SRui Ueyama StringMatcher ExcludeFilePat; 4532ec34544SRui Ueyama if (consume("EXCLUDE_FILE")) { 4542ec34544SRui Ueyama expect("("); 4552ec34544SRui Ueyama ExcludeFilePat = readFilePatterns(); 4562ec34544SRui Ueyama } 4572ec34544SRui Ueyama 4582ec34544SRui Ueyama std::vector<StringRef> V; 4592ec34544SRui Ueyama while (!Error && peek() != ")" && peek() != "EXCLUDE_FILE") 4602ec34544SRui Ueyama V.push_back(next()); 4612ec34544SRui Ueyama 4622ec34544SRui Ueyama if (!V.empty()) 4632ec34544SRui Ueyama Ret.push_back({std::move(ExcludeFilePat), StringMatcher(V)}); 4642ec34544SRui Ueyama else 4652ec34544SRui Ueyama setError("section pattern is expected"); 4662ec34544SRui Ueyama } 4672ec34544SRui Ueyama return Ret; 4682ec34544SRui Ueyama } 4692ec34544SRui Ueyama 4702ec34544SRui Ueyama // Reads contents of "SECTIONS" directive. That directive contains a 4712ec34544SRui Ueyama // list of glob patterns for input sections. The grammar is as follows. 4722ec34544SRui Ueyama // 4732ec34544SRui Ueyama // <patterns> ::= <section-list> 4742ec34544SRui Ueyama // | <sort> "(" <section-list> ")" 4752ec34544SRui Ueyama // | <sort> "(" <sort> "(" <section-list> ")" ")" 4762ec34544SRui Ueyama // 4772ec34544SRui Ueyama // <sort> ::= "SORT" | "SORT_BY_NAME" | "SORT_BY_ALIGNMENT" 4782ec34544SRui Ueyama // | "SORT_BY_INIT_PRIORITY" | "SORT_NONE" 4792ec34544SRui Ueyama // 4802ec34544SRui Ueyama // <section-list> is parsed by readInputSectionsList(). 4812ec34544SRui Ueyama InputSectionDescription * 4822ec34544SRui Ueyama ScriptParser::readInputSectionRules(StringRef FilePattern) { 4832ec34544SRui Ueyama auto *Cmd = make<InputSectionDescription>(FilePattern); 4842ec34544SRui Ueyama expect("("); 4852ec34544SRui Ueyama 4862ec34544SRui Ueyama while (!Error && !consume(")")) { 4872ec34544SRui Ueyama SortSectionPolicy Outer = readSortKind(); 4882ec34544SRui Ueyama SortSectionPolicy Inner = SortSectionPolicy::Default; 4892ec34544SRui Ueyama std::vector<SectionPattern> V; 4902ec34544SRui Ueyama if (Outer != SortSectionPolicy::Default) { 4912ec34544SRui Ueyama expect("("); 4922ec34544SRui Ueyama Inner = readSortKind(); 4932ec34544SRui Ueyama if (Inner != SortSectionPolicy::Default) { 4942ec34544SRui Ueyama expect("("); 4952ec34544SRui Ueyama V = readInputSectionsList(); 4962ec34544SRui Ueyama expect(")"); 4972ec34544SRui Ueyama } else { 4982ec34544SRui Ueyama V = readInputSectionsList(); 4992ec34544SRui Ueyama } 5002ec34544SRui Ueyama expect(")"); 5012ec34544SRui Ueyama } else { 5022ec34544SRui Ueyama V = readInputSectionsList(); 5032ec34544SRui Ueyama } 5042ec34544SRui Ueyama 5052ec34544SRui Ueyama for (SectionPattern &Pat : V) { 5062ec34544SRui Ueyama Pat.SortInner = Inner; 5072ec34544SRui Ueyama Pat.SortOuter = Outer; 5082ec34544SRui Ueyama } 5092ec34544SRui Ueyama 5102ec34544SRui Ueyama std::move(V.begin(), V.end(), std::back_inserter(Cmd->SectionPatterns)); 5112ec34544SRui Ueyama } 5122ec34544SRui Ueyama return Cmd; 5132ec34544SRui Ueyama } 5142ec34544SRui Ueyama 5152ec34544SRui Ueyama InputSectionDescription * 5162ec34544SRui Ueyama ScriptParser::readInputSectionDescription(StringRef Tok) { 5172ec34544SRui Ueyama // Input section wildcard can be surrounded by KEEP. 5182ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep 5192ec34544SRui Ueyama if (Tok == "KEEP") { 5202ec34544SRui Ueyama expect("("); 5212ec34544SRui Ueyama StringRef FilePattern = next(); 5222ec34544SRui Ueyama InputSectionDescription *Cmd = readInputSectionRules(FilePattern); 5232ec34544SRui Ueyama expect(")"); 5242ec34544SRui Ueyama Script->Opt.KeptSections.push_back(Cmd); 5252ec34544SRui Ueyama return Cmd; 5262ec34544SRui Ueyama } 5272ec34544SRui Ueyama return readInputSectionRules(Tok); 5282ec34544SRui Ueyama } 5292ec34544SRui Ueyama 5302ec34544SRui Ueyama void ScriptParser::readSort() { 5312ec34544SRui Ueyama expect("("); 5322ec34544SRui Ueyama expect("CONSTRUCTORS"); 5332ec34544SRui Ueyama expect(")"); 5342ec34544SRui Ueyama } 5352ec34544SRui Ueyama 5362ec34544SRui Ueyama Expr ScriptParser::readAssert() { 5372ec34544SRui Ueyama expect("("); 5382ec34544SRui Ueyama Expr E = readExpr(); 5392ec34544SRui Ueyama expect(","); 5402ec34544SRui Ueyama StringRef Msg = unquote(next()); 5412ec34544SRui Ueyama expect(")"); 5422ec34544SRui Ueyama return [=] { 5432ec34544SRui Ueyama if (!E().getValue()) 5442ec34544SRui Ueyama error(Msg); 5452ec34544SRui Ueyama return Script->getDot(); 5462ec34544SRui Ueyama }; 5472ec34544SRui Ueyama } 5482ec34544SRui Ueyama 5492ec34544SRui Ueyama // Reads a FILL(expr) command. We handle the FILL command as an 5502ec34544SRui Ueyama // alias for =fillexp section attribute, which is different from 5512ec34544SRui Ueyama // what GNU linkers do. 5522ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Data.html 5532ec34544SRui Ueyama uint32_t ScriptParser::readFill() { 5542ec34544SRui Ueyama expect("("); 5552ec34544SRui Ueyama uint32_t V = readOutputSectionFiller(next()); 5562ec34544SRui Ueyama expect(")"); 5572ec34544SRui Ueyama expect(";"); 5582ec34544SRui Ueyama return V; 5592ec34544SRui Ueyama } 5602ec34544SRui Ueyama 5612ec34544SRui Ueyama OutputSectionCommand * 5622ec34544SRui Ueyama ScriptParser::readOutputSectionDescription(StringRef OutSec) { 5632ec34544SRui Ueyama OutputSectionCommand *Cmd = make<OutputSectionCommand>(OutSec); 5642ec34544SRui Ueyama Cmd->Location = getCurrentLocation(); 5652ec34544SRui Ueyama 5662ec34544SRui Ueyama // Read an address expression. 5672ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html#Output-Section-Address 5682ec34544SRui Ueyama if (peek() != ":") 5692ec34544SRui Ueyama Cmd->AddrExpr = readExpr(); 5702ec34544SRui Ueyama 5712ec34544SRui Ueyama expect(":"); 5722ec34544SRui Ueyama 5732ec34544SRui Ueyama if (consume("AT")) 5742ec34544SRui Ueyama Cmd->LMAExpr = readParenExpr(); 5752ec34544SRui Ueyama if (consume("ALIGN")) 5762ec34544SRui Ueyama Cmd->AlignExpr = readParenExpr(); 5772ec34544SRui Ueyama if (consume("SUBALIGN")) 5782ec34544SRui Ueyama Cmd->SubalignExpr = readParenExpr(); 5792ec34544SRui Ueyama 5802ec34544SRui Ueyama // Parse constraints. 5812ec34544SRui Ueyama if (consume("ONLY_IF_RO")) 5822ec34544SRui Ueyama Cmd->Constraint = ConstraintKind::ReadOnly; 5832ec34544SRui Ueyama if (consume("ONLY_IF_RW")) 5842ec34544SRui Ueyama Cmd->Constraint = ConstraintKind::ReadWrite; 5852ec34544SRui Ueyama expect("{"); 5862ec34544SRui Ueyama 5872ec34544SRui Ueyama while (!Error && !consume("}")) { 5882ec34544SRui Ueyama StringRef Tok = next(); 5892ec34544SRui Ueyama if (Tok == ";") { 5902ec34544SRui Ueyama // Empty commands are allowed. Do nothing here. 5912ec34544SRui Ueyama } else if (SymbolAssignment *Assignment = readProvideOrAssignment(Tok)) { 5922ec34544SRui Ueyama Cmd->Commands.push_back(Assignment); 5932ec34544SRui Ueyama } else if (BytesDataCommand *Data = readBytesDataCommand(Tok)) { 5942ec34544SRui Ueyama Cmd->Commands.push_back(Data); 5952ec34544SRui Ueyama } else if (Tok == "ASSERT") { 5962ec34544SRui Ueyama Cmd->Commands.push_back(make<AssertCommand>(readAssert())); 5972ec34544SRui Ueyama expect(";"); 5982ec34544SRui Ueyama } else if (Tok == "CONSTRUCTORS") { 5992ec34544SRui Ueyama // CONSTRUCTORS is a keyword to make the linker recognize C++ ctors/dtors 6002ec34544SRui Ueyama // by name. This is for very old file formats such as ECOFF/XCOFF. 6012ec34544SRui Ueyama // For ELF, we should ignore. 6022ec34544SRui Ueyama } else if (Tok == "FILL") { 6032ec34544SRui Ueyama Cmd->Filler = readFill(); 6042ec34544SRui Ueyama } else if (Tok == "SORT") { 6052ec34544SRui Ueyama readSort(); 6062ec34544SRui Ueyama } else if (peek() == "(") { 6072ec34544SRui Ueyama Cmd->Commands.push_back(readInputSectionDescription(Tok)); 6082ec34544SRui Ueyama } else { 6092ec34544SRui Ueyama setError("unknown command " + Tok); 6102ec34544SRui Ueyama } 6112ec34544SRui Ueyama } 6122ec34544SRui Ueyama 6132ec34544SRui Ueyama if (consume(">")) 6142ec34544SRui Ueyama Cmd->MemoryRegionName = next(); 6152ec34544SRui Ueyama 6162ec34544SRui Ueyama Cmd->Phdrs = readOutputSectionPhdrs(); 6172ec34544SRui Ueyama 6182ec34544SRui Ueyama if (consume("=")) 6192ec34544SRui Ueyama Cmd->Filler = readOutputSectionFiller(next()); 6202ec34544SRui Ueyama else if (peek().startswith("=")) 6212ec34544SRui Ueyama Cmd->Filler = readOutputSectionFiller(next().drop_front()); 6222ec34544SRui Ueyama 6232ec34544SRui Ueyama // Consume optional comma following output section command. 6242ec34544SRui Ueyama consume(","); 6252ec34544SRui Ueyama 6262ec34544SRui Ueyama return Cmd; 6272ec34544SRui Ueyama } 6282ec34544SRui Ueyama 6292ec34544SRui Ueyama // Read "=<number>" where <number> is an octal/decimal/hexadecimal number. 6302ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html 6312ec34544SRui Ueyama // 6322ec34544SRui Ueyama // ld.gold is not fully compatible with ld.bfd. ld.bfd handles 6332ec34544SRui Ueyama // hexstrings as blobs of arbitrary sizes, while ld.gold handles them 6342ec34544SRui Ueyama // as 32-bit big-endian values. We will do the same as ld.gold does 6352ec34544SRui Ueyama // because it's simpler than what ld.bfd does. 6362ec34544SRui Ueyama uint32_t ScriptParser::readOutputSectionFiller(StringRef Tok) { 6372ec34544SRui Ueyama uint32_t V; 6382ec34544SRui Ueyama if (!Tok.getAsInteger(0, V)) 6392ec34544SRui Ueyama return V; 6402ec34544SRui Ueyama setError("invalid filler expression: " + Tok); 6412ec34544SRui Ueyama return 0; 6422ec34544SRui Ueyama } 6432ec34544SRui Ueyama 6442ec34544SRui Ueyama SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) { 6452ec34544SRui Ueyama expect("("); 6462ec34544SRui Ueyama SymbolAssignment *Cmd = readAssignment(next()); 6472ec34544SRui Ueyama Cmd->Provide = Provide; 6482ec34544SRui Ueyama Cmd->Hidden = Hidden; 6492ec34544SRui Ueyama expect(")"); 6502ec34544SRui Ueyama expect(";"); 6512ec34544SRui Ueyama return Cmd; 6522ec34544SRui Ueyama } 6532ec34544SRui Ueyama 6542ec34544SRui Ueyama SymbolAssignment *ScriptParser::readProvideOrAssignment(StringRef Tok) { 6552ec34544SRui Ueyama SymbolAssignment *Cmd = nullptr; 6562ec34544SRui Ueyama if (peek() == "=" || peek() == "+=") { 6572ec34544SRui Ueyama Cmd = readAssignment(Tok); 6582ec34544SRui Ueyama expect(";"); 6592ec34544SRui Ueyama } else if (Tok == "PROVIDE") { 6602ec34544SRui Ueyama Cmd = readProvideHidden(true, false); 6612ec34544SRui Ueyama } else if (Tok == "HIDDEN") { 6622ec34544SRui Ueyama Cmd = readProvideHidden(false, true); 6632ec34544SRui Ueyama } else if (Tok == "PROVIDE_HIDDEN") { 6642ec34544SRui Ueyama Cmd = readProvideHidden(true, true); 6652ec34544SRui Ueyama } 6662ec34544SRui Ueyama return Cmd; 6672ec34544SRui Ueyama } 6682ec34544SRui Ueyama 6692ec34544SRui Ueyama SymbolAssignment *ScriptParser::readAssignment(StringRef Name) { 6702ec34544SRui Ueyama StringRef Op = next(); 6712ec34544SRui Ueyama assert(Op == "=" || Op == "+="); 6722ec34544SRui Ueyama Expr E = readExpr(); 6732ec34544SRui Ueyama if (Op == "+=") { 6742ec34544SRui Ueyama std::string Loc = getCurrentLocation(); 6752ec34544SRui Ueyama E = [=] { return add(Script->getSymbolValue(Loc, Name), E()); }; 6762ec34544SRui Ueyama } 6772ec34544SRui Ueyama return make<SymbolAssignment>(Name, E, getCurrentLocation()); 6782ec34544SRui Ueyama } 6792ec34544SRui Ueyama 6802ec34544SRui Ueyama // This is an operator-precedence parser to parse a linker 6812ec34544SRui Ueyama // script expression. 6822ec34544SRui Ueyama Expr ScriptParser::readExpr() { 6832ec34544SRui Ueyama // Our lexer is context-aware. Set the in-expression bit so that 6842ec34544SRui Ueyama // they apply different tokenization rules. 6852ec34544SRui Ueyama bool Orig = InExpr; 6862ec34544SRui Ueyama InExpr = true; 6872ec34544SRui Ueyama Expr E = readExpr1(readPrimary(), 0); 6882ec34544SRui Ueyama InExpr = Orig; 6892ec34544SRui Ueyama return E; 6902ec34544SRui Ueyama } 6912ec34544SRui Ueyama 6922ec34544SRui Ueyama static Expr combine(StringRef Op, Expr L, Expr R) { 6932ec34544SRui Ueyama if (Op == "*") 6942ec34544SRui Ueyama return [=] { return mul(L(), R()); }; 6952ec34544SRui Ueyama if (Op == "/") { 6962ec34544SRui Ueyama return [=] { return div(L(), R()); }; 6972ec34544SRui Ueyama } 6982ec34544SRui Ueyama if (Op == "+") 6992ec34544SRui Ueyama return [=] { return add(L(), R()); }; 7002ec34544SRui Ueyama if (Op == "-") 7012ec34544SRui Ueyama return [=] { return sub(L(), R()); }; 7022ec34544SRui Ueyama if (Op == "<<") 703*7e915511SRui Ueyama return [=] { return L().getValue() << R().getValue(); }; 7042ec34544SRui Ueyama if (Op == ">>") 705*7e915511SRui Ueyama return [=] { return L().getValue() >> R().getValue(); }; 7062ec34544SRui Ueyama if (Op == "<") 7072ec34544SRui Ueyama return [=] { return L().getValue() < R().getValue(); }; 7082ec34544SRui Ueyama if (Op == ">") 7092ec34544SRui Ueyama return [=] { return L().getValue() > R().getValue(); }; 7102ec34544SRui Ueyama if (Op == ">=") 7112ec34544SRui Ueyama return [=] { return L().getValue() >= R().getValue(); }; 7122ec34544SRui Ueyama if (Op == "<=") 7132ec34544SRui Ueyama return [=] { return L().getValue() <= R().getValue(); }; 7142ec34544SRui Ueyama if (Op == "==") 7152ec34544SRui Ueyama return [=] { return L().getValue() == R().getValue(); }; 7162ec34544SRui Ueyama if (Op == "!=") 7172ec34544SRui Ueyama return [=] { return L().getValue() != R().getValue(); }; 7182ec34544SRui Ueyama if (Op == "&") 7192ec34544SRui Ueyama return [=] { return bitAnd(L(), R()); }; 7202ec34544SRui Ueyama if (Op == "|") 7212ec34544SRui Ueyama return [=] { return bitOr(L(), R()); }; 7222ec34544SRui Ueyama llvm_unreachable("invalid operator"); 7232ec34544SRui Ueyama } 7242ec34544SRui Ueyama 7252ec34544SRui Ueyama // This is a part of the operator-precedence parser. This function 7262ec34544SRui Ueyama // assumes that the remaining token stream starts with an operator. 7272ec34544SRui Ueyama Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) { 7282ec34544SRui Ueyama while (!atEOF() && !Error) { 7292ec34544SRui Ueyama // Read an operator and an expression. 7302ec34544SRui Ueyama if (consume("?")) 7312ec34544SRui Ueyama return readTernary(Lhs); 7322ec34544SRui Ueyama StringRef Op1 = peek(); 7332ec34544SRui Ueyama if (precedence(Op1) < MinPrec) 7342ec34544SRui Ueyama break; 7352ec34544SRui Ueyama skip(); 7362ec34544SRui Ueyama Expr Rhs = readPrimary(); 7372ec34544SRui Ueyama 7382ec34544SRui Ueyama // Evaluate the remaining part of the expression first if the 7392ec34544SRui Ueyama // next operator has greater precedence than the previous one. 7402ec34544SRui Ueyama // For example, if we have read "+" and "3", and if the next 7412ec34544SRui Ueyama // operator is "*", then we'll evaluate 3 * ... part first. 7422ec34544SRui Ueyama while (!atEOF()) { 7432ec34544SRui Ueyama StringRef Op2 = peek(); 7442ec34544SRui Ueyama if (precedence(Op2) <= precedence(Op1)) 7452ec34544SRui Ueyama break; 7462ec34544SRui Ueyama Rhs = readExpr1(Rhs, precedence(Op2)); 7472ec34544SRui Ueyama } 7482ec34544SRui Ueyama 7492ec34544SRui Ueyama Lhs = combine(Op1, Lhs, Rhs); 7502ec34544SRui Ueyama } 7512ec34544SRui Ueyama return Lhs; 7522ec34544SRui Ueyama } 7532ec34544SRui Ueyama 7542ec34544SRui Ueyama uint64_t static getConstant(StringRef S) { 7552ec34544SRui Ueyama if (S == "COMMONPAGESIZE") 7562ec34544SRui Ueyama return Target->PageSize; 7572ec34544SRui Ueyama if (S == "MAXPAGESIZE") 7582ec34544SRui Ueyama return Config->MaxPageSize; 7592ec34544SRui Ueyama error("unknown constant: " + S); 7602ec34544SRui Ueyama return 0; 7612ec34544SRui Ueyama } 7622ec34544SRui Ueyama 7632ec34544SRui Ueyama // Parses Tok as an integer. Returns true if successful. 7642ec34544SRui Ueyama // It recognizes hexadecimal (prefixed with "0x" or suffixed with "H") 7652ec34544SRui Ueyama // and decimal numbers. Decimal numbers may have "K" (kilo) or 7662ec34544SRui Ueyama // "M" (mega) prefixes. 7672ec34544SRui Ueyama static bool readInteger(StringRef Tok, uint64_t &Result) { 7682ec34544SRui Ueyama // Negative number 7692ec34544SRui Ueyama if (Tok.startswith("-")) { 7702ec34544SRui Ueyama if (!readInteger(Tok.substr(1), Result)) 7712ec34544SRui Ueyama return false; 7722ec34544SRui Ueyama Result = -Result; 7732ec34544SRui Ueyama return true; 7742ec34544SRui Ueyama } 7752ec34544SRui Ueyama 7762ec34544SRui Ueyama // Hexadecimal 7772ec34544SRui Ueyama if (Tok.startswith_lower("0x")) 7782ec34544SRui Ueyama return !Tok.substr(2).getAsInteger(16, Result); 7792ec34544SRui Ueyama if (Tok.endswith_lower("H")) 7802ec34544SRui Ueyama return !Tok.drop_back().getAsInteger(16, Result); 7812ec34544SRui Ueyama 7822ec34544SRui Ueyama // Decimal 7832ec34544SRui Ueyama int Suffix = 1; 7842ec34544SRui Ueyama if (Tok.endswith_lower("K")) { 7852ec34544SRui Ueyama Suffix = 1024; 7862ec34544SRui Ueyama Tok = Tok.drop_back(); 7872ec34544SRui Ueyama } else if (Tok.endswith_lower("M")) { 7882ec34544SRui Ueyama Suffix = 1024 * 1024; 7892ec34544SRui Ueyama Tok = Tok.drop_back(); 7902ec34544SRui Ueyama } 7912ec34544SRui Ueyama if (Tok.getAsInteger(10, Result)) 7922ec34544SRui Ueyama return false; 7932ec34544SRui Ueyama Result *= Suffix; 7942ec34544SRui Ueyama return true; 7952ec34544SRui Ueyama } 7962ec34544SRui Ueyama 7972ec34544SRui Ueyama BytesDataCommand *ScriptParser::readBytesDataCommand(StringRef Tok) { 7982ec34544SRui Ueyama int Size = StringSwitch<unsigned>(Tok) 7992ec34544SRui Ueyama .Case("BYTE", 1) 8002ec34544SRui Ueyama .Case("SHORT", 2) 8012ec34544SRui Ueyama .Case("LONG", 4) 8022ec34544SRui Ueyama .Case("QUAD", 8) 8032ec34544SRui Ueyama .Default(-1); 8042ec34544SRui Ueyama if (Size == -1) 8052ec34544SRui Ueyama return nullptr; 8062ec34544SRui Ueyama 8072ec34544SRui Ueyama return make<BytesDataCommand>(readParenExpr(), Size); 8082ec34544SRui Ueyama } 8092ec34544SRui Ueyama 8102ec34544SRui Ueyama StringRef ScriptParser::readParenLiteral() { 8112ec34544SRui Ueyama expect("("); 8122ec34544SRui Ueyama StringRef Tok = next(); 8132ec34544SRui Ueyama expect(")"); 8142ec34544SRui Ueyama return Tok; 8152ec34544SRui Ueyama } 8162ec34544SRui Ueyama 8172ec34544SRui Ueyama Expr ScriptParser::readPrimary() { 8182ec34544SRui Ueyama if (peek() == "(") 8192ec34544SRui Ueyama return readParenExpr(); 8202ec34544SRui Ueyama 8212ec34544SRui Ueyama StringRef Tok = next(); 8222ec34544SRui Ueyama std::string Location = getCurrentLocation(); 8232ec34544SRui Ueyama 8242ec34544SRui Ueyama if (Tok == "~") { 8252ec34544SRui Ueyama Expr E = readPrimary(); 8262ec34544SRui Ueyama return [=] { return bitNot(E()); }; 8272ec34544SRui Ueyama } 8282ec34544SRui Ueyama if (Tok == "-") { 8292ec34544SRui Ueyama Expr E = readPrimary(); 8302ec34544SRui Ueyama return [=] { return minus(E()); }; 8312ec34544SRui Ueyama } 8322ec34544SRui Ueyama 8332ec34544SRui Ueyama // Built-in functions are parsed here. 8342ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html. 8352ec34544SRui Ueyama if (Tok == "ABSOLUTE") { 8362ec34544SRui Ueyama Expr Inner = readParenExpr(); 8372ec34544SRui Ueyama return [=] { 8382ec34544SRui Ueyama ExprValue I = Inner(); 8392ec34544SRui Ueyama I.ForceAbsolute = true; 8402ec34544SRui Ueyama return I; 8412ec34544SRui Ueyama }; 8422ec34544SRui Ueyama } 8432ec34544SRui Ueyama if (Tok == "ADDR") { 8442ec34544SRui Ueyama StringRef Name = readParenLiteral(); 8452ec34544SRui Ueyama return [=]() -> ExprValue { 8462ec34544SRui Ueyama return {Script->getOutputSection(Location, Name), 0}; 8472ec34544SRui Ueyama }; 8482ec34544SRui Ueyama } 8492ec34544SRui Ueyama if (Tok == "ALIGN") { 8502ec34544SRui Ueyama expect("("); 8512ec34544SRui Ueyama Expr E = readExpr(); 8522ec34544SRui Ueyama if (consume(",")) { 8532ec34544SRui Ueyama Expr E2 = readExpr(); 8542ec34544SRui Ueyama expect(")"); 8552ec34544SRui Ueyama return [=] { return alignTo(E().getValue(), E2().getValue()); }; 8562ec34544SRui Ueyama } 8572ec34544SRui Ueyama expect(")"); 8582ec34544SRui Ueyama return [=] { return alignTo(Script->getDot(), E().getValue()); }; 8592ec34544SRui Ueyama } 8602ec34544SRui Ueyama if (Tok == "ALIGNOF") { 8612ec34544SRui Ueyama StringRef Name = readParenLiteral(); 8622ec34544SRui Ueyama return [=] { return Script->getOutputSection(Location, Name)->Alignment; }; 8632ec34544SRui Ueyama } 8642ec34544SRui Ueyama if (Tok == "ASSERT") 8652ec34544SRui Ueyama return readAssert(); 8662ec34544SRui Ueyama if (Tok == "CONSTANT") { 8672ec34544SRui Ueyama StringRef Name = readParenLiteral(); 8682ec34544SRui Ueyama return [=] { return getConstant(Name); }; 8692ec34544SRui Ueyama } 8702ec34544SRui Ueyama if (Tok == "DATA_SEGMENT_ALIGN") { 8712ec34544SRui Ueyama expect("("); 8722ec34544SRui Ueyama Expr E = readExpr(); 8732ec34544SRui Ueyama expect(","); 8742ec34544SRui Ueyama readExpr(); 8752ec34544SRui Ueyama expect(")"); 8762ec34544SRui Ueyama return [=] { return alignTo(Script->getDot(), E().getValue()); }; 8772ec34544SRui Ueyama } 8782ec34544SRui Ueyama if (Tok == "DATA_SEGMENT_END") { 8792ec34544SRui Ueyama expect("("); 8802ec34544SRui Ueyama expect("."); 8812ec34544SRui Ueyama expect(")"); 8822ec34544SRui Ueyama return [] { return Script->getDot(); }; 8832ec34544SRui Ueyama } 8842ec34544SRui Ueyama if (Tok == "DATA_SEGMENT_RELRO_END") { 8852ec34544SRui Ueyama // GNU linkers implements more complicated logic to handle 8862ec34544SRui Ueyama // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and 8872ec34544SRui Ueyama // just align to the next page boundary for simplicity. 8882ec34544SRui Ueyama expect("("); 8892ec34544SRui Ueyama readExpr(); 8902ec34544SRui Ueyama expect(","); 8912ec34544SRui Ueyama readExpr(); 8922ec34544SRui Ueyama expect(")"); 8932ec34544SRui Ueyama return [] { return alignTo(Script->getDot(), Target->PageSize); }; 8942ec34544SRui Ueyama } 8952ec34544SRui Ueyama if (Tok == "DEFINED") { 8962ec34544SRui Ueyama StringRef Name = readParenLiteral(); 8972ec34544SRui Ueyama return [=] { return Script->isDefined(Name) ? 1 : 0; }; 8982ec34544SRui Ueyama } 8992ec34544SRui Ueyama if (Tok == "LOADADDR") { 9002ec34544SRui Ueyama StringRef Name = readParenLiteral(); 9012ec34544SRui Ueyama return [=] { return Script->getOutputSection(Location, Name)->getLMA(); }; 9022ec34544SRui Ueyama } 9032ec34544SRui Ueyama if (Tok == "SEGMENT_START") { 9042ec34544SRui Ueyama expect("("); 9052ec34544SRui Ueyama skip(); 9062ec34544SRui Ueyama expect(","); 9072ec34544SRui Ueyama Expr E = readExpr(); 9082ec34544SRui Ueyama expect(")"); 9092ec34544SRui Ueyama return [=] { return E(); }; 9102ec34544SRui Ueyama } 9112ec34544SRui Ueyama if (Tok == "SIZEOF") { 9122ec34544SRui Ueyama StringRef Name = readParenLiteral(); 9132ec34544SRui Ueyama return [=] { return Script->getOutputSectionSize(Name); }; 9142ec34544SRui Ueyama } 9152ec34544SRui Ueyama if (Tok == "SIZEOF_HEADERS") 9162ec34544SRui Ueyama return [=] { return elf::getHeaderSize(); }; 9172ec34544SRui Ueyama 9182ec34544SRui Ueyama // Tok is a literal number. 9192ec34544SRui Ueyama uint64_t V; 9202ec34544SRui Ueyama if (readInteger(Tok, V)) 9212ec34544SRui Ueyama return [=] { return V; }; 9222ec34544SRui Ueyama 9232ec34544SRui Ueyama // Tok is a symbol name. 9242ec34544SRui Ueyama if (Tok != ".") { 9252ec34544SRui Ueyama if (!isValidCIdentifier(Tok)) 9262ec34544SRui Ueyama setError("malformed number: " + Tok); 9272ec34544SRui Ueyama Script->Opt.UndefinedSymbols.push_back(Tok); 9282ec34544SRui Ueyama } 9292ec34544SRui Ueyama return [=] { return Script->getSymbolValue(Location, Tok); }; 9302ec34544SRui Ueyama } 9312ec34544SRui Ueyama 9322ec34544SRui Ueyama Expr ScriptParser::readTernary(Expr Cond) { 9332ec34544SRui Ueyama Expr L = readExpr(); 9342ec34544SRui Ueyama expect(":"); 9352ec34544SRui Ueyama Expr R = readExpr(); 9362ec34544SRui Ueyama return [=] { return Cond().getValue() ? L() : R(); }; 9372ec34544SRui Ueyama } 9382ec34544SRui Ueyama 9392ec34544SRui Ueyama Expr ScriptParser::readParenExpr() { 9402ec34544SRui Ueyama expect("("); 9412ec34544SRui Ueyama Expr E = readExpr(); 9422ec34544SRui Ueyama expect(")"); 9432ec34544SRui Ueyama return E; 9442ec34544SRui Ueyama } 9452ec34544SRui Ueyama 9462ec34544SRui Ueyama std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() { 9472ec34544SRui Ueyama std::vector<StringRef> Phdrs; 9482ec34544SRui Ueyama while (!Error && peek().startswith(":")) { 9492ec34544SRui Ueyama StringRef Tok = next(); 9502ec34544SRui Ueyama Phdrs.push_back((Tok.size() == 1) ? next() : Tok.substr(1)); 9512ec34544SRui Ueyama } 9522ec34544SRui Ueyama return Phdrs; 9532ec34544SRui Ueyama } 9542ec34544SRui Ueyama 9552ec34544SRui Ueyama // Read a program header type name. The next token must be a 9562ec34544SRui Ueyama // name of a program header type or a constant (e.g. "0x3"). 9572ec34544SRui Ueyama unsigned ScriptParser::readPhdrType() { 9582ec34544SRui Ueyama StringRef Tok = next(); 9592ec34544SRui Ueyama uint64_t Val; 9602ec34544SRui Ueyama if (readInteger(Tok, Val)) 9612ec34544SRui Ueyama return Val; 9622ec34544SRui Ueyama 9632ec34544SRui Ueyama unsigned Ret = StringSwitch<unsigned>(Tok) 9642ec34544SRui Ueyama .Case("PT_NULL", PT_NULL) 9652ec34544SRui Ueyama .Case("PT_LOAD", PT_LOAD) 9662ec34544SRui Ueyama .Case("PT_DYNAMIC", PT_DYNAMIC) 9672ec34544SRui Ueyama .Case("PT_INTERP", PT_INTERP) 9682ec34544SRui Ueyama .Case("PT_NOTE", PT_NOTE) 9692ec34544SRui Ueyama .Case("PT_SHLIB", PT_SHLIB) 9702ec34544SRui Ueyama .Case("PT_PHDR", PT_PHDR) 9712ec34544SRui Ueyama .Case("PT_TLS", PT_TLS) 9722ec34544SRui Ueyama .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME) 9732ec34544SRui Ueyama .Case("PT_GNU_STACK", PT_GNU_STACK) 9742ec34544SRui Ueyama .Case("PT_GNU_RELRO", PT_GNU_RELRO) 9752ec34544SRui Ueyama .Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE) 9762ec34544SRui Ueyama .Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED) 9772ec34544SRui Ueyama .Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA) 9782ec34544SRui Ueyama .Default(-1); 9792ec34544SRui Ueyama 9802ec34544SRui Ueyama if (Ret == (unsigned)-1) { 9812ec34544SRui Ueyama setError("invalid program header type: " + Tok); 9822ec34544SRui Ueyama return PT_NULL; 9832ec34544SRui Ueyama } 9842ec34544SRui Ueyama return Ret; 9852ec34544SRui Ueyama } 9862ec34544SRui Ueyama 9872ec34544SRui Ueyama // Reads an anonymous version declaration. 9882ec34544SRui Ueyama void ScriptParser::readAnonymousDeclaration() { 9892ec34544SRui Ueyama std::vector<SymbolVersion> Locals; 9902ec34544SRui Ueyama std::vector<SymbolVersion> Globals; 9912ec34544SRui Ueyama std::tie(Locals, Globals) = readSymbols(); 9922ec34544SRui Ueyama 9932ec34544SRui Ueyama for (SymbolVersion V : Locals) { 9942ec34544SRui Ueyama if (V.Name == "*") 9952ec34544SRui Ueyama Config->DefaultSymbolVersion = VER_NDX_LOCAL; 9962ec34544SRui Ueyama else 9972ec34544SRui Ueyama Config->VersionScriptLocals.push_back(V); 9982ec34544SRui Ueyama } 9992ec34544SRui Ueyama 10002ec34544SRui Ueyama for (SymbolVersion V : Globals) 10012ec34544SRui Ueyama Config->VersionScriptGlobals.push_back(V); 10022ec34544SRui Ueyama 10032ec34544SRui Ueyama expect(";"); 10042ec34544SRui Ueyama } 10052ec34544SRui Ueyama 10062ec34544SRui Ueyama // Reads a non-anonymous version definition, 10072ec34544SRui Ueyama // e.g. "VerStr { global: foo; bar; local: *; };". 10082ec34544SRui Ueyama void ScriptParser::readVersionDeclaration(StringRef VerStr) { 10092ec34544SRui Ueyama // Read a symbol list. 10102ec34544SRui Ueyama std::vector<SymbolVersion> Locals; 10112ec34544SRui Ueyama std::vector<SymbolVersion> Globals; 10122ec34544SRui Ueyama std::tie(Locals, Globals) = readSymbols(); 10132ec34544SRui Ueyama 10142ec34544SRui Ueyama for (SymbolVersion V : Locals) { 10152ec34544SRui Ueyama if (V.Name == "*") 10162ec34544SRui Ueyama Config->DefaultSymbolVersion = VER_NDX_LOCAL; 10172ec34544SRui Ueyama else 10182ec34544SRui Ueyama Config->VersionScriptLocals.push_back(V); 10192ec34544SRui Ueyama } 10202ec34544SRui Ueyama 10212ec34544SRui Ueyama // Create a new version definition and add that to the global symbols. 10222ec34544SRui Ueyama VersionDefinition Ver; 10232ec34544SRui Ueyama Ver.Name = VerStr; 10242ec34544SRui Ueyama Ver.Globals = Globals; 10252ec34544SRui Ueyama 10262ec34544SRui Ueyama // User-defined version number starts from 2 because 0 and 1 are 10272ec34544SRui Ueyama // reserved for VER_NDX_LOCAL and VER_NDX_GLOBAL, respectively. 10282ec34544SRui Ueyama Ver.Id = Config->VersionDefinitions.size() + 2; 10292ec34544SRui Ueyama Config->VersionDefinitions.push_back(Ver); 10302ec34544SRui Ueyama 10312ec34544SRui Ueyama // Each version may have a parent version. For example, "Ver2" 10322ec34544SRui Ueyama // defined as "Ver2 { global: foo; local: *; } Ver1;" has "Ver1" 10332ec34544SRui Ueyama // as a parent. This version hierarchy is, probably against your 10342ec34544SRui Ueyama // instinct, purely for hint; the runtime doesn't care about it 10352ec34544SRui Ueyama // at all. In LLD, we simply ignore it. 10362ec34544SRui Ueyama if (peek() != ";") 10372ec34544SRui Ueyama skip(); 10382ec34544SRui Ueyama expect(";"); 10392ec34544SRui Ueyama } 10402ec34544SRui Ueyama 10412ec34544SRui Ueyama // Reads a list of symbols, e.g. "{ global: foo; bar; local: *; };". 10422ec34544SRui Ueyama std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>> 10432ec34544SRui Ueyama ScriptParser::readSymbols() { 10442ec34544SRui Ueyama std::vector<SymbolVersion> Locals; 10452ec34544SRui Ueyama std::vector<SymbolVersion> Globals; 10462ec34544SRui Ueyama std::vector<SymbolVersion> *V = &Globals; 10472ec34544SRui Ueyama 10482ec34544SRui Ueyama while (!Error) { 10492ec34544SRui Ueyama if (consume("}")) 10502ec34544SRui Ueyama break; 10512ec34544SRui Ueyama if (consumeLabel("local")) { 10522ec34544SRui Ueyama V = &Locals; 10532ec34544SRui Ueyama continue; 10542ec34544SRui Ueyama } 10552ec34544SRui Ueyama if (consumeLabel("global")) { 10562ec34544SRui Ueyama V = &Globals; 10572ec34544SRui Ueyama continue; 10582ec34544SRui Ueyama } 10592ec34544SRui Ueyama 10602ec34544SRui Ueyama if (consume("extern")) { 10612ec34544SRui Ueyama std::vector<SymbolVersion> Ext = readVersionExtern(); 10622ec34544SRui Ueyama V->insert(V->end(), Ext.begin(), Ext.end()); 10632ec34544SRui Ueyama } else { 10642ec34544SRui Ueyama StringRef Tok = next(); 10652ec34544SRui Ueyama V->push_back({unquote(Tok), false, hasWildcard(Tok)}); 10662ec34544SRui Ueyama } 10672ec34544SRui Ueyama expect(";"); 10682ec34544SRui Ueyama } 10692ec34544SRui Ueyama return {Locals, Globals}; 10702ec34544SRui Ueyama } 10712ec34544SRui Ueyama 10722ec34544SRui Ueyama // Reads an "extern C++" directive, e.g., 10732ec34544SRui Ueyama // "extern "C++" { ns::*; "f(int, double)"; };" 10742ec34544SRui Ueyama std::vector<SymbolVersion> ScriptParser::readVersionExtern() { 10752ec34544SRui Ueyama StringRef Tok = next(); 10762ec34544SRui Ueyama bool IsCXX = Tok == "\"C++\""; 10772ec34544SRui Ueyama if (!IsCXX && Tok != "\"C\"") 10782ec34544SRui Ueyama setError("Unknown language"); 10792ec34544SRui Ueyama expect("{"); 10802ec34544SRui Ueyama 10812ec34544SRui Ueyama std::vector<SymbolVersion> Ret; 10822ec34544SRui Ueyama while (!Error && peek() != "}") { 10832ec34544SRui Ueyama StringRef Tok = next(); 10842ec34544SRui Ueyama bool HasWildcard = !Tok.startswith("\"") && hasWildcard(Tok); 10852ec34544SRui Ueyama Ret.push_back({unquote(Tok), IsCXX, HasWildcard}); 10862ec34544SRui Ueyama expect(";"); 10872ec34544SRui Ueyama } 10882ec34544SRui Ueyama 10892ec34544SRui Ueyama expect("}"); 10902ec34544SRui Ueyama return Ret; 10912ec34544SRui Ueyama } 10922ec34544SRui Ueyama 10932ec34544SRui Ueyama uint64_t ScriptParser::readMemoryAssignment(StringRef S1, StringRef S2, 10942ec34544SRui Ueyama StringRef S3) { 10952ec34544SRui Ueyama if (!(consume(S1) || consume(S2) || consume(S3))) { 10962ec34544SRui Ueyama setError("expected one of: " + S1 + ", " + S2 + ", or " + S3); 10972ec34544SRui Ueyama return 0; 10982ec34544SRui Ueyama } 10992ec34544SRui Ueyama expect("="); 11002ec34544SRui Ueyama 11012ec34544SRui Ueyama // TODO: Fully support constant expressions. 11022ec34544SRui Ueyama uint64_t Val; 11032ec34544SRui Ueyama if (!readInteger(next(), Val)) 11042ec34544SRui Ueyama setError("nonconstant expression for " + S1); 11052ec34544SRui Ueyama return Val; 11062ec34544SRui Ueyama } 11072ec34544SRui Ueyama 11082ec34544SRui Ueyama // Parse the MEMORY command as specified in: 11092ec34544SRui Ueyama // https://sourceware.org/binutils/docs/ld/MEMORY.html 11102ec34544SRui Ueyama // 11112ec34544SRui Ueyama // MEMORY { name [(attr)] : ORIGIN = origin, LENGTH = len ... } 11122ec34544SRui Ueyama void ScriptParser::readMemory() { 11132ec34544SRui Ueyama expect("{"); 11142ec34544SRui Ueyama while (!Error && !consume("}")) { 11152ec34544SRui Ueyama StringRef Name = next(); 11162ec34544SRui Ueyama 11172ec34544SRui Ueyama uint32_t Flags = 0; 11182ec34544SRui Ueyama uint32_t NegFlags = 0; 11192ec34544SRui Ueyama if (consume("(")) { 11202ec34544SRui Ueyama std::tie(Flags, NegFlags) = readMemoryAttributes(); 11212ec34544SRui Ueyama expect(")"); 11222ec34544SRui Ueyama } 11232ec34544SRui Ueyama expect(":"); 11242ec34544SRui Ueyama 11252ec34544SRui Ueyama uint64_t Origin = readMemoryAssignment("ORIGIN", "org", "o"); 11262ec34544SRui Ueyama expect(","); 11272ec34544SRui Ueyama uint64_t Length = readMemoryAssignment("LENGTH", "len", "l"); 11282ec34544SRui Ueyama 11292ec34544SRui Ueyama // Add the memory region to the region map (if it doesn't already exist). 11302ec34544SRui Ueyama auto It = Script->Opt.MemoryRegions.find(Name); 11312ec34544SRui Ueyama if (It != Script->Opt.MemoryRegions.end()) 11322ec34544SRui Ueyama setError("region '" + Name + "' already defined"); 11332ec34544SRui Ueyama else 11342ec34544SRui Ueyama Script->Opt.MemoryRegions[Name] = {Name, Origin, Length, 11352ec34544SRui Ueyama Origin, Flags, NegFlags}; 11362ec34544SRui Ueyama } 11372ec34544SRui Ueyama } 11382ec34544SRui Ueyama 11392ec34544SRui Ueyama // This function parses the attributes used to match against section 11402ec34544SRui Ueyama // flags when placing output sections in a memory region. These flags 11412ec34544SRui Ueyama // are only used when an explicit memory region name is not used. 11422ec34544SRui Ueyama std::pair<uint32_t, uint32_t> ScriptParser::readMemoryAttributes() { 11432ec34544SRui Ueyama uint32_t Flags = 0; 11442ec34544SRui Ueyama uint32_t NegFlags = 0; 11452ec34544SRui Ueyama bool Invert = false; 11462ec34544SRui Ueyama 11472ec34544SRui Ueyama for (char C : next().lower()) { 11482ec34544SRui Ueyama uint32_t Flag = 0; 11492ec34544SRui Ueyama if (C == '!') 11502ec34544SRui Ueyama Invert = !Invert; 11512ec34544SRui Ueyama else if (C == 'w') 11522ec34544SRui Ueyama Flag = SHF_WRITE; 11532ec34544SRui Ueyama else if (C == 'x') 11542ec34544SRui Ueyama Flag = SHF_EXECINSTR; 11552ec34544SRui Ueyama else if (C == 'a') 11562ec34544SRui Ueyama Flag = SHF_ALLOC; 11572ec34544SRui Ueyama else if (C != 'r') 11582ec34544SRui Ueyama setError("invalid memory region attribute"); 11592ec34544SRui Ueyama 11602ec34544SRui Ueyama if (Invert) 11612ec34544SRui Ueyama NegFlags |= Flag; 11622ec34544SRui Ueyama else 11632ec34544SRui Ueyama Flags |= Flag; 11642ec34544SRui Ueyama } 11652ec34544SRui Ueyama return {Flags, NegFlags}; 11662ec34544SRui Ueyama } 11672ec34544SRui Ueyama 11682ec34544SRui Ueyama void elf::readLinkerScript(MemoryBufferRef MB) { 11692ec34544SRui Ueyama ScriptParser(MB).readLinkerScript(); 11702ec34544SRui Ueyama } 11712ec34544SRui Ueyama 11722ec34544SRui Ueyama void elf::readVersionScript(MemoryBufferRef MB) { 11732ec34544SRui Ueyama ScriptParser(MB).readVersionScript(); 11742ec34544SRui Ueyama } 11752ec34544SRui Ueyama 11762ec34544SRui Ueyama void elf::readDynamicList(MemoryBufferRef MB) { 11772ec34544SRui Ueyama ScriptParser(MB).readDynamicList(); 11782ec34544SRui Ueyama } 1179