[lld] 4629aa1 - [ELF] Move script into Ctx. NFC

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 21 21:23:33 PDT 2024


Author: Fangrui Song
Date: 2024-08-21T21:23:28-07:00
New Revision: 4629aa17976b4110e6e94e7c92926c789730702e

URL: https://github.com/llvm/llvm-project/commit/4629aa17976b4110e6e94e7c92926c789730702e
DIFF: https://github.com/llvm/llvm-project/commit/4629aa17976b4110e6e94e7c92926c789730702e.diff

LOG: [ELF] Move script into Ctx. NFC

Ctx was introduced in March 2022 as a more suitable place for such
singletons.

We now use default-initialization for `LinkerScript` and should pay
attention to non-class types (e.g. `dot` is initialized by commit
503907dc505db1e439e7061113bf84dd105f2e35).

Added: 
    

Modified: 
    lld/ELF/Config.h
    lld/ELF/Driver.cpp
    lld/ELF/ICF.cpp
    lld/ELF/LinkerScript.cpp
    lld/ELF/LinkerScript.h
    lld/ELF/MapFile.cpp
    lld/ELF/MarkLive.cpp
    lld/ELF/Relocations.cpp
    lld/ELF/ScriptParser.cpp
    lld/ELF/SyntheticSections.cpp
    lld/ELF/Writer.cpp

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 0c7bfe1bef7e5..5987edee0e93e 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -46,6 +46,7 @@ class Defined;
 class Symbol;
 class BitcodeCompiler;
 class OutputSection;
+class LinkerScript;
 struct Partition;
 struct PhdrEntry;
 
