[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