From cf57a670bb3b85a362098b931a3176f2debe6a6a Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 21 Sep 2024 11:06:06 -0700 Subject: [PATCH] [ELF] ScriptParser: pass Ctx to ScriptParser and ScriptLexer. NFC --- lld/ELF/Driver.cpp | 12 ++--- lld/ELF/ScriptLexer.cpp | 9 ++-- lld/ELF/ScriptLexer.h | 5 +- lld/ELF/ScriptParser.cpp | 101 ++++++++++++++++++++------------------- lld/ELF/ScriptParser.h | 9 ++-- 5 files changed, 70 insertions(+), 66 deletions(-) diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 2d8752cea03c..95baaeec1a18 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -293,7 +293,7 @@ void LinkerDriver::addFile(StringRef path, bool withLOption) { switch (identify_magic(mbref.getBuffer())) { case file_magic::unknown: - readLinkerScript(mbref); + readLinkerScript(ctx, mbref); return; case file_magic::archive: { auto members = getArchiveMembers(mbref); @@ -1810,12 +1810,12 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) { for (auto *arg : args.filtered(OPT_dynamic_list, OPT_export_dynamic_symbol_list)) if (std::optional buffer = readFile(arg->getValue())) - readDynamicList(*buffer); + readDynamicList(ctx, *buffer); for (auto *arg : args.filtered(OPT_version_script)) if (std::optional path = searchScript(arg->getValue())) { if (std::optional buffer = readFile(*path)) - readVersionScript(*buffer); + readVersionScript(ctx, *buffer); } else { error(Twine("cannot find version script ") + arg->getValue()); } @@ -1943,7 +1943,7 @@ void LinkerDriver::createFiles(opt::InputArgList &args) { hasInput = true; break; case OPT_defsym: { - readDefsym(MemoryBufferRef(arg->getValue(), "--defsym")); + readDefsym(ctx, MemoryBufferRef(arg->getValue(), "--defsym")); break; } case OPT_script: @@ -1953,7 +1953,7 @@ void LinkerDriver::createFiles(opt::InputArgList &args) { if (arg->getOption().matches(OPT_default_script)) { defaultScript = mb; } else { - readLinkerScript(*mb); + readLinkerScript(ctx, *mb); hasScript = true; } } @@ -2039,7 +2039,7 @@ void LinkerDriver::createFiles(opt::InputArgList &args) { } if (defaultScript && !hasScript) - readLinkerScript(*defaultScript); + readLinkerScript(ctx, *defaultScript); if (files.empty() && !hasInput && errorCount() == 0) error("no input files"); } diff --git a/lld/ELF/ScriptLexer.cpp b/lld/ELF/ScriptLexer.cpp index 40528f0cd7f6..7b45e26ee405 100644 --- a/lld/ELF/ScriptLexer.cpp +++ b/lld/ELF/ScriptLexer.cpp @@ -39,21 +39,22 @@ using namespace llvm; using namespace lld; using namespace lld::elf; -ScriptLexer::Buffer::Buffer(MemoryBufferRef mb) +ScriptLexer::Buffer::Buffer(Ctx &ctx, MemoryBufferRef mb) : s(mb.getBuffer()), filename(mb.getBufferIdentifier()), begin(mb.getBufferStart()) { - if (config->sysroot == "") + if (ctx.arg.sysroot == "") return; StringRef path = filename; for (; !path.empty(); path = sys::path::parent_path(path)) { - if (!sys::fs::equivalent(config->sysroot, path)) + if (!sys::fs::equivalent(ctx.arg.sysroot, path)) continue; isUnderSysroot = true; return; } } -ScriptLexer::ScriptLexer(MemoryBufferRef mb) : curBuf(mb), mbs(1, mb) { +ScriptLexer::ScriptLexer(Ctx &ctx, MemoryBufferRef mb) + : curBuf(ctx, mb), mbs(1, mb) { activeFilenames.insert(mb.getBufferIdentifier()); } diff --git a/lld/ELF/ScriptLexer.h b/lld/ELF/ScriptLexer.h index ffd84411f22a..0f31ef17844b 100644 --- a/lld/ELF/ScriptLexer.h +++ b/lld/ELF/ScriptLexer.h @@ -17,6 +17,7 @@ #include namespace lld::elf { +struct Ctx; class ScriptLexer { protected: @@ -30,7 +31,7 @@ protected: bool isUnderSysroot = false; Buffer() = default; - Buffer(MemoryBufferRef mb); + Buffer(Ctx &ctx, MemoryBufferRef mb); }; // The current buffer and parent buffers due to INCLUDE. Buffer curBuf; @@ -57,7 +58,7 @@ protected: bool eof = false; public: - explicit ScriptLexer(MemoryBufferRef mb); + explicit ScriptLexer(Ctx &ctx, MemoryBufferRef mb); void setError(const Twine &msg); void lex(); diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp index 819036a1ab18..6816138467cd 100644 --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -47,8 +47,7 @@ using namespace lld::elf; namespace { class ScriptParser final : ScriptLexer { public: - ScriptParser(MemoryBufferRef mb) : ScriptLexer(mb) { - } + ScriptParser(Ctx &ctx, MemoryBufferRef mb) : ScriptLexer(ctx, mb) {} void readLinkerScript(); void readVersionScript(); @@ -197,7 +196,7 @@ void ScriptParser::readDynamicList() { } for (SymbolVersion v : globals) - config->dynamicList.push_back(v); + ctx.arg.dynamicList.push_back(v); } void ScriptParser::readVersionScript() { @@ -313,11 +312,11 @@ void ScriptParser::readNoCrossRefs(bool to) { void ScriptParser::addFile(StringRef s) { if (curBuf.isUnderSysroot && s.starts_with("/")) { SmallString<128> pathData; - StringRef path = (config->sysroot + s).toStringRef(pathData); + StringRef path = (ctx.arg.sysroot + s).toStringRef(pathData); if (sys::fs::exists(path)) ctx.driver.addFile(saver().save(path), /*withLOption=*/false); else - setError("cannot find " + s + " inside " + config->sysroot); + setError("cannot find " + s + " inside " + ctx.arg.sysroot); return; } @@ -326,10 +325,10 @@ void ScriptParser::addFile(StringRef s) { ctx.driver.addFile(s, /*withLOption=*/false); } else if (s.starts_with("=")) { // Case 2: relative to the sysroot. - if (config->sysroot.empty()) + if (ctx.arg.sysroot.empty()) ctx.driver.addFile(s.substr(1), /*withLOption=*/false); else - ctx.driver.addFile(saver().save(config->sysroot + "/" + s.substr(1)), + ctx.driver.addFile(saver().save(ctx.arg.sysroot + "/" + s.substr(1)), /*withLOption=*/false); } else if (s.starts_with("-l")) { // Case 3: search in the list of library paths. @@ -361,26 +360,26 @@ void ScriptParser::addFile(StringRef s) { void ScriptParser::readAsNeeded() { expect("("); - bool orig = config->asNeeded; - config->asNeeded = true; + bool orig = ctx.arg.asNeeded; + ctx.arg.asNeeded = true; while (auto tok = till(")")) addFile(unquote(tok)); - config->asNeeded = orig; + ctx.arg.asNeeded = orig; } void ScriptParser::readEntry() { // -e takes predecence over ENTRY(). expect("("); StringRef name = readName(); - if (config->entry.empty()) - config->entry = name; + if (ctx.arg.entry.empty()) + ctx.arg.entry = name; expect(")"); } void ScriptParser::readExtern() { expect("("); while (auto tok = till(")")) - config->undefined.push_back(unquote(tok)); + ctx.arg.undefined.push_back(unquote(tok)); } void ScriptParser::readGroup() { @@ -402,7 +401,7 @@ void ScriptParser::readInclude() { if (std::optional path = searchScript(name)) { if (std::optional mb = readFile(*path)) { buffers.push_back(curBuf); - curBuf = Buffer(*mb); + curBuf = Buffer(ctx, *mb); mbs.push_back(*mb); } return; @@ -424,8 +423,8 @@ void ScriptParser::readOutput() { // -o takes predecence over OUTPUT(). expect("("); StringRef name = readName(); - if (config->outputFile.empty()) - config->outputFile = name; + if (ctx.arg.outputFile.empty()) + ctx.arg.outputFile = name; expect(")"); } @@ -479,34 +478,34 @@ void ScriptParser::readOutputFormat() { if (!consume(")")) { expect(","); StringRef tmp = readName(); - if (config->optEB) + if (ctx.arg.optEB) s = tmp; expect(","); tmp = readName(); - if (config->optEL) + if (ctx.arg.optEL) s = tmp; consume(")"); } // If more than one OUTPUT_FORMAT is specified, only the first is checked. - if (!config->bfdname.empty()) + if (!ctx.arg.bfdname.empty()) return; - config->bfdname = s; + ctx.arg.bfdname = s; if (s == "binary") { - config->oFormatBinary = true; + ctx.arg.oFormatBinary = true; return; } if (s.consume_back("-freebsd")) - config->osabi = ELFOSABI_FREEBSD; + ctx.arg.osabi = ELFOSABI_FREEBSD; - std::tie(config->ekind, config->emachine) = parseBfdName(s); - if (config->emachine == EM_NONE) - setError("unknown output format name: " + config->bfdname); + std::tie(ctx.arg.ekind, ctx.arg.emachine) = parseBfdName(s); + if (ctx.arg.emachine == EM_NONE) + setError("unknown output format name: " + ctx.arg.bfdname); if (s == "elf32-ntradlittlemips" || s == "elf32-ntradbigmips") - config->mipsN32Abi = true; - if (config->emachine == EM_MSP430) - config->osabi = ELFOSABI_STANDALONE; + ctx.arg.mipsN32Abi = true; + if (ctx.arg.emachine == EM_MSP430) + ctx.arg.osabi = ELFOSABI_STANDALONE; } void ScriptParser::readPhdrs() { @@ -550,8 +549,8 @@ void ScriptParser::readRegionAlias() { void ScriptParser::readSearchDir() { expect("("); StringRef name = readName(); - if (!config->nostdlib) - config->searchPaths.push_back(name); + if (!ctx.arg.nostdlib) + ctx.arg.searchPaths.push_back(name); expect(")"); } @@ -562,7 +561,7 @@ void ScriptParser::readSearchDir() { SmallVector ScriptParser::readOverlay() { Expr addrExpr; if (consume(":")) { - addrExpr = [] { return ctx.script->getDot(); }; + addrExpr = [&] { return ctx.script->getDot(); }; } else { addrExpr = readExpr(); expect(":"); @@ -570,7 +569,7 @@ SmallVector ScriptParser::readOverlay() { // When AT is omitted, LMA should equal VMA. script->getDot() when evaluating // lmaExpr will ensure this, even if the start address is specified. Expr lmaExpr = - consume("AT") ? readParenExpr() : [] { return ctx.script->getDot(); }; + consume("AT") ? readParenExpr() : [&] { return ctx.script->getDot(); }; expect("{"); SmallVector v; @@ -704,9 +703,9 @@ void ScriptParser::readTarget() { expect(")"); if (tok.starts_with("elf")) - config->formatBinary = false; + ctx.arg.formatBinary = false; else if (tok == "binary") - config->formatBinary = true; + ctx.arg.formatBinary = true; else setError("unknown target: " + tok); } @@ -1327,7 +1326,7 @@ Expr ScriptParser::getPageSize() { std::string location = getCurrentLocation(); return [=]() -> uint64_t { if (ctx.target) - return config->commonPageSize; + return ctx.arg.commonPageSize; error(location + ": unable to calculate page size"); return 4096; // Return a dummy value. }; @@ -1338,7 +1337,7 @@ Expr ScriptParser::readConstant() { if (s == "COMMONPAGESIZE") return getPageSize(); if (s == "MAXPAGESIZE") - return [] { return config->maxPageSize; }; + return [&] { return ctx.arg.maxPageSize; }; setError("unknown constant: " + s); return [] { return 0; }; } @@ -1556,7 +1555,7 @@ Expr ScriptParser::readPrimary() { expect("("); expect("."); expect(")"); - return [] { return ctx.script->getDot(); }; + return [&] { return ctx.script->getDot(); }; } if (tok == "DATA_SEGMENT_RELRO_END") { // GNU linkers implements more complicated logic to handle @@ -1568,8 +1567,8 @@ Expr ScriptParser::readPrimary() { readExpr(); expect(")"); ctx.script->seenRelroEnd = true; - return [=] { - return alignToPowerOf2(ctx.script->getDot(), config->maxPageSize); + return [&] { + return alignToPowerOf2(ctx.script->getDot(), ctx.arg.maxPageSize); }; } if (tok == "DEFINED") { @@ -1728,9 +1727,9 @@ void ScriptParser::readAnonymousDeclaration() { SmallVector globals; std::tie(locals, globals) = readSymbols(); for (const SymbolVersion &pat : locals) - config->versionDefinitions[VER_NDX_LOCAL].localPatterns.push_back(pat); + ctx.arg.versionDefinitions[VER_NDX_LOCAL].localPatterns.push_back(pat); for (const SymbolVersion &pat : globals) - config->versionDefinitions[VER_NDX_GLOBAL].nonLocalPatterns.push_back(pat); + ctx.arg.versionDefinitions[VER_NDX_GLOBAL].nonLocalPatterns.push_back(pat); expect(";"); } @@ -1748,8 +1747,8 @@ void ScriptParser::readVersionDeclaration(StringRef verStr) { ver.name = verStr; ver.nonLocalPatterns = std::move(globals); ver.localPatterns = std::move(locals); - ver.id = config->versionDefinitions.size(); - config->versionDefinitions.push_back(ver); + ver.id = ctx.arg.versionDefinitions.size(); + ctx.arg.versionDefinitions.push_back(ver); // Each version may have a parent version. For example, "Ver2" // defined as "Ver2 { global: foo; local: *; } Ver1;" has "Ver1" @@ -1891,21 +1890,23 @@ void ScriptParser::readMemoryAttributes(uint32_t &flags, uint32_t &invFlags, } } -void elf::readLinkerScript(MemoryBufferRef mb) { +void elf::readLinkerScript(Ctx &ctx, MemoryBufferRef mb) { llvm::TimeTraceScope timeScope("Read linker script", mb.getBufferIdentifier()); - ScriptParser(mb).readLinkerScript(); + ScriptParser(ctx, mb).readLinkerScript(); } -void elf::readVersionScript(MemoryBufferRef mb) { +void elf::readVersionScript(Ctx &ctx, MemoryBufferRef mb) { llvm::TimeTraceScope timeScope("Read version script", mb.getBufferIdentifier()); - ScriptParser(mb).readVersionScript(); + ScriptParser(ctx, mb).readVersionScript(); } -void elf::readDynamicList(MemoryBufferRef mb) { +void elf::readDynamicList(Ctx &ctx, MemoryBufferRef mb) { llvm::TimeTraceScope timeScope("Read dynamic list", mb.getBufferIdentifier()); - ScriptParser(mb).readDynamicList(); + ScriptParser(ctx, mb).readDynamicList(); } -void elf::readDefsym(MemoryBufferRef mb) { ScriptParser(mb).readDefsym(); } +void elf::readDefsym(Ctx &ctx, MemoryBufferRef mb) { + ScriptParser(ctx, mb).readDefsym(); +} diff --git a/lld/ELF/ScriptParser.h b/lld/ELF/ScriptParser.h index d6f71c5ee632..3af4fa3ea65f 100644 --- a/lld/ELF/ScriptParser.h +++ b/lld/ELF/ScriptParser.h @@ -13,18 +13,19 @@ #include "llvm/Support/MemoryBufferRef.h" namespace lld::elf { +struct Ctx; // Parses a linker script. Calling this function updates // lld::elf::config and lld::elf::script. -void readLinkerScript(MemoryBufferRef mb); +void readLinkerScript(Ctx &ctx, MemoryBufferRef mb); // Parses a version script. -void readVersionScript(MemoryBufferRef mb); +void readVersionScript(Ctx &ctx, MemoryBufferRef mb); -void readDynamicList(MemoryBufferRef mb); +void readDynamicList(Ctx &ctx, MemoryBufferRef mb); // Parses the defsym expression. -void readDefsym(MemoryBufferRef mb); +void readDefsym(Ctx &ctx, MemoryBufferRef mb); bool hasWildcard(StringRef s);