@@ -483,6 +484,7 @@ struct DuplicateSymbol {
 
 struct Ctx {
   LinkerDriver driver;
+  LinkerScript *script;
 
   // These variables are initialized by Writer and should not be used before
   // Writer is initialized.

diff  --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index ced06a1c46a82..308fd86c29ba1 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -93,6 +93,7 @@ void elf::errorOrWarn(const Twine &msg) {
 
 void Ctx::reset() {
   driver = LinkerDriver();
+  script = nullptr;
 
   bufferStart = nullptr;
   mainPart = nullptr;
@@ -160,8 +161,9 @@ bool link(ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
                                  "--error-limit=0 to see all errors)";
 
   config = ConfigWrapper();
-  script = ScriptWrapper();
 
+  LinkerScript script;
+  elf::ctx.script = &script;
   elf::ctx.symAux.emplace_back();
 
   partitions.clear();
@@ -463,7 +465,7 @@ static void checkOptions() {
     if (config->emachine != EM_AARCH64)
       error("--execute-only is only supported on AArch64 targets");
 
-    if (config->singleRoRx && !script->hasSectionsCommand)
+    if (config->singleRoRx && !ctx.script->hasSectionsCommand)
       error("--execute-only and --no-rosegment cannot be used together");
   }
 
@@ -2456,10 +2458,10 @@ static void readSymbolPartitionSection(InputSectionBase *s) {
   // Forbid partitions from being used on incompatible targets, and forbid them
   // from being used together with various linker features that assume a single
   // set of output sections.
-  if (script->hasSectionsCommand)
+  if (ctx.script->hasSectionsCommand)
     error(toString(s->file) +
           ": partitions cannot be used with the SECTIONS command");
-  if (script->hasPhdrsCommands())
+  if (ctx.script->hasPhdrsCommands())
     error(toString(s->file) +
           ": partitions cannot be used with the PHDRS command");
   if (!config->sectionStartMap.empty())
@@ -2873,7 +2875,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
   // After potential archive member extraction involving ENTRY and
   // -u/--undefined-glob, check whether PROVIDE symbols should be defined (the
   // RHS may refer to definitions in just extracted object files).
-  script->addScriptReferencedSymbolsToSymTable();
+  ctx.script->addScriptReferencedSymbolsToSymTable();
 
   // Prevent LTO from removing any definition referenced by -u.
   for (StringRef name : config->undefined)
@@ -2939,7 +2941,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
   // We want to declare linker script's symbols early,
   // so that we can version them.
   // They also might be exported if referenced by DSOs.
-  script->declareSymbols();
+  ctx.script->declareSymbols();
 
   // Handle --exclude-libs. This is before scanVersionScript() due to a
   // workaround for Android ndk: for a defined versioned symbol in an archive
@@ -3158,13 +3160,13 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
     llvm::TimeTraceScope timeScope("Assign sections");
 
     // Create output sections described by SECTIONS commands.
-    script->processSectionCommands();
+    ctx.script->processSectionCommands();
 
     // Linker scripts control how input sections are assigned to output
     // sections. Input sections that were not handled by scripts are called
     // "orphans", and they are assigned to output sections by the default rule.
     // Process that.
-    script->addOrphanSections();
+    ctx.script->addOrphanSections();
   }
 
   {
@@ -3174,9 +3176,9 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
     // merging MergeInputSections into a single MergeSyntheticSection. From this
     // point onwards InputSectionDescription::sections should be used instead of
     // sectionBases.
-    for (SectionCommand *cmd : script->sectionCommands)
+    for (SectionCommand *cmd : ctx.script->sectionCommands)
       if (auto *osd = dyn_cast<OutputDesc>(cmd))
-        osd->osec.finalizeInputSections(&script.s);
+        osd->osec.finalizeInputSections(ctx.script);
   }
 
   // Two input sections with 
diff erent output sections should not be folded.

diff  --git a/lld/ELF/ICF.cpp b/lld/ELF/ICF.cpp
index 44e8a71cc6286..92b3bbb46cc95 100644
--- a/lld/ELF/ICF.cpp
+++ b/lld/ELF/ICF.cpp
@@ -577,7 +577,7 @@ template <class ELFT> void ICF<ELFT>::run() {
 
   // InputSectionDescription::sections is populated by processSectionCommands().
   // ICF may fold some input sections assigned to output sections. Remove them.
-  for (SectionCommand *cmd : script->sectionCommands)
+  for (SectionCommand *cmd : ctx.script->sectionCommands)
     if (auto *osd = dyn_cast<OutputDesc>(cmd))
       for (SectionCommand *subCmd : osd->osec.commands)
         if (auto *isd = dyn_cast<InputSectionDescription>(subCmd))

diff  --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 2f781379a2724..9ddda99d90f02 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -44,8 +44,6 @@ using namespace llvm::support::endian;
 using namespace lld;
 using namespace lld::elf;
 
-ScriptWrapper elf::script;
-
 static bool isSectionPrefix(StringRef prefix, StringRef name) {
   return name.consume_front(prefix) && (name.empty() || name[0] == '.');
 }
@@ -862,7 +860,7 @@ static OutputSection *findByName(ArrayRef<SectionCommand *> vec,
 }
 
 static OutputDesc *createSection(InputSectionBase *isec, StringRef outsecName) {
-  OutputDesc *osd = script->createOutputSection(outsecName, "<internal>");
+  OutputDesc *osd = ctx.script->createOutputSection(outsecName, "<internal>");
   osd->osec.recordSection(isec);
   return osd;
 }
@@ -1470,7 +1468,7 @@ void LinkerScript::allocateHeaders(SmallVector<PhdrEntry *, 0> &phdrs) {
 }
 
 LinkerScript::AddressState::AddressState() {
-  for (auto &mri : script->memoryRegions) {
+  for (auto &mri : ctx.script->memoryRegions) {
     MemoryRegion *mr = mri.second;
     mr->curPos = (mr->origin)().getValue();
   }

diff  --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h
index 6634478160bc6..dee558722299f 100644
--- a/lld/ELF/LinkerScript.h
+++ b/lld/ELF/LinkerScript.h
@@ -446,13 +446,6 @@ class LinkerScript final {
   llvm::DenseMap<llvm::CachedHashStringRef, SectionClassDesc *> sectionClasses;
 };
 
-struct ScriptWrapper {
-  LinkerScript s;
-  LinkerScript *operator->() { return &s; }
-};
-
-LLVM_LIBRARY_VISIBILITY extern ScriptWrapper script;
-
 } // end namespace lld::elf
 
 #endif // LLD_ELF_LINKER_SCRIPT_H

diff  --git a/lld/ELF/MapFile.cpp b/lld/ELF/MapFile.cpp
index 1bad529b40329..26de8e4f0d835 100644
--- a/lld/ELF/MapFile.cpp
+++ b/lld/ELF/MapFile.cpp
@@ -158,7 +158,7 @@ static void writeMapFile(raw_fd_ostream &os) {
      << "     Size Align Out     In      Symbol\n";
 
   OutputSection *osec = nullptr;
-  for (SectionCommand *cmd : script->sectionCommands) {
+  for (SectionCommand *cmd : ctx.script->sectionCommands) {
     if (auto *assign = dyn_cast<SymbolAssignment>(cmd)) {
       if (assign->provide && !assign->sym)
         continue;

diff  --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp
index 16e5883c2002c..b2558a20ba1a7 100644
--- a/lld/ELF/MarkLive.cpp
+++ b/lld/ELF/MarkLive.cpp
@@ -234,7 +234,7 @@ template <class ELFT> void MarkLive<ELFT>::run() {
   markSymbol(symtab.find(config->fini));
   for (StringRef s : config->undefined)
     markSymbol(symtab.find(s));
-  for (StringRef s : script->referencedSymbols)
+  for (StringRef s : ctx.script->referencedSymbols)
     markSymbol(symtab.find(s));
   for (auto [symName, _] : symtab.cmseSymMap) {
     markSymbol(symtab.cmseSymMap[symName].sym);
@@ -293,7 +293,7 @@ template <class ELFT> void MarkLive<ELFT>::run() {
 
     // Preserve special sections and those which are specified in linker
     // script KEEP command.
-    if (isReserved(sec) || script->shouldKeep(sec)) {
+    if (isReserved(sec) || ctx.script->shouldKeep(sec)) {
       enqueue(sec, 0);
     } else if ((!config->zStartStopGC || sec->name.starts_with("__libc_")) &&
                isValidCIdentifier(sec->name)) {

diff  --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 9ccef389d48e3..fa94842f3636b 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -66,7 +66,7 @@ using namespace lld;
 using namespace lld::elf;
 
 static std::optional<std::string> getLinkerScriptLocation(const Symbol &sym) {
-  for (SectionCommand *cmd : script->sectionCommands)
+  for (SectionCommand *cmd : ctx.script->sectionCommands)
     if (auto *assign = dyn_cast<SymbolAssignment>(cmd))
       if (assign->sym == &sym)
         return assign->location;
@@ -2420,7 +2420,7 @@ static void scanCrossRefs(const NoCrossRefCommand &cmd, OutputSection *osec,
 // scan relocations from its input sections for prohibited cross references.
 template <class ELFT> void elf::checkNoCrossRefs() {
   for (OutputSection *osec : ctx.outputSections) {
-    for (const NoCrossRefCommand &noxref : script->noCrossRefs) {
+    for (const NoCrossRefCommand &noxref : ctx.script->noCrossRefs) {
       if (!llvm::is_contained(noxref.outputSections, osec->name) ||
           (noxref.toFirst && noxref.outputSections[0] == osec->name))
         continue;

diff  --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index bdbce396cba1f..08773bfb6ffe0 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -145,7 +145,7 @@ static void moveAbsRight(ExprValue &a, ExprValue &b) {
   if (a.sec == nullptr || (a.forceAbsolute && !b.isAbsolute()))
     std::swap(a, b);
   if (!b.isAbsolute())
-    script->recordError(
+    ctx.script->recordError(
         a.loc + ": at least one side of the expression must be absolute");
 }
 
@@ -278,7 +278,7 @@ void ScriptParser::readLinkerScript() {
     } else if (tok == "NOCROSSREFS_TO") {
       readNoCrossRefs(/*to=*/true);
     } else if (SymbolAssignment *cmd = readAssignment(tok)) {
-      script->sectionCommands.push_back(cmd);
+      ctx.script->sectionCommands.push_back(cmd);
     } else {
       setError("unknown directive: " + tok);
     }
@@ -296,7 +296,7 @@ void ScriptParser::readDefsym() {
     setError("EOF expected, but got " + next());
   auto *cmd = make<SymbolAssignment>(
       name, e, 0, getCurrentMB().getBufferIdentifier().str());
-  script->sectionCommands.push_back(cmd);
+  ctx.script->sectionCommands.push_back(cmd);
 }
 
 void ScriptParser::readNoCrossRefs(bool to) {
@@ -307,7 +307,7 @@ void ScriptParser::readNoCrossRefs(bool to) {
   if (cmd.outputSections.size() < 2)
     warn(getCurrentLocation() + ": ignored with fewer than 2 output sections");
   else
-    script->noCrossRefs.push_back(std::move(cmd));
+    ctx.script->noCrossRefs.push_back(std::move(cmd));
 }
 
 void ScriptParser::addFile(StringRef s) {
@@ -529,7 +529,7 @@ void ScriptParser::readPhdrs() {
         setError("unexpected header attribute: " + next());
     }
 
-    script->phdrsCommands.push_back(cmd);
+    ctx.script->phdrsCommands.push_back(cmd);
   }
 }
 
@@ -540,11 +540,11 @@ void ScriptParser::readRegionAlias() {
   StringRef name = readName();
   expect(")");
 
-  if (script->memoryRegions.count(alias))
+  if (ctx.script->memoryRegions.count(alias))
     setError("redefinition of memory region '" + alias + "'");
-  if (!script->memoryRegions.count(name))
+  if (!ctx.script->memoryRegions.count(name))
     setError("memory region '" + name + "' is not defined");
-  script->memoryRegions.insert({alias, script->memoryRegions[name]});
+  ctx.script->memoryRegions.insert({alias, ctx.script->memoryRegions[name]});
 }
 
 void ScriptParser::readSearchDir() {
@@ -562,7 +562,7 @@ void ScriptParser::readSearchDir() {
 SmallVector<SectionCommand *, 0> ScriptParser::readOverlay() {
   Expr addrExpr;
   if (consume(":")) {
-    addrExpr = [] { return script->getDot(); };
+    addrExpr = [] { return ctx.script->getDot(); };
   } else {
     addrExpr = readExpr();
     expect(":");
@@ -570,7 +570,7 @@ SmallVector<SectionCommand *, 0> 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 script->getDot(); };
+      consume("AT") ? readParenExpr() : [] { return ctx.script->getDot(); };
   expect("{");
 
   SmallVector<SectionCommand *, 0> v;
@@ -610,7 +610,8 @@ SmallVector<SectionCommand *, 0> ScriptParser::readOverlay() {
 SectionClassDesc *ScriptParser::readSectionClassDescription() {
   StringRef name = readSectionClassName();
   SectionClassDesc *desc = make<SectionClassDesc>(name);
-  if (!script->sectionClasses.insert({CachedHashStringRef(name), desc}).second)
+  if (!ctx.script->sectionClasses.insert({CachedHashStringRef(name), desc})
+           .second)
     setError("section class '" + name + "' already defined");
   expect("{");
   while (auto tok = till("}")) {
@@ -637,7 +638,7 @@ StringRef ScriptParser::readSectionClassName() {
 void ScriptParser::readOverwriteSections() {
   expect("{");
   while (auto tok = till("}"))
-    script->overwriteSections.push_back(readOutputSectionDescription(tok));
+    ctx.script->overwriteSections.push_back(readOutputSectionDescription(tok));
 }
 
 void ScriptParser::readSections() {
@@ -666,16 +667,16 @@ void ScriptParser::readSections() {
 
   // If DATA_SEGMENT_RELRO_END is absent, for sections after DATA_SEGMENT_ALIGN,
   // the relro fields should be cleared.
-  if (!script->seenRelroEnd)
+  if (!ctx.script->seenRelroEnd)
     for (SectionCommand *cmd : v)
       if (auto *osd = dyn_cast<OutputDesc>(cmd))
         osd->osec.relro = false;
 
-  script->sectionCommands.insert(script->sectionCommands.end(), v.begin(),
-                                 v.end());
+  ctx.script->sectionCommands.insert(ctx.script->sectionCommands.end(),
+                                     v.begin(), v.end());
 
   if (atEOF() || !consume("INSERT")) {
-    script->hasSectionsCommand = true;
+    ctx.script->hasSectionsCommand = true;
     return;
   }
 
@@ -690,7 +691,7 @@ void ScriptParser::readSections() {
     if (auto *os = dyn_cast<OutputDesc>(cmd))
       names.push_back(os->osec.name);
   if (!names.empty())
-    script->insertCommands.push_back({std::move(names), isAfter, where});
+    ctx.script->insertCommands.push_back({std::move(names), isAfter, where});
 }
 
 void ScriptParser::readTarget() {
@@ -865,7 +866,7 @@ ScriptParser::readInputSectionDescription(StringRef tok) {
     else
       cmd = readInputSectionRules(tok, withFlags, withoutFlags);
     expect(")");
-    script->keptSections.push_back(cmd);
+    ctx.script->keptSections.push_back(cmd);
     return cmd;
   }
   if (tok == "INPUT_SECTION_FLAGS") {
@@ -894,7 +895,7 @@ Expr ScriptParser::readAssert() {
   return [=] {
     if (!e().getValue())
       errorOrWarn(msg);
-    return script->getDot();
+    return ctx.script->getDot();
   };
 }
 
@@ -984,7 +985,7 @@ static Expr checkAlignment(Expr e, std::string &loc) {
 
 OutputDesc *ScriptParser::readOverlaySectionDescription() {
   OutputDesc *osd =
-      script->createOutputSection(readName(), getCurrentLocation());
+      ctx.script->createOutputSection(readName(), getCurrentLocation());
   osd->osec.inOverlay = true;
   expect("{");
   while (auto tok = till("}")) {
@@ -1007,12 +1008,12 @@ OutputDesc *ScriptParser::readOverlaySectionDescription() {
 
 OutputDesc *ScriptParser::readOutputSectionDescription(StringRef outSec) {
   OutputDesc *cmd =
-      script->createOutputSection(unquote(outSec), getCurrentLocation());
+      ctx.script->createOutputSection(unquote(outSec), getCurrentLocation());
   OutputSection *osec = &cmd->osec;
   // Maybe relro. Will reset to false if DATA_SEGMENT_RELRO_END is absent.
-  osec->relro = script->seenDataAlign && !script->seenRelroEnd;
+  osec->relro = ctx.script->seenDataAlign && !ctx.script->seenRelroEnd;
 
-  size_t symbolsReferenced = script->referencedSymbols.size();
+  size_t symbolsReferenced = ctx.script->referencedSymbols.size();
 
   if (peek() != ":")
     readSectionAddressType(osec);
@@ -1095,7 +1096,7 @@ OutputDesc *ScriptParser::readOutputSectionDescription(StringRef outSec) {
   // Consume optional comma following output section command.
   consume(",");
 
-  if (script->referencedSymbols.size() > symbolsReferenced)
+  if (ctx.script->referencedSymbols.size() > symbolsReferenced)
     osec->expressionsUseSymbols = true;
   return cmd;
 }
@@ -1158,7 +1159,7 @@ SymbolAssignment *ScriptParser::readAssignment(StringRef tok) {
 
   const char *oldS = prevTok.data();
   SymbolAssignment *cmd = nullptr;
-  bool savedSeenRelroEnd = script->seenRelroEnd;
+  bool savedSeenRelroEnd = ctx.script->seenRelroEnd;
   const StringRef op = peek();
   {
     SaveAndRestore saved(inExpr, true);
@@ -1178,7 +1179,7 @@ SymbolAssignment *ScriptParser::readAssignment(StringRef tok) {
   }
 
   if (cmd) {
-    cmd->dataSegmentRelroEnd = !savedSeenRelroEnd && script->seenRelroEnd;
+    cmd->dataSegmentRelroEnd = !savedSeenRelroEnd && ctx.script->seenRelroEnd;
     cmd->commandString = StringRef(oldS, curTok.data() - oldS).str();
     squeezeSpaces(cmd->commandString);
     expect(";");
@@ -1197,7 +1198,7 @@ SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef name) {
   if (op != "=") {
     std::string loc = getCurrentLocation();
     e = [=, c = op[0]]() -> ExprValue {
-      ExprValue lhs = script->getSymbolValue(name, loc);
+      ExprValue lhs = ctx.script->getSymbolValue(name, loc);
       switch (c) {
       case '*':
         return lhs.getValue() * e().getValue();
@@ -1460,8 +1461,8 @@ StringRef ScriptParser::readParenName() {
 }
 
 static void checkIfExists(const OutputSection &osec, StringRef location) {
-  if (osec.location.empty() && script->errorOnMissingSection)
-    script->recordError(location + ": undefined section " + osec.name);
+  if (osec.location.empty() && ctx.script->errorOnMissingSection)
+    ctx.script->recordError(location + ": undefined section " + osec.name);
 }
 
 static bool isValidSymbolName(StringRef s) {
@@ -1503,7 +1504,7 @@ Expr ScriptParser::readPrimary() {
   }
   if (tok == "ADDR") {
     StringRef name = readParenName();
-    OutputSection *osec = &script->getOrCreateOutputSection(name)->osec;
+    OutputSection *osec = &ctx.script->getOrCreateOutputSection(name)->osec;
     osec->usedInExpression = true;
     return [=]() -> ExprValue {
       checkIfExists(*osec, location);
@@ -1515,7 +1516,8 @@ Expr ScriptParser::readPrimary() {
     Expr e = readExpr();
     if (consume(")")) {
       e = checkAlignment(e, location);
-      return [=] { return alignToPowerOf2(script->getDot(), e().getValue()); };
+      return
+          [=] { return alignToPowerOf2(ctx.script->getDot(), e().getValue()); };
     }
     expect(",");
     Expr e2 = checkAlignment(readExpr(), location);
@@ -1528,7 +1530,7 @@ Expr ScriptParser::readPrimary() {
   }
   if (tok == "ALIGNOF") {
     StringRef name = readParenName();
-    OutputSection *osec = &script->getOrCreateOutputSection(name)->osec;
+    OutputSection *osec = &ctx.script->getOrCreateOutputSection(name)->osec;
     return [=] {
       checkIfExists(*osec, location);
       return osec->addralign;
@@ -1544,17 +1546,17 @@ Expr ScriptParser::readPrimary() {
     expect(",");
     readExpr();
     expect(")");
-    script->seenDataAlign = true;
+    ctx.script->seenDataAlign = true;
     return [=] {
       uint64_t align = std::max(uint64_t(1), e().getValue());
-      return (script->getDot() + align - 1) & -align;
+      return (ctx.script->getDot() + align - 1) & -align;
     };
   }
   if (tok == "DATA_SEGMENT_END") {
     expect("(");
     expect(".");
     expect(")");
-    return [] { return script->getDot(); };
+    return [] { return ctx.script->getDot(); };
   }
   if (tok == "DATA_SEGMENT_RELRO_END") {
     // GNU linkers implements more complicated logic to handle
@@ -1565,8 +1567,10 @@ Expr ScriptParser::readPrimary() {
     expect(",");
     readExpr();
     expect(")");
-    script->seenRelroEnd = true;
-    return [=] { return alignToPowerOf2(script->getDot(), config->maxPageSize); };
+    ctx.script->seenRelroEnd = true;
+    return [=] {
+      return alignToPowerOf2(ctx.script->getDot(), config->maxPageSize);
+    };
   }
   if (tok == "DEFINED") {
     StringRef name = readParenName();
@@ -1581,15 +1585,15 @@ Expr ScriptParser::readPrimary() {
   }
   if (tok == "LENGTH") {
     StringRef name = readParenName();
-    if (script->memoryRegions.count(name) == 0) {
+    if (ctx.script->memoryRegions.count(name) == 0) {
       setError("memory region not defined: " + name);
       return [] { return 0; };
     }
-    return script->memoryRegions[name]->length;
+    return ctx.script->memoryRegions[name]->length;
   }
   if (tok == "LOADADDR") {
     StringRef name = readParenName();
-    OutputSection *osec = &script->getOrCreateOutputSection(name)->osec;
+    OutputSection *osec = &ctx.script->getOrCreateOutputSection(name)->osec;
     osec->usedInExpression = true;
     return [=] {
       checkIfExists(*osec, location);
@@ -1617,11 +1621,11 @@ Expr ScriptParser::readPrimary() {
   }
   if (tok == "ORIGIN") {
     StringRef name = readParenName();
-    if (script->memoryRegions.count(name) == 0) {
+    if (ctx.script->memoryRegions.count(name) == 0) {
       setError("memory region not defined: " + name);
       return [] { return 0; };
     }
-    return script->memoryRegions[name]->origin;
+    return ctx.script->memoryRegions[name]->origin;
   }
   if (tok == "SEGMENT_START") {
     expect("(");
@@ -1633,7 +1637,7 @@ Expr ScriptParser::readPrimary() {
   }
   if (tok == "SIZEOF") {
     StringRef name = readParenName();
-    OutputSection *cmd = &script->getOrCreateOutputSection(name)->osec;
+    OutputSection *cmd = &ctx.script->getOrCreateOutputSection(name)->osec;
     // Linker script does not create an output section if its content is empty.
     // We want to allow SIZEOF(.foo) where .foo is a section which happened to
     // be empty.
@@ -1644,7 +1648,7 @@ Expr ScriptParser::readPrimary() {
 
   // Tok is the dot.
   if (tok == ".")
-    return [=] { return script->getSymbolValue(tok, location); };
+    return [=] { return ctx.script->getSymbolValue(tok, location); };
 
   // Tok is a literal number.
   if (std::optional<uint64_t> val = parseInt(tok))
@@ -1656,10 +1660,10 @@ Expr ScriptParser::readPrimary() {
   else if (!isValidSymbolName(tok))
     setError("malformed number: " + tok);
   if (activeProvideSym)
-    script->provideMap[*activeProvideSym].push_back(tok);
+    ctx.script->provideMap[*activeProvideSym].push_back(tok);
   else
-    script->referencedSymbols.push_back(tok);
-  return [=] { return script->getSymbolValue(tok, location); };
+    ctx.script->referencedSymbols.push_back(tok);
+  return [=] { return ctx.script->getSymbolValue(tok, location); };
 }
 
 Expr ScriptParser::readTernary(Expr cond) {
@@ -1849,7 +1853,7 @@ void ScriptParser::readMemory() {
     // Add the memory region to the region map.
     MemoryRegion *mr = make<MemoryRegion>(tok, origin, length, flags, invFlags,
                                           negFlags, negInvFlags);
-    if (!script->memoryRegions.insert({tok, mr}).second)
+    if (!ctx.script->memoryRegions.insert({tok, mr}).second)
       setError("region '" + tok + "' already defined");
   }
 }

diff  --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 1dbbd117290a4..4c2b6db08b99a 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -2343,7 +2343,7 @@ bool SymtabShndxSection::isNeeded() const {
   // late, and we do not know them here. For simplicity, we just always create
   // a .symtab_shndx section when the amount of output sections is huge.
   size_t size = 0;
-  for (SectionCommand *cmd : script->sectionCommands)
+  for (SectionCommand *cmd : ctx.script->sectionCommands)
     if (isa<OutputDesc>(cmd))
       ++size;
   return size >= SHN_LORESERVE;
@@ -4495,7 +4495,7 @@ void InStruct::reset() {
 
 static bool needsInterpSection() {
   return !config->relocatable && !config->shared &&
-         !config->dynamicLinker.empty() && script->needsInterpSection();
+         !config->dynamicLinker.empty() && ctx.script->needsInterpSection();
 }
 
 bool elf::hasMemtag() {
@@ -4630,7 +4630,7 @@ size_t MemtagGlobalDescriptors::getSize() const {
 }
 
 static OutputSection *findSection(StringRef name) {
-  for (SectionCommand *cmd : script->sectionCommands)
+  for (SectionCommand *cmd : ctx.script->sectionCommands)
     if (auto *osd = dyn_cast<OutputDesc>(cmd))
       if (osd->osec.name == name)
         return &osd->osec;
@@ -4682,7 +4682,8 @@ template <class ELFT> void elf::createSyntheticSections() {
   // If there is a SECTIONS command and a .data.rel.ro section name use name
   // .data.rel.ro.bss so that we match in the .data.rel.ro output section.
   // This makes sure our relro is contiguous.
-  bool hasDataRelRo = script->hasSectionsCommand && findSection(".data.rel.ro");
+  bool hasDataRelRo =
+      ctx.script->hasSectionsCommand && findSection(".data.rel.ro");
   in.bssRelRo = std::make_unique<BssSection>(
       hasDataRelRo ? ".data.rel.ro.bss" : ".bss.rel.ro", 0, 1);
   add(*in.bssRelRo);
@@ -4851,8 +4852,8 @@ template <class ELFT> void elf::createSyntheticSections() {
   // Add .relro_padding if DATA_SEGMENT_RELRO_END is used; otherwise, add the
   // section in the absence of PHDRS/SECTIONS commands.
   if (config->zRelro &&
-      ((script->phdrsCommands.empty() && !script->hasSectionsCommand) ||
-       script->seenRelroEnd)) {
+      ((ctx.script->phdrsCommands.empty() && !ctx.script->hasSectionsCommand) ||
+       ctx.script->seenRelroEnd)) {
     in.relroPadding = std::make_unique<RelroPaddingSection>();
     add(*in.relroPadding);
   }

diff  --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 2091058c9c887..087804b43918a 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -231,7 +231,7 @@ void elf::addReservedSymbols() {
   addOptionalRegular("__dso_handle", ctx.out.elfHeader, 0, STV_HIDDEN);
 
   // If linker script do layout we do not need to create any standard symbols.
-  if (script->hasSectionsCommand)
+  if (ctx.script->hasSectionsCommand)
     return;
 
   auto add = [](StringRef s, int64_t pos) {
@@ -293,7 +293,7 @@ static void demoteSymbolsAndComputeIsPreemptible() {
 }
 
 static OutputSection *findSection(StringRef name, unsigned partition = 1) {
-  for (SectionCommand *cmd : script->sectionCommands)
+  for (SectionCommand *cmd : ctx.script->sectionCommands)
     if (auto *osd = dyn_cast<OutputDesc>(cmd))
       if (osd->osec.name == name && osd->osec.partition == partition)
         return &osd->osec;
@@ -314,8 +314,8 @@ template <class ELFT> void Writer<ELFT>::run() {
   for (OutputSection *sec : ctx.outputSections)
     sec->maybeCompress<ELFT>();
 
-  if (script->hasSectionsCommand)
-    script->allocateHeaders(ctx.mainPart->phdrs);
+  if (ctx.script->hasSectionsCommand)
+    ctx.script->allocateHeaders(ctx.mainPart->phdrs);
 
   // Remove empty PT_LOAD to avoid causing the dynamic linker to try to mmap a
   // 0 sized region. This has to be done late since only after assignAddresses
@@ -338,7 +338,7 @@ template <class ELFT> void Writer<ELFT>::run() {
 
   // Handle --print-memory-usage option.
   if (config->printMemoryUsage)
-    script->printMemoryUsage(lld::outs());
+    ctx.script->printMemoryUsage(lld::outs());
 
   if (config->checkSections)
     checkSections();
@@ -496,7 +496,7 @@ static void demoteAndCopyLocalSymbols() {
 // referring to a section (that happens if the section is a synthetic one), we
 // don't create a section symbol for that section.
 template <class ELFT> void Writer<ELFT>::addSectionSymbols() {
-  for (SectionCommand *cmd : script->sectionCommands) {
+  for (SectionCommand *cmd : ctx.script->sectionCommands) {
     auto *osd = dyn_cast<OutputDesc>(cmd);
     if (!osd)
       continue;
@@ -995,7 +995,8 @@ findOrphanPos(SmallVectorImpl<SectionCommand *>::iterator b,
   // making a read-only segment writable. If memory regions are defined, an
   // orphan section should continue the same region as the found section to
   // better resemble the behavior of GNU ld.
-  bool mustAfter = script->hasPhdrsCommands() || !script->memoryRegions.empty();
+  bool mustAfter =
+      ctx.script->hasPhdrsCommands() || !ctx.script->memoryRegions.empty();
   if (cast<OutputDesc>(*i)->osec.sortRank <= sec->sortRank || mustAfter) {
     for (auto j = ++i; j != e; ++j) {
       if (!isOutputSecWithInputSections(*j))
@@ -1212,7 +1213,7 @@ static void sortSection(OutputSection &osec,
       if (auto *isd = dyn_cast<InputSectionDescription>(b))
         sortISDBySectionOrder(isd, order, osec.flags & SHF_EXECINSTR);
 
-  if (script->hasSectionsCommand)
+  if (ctx.script->hasSectionsCommand)
     return;
 
   if (name == ".init_array" || name == ".fini_array") {
@@ -1241,7 +1242,7 @@ template <class ELFT> void Writer<ELFT>::sortInputSections() {
   // Build the order once since it is expensive.
   DenseMap<const InputSectionBase *, int> order = buildSectionOrder();
   maybeShuffle(order);
-  for (SectionCommand *cmd : script->sectionCommands)
+  for (SectionCommand *cmd : ctx.script->sectionCommands)
     if (auto *osd = dyn_cast<OutputDesc>(cmd))
       sortSection(osd->osec, order);
 }
@@ -1252,33 +1253,33 @@ template <class ELFT> void Writer<ELFT>::sortSections() {
   // Don't sort if using -r. It is not necessary and we want to preserve the
   // relative order for SHF_LINK_ORDER sections.
   if (config->relocatable) {
-    script->adjustOutputSections();
+    ctx.script->adjustOutputSections();
     return;
   }
 
   sortInputSections();
 
-  for (SectionCommand *cmd : script->sectionCommands)
+  for (SectionCommand *cmd : ctx.script->sectionCommands)
     if (auto *osd = dyn_cast<OutputDesc>(cmd))
       osd->osec.sortRank = getSectionRank(osd->osec);
-  if (!script->hasSectionsCommand) {
+  if (!ctx.script->hasSectionsCommand) {
     // OutputDescs are mostly contiguous, but may be interleaved with
     // SymbolAssignments in the presence of INSERT commands.
     auto mid = std::stable_partition(
-        script->sectionCommands.begin(), script->sectionCommands.end(),
+        ctx.script->sectionCommands.begin(), ctx.script->sectionCommands.end(),
         [](SectionCommand *cmd) { return isa<OutputDesc>(cmd); });
-    std::stable_sort(script->sectionCommands.begin(), mid, compareSections);
+    std::stable_sort(ctx.script->sectionCommands.begin(), mid, compareSections);
   }
 
   // Process INSERT commands and update output section attributes. From this
   // point onwards the order of script->sectionCommands is fixed.
-  script->processInsertCommands();
-  script->adjustOutputSections();
+  ctx.script->processInsertCommands();
+  ctx.script->adjustOutputSections();
 
-  if (script->hasSectionsCommand)
+  if (ctx.script->hasSectionsCommand)
     sortOrphanSections();
 
-  script->adjustSectionsAfterSorting();
+  ctx.script->adjustSectionsAfterSorting();
 }
 
 template <class ELFT> void Writer<ELFT>::sortOrphanSections() {
@@ -1321,8 +1322,8 @@ template <class ELFT> void Writer<ELFT>::sortOrphanSections() {
   // after another commands. For the details, look at shouldSkip
   // function.
 
-  auto i = script->sectionCommands.begin();
-  auto e = script->sectionCommands.end();
+  auto i = ctx.script->sectionCommands.begin();
+  auto e = ctx.script->sectionCommands.end();
   auto nonScriptI = std::find_if(i, e, [](SectionCommand *cmd) {
     if (auto *osd = dyn_cast<OutputDesc>(cmd))
       return osd->osec.sectionIndex == UINT32_MAX;
@@ -1434,7 +1435,7 @@ template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
   ThunkCreator tc;
   AArch64Err843419Patcher a64p;
   ARMErr657417Patcher a32p;
-  script->assignAddresses();
+  ctx.script->assignAddresses();
 
   // .ARM.exidx and SHF_LINK_ORDER do not require precise addresses, but they
   // do require the relative addresses of OutputSections because linker scripts
@@ -1457,7 +1458,7 @@ template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
     bool changed = target->needsThunks
                        ? tc.createThunks(pass, ctx.outputSections)
                        : target->relaxOnce(pass);
-    bool spilled = script->spillSections();
+    bool spilled = ctx.script->spillSections();
     changed |= spilled;
     ++pass;
 
@@ -1471,12 +1472,12 @@ template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
 
     if (config->fixCortexA53Errata843419) {
       if (changed)
-        script->assignAddresses();
+        ctx.script->assignAddresses();
       changed |= a64p.createFixes();
     }
     if (config->fixCortexA8) {
       if (changed)
-        script->assignAddresses();
+        ctx.script->assignAddresses();
       changed |= a32p.createFixes();
     }
 
@@ -1517,7 +1518,7 @@ template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
     }
 
     std::pair<const OutputSection *, const Defined *> changes =
-        script->assignAddresses();
+        ctx.script->assignAddresses();
     if (!changed) {
       // Some symbols may be dependent on section addresses. When we break the
       // loop, the symbol values are finalized because a previous
@@ -1548,7 +1549,7 @@ template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
 
   // If addrExpr is set, the address may not be a multiple of the alignment.
   // Warn because this is error-prone.
-  for (SectionCommand *cmd : script->sectionCommands)
+  for (SectionCommand *cmd : ctx.script->sectionCommands)
     if (auto *osd = dyn_cast<OutputDesc>(cmd)) {
       OutputSection *osec = &osd->osec;
       if (osec->addr % osec->addralign != 0)
@@ -1559,7 +1560,7 @@ template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
 
   // Sizes are no longer allowed to grow, so all allowable spills have been
   // taken. Remove any leftover potential spills.
-  script->erasePotentialSpillSections();
+  ctx.script->erasePotentialSpillSections();
 }
 
 // If Input Sections have been shrunk (basic block sections) then
@@ -1613,7 +1614,7 @@ template <class ELFT> void Writer<ELFT>::optimizeBasicBlockJumps() {
   assert(config->optimizeBBJumps);
   SmallVector<InputSection *, 0> storage;
 
-  script->assignAddresses();
+  ctx.script->assignAddresses();
   // For every output section that has executable input sections, this
   // does the following:
   //   1. Deletes all direct jump instructions in input sections that
@@ -1634,7 +1635,7 @@ template <class ELFT> void Writer<ELFT>::optimizeBasicBlockJumps() {
       numDeleted += target->deleteFallThruJmpInsn(sec, sec.file, next);
     }
     if (numDeleted > 0) {
-      script->assignAddresses();
+      ctx.script->assignAddresses();
       LLVM_DEBUG(llvm::dbgs()
                  << "Removing " << numDeleted << " fall through jumps\n");
     }
@@ -1697,7 +1698,7 @@ static void removeUnusedSyntheticSections() {
           llvm::erase_if(isd->sections, [&](InputSection *isec) {
             return unused.count(isec);
           });
-  llvm::erase_if(script->orphanSections, [&](const InputSectionBase *sec) {
+  llvm::erase_if(ctx.script->orphanSections, [&](const InputSectionBase *sec) {
     return unused.count(sec);
   });
 }
@@ -1713,7 +1714,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
     // symbols for sections, so that the runtime can get the start and end
     // addresses of each section by section name. Add such symbols.
     addStartEndSymbols();
-    for (SectionCommand *cmd : script->sectionCommands)
+    for (SectionCommand *cmd : ctx.script->sectionCommands)
       if (auto *osd = dyn_cast<OutputDesc>(cmd))
         addStartStopSymbols(osd->osec);
 
@@ -1792,7 +1793,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
 
   // Change values of linker-script-defined symbols from placeholders (assigned
   // by declareSymbols) to actual definitions.
-  script->processSymbolAssignments();
+  ctx.script->processSymbolAssignments();
 
   if (!config->relocatable) {
     llvm::TimeTraceScope timeScope("Scan relocations");
@@ -1888,14 +1889,14 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
     in.mipsGot->build();
 
   removeUnusedSyntheticSections();
-  script->diagnoseOrphanHandling();
-  script->diagnoseMissingSGSectionAddress();
+  ctx.script->diagnoseOrphanHandling();
+  ctx.script->diagnoseMissingSGSectionAddress();
 
   sortSections();
 
   // Create a list of OutputSections, assign sectionIndex, and populate
   // in.shStrTab. If -z nosectionheader is specified, drop non-ALLOC sections.
-  for (SectionCommand *cmd : script->sectionCommands)
+  for (SectionCommand *cmd : ctx.script->sectionCommands)
     if (auto *osd = dyn_cast<OutputDesc>(cmd)) {
       OutputSection *osec = &osd->osec;
       if (!in.shStrTab && !(osec->flags & SHF_ALLOC))
@@ -1935,8 +1936,8 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
   // image base and the dynamic section on mips includes the image base.
   if (!config->relocatable && !config->oFormatBinary) {
     for (Partition &part : partitions) {
-      part.phdrs = script->hasPhdrsCommands() ? script->createPhdrs()
-                                              : createPhdrs(part);
+      part.phdrs = ctx.script->hasPhdrsCommands() ? ctx.script->createPhdrs()
+                                                  : createPhdrs(part);
       if (config->emachine == EM_ARM) {
         // PT_ARM_EXIDX is the ARM EHABI equivalent of PT_GNU_EH_FRAME
         addPhdrForSection(part, SHT_ARM_EXIDX, PT_ARM_EXIDX, PF_R);
@@ -1967,7 +1968,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
   // have the headers, we can find out which sections they point to.
   setReservedSymbolSections();
 
-  if (script->noCrossRefs.size()) {
+  if (ctx.script->noCrossRefs.size()) {
     llvm::TimeTraceScope timeScope("Check NOCROSSREFS");
     checkNoCrossRefs<ELFT>();
   }
@@ -2019,7 +2020,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
     }
   }
 
-  if (!script->hasSectionsCommand && !config->relocatable)
+  if (!ctx.script->hasSectionsCommand && !config->relocatable)
     fixSectionAlignments();
 
   // This is used to:
@@ -2071,7 +2072,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
   for (OutputSection *sec : ctx.outputSections)
     sec->finalize();
 
-  script->checkFinalScriptConditions();
+  ctx.script->checkFinalScriptConditions();
 
   if (config->emachine == EM_ARM && !config->isLE && config->armBe8) {
     addArmInputSectionMappingSymbols();
@@ -2276,7 +2277,7 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
     if (load && sec != relroEnd &&
         sec->memRegion == load->firstSec->memRegion &&
         (sameLMARegion || load->lastSec == ctx.out.programHeaders) &&
-        (script->hasSectionsCommand || sec->type == SHT_NOBITS ||
+        (ctx.script->hasSectionsCommand || sec->type == SHT_NOBITS ||
          load->lastSec->type != SHT_NOBITS)) {
       load->p_flags |= newFlags;
     } else {
@@ -2407,7 +2408,7 @@ template <class ELFT> void Writer<ELFT>::fixSectionAlignments() {
            (prev->p_flags & PF_X) != (p->p_flags & PF_X)) ||
           cmd->type == SHT_LLVM_PART_EHDR)
         cmd->addrExpr = [] {
-          return alignToPowerOf2(script->getDot(), config->maxPageSize);
+          return alignToPowerOf2(ctx.script->getDot(), config->maxPageSize);
         };
       // PT_TLS is at the start of the first RW PT_LOAD. If `p` includes PT_TLS,
       // it must be the RW. Align to p_align(PT_TLS) to make sure
@@ -2424,14 +2425,14 @@ template <class ELFT> void Writer<ELFT>::fixSectionAlignments() {
       // blocks correctly. We need to keep the workaround for a while.
       else if (ctx.tlsPhdr && ctx.tlsPhdr->firstSec == p->firstSec)
         cmd->addrExpr = [] {
-          return alignToPowerOf2(script->getDot(), config->maxPageSize) +
-                 alignToPowerOf2(script->getDot() % config->maxPageSize,
+          return alignToPowerOf2(ctx.script->getDot(), config->maxPageSize) +
+                 alignToPowerOf2(ctx.script->getDot() % config->maxPageSize,
                                  ctx.tlsPhdr->p_align);
         };
       else
         cmd->addrExpr = [] {
-          return alignToPowerOf2(script->getDot(), config->maxPageSize) +
-                 script->getDot() % config->maxPageSize;
+          return alignToPowerOf2(ctx.script->getDot(), config->maxPageSize) +
+                 ctx.script->getDot() % config->maxPageSize;
         };
     }
   };


        


More information about the llvm-commits mailing list