From 7051aeef7a1ef609aaeea0bf87d90a2ec6340a37 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 25 Nov 2021 20:24:23 -0800 Subject: [PATCH] [ELF] Rename BaseCommand to SectionCommand. NFC BaseCommand was picked when PHDRS/INSERT/etc were not implemented. Rename it to SectionCommand to match `sectionCommands` and make it clear that the commands are used in SECTIONS (except a special case for SymbolAssignment). Also, improve naming of some BaseCommand variables (base -> cmd). --- lld/ELF/AArch64ErrataFix.cpp | 4 +- lld/ELF/ARMErrataFix.cpp | 4 +- lld/ELF/Driver.cpp | 4 +- lld/ELF/ICF.cpp | 8 +-- lld/ELF/LinkerScript.cpp | 141 +++++++++++++++++++++--------------------- lld/ELF/LinkerScript.h | 25 ++++---- lld/ELF/MapFile.cpp | 37 +++++------ lld/ELF/OutputSections.cpp | 36 +++++------ lld/ELF/OutputSections.h | 6 +- lld/ELF/Relocations.cpp | 12 ++-- lld/ELF/ScriptParser.cpp | 16 ++--- lld/ELF/SyntheticSections.cpp | 14 ++--- lld/ELF/Writer.cpp | 67 ++++++++++---------- 13 files changed, 190 insertions(+), 184 deletions(-) diff --git a/lld/ELF/AArch64ErrataFix.cpp b/lld/ELF/AArch64ErrataFix.cpp index 331a5786..741ff26 100644 --- a/lld/ELF/AArch64ErrataFix.cpp +++ b/lld/ELF/AArch64ErrataFix.cpp @@ -630,8 +630,8 @@ bool AArch64Err843419Patcher::createFixes() { for (OutputSection *os : outputSections) { if (!(os->flags & SHF_ALLOC) || !(os->flags & SHF_EXECINSTR)) continue; - for (BaseCommand *bc : os->commands) - if (auto *isd = dyn_cast(bc)) { + for (SectionCommand *cmd : os->commands) + if (auto *isd = dyn_cast(cmd)) { std::vector patches = patchInputSectionDescription(*isd); if (!patches.empty()) { diff --git a/lld/ELF/ARMErrataFix.cpp b/lld/ELF/ARMErrataFix.cpp index bf41f65..fe6ec09 100644 --- a/lld/ELF/ARMErrataFix.cpp +++ b/lld/ELF/ARMErrataFix.cpp @@ -525,8 +525,8 @@ bool ARMErr657417Patcher::createFixes() { for (OutputSection *os : outputSections) { if (!(os->flags & SHF_ALLOC) || !(os->flags & SHF_EXECINSTR)) continue; - for (BaseCommand *bc : os->commands) - if (auto *isd = dyn_cast(bc)) { + for (SectionCommand *cmd : os->commands) + if (auto *isd = dyn_cast(cmd)) { std::vector patches = patchInputSectionDescription(*isd); if (!patches.empty()) { diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 9fac045..8c66887 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -2476,8 +2476,8 @@ template 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 (BaseCommand *base : script->sectionCommands) - if (auto *sec = dyn_cast(base)) + for (SectionCommand *cmd : script->sectionCommands) + if (auto *sec = dyn_cast(cmd)) sec->finalizeInputSections(); llvm::erase_if(inputSections, [](InputSectionBase *s) { return isa(s); diff --git a/lld/ELF/ICF.cpp b/lld/ELF/ICF.cpp index b35e46b..0ec748e 100644 --- a/lld/ELF/ICF.cpp +++ b/lld/ELF/ICF.cpp @@ -552,10 +552,10 @@ template void ICF::run() { // InputSectionDescription::sections is populated by processSectionCommands(). // ICF may fold some input sections assigned to output sections. Remove them. - for (BaseCommand *base : script->sectionCommands) - if (auto *sec = dyn_cast(base)) - for (BaseCommand *sub_base : sec->commands) - if (auto *isd = dyn_cast(sub_base)) + for (SectionCommand *cmd : script->sectionCommands) + if (auto *sec = dyn_cast(cmd)) + for (SectionCommand *subCmd : sec->commands) + if (auto *isd = dyn_cast(subCmd)) llvm::erase_if(isd->sections, [](InputSection *isec) { return !isec->isLive(); }); } diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index d9346c8..40befb6 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -275,21 +275,21 @@ using SymbolAssignmentMap = // Collect section/value pairs of linker-script-defined symbols. This is used to // check whether symbol values converge. -static SymbolAssignmentMap -getSymbolAssignmentValues(const std::vector §ionCommands) { +static SymbolAssignmentMap getSymbolAssignmentValues( + const std::vector §ionCommands) { SymbolAssignmentMap ret; - for (BaseCommand *base : sectionCommands) { - if (auto *cmd = dyn_cast(base)) { - if (cmd->sym) // sym is nullptr for dot. - ret.try_emplace(cmd->sym, - std::make_pair(cmd->sym->section, cmd->sym->value)); + for (SectionCommand *cmd : sectionCommands) { + if (auto *assign = dyn_cast(cmd)) { + if (assign->sym) // sym is nullptr for dot. + ret.try_emplace(assign->sym, std::make_pair(assign->sym->section, + assign->sym->value)); continue; } - for (BaseCommand *sub_base : cast(base)->commands) - if (auto *cmd = dyn_cast(sub_base)) - if (cmd->sym) - ret.try_emplace(cmd->sym, - std::make_pair(cmd->sym->section, cmd->sym->value)); + for (SectionCommand *subCmd : cast(cmd)->commands) + if (auto *assign = dyn_cast(subCmd)) + if (assign->sym) + ret.try_emplace(assign->sym, std::make_pair(assign->sym->section, + assign->sym->value)); } return ret; } @@ -316,9 +316,9 @@ void LinkerScript::processInsertCommands() { for (StringRef name : cmd.names) { // If base is empty, it may have been discarded by // adjustSectionsBeforeSorting(). We do not handle such output sections. - auto from = llvm::find_if(sectionCommands, [&](BaseCommand *base) { - return isa(base) && - cast(base)->name == name; + auto from = llvm::find_if(sectionCommands, [&](SectionCommand *subCmd) { + return isa(subCmd) && + cast(subCmd)->name == name; }); if (from == sectionCommands.end()) continue; @@ -326,10 +326,11 @@ void LinkerScript::processInsertCommands() { sectionCommands.erase(from); } - auto insertPos = llvm::find_if(sectionCommands, [&cmd](BaseCommand *base) { - auto *to = dyn_cast(base); - return to != nullptr && to->name == cmd.where; - }); + auto insertPos = + llvm::find_if(sectionCommands, [&cmd](SectionCommand *subCmd) { + auto *to = dyn_cast(subCmd); + return to != nullptr && to->name == cmd.where; + }); if (insertPos == sectionCommands.end()) { error("unable to insert " + cmd.names[0] + (cmd.isAfter ? " after " : " before ") + cmd.where); @@ -347,9 +348,9 @@ void LinkerScript::processInsertCommands() { // over symbol assignment commands and create placeholder symbols if needed. void LinkerScript::declareSymbols() { assert(!ctx); - for (BaseCommand *base : sectionCommands) { - if (auto *cmd = dyn_cast(base)) { - declareSymbol(cmd); + for (SectionCommand *cmd : sectionCommands) { + if (auto *assign = dyn_cast(cmd)) { + declareSymbol(assign); continue; } @@ -357,12 +358,12 @@ void LinkerScript::declareSymbols() { // we can't say for sure if it is going to be included or not. // Skip such sections for now. Improve the checks if we ever // need symbols from that sections to be declared early. - auto *sec = cast(base); + auto *sec = cast(cmd); if (sec->constraint != ConstraintKind::NoConstraint) continue; - for (BaseCommand *base2 : sec->commands) - if (auto *cmd = dyn_cast(base2)) - declareSymbol(cmd); + for (SectionCommand *cmd : sec->commands) + if (auto *assign = dyn_cast(cmd)) + declareSymbol(assign); } } @@ -588,10 +589,10 @@ void LinkerScript::discardSynthetic(OutputSection &outCmd) { continue; std::vector secs(part.armExidx->exidxSections.begin(), part.armExidx->exidxSections.end()); - for (BaseCommand *base : outCmd.commands) - if (auto *cmd = dyn_cast(base)) { + for (SectionCommand *cmd : outCmd.commands) + if (auto *isd = dyn_cast(cmd)) { std::vector matches = - computeInputSections(cmd, secs); + computeInputSections(isd, secs); for (InputSectionBase *s : matches) discard(s); } @@ -602,12 +603,12 @@ std::vector LinkerScript::createInputSectionList(OutputSection &outCmd) { std::vector ret; - for (BaseCommand *base : outCmd.commands) { - if (auto *cmd = dyn_cast(base)) { - cmd->sectionBases = computeInputSections(cmd, inputSections); - for (InputSectionBase *s : cmd->sectionBases) + for (SectionCommand *cmd : outCmd.commands) { + if (auto *isd = dyn_cast(cmd)) { + isd->sectionBases = computeInputSections(isd, inputSections); + for (InputSectionBase *s : isd->sectionBases) s->parent = &outCmd; - ret.insert(ret.end(), cmd->sectionBases.begin(), cmd->sectionBases.end()); + ret.insert(ret.end(), isd->sectionBases.begin(), isd->sectionBases.end()); } } return ret; @@ -665,7 +666,7 @@ void LinkerScript::processSectionCommands() { for (OutputSection *osec : overwriteSections) if (process(osec) && !map.try_emplace(osec->name, osec).second) warn("OVERWRITE_SECTIONS specifies duplicate " + osec->name); - for (BaseCommand *&base : sectionCommands) + for (SectionCommand *&base : sectionCommands) if (auto *osec = dyn_cast(base)) { if (OutputSection *overwrite = map.lookup(osec->name)) { log(overwrite->location + " overwrites " + osec->name); @@ -699,22 +700,22 @@ void LinkerScript::processSymbolAssignments() { ctx = &state; ctx->outSec = aether; - for (BaseCommand *base : sectionCommands) { - if (auto *cmd = dyn_cast(base)) - addSymbol(cmd); + for (SectionCommand *cmd : sectionCommands) { + if (auto *assign = dyn_cast(cmd)) + addSymbol(assign); else - for (BaseCommand *sub_base : cast(base)->commands) - if (auto *cmd = dyn_cast(sub_base)) - addSymbol(cmd); + for (SectionCommand *subCmd : cast(cmd)->commands) + if (auto *assign = dyn_cast(subCmd)) + addSymbol(assign); } ctx = nullptr; } -static OutputSection *findByName(ArrayRef vec, +static OutputSection *findByName(ArrayRef vec, StringRef name) { - for (BaseCommand *base : vec) - if (auto *sec = dyn_cast(base)) + for (SectionCommand *cmd : vec) + if (auto *sec = dyn_cast(cmd)) if (sec->name == name) return sec; return nullptr; @@ -1058,27 +1059,27 @@ void LinkerScript::assignOffsets(OutputSection *sec) { // We visited SectionsCommands from processSectionCommands to // layout sections. Now, we visit SectionsCommands again to fix // section offsets. - for (BaseCommand *base : sec->commands) { + for (SectionCommand *cmd : sec->commands) { // This handles the assignments to symbol or to the dot. - if (auto *cmd = dyn_cast(base)) { - cmd->addr = dot; - assignSymbol(cmd, true); - cmd->size = dot - cmd->addr; + if (auto *assign = dyn_cast(cmd)) { + assign->addr = dot; + assignSymbol(assign, true); + assign->size = dot - assign->addr; continue; } // Handle BYTE(), SHORT(), LONG(), or QUAD(). - if (auto *cmd = dyn_cast(base)) { - cmd->offset = dot - ctx->outSec->addr; - dot += cmd->size; - expandOutputSection(cmd->size); + if (auto *data = dyn_cast(cmd)) { + data->offset = dot - ctx->outSec->addr; + dot += data->size; + expandOutputSection(data->size); continue; } // Handle a single input section description command. // It calculates and assigns the offsets for each section and also // updates the output section size. - for (InputSection *sec : cast(base)->sections) + for (InputSection *sec : cast(cmd)->sections) output(sec); } @@ -1109,14 +1110,14 @@ static bool isDiscardable(const OutputSection &sec) { if (sec.usedInExpression) return false; - for (BaseCommand *base : sec.commands) { - if (auto cmd = dyn_cast(base)) + for (SectionCommand *cmd : sec.commands) { + if (auto assign = dyn_cast(cmd)) // Don't create empty output sections just for unreferenced PROVIDE // symbols. - if (cmd->name != "." && !cmd->sym) + if (assign->name != "." && !assign->sym) continue; - if (!isa(*base)) + if (!isa(*cmd)) return false; } return true; @@ -1163,7 +1164,7 @@ void LinkerScript::adjustSectionsBeforeSorting() { uint64_t flags = SHF_ALLOC; std::vector defPhdrs; - for (BaseCommand *&cmd : sectionCommands) { + for (SectionCommand *&cmd : sectionCommands) { auto *sec = dyn_cast(cmd); if (!sec) continue; @@ -1209,14 +1210,14 @@ void LinkerScript::adjustSectionsBeforeSorting() { // clutter the output. // We instead remove trivially empty sections. The bfd linker seems even // more aggressive at removing them. - llvm::erase_if(sectionCommands, [&](BaseCommand *base) { return !base; }); + llvm::erase_if(sectionCommands, [&](SectionCommand *cmd) { return !cmd; }); } void LinkerScript::adjustSectionsAfterSorting() { // Try and find an appropriate memory region to assign offsets in. MemoryRegion *hint = nullptr; - for (BaseCommand *base : sectionCommands) { - if (auto *sec = dyn_cast(base)) { + for (SectionCommand *cmd : sectionCommands) { + if (auto *sec = dyn_cast(cmd)) { if (!sec->lmaRegionName.empty()) { if (MemoryRegion *m = memoryRegions.lookup(sec->lmaRegionName)) sec->lmaRegion = m; @@ -1242,8 +1243,8 @@ void LinkerScript::adjustSectionsAfterSorting() { // Walk the commands and propagate the program headers to commands that don't // explicitly specify them. - for (BaseCommand *base : sectionCommands) - if (auto *sec = dyn_cast(base)) + for (SectionCommand *cmd : sectionCommands) + if (auto *sec = dyn_cast(cmd)) maybePropagatePhdrs(*sec, defPhdrs); } @@ -1332,14 +1333,14 @@ const Defined *LinkerScript::assignAddresses() { switchTo(aether); SymbolAssignmentMap oldValues = getSymbolAssignmentValues(sectionCommands); - for (BaseCommand *base : sectionCommands) { - if (auto *cmd = dyn_cast(base)) { - cmd->addr = dot; - assignSymbol(cmd, false); - cmd->size = dot - cmd->addr; + for (SectionCommand *cmd : sectionCommands) { + if (auto *assign = dyn_cast(cmd)) { + assign->addr = dot; + assignSymbol(assign, false); + assign->size = dot - assign->addr; continue; } - assignOffsets(cast(base)); + assignOffsets(cast(cmd)); } ctx = nullptr; diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h index a94212e..f9db8f6 100644 --- a/lld/ELF/LinkerScript.h +++ b/lld/ELF/LinkerScript.h @@ -82,17 +82,18 @@ enum SectionsCommandKind { ByteKind // BYTE(expr), SHORT(expr), LONG(expr) or QUAD(expr) }; -struct BaseCommand { - BaseCommand(int k) : kind(k) {} +struct SectionCommand { + SectionCommand(int k) : kind(k) {} int kind; }; // This represents ". = " or " = ". -struct SymbolAssignment : BaseCommand { +struct SymbolAssignment : SectionCommand { SymbolAssignment(StringRef name, Expr e, std::string loc) - : BaseCommand(AssignmentKind), name(name), expression(e), location(loc) {} + : SectionCommand(AssignmentKind), name(name), expression(e), + location(loc) {} - static bool classof(const BaseCommand *c) { + static bool classof(const SectionCommand *c) { return c->kind == AssignmentKind; } @@ -182,7 +183,7 @@ public: SortSectionPolicy sortInner; }; -class InputSectionDescription : public BaseCommand { +class InputSectionDescription : public SectionCommand { SingleStringMatcher filePat; // Cache of the most recent input argument and result of matchesFile(). @@ -191,10 +192,10 @@ class InputSectionDescription : public BaseCommand { public: InputSectionDescription(StringRef filePattern, uint64_t withFlags = 0, uint64_t withoutFlags = 0) - : BaseCommand(InputSectionKind), filePat(filePattern), + : SectionCommand(InputSectionKind), filePat(filePattern), withFlags(withFlags), withoutFlags(withoutFlags) {} - static bool classof(const BaseCommand *c) { + static bool classof(const SectionCommand *c) { return c->kind == InputSectionKind; } @@ -223,12 +224,12 @@ public: }; // Represents BYTE(), SHORT(), LONG(), or QUAD(). -struct ByteCommand : BaseCommand { +struct ByteCommand : SectionCommand { ByteCommand(Expr e, unsigned size, std::string commandString) - : BaseCommand(ByteKind), commandString(commandString), expression(e), + : SectionCommand(ByteKind), commandString(commandString), expression(e), size(size) {} - static bool classof(const BaseCommand *c) { return c->kind == ByteKind; } + static bool classof(const SectionCommand *c) { return c->kind == ByteKind; } // Keeps string representing the command. Used for -Map" is perhaps better. std::string commandString; @@ -340,7 +341,7 @@ public: void processInsertCommands(); // SECTIONS command list. - std::vector sectionCommands; + std::vector sectionCommands; // PHDRS command list. std::vector phdrsCommands; diff --git a/lld/ELF/MapFile.cpp b/lld/ELF/MapFile.cpp index 9ae8d7b..56c215d 100644 --- a/lld/ELF/MapFile.cpp +++ b/lld/ELF/MapFile.cpp @@ -164,23 +164,23 @@ void elf::writeMapFile() { << " Size Align Out In Symbol\n"; OutputSection* osec = nullptr; - for (BaseCommand *base : script->sectionCommands) { - if (auto *cmd = dyn_cast(base)) { - if (cmd->provide && !cmd->sym) + for (SectionCommand *cmd : script->sectionCommands) { + if (auto *assign = dyn_cast(cmd)) { + if (assign->provide && !assign->sym) continue; - uint64_t lma = osec ? osec->getLMA() + cmd->addr - osec->getVA(0) : 0; - writeHeader(os, cmd->addr, lma, cmd->size, 1); - os << cmd->commandString << '\n'; + uint64_t lma = osec ? osec->getLMA() + assign->addr - osec->getVA(0) : 0; + writeHeader(os, assign->addr, lma, assign->size, 1); + os << assign->commandString << '\n'; continue; } - osec = cast(base); + osec = cast(cmd); writeHeader(os, osec->addr, osec->getLMA(), osec->size, osec->alignment); os << osec->name << '\n'; // Dump symbols for each input section. - for (BaseCommand *base : osec->commands) { - if (auto *isd = dyn_cast(base)) { + for (SectionCommand *subCmd : osec->commands) { + if (auto *isd = dyn_cast(subCmd)) { for (InputSection *isec : isd->sections) { if (auto *ehSec = dyn_cast(isec)) { printEhFrame(os, ehSec); @@ -196,19 +196,20 @@ void elf::writeMapFile() { continue; } - if (auto *cmd = dyn_cast(base)) { - writeHeader(os, osec->addr + cmd->offset, osec->getLMA() + cmd->offset, - cmd->size, 1); - os << indent8 << cmd->commandString << '\n'; + if (auto *data = dyn_cast(subCmd)) { + writeHeader(os, osec->addr + data->offset, + osec->getLMA() + data->offset, data->size, 1); + os << indent8 << data->commandString << '\n'; continue; } - if (auto *cmd = dyn_cast(base)) { - if (cmd->provide && !cmd->sym) + if (auto *assign = dyn_cast(subCmd)) { + if (assign->provide && !assign->sym) continue; - writeHeader(os, cmd->addr, osec->getLMA() + cmd->addr - osec->getVA(0), - cmd->size, 1); - os << indent8 << cmd->commandString << '\n'; + writeHeader(os, assign->addr, + osec->getLMA() + assign->addr - osec->getVA(0), + assign->size, 1); + os << indent8 << assign->commandString << '\n'; continue; } } diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 8890427..7b9cdc7 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -69,7 +69,7 @@ void OutputSection::writeHeaderTo(typename ELFT::Shdr *shdr) { } OutputSection::OutputSection(StringRef name, uint32_t type, uint64_t flags) - : BaseCommand(OutputSectionKind), + : SectionCommand(OutputSectionKind), SectionBase(Output, name, flags, /*Entsize*/ 0, /*Alignment*/ 1, type, /*Info*/ 0, /*Link*/ 0) {} @@ -165,15 +165,15 @@ void OutputSection::commitSection(InputSection *isec) { // to compute an output offset for each piece of each input section. void OutputSection::finalizeInputSections() { std::vector mergeSections; - for (BaseCommand *base : commands) { - auto *cmd = dyn_cast(base); - if (!cmd) + for (SectionCommand *cmd : commands) { + auto *isd = dyn_cast(cmd); + if (!isd) continue; - cmd->sections.reserve(cmd->sectionBases.size()); - for (InputSectionBase *s : cmd->sectionBases) { + isd->sections.reserve(isd->sectionBases.size()); + for (InputSectionBase *s : isd->sectionBases) { MergeInputSection *ms = dyn_cast(s); if (!ms) { - cmd->sections.push_back(cast(s)); + isd->sections.push_back(cast(s)); continue; } @@ -202,17 +202,17 @@ void OutputSection::finalizeInputSections() { mergeSections.push_back(syn); i = std::prev(mergeSections.end()); syn->entsize = ms->entsize; - cmd->sections.push_back(syn); + isd->sections.push_back(syn); } (*i)->addSection(ms); } // sectionBases should not be used from this point onwards. Clear it to // catch misuses. - cmd->sectionBases.clear(); + isd->sectionBases.clear(); // Some input sections may be removed from the list after ICF. - for (InputSection *s : cmd->sections) + for (InputSection *s : isd->sections) commitSection(s); } for (auto *ms : mergeSections) @@ -236,13 +236,13 @@ uint64_t elf::getHeaderSize() { return Out::elfHeader->size + Out::programHeaders->size; } -bool OutputSection::classof(const BaseCommand *c) { +bool OutputSection::classof(const SectionCommand *c) { return c->kind == OutputSectionKind; } void OutputSection::sort(llvm::function_ref order) { assert(isLive()); - for (BaseCommand *b : commands) + for (SectionCommand *b : commands) if (auto *isd = dyn_cast(b)) sortByOrder(isd->sections, order); } @@ -366,8 +366,8 @@ template void OutputSection::writeTo(uint8_t *buf) { // Linker scripts may have BYTE()-family commands with which you // can write arbitrary bytes to the output. Process them if any. - for (BaseCommand *base : commands) - if (auto *data = dyn_cast(base)) + for (SectionCommand *cmd : commands) + if (auto *data = dyn_cast(cmd)) writeInt(buf + data->offset, data->expression().getValue(), data->size); } @@ -504,8 +504,8 @@ int elf::getPriority(StringRef s) { } InputSection *elf::getFirstInputSection(const OutputSection *os) { - for (BaseCommand *base : os->commands) - if (auto *isd = dyn_cast(base)) + for (SectionCommand *cmd : os->commands) + if (auto *isd = dyn_cast(cmd)) if (!isd->sections.empty()) return isd->sections[0]; return nullptr; @@ -513,8 +513,8 @@ InputSection *elf::getFirstInputSection(const OutputSection *os) { std::vector elf::getInputSections(const OutputSection *os) { std::vector ret; - for (BaseCommand *base : os->commands) - if (auto *isd = dyn_cast(base)) + for (SectionCommand *cmd : os->commands) + if (auto *isd = dyn_cast(cmd)) ret.insert(ret.end(), isd->sections.begin(), isd->sections.end()); return ret; } diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h index fe9fd4e..316fc33 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -29,7 +29,7 @@ class InputSectionBase; // It is composed of multiple InputSections. // The writer creates multiple OutputSections and assign them unique, // non-overlapping file offsets and VAs. -class OutputSection final : public BaseCommand, public SectionBase { +class OutputSection final : public SectionCommand, public SectionBase { public: OutputSection(StringRef name, uint32_t type, uint64_t flags); @@ -37,7 +37,7 @@ public: return s->kind() == SectionBase::Output; } - static bool classof(const BaseCommand *c); + static bool classof(const SectionCommand *c); uint64_t getLMA() const { return ptLoad ? addr + ptLoad->lmaOffset : addr; } template void writeHeaderTo(typename ELFT::Shdr *sHdr); @@ -82,7 +82,7 @@ public: Expr alignExpr; Expr lmaExpr; Expr subalignExpr; - std::vector commands; + std::vector commands; std::vector phdrs; llvm::Optional> filler; ConstraintKind constraint = ConstraintKind::NoConstraint; diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 023a04f..5435261 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -66,10 +66,10 @@ using namespace lld; using namespace lld::elf; static Optional getLinkerScriptLocation(const Symbol &sym) { - for (BaseCommand *base : script->sectionCommands) - if (auto *cmd = dyn_cast(base)) - if (cmd->sym == &sym) - return cmd->location; + for (SectionCommand *cmd : script->sectionCommands) + if (auto *assign = dyn_cast(cmd)) + if (assign->sym == &sym) + return assign->location; return None; } @@ -1640,7 +1640,7 @@ static void forEachInputSectionDescription( for (OutputSection *os : outputSections) { if (!(os->flags & SHF_ALLOC) || !(os->flags & SHF_EXECINSTR)) continue; - for (BaseCommand *bc : os->commands) + for (SectionCommand *bc : os->commands) if (auto *isd = dyn_cast(bc)) fn(os, isd); } @@ -1817,7 +1817,7 @@ ThunkSection *ThunkCreator::getISThunkSec(InputSection *isec) { // Find InputSectionRange within Target Output Section (TOS) that the // InputSection (IS) that we need to precede is in. OutputSection *tos = isec->getParent(); - for (BaseCommand *bc : tos->commands) { + for (SectionCommand *bc : tos->commands) { auto *isd = dyn_cast(bc); if (!isd || isd->sections.empty()) continue; diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp index d91caed..d3b0296 100644 --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -93,7 +93,7 @@ private: void readSectionAddressType(OutputSection *cmd); OutputSection *readOverlaySectionDescription(); OutputSection *readOutputSectionDescription(StringRef outSec); - std::vector readOverlay(); + std::vector readOverlay(); std::vector readOutputSectionPhdrs(); std::pair readInputSectionFlags(); InputSectionDescription *readInputSectionDescription(StringRef tok); @@ -519,7 +519,7 @@ void ScriptParser::readSearchDir() { // sections that use the same virtual memory range and normally would trigger // linker's sections sanity check failures. // https://sourceware.org/binutils/docs/ld/Overlay-Description.html#Overlay-Description -std::vector ScriptParser::readOverlay() { +std::vector ScriptParser::readOverlay() { // VA and LMA expressions are optional, though for simplicity of // implementation we assume they are not. That is what OVERLAY was designed // for first of all: to allow sections with overlapping VAs at different LMAs. @@ -529,7 +529,7 @@ std::vector ScriptParser::readOverlay() { Expr lmaExpr = readParenExpr(); expect("{"); - std::vector v; + std::vector v; OutputSection *prev = nullptr; while (!errorCount() && !consume("}")) { // VA is the same for all sections. The LMAs are consecutive in memory @@ -550,7 +550,7 @@ std::vector ScriptParser::readOverlay() { // Here we want to create the Dot assignment command to achieve that. Expr moveDot = [=] { uint64_t max = 0; - for (BaseCommand *cmd : v) + for (SectionCommand *cmd : v) max = std::max(max, cast(cmd)->size); return addrExpr().getValue() + max; }; @@ -566,11 +566,11 @@ void ScriptParser::readOverwriteSections() { void ScriptParser::readSections() { expect("{"); - std::vector v; + std::vector v; while (!errorCount() && !consume("}")) { StringRef tok = next(); if (tok == "OVERLAY") { - for (BaseCommand *cmd : readOverlay()) + for (SectionCommand *cmd : readOverlay()) v.push_back(cmd); continue; } else if (tok == "INCLUDE") { @@ -578,7 +578,7 @@ void ScriptParser::readSections() { continue; } - if (BaseCommand *cmd = readAssignment(tok)) + if (SectionCommand *cmd = readAssignment(tok)) v.push_back(cmd); else v.push_back(readOutputSectionDescription(tok)); @@ -598,7 +598,7 @@ void ScriptParser::readSections() { setError("expected AFTER/BEFORE, but got '" + next() + "'"); StringRef where = next(); std::vector names; - for (BaseCommand *cmd : v) + for (SectionCommand *cmd : v) if (auto *os = dyn_cast(cmd)) names.push_back(os->name); if (!names.empty()) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 0413e31..8eb3703 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -900,7 +900,7 @@ void MipsGotSection::build() { got.pagesMap) { const OutputSection *os = p.first; uint64_t secSize = 0; - for (BaseCommand *cmd : os->commands) { + for (SectionCommand *cmd : os->commands) { if (auto *isd = dyn_cast(cmd)) for (InputSection *isec : isd->sections) { uint64_t off = alignTo(secSize, isec->alignment); @@ -2300,8 +2300,8 @@ 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 (BaseCommand *base : script->sectionCommands) - if (isa(base)) + for (SectionCommand *cmd : script->sectionCommands) + if (isa(cmd)) ++size; return size >= SHN_LORESERVE; } @@ -3604,8 +3604,8 @@ PPC32Got2Section::PPC32Got2Section() bool PPC32Got2Section::isNeeded() const { // See the comment below. This is not needed if there is no other // InputSection. - for (BaseCommand *base : getParent()->commands) - if (auto *isd = dyn_cast(base)) + for (SectionCommand *cmd : getParent()->commands) + if (auto *isd = dyn_cast(cmd)) for (InputSection *isec : isd->sections) if (isec != this) return true; @@ -3618,8 +3618,8 @@ void PPC32Got2Section::finalizeContents() { // PPC32PltCallStub::writeTo(). The purpose of this empty synthetic section is // to collect input sections named ".got2". uint32_t offset = 0; - for (BaseCommand *base : getParent()->commands) - if (auto *isd = dyn_cast(base)) { + for (SectionCommand *cmd : getParent()->commands) + if (auto *isd = dyn_cast(cmd)) { for (InputSection *isec : isd->sections) { if (isec == this) continue; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 59a7519..a870a03 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -271,8 +271,8 @@ void elf::addReservedSymbols() { } static OutputSection *findSection(StringRef name, unsigned partition = 1) { - for (BaseCommand *base : script->sectionCommands) - if (auto *sec = dyn_cast(base)) + for (SectionCommand *cmd : script->sectionCommands) + if (auto *sec = dyn_cast(cmd)) if (sec->name == name && sec->partition == partition) return sec; return nullptr; @@ -725,12 +725,12 @@ template void Writer::copyLocalSymbols() { // referring to a section (that happens if the section is a synthetic one), we // don't create a section symbol for that section. template void Writer::addSectionSymbols() { - for (BaseCommand *base : script->sectionCommands) { - auto *sec = dyn_cast(base); + for (SectionCommand *cmd : script->sectionCommands) { + auto *sec = dyn_cast(cmd); if (!sec) continue; - auto i = llvm::find_if(sec->commands, [](BaseCommand *base) { - if (auto *isd = dyn_cast(base)) + auto i = llvm::find_if(sec->commands, [](SectionCommand *cmd) { + if (auto *isd = dyn_cast(cmd)) return !isd->sections.empty(); return false; }); @@ -991,7 +991,8 @@ static unsigned getSectionRank(const OutputSection *sec) { return rank; } -static bool compareSections(const BaseCommand *aCmd, const BaseCommand *bCmd) { +static bool compareSections(const SectionCommand *aCmd, + const SectionCommand *bCmd) { const OutputSection *a = cast(aCmd); const OutputSection *b = cast(bCmd); @@ -1148,7 +1149,7 @@ static int getRankProximityAux(OutputSection *a, OutputSection *b) { return countLeadingZeros(a->sortRank ^ b->sortRank); } -static int getRankProximity(OutputSection *a, BaseCommand *b) { +static int getRankProximity(OutputSection *a, SectionCommand *b) { auto *sec = dyn_cast(b); return (sec && sec->hasInputSections) ? getRankProximityAux(a, sec) : -1; } @@ -1167,7 +1168,7 @@ static int getRankProximity(OutputSection *a, BaseCommand *b) { // /* The RW PT_LOAD starts here*/ // rw_sec : { *(rw_sec) } // would mean that the RW PT_LOAD would become unaligned. -static bool shouldSkip(BaseCommand *cmd) { +static bool shouldSkip(SectionCommand *cmd) { if (auto *assign = dyn_cast(cmd)) return assign->name != "."; return false; @@ -1176,13 +1177,13 @@ static bool shouldSkip(BaseCommand *cmd) { // We want to place orphan sections so that they share as much // characteristics with their neighbors as possible. For example, if // both are rw, or both are tls. -static std::vector::iterator -findOrphanPos(std::vector::iterator b, - std::vector::iterator e) { +static std::vector::iterator +findOrphanPos(std::vector::iterator b, + std::vector::iterator e) { OutputSection *sec = cast(*e); // Find the first element that has as close a rank as possible. - auto i = std::max_element(b, e, [=](BaseCommand *a, BaseCommand *b) { + auto i = std::max_element(b, e, [=](SectionCommand *a, SectionCommand *b) { return getRankProximity(sec, a) < getRankProximity(sec, b); }); if (i == e) @@ -1211,7 +1212,7 @@ findOrphanPos(std::vector::iterator b, break; } - auto isOutputSecWithInputSections = [](BaseCommand *cmd) { + auto isOutputSecWithInputSections = [](SectionCommand *cmd) { auto *os = dyn_cast(cmd); return os && os->hasInputSections; }; @@ -1420,7 +1421,7 @@ static void sortSection(OutputSection *sec, // digit radix sort. The sections may be sorted stably again by a more // significant key. if (!order.empty()) - for (BaseCommand *b : sec->commands) + for (SectionCommand *b : sec->commands) if (auto *isd = dyn_cast(b)) sortISDBySectionOrder(isd, order); @@ -1453,8 +1454,8 @@ template void Writer::sortInputSections() { // Build the order once since it is expensive. DenseMap order = buildSectionOrder(); maybeShuffle(order); - for (BaseCommand *base : script->sectionCommands) - if (auto *sec = dyn_cast(base)) + for (SectionCommand *cmd : script->sectionCommands) + if (auto *sec = dyn_cast(cmd)) sortSection(sec, order); } @@ -1469,8 +1470,8 @@ template void Writer::sortSections() { sortInputSections(); - for (BaseCommand *base : script->sectionCommands) { - auto *os = dyn_cast(base); + for (SectionCommand *cmd : script->sectionCommands) { + auto *os = dyn_cast(cmd); if (!os) continue; os->sortRank = getSectionRank(os); @@ -1485,7 +1486,9 @@ template void Writer::sortSections() { if (!script->hasSectionsCommand) { // We know that all the OutputSections are contiguous in this case. - auto isSection = [](BaseCommand *base) { return isa(base); }; + auto isSection = [](SectionCommand *cmd) { + return isa(cmd); + }; std::stable_sort( llvm::find_if(script->sectionCommands, isSection), llvm::find_if(llvm::reverse(script->sectionCommands), isSection).base(), @@ -1540,8 +1543,8 @@ template void Writer::sortSections() { auto i = script->sectionCommands.begin(); auto e = script->sectionCommands.end(); - auto nonScriptI = std::find_if(i, e, [](BaseCommand *base) { - if (auto *sec = dyn_cast(base)) + auto nonScriptI = std::find_if(i, e, [](SectionCommand *cmd) { + if (auto *sec = dyn_cast(cmd)) return sec->sectionIndex == UINT32_MAX; return false; }); @@ -1554,7 +1557,7 @@ template void Writer::sortSections() { // the script with ". = 0xabcd" and the expectation is that every section is // after that. auto firstSectionOrDotAssignment = - std::find_if(i, e, [](BaseCommand *cmd) { return !shouldSkip(cmd); }); + std::find_if(i, e, [](SectionCommand *cmd) { return !shouldSkip(cmd); }); if (firstSectionOrDotAssignment != e && isa(**firstSectionOrDotAssignment)) ++firstSectionOrDotAssignment; @@ -1567,7 +1570,7 @@ template void Writer::sortSections() { // As an optimization, find all sections with the same sort rank // and insert them with one rotate. unsigned rank = orphan->sortRank; - auto end = std::find_if(nonScriptI + 1, e, [=](BaseCommand *cmd) { + auto end = std::find_if(nonScriptI + 1, e, [=](SectionCommand *cmd) { return cast(cmd)->sortRank != rank; }); std::rotate(pos, nonScriptI, end); @@ -1608,8 +1611,8 @@ template void Writer::resolveShfLinkOrder() { // Sorting is performed separately. std::vector scriptSections; std::vector sections; - for (BaseCommand *base : sec->commands) { - auto *isd = dyn_cast(base); + for (SectionCommand *cmd : sec->commands) { + auto *isd = dyn_cast(cmd); if (!isd) continue; bool hasLinkOrder = false; @@ -1712,7 +1715,7 @@ template void Writer::finalizeAddressDependentContent() { // If addrExpr is set, the address may not be a multiple of the alignment. // Warn because this is error-prone. - for (BaseCommand *cmd : script->sectionCommands) + for (SectionCommand *cmd : script->sectionCommands) if (auto *os = dyn_cast(cmd)) if (os->addr % os->alignment != 0) warn("address (0x" + Twine::utohexstr(os->addr) + ") of section " + @@ -1842,7 +1845,7 @@ static void removeUnusedSyntheticSections() { // If we reach here, then ss is an unused synthetic section and we want // to remove it from the corresponding input section description, and // orphanSections. - for (BaseCommand *b : os->commands) + for (SectionCommand *b : os->commands) if (auto *isd = dyn_cast(b)) isdSet.insert(isd); @@ -1873,8 +1876,8 @@ template void Writer::finalizeSections() { // addresses of each section by section name. Add such symbols. if (!config->relocatable) { addStartEndSymbols(); - for (BaseCommand *base : script->sectionCommands) - if (auto *sec = dyn_cast(base)) + for (SectionCommand *cmd : script->sectionCommands) + if (auto *sec = dyn_cast(cmd)) addStartStopSymbols(sec); } @@ -2027,8 +2030,8 @@ template void Writer::finalizeSections() { // Now that we have the final list, create a list of all the // OutputSections for convenience. - for (BaseCommand *base : script->sectionCommands) - if (auto *sec = dyn_cast(base)) + for (SectionCommand *cmd : script->sectionCommands) + if (auto *sec = dyn_cast(cmd)) outputSections.push_back(sec); // Prefer command line supplied address over other constraints. -- 2.7.4