From ac27de9dc707bb1dd191a2deb6ad347e0f9df602 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Wed, 11 Oct 2017 01:19:33 +0000 Subject: [PATCH] Remove ScriptConfiguration class and move the members to LinkerScript class. ScriptConfiguration was a class to contain parsed results of linker scripts. LinkerScript is a class to interpret it. That ditinction was needed because we haven't instantiated LinkerScript early (because, IIRC, LinkerScript class was a ELFT template function). So, when we parse linker scripts, we couldn't directly store the result to a LinkerScript instance. Now, that limitation is gone. We instantiate LinkerScript at the very beginning of our main function. We can directly store parse results to a LinkerScript instance. llvm-svn: 315403 --- lld/ELF/Driver.cpp | 2 +- lld/ELF/LTO.cpp | 2 +- lld/ELF/LinkerScript.cpp | 63 ++++++++++++++++++++-------------------- lld/ELF/LinkerScript.h | 45 +++++++++++++--------------- lld/ELF/MarkLive.cpp | 2 +- lld/ELF/ScriptParser.cpp | 32 ++++++++++---------- lld/ELF/Writer.cpp | 37 ++++++++++++----------- 7 files changed, 88 insertions(+), 95 deletions(-) diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index fea7fb552c45..b470f7094509 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -1035,7 +1035,7 @@ template void LinkerDriver::link(opt::InputArgList &Args) { // Some symbols (such as __ehdr_start) are defined lazily only when there // are undefined symbols for them, so we add these to trigger that logic. - for (StringRef Sym : Script->Opt.ReferencedSymbols) + for (StringRef Sym : Script->ReferencedSymbols) Symtab->addUndefined(Sym); // Handle the `--undefined ` options. diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp index 925c3ec1ebd4..626ba192b9e0 100644 --- a/lld/ELF/LTO.cpp +++ b/lld/ELF/LTO.cpp @@ -130,7 +130,7 @@ void BitcodeCompiler::add(BitcodeFile &F) { std::vector Resols(Syms.size()); DenseSet ScriptSymbols; - for (BaseCommand *Base : Script->Opt.Commands) + for (BaseCommand *Base : Script->Commands) if (auto *Cmd = dyn_cast(Base)) ScriptSymbols.insert(Cmd->Name); diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 14861d9bb689..ae413b5c5c26 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -201,7 +201,7 @@ static std::string filename(InputFile *File) { } bool LinkerScript::shouldKeep(InputSectionBase *S) { - for (InputSectionDescription *ID : Opt.KeptSections) { + for (InputSectionDescription *ID : KeptSections) { std::string Filename = filename(S->File); if (ID->FilePat.match(Filename)) for (SectionPattern &P : ID->SectionPatterns) @@ -366,7 +366,7 @@ void LinkerScript::processCommands(OutputSectionFactory &Factory) { // which will map to whatever the first actual section is. Aether = make("", 0, SHF_ALLOC); Aether->SectionIndex = 1; - auto State = make_unique(Opt); + auto State = make_unique(); // CurAddressState captures the local AddressState and makes it accessible // deliberately. This is needed as there are some cases where we cannot just @@ -375,14 +375,14 @@ void LinkerScript::processCommands(OutputSectionFactory &Factory) { CurAddressState = State.get(); CurAddressState->OutSec = Aether; - for (size_t I = 0; I < Opt.Commands.size(); ++I) { + for (size_t I = 0; I < Commands.size(); ++I) { // Handle symbol assignments outside of any output section. - if (auto *Cmd = dyn_cast(Opt.Commands[I])) { + if (auto *Cmd = dyn_cast(Commands[I])) { addSymbol(Cmd); continue; } - if (auto *Sec = dyn_cast(Opt.Commands[I])) { + if (auto *Sec = dyn_cast(Commands[I])) { std::vector V = createInputSectionList(*Sec); // The output section name `/DISCARD/' is special. @@ -402,7 +402,7 @@ void LinkerScript::processCommands(OutputSectionFactory &Factory) { if (!matchConstraints(V, Sec->Constraint)) { for (InputSectionBase *S : V) S->Assigned = false; - Opt.Commands.erase(Opt.Commands.begin() + I); + Commands.erase(Commands.begin() + I); --I; continue; } @@ -448,8 +448,7 @@ void LinkerScript::fabricateDefaultCommands() { auto Expr = [=] { return std::min(StartAddr, Target->getImageBase() + elf::getHeaderSize()); }; - Opt.Commands.insert(Opt.Commands.begin(), - make(".", Expr, "")); + Commands.insert(Commands.begin(), make(".", Expr, "")); } static OutputSection *findByName(ArrayRef Vec, @@ -463,7 +462,7 @@ static OutputSection *findByName(ArrayRef Vec, // Add sections that didn't match any sections command. void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) { - unsigned End = Opt.Commands.size(); + unsigned End = Commands.size(); for (InputSectionBase *S : InputSections) { if (!S->Live || S->Parent) @@ -472,14 +471,14 @@ void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) { StringRef Name = getOutputSectionName(S->Name); log(toString(S) + " is being placed in '" + Name + "'"); - if (OutputSection *Sec = findByName( - makeArrayRef(Opt.Commands).slice(0, End), Name)) { + if (OutputSection *Sec = + findByName(makeArrayRef(Commands).slice(0, End), Name)) { Sec->addSection(cast(S)); continue; } if (OutputSection *OS = Factory.addInputSec(S, Name)) - Script->Opt.Commands.push_back(OS); + Script->Commands.push_back(OS); assert(S->getOutputSection()->SectionIndex == INT_MAX); } } @@ -588,8 +587,8 @@ MemoryRegion *LinkerScript::findMemoryRegion(OutputSection *Sec) { // If a memory region name was specified in the output section command, // then try to find that region first. if (!Sec->MemoryRegionName.empty()) { - auto It = Opt.MemoryRegions.find(Sec->MemoryRegionName); - if (It != Opt.MemoryRegions.end()) + auto It = MemoryRegions.find(Sec->MemoryRegionName); + if (It != MemoryRegions.end()) return It->second; error("memory region '" + Sec->MemoryRegionName + "' not declared"); return nullptr; @@ -598,11 +597,11 @@ MemoryRegion *LinkerScript::findMemoryRegion(OutputSection *Sec) { // If at least one memory region is defined, all sections must // belong to some memory region. Otherwise, we don't need to do // anything for memory regions. - if (Opt.MemoryRegions.empty()) + if (MemoryRegions.empty()) return nullptr; // See if a region can be found by matching section flags. - for (auto &Pair : Opt.MemoryRegions) { + for (auto &Pair : MemoryRegions) { MemoryRegion *M = Pair.second; if ((M->Flags & Sec->Flags) && (M->NegFlags & Sec->Flags) == 0) return M; @@ -649,7 +648,7 @@ void LinkerScript::removeEmptyCommands() { // clutter the output. // We instead remove trivially empty sections. The bfd linker seems even // more aggressive at removing them. - llvm::erase_if(Opt.Commands, [&](BaseCommand *Base) { + llvm::erase_if(Commands, [&](BaseCommand *Base) { if (auto *Sec = dyn_cast(Base)) return !Sec->Live; return false; @@ -670,7 +669,7 @@ void LinkerScript::adjustSectionsBeforeSorting() { // consequeces and gives us a section to put the symbol in. uint64_t Flags = SHF_ALLOC; - for (BaseCommand * Cmd : Opt.Commands) { + for (BaseCommand *Cmd : Commands) { auto *Sec = dyn_cast(Cmd); if (!Sec) continue; @@ -689,7 +688,7 @@ void LinkerScript::adjustSectionsBeforeSorting() { void LinkerScript::adjustSectionsAfterSorting() { // Try and find an appropriate memory region to assign offsets in. - for (BaseCommand *Base : Opt.Commands) { + for (BaseCommand *Base : Commands) { if (auto *Sec = dyn_cast(Base)) { if (!Sec->Live) continue; @@ -709,14 +708,14 @@ void LinkerScript::adjustSectionsAfterSorting() { // SECTIONS { .aaa : { *(.aaa) } } std::vector DefPhdrs; auto FirstPtLoad = - std::find_if(Opt.PhdrsCommands.begin(), Opt.PhdrsCommands.end(), + std::find_if(PhdrsCommands.begin(), PhdrsCommands.end(), [](const PhdrsCommand &Cmd) { return Cmd.Type == PT_LOAD; }); - if (FirstPtLoad != Opt.PhdrsCommands.end()) + if (FirstPtLoad != PhdrsCommands.end()) DefPhdrs.push_back(FirstPtLoad->Name); // Walk the commands and propagate the program headers to commands that don't // explicitly specify them. - for (BaseCommand *Base : Opt.Commands) { + for (BaseCommand *Base : Commands) { auto *Sec = dyn_cast(Base); if (!Sec) continue; @@ -765,7 +764,7 @@ void LinkerScript::allocateHeaders(std::vector &Phdrs) { uint64_t HeaderSize = getHeaderSize(); // When linker script with SECTIONS is being used, don't output headers // unless there's a space for them. - uint64_t Base = Opt.HasSections ? alignDown(Min, Config->MaxPageSize) : 0; + uint64_t Base = HasSections ? alignDown(Min, Config->MaxPageSize) : 0; if (HeaderSize <= Min - Base || Script->hasPhdrsCommands()) { Min = alignDown(Min - HeaderSize, Config->MaxPageSize); Out::ElfHeader->Addr = Min; @@ -781,8 +780,8 @@ void LinkerScript::allocateHeaders(std::vector &Phdrs) { [](const PhdrEntry *E) { return E->p_type == PT_PHDR; }); } -LinkerScript::AddressState::AddressState(const ScriptConfiguration &Opt) { - for (auto &MRI : Opt.MemoryRegions) { +LinkerScript::AddressState::AddressState() { + for (auto &MRI : Script->MemoryRegions) { const MemoryRegion *MR = MRI.second; MemRegionOffset[MR] = MR->Origin; } @@ -793,7 +792,7 @@ void LinkerScript::assignAddresses() { // By default linker scripts use an initial value of 0 for '.', but prefer // -image-base if set. Dot = Config->ImageBase ? *Config->ImageBase : 0; - auto State = make_unique(Opt); + auto State = make_unique(); // CurAddressState captures the local AddressState and makes it accessible // deliberately. This is needed as there are some cases where we cannot just @@ -803,7 +802,7 @@ void LinkerScript::assignAddresses() { ErrorOnMissingSection = true; switchTo(Aether); - for (BaseCommand *Base : Opt.Commands) { + for (BaseCommand *Base : Commands) { if (auto *Cmd = dyn_cast(Base)) { assignSymbol(Cmd, false); continue; @@ -825,7 +824,7 @@ std::vector LinkerScript::createPhdrs() { // Process PHDRS and FILEHDR keywords because they are not // real output sections and cannot be added in the following loop. - for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) { + for (const PhdrsCommand &Cmd : PhdrsCommands) { PhdrEntry *Phdr = make(Cmd.Type, Cmd.Flags ? *Cmd.Flags : PF_R); if (Cmd.HasFilehdr) @@ -845,7 +844,7 @@ std::vector LinkerScript::createPhdrs() { // Assign headers specified by linker script for (size_t Id : getPhdrIndices(Sec)) { Ret[Id]->add(Sec); - if (!Opt.PhdrsCommands[Id].Flags.hasValue()) + if (!PhdrsCommands[Id].Flags.hasValue()) Ret[Id]->p_flags |= Sec->getPhdrFlags(); } } @@ -858,9 +857,9 @@ std::vector LinkerScript::createPhdrs() { // no PT_INTERP is there, there's no place to emit an // .interp, so we don't do that in that case. bool LinkerScript::needsInterpSection() { - if (Opt.PhdrsCommands.empty()) + if (PhdrsCommands.empty()) return true; - for (PhdrsCommand &Cmd : Opt.PhdrsCommands) + for (PhdrsCommand &Cmd : PhdrsCommands) if (Cmd.Type == PT_INTERP) return true; return false; @@ -899,7 +898,7 @@ std::vector LinkerScript::getPhdrIndices(OutputSection *Cmd) { std::vector Ret; for (StringRef S : Cmd->Phdrs) { - if (Optional Idx = getPhdrIndex(Opt.PhdrsCommands, S)) + if (Optional Idx = getPhdrIndex(PhdrsCommands, S)) Ret.push_back(*Idx); else if (S != "NONE") error(Cmd->Location + ": section header '" + S + diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h index 26c9b20e1374..145cb31fbffc 100644 --- a/lld/ELF/LinkerScript.h +++ b/lld/ELF/LinkerScript.h @@ -181,39 +181,19 @@ struct PhdrsCommand { Expr LMAExpr = nullptr; }; -// ScriptConfiguration holds linker script parse results. -struct ScriptConfiguration { - // Used to assign addresses to sections. - std::vector Commands; - - // Used to assign sections to headers. - std::vector PhdrsCommands; - - bool HasSections = false; - - // List of section patterns specified with KEEP commands. They will - // be kept even if they are unused and --gc-sections is specified. - std::vector KeptSections; - - // A map from memory region name to a memory region descriptor. - llvm::DenseMap MemoryRegions; - - // A list of symbols referenced by the script. - std::vector ReferencedSymbols; -}; - class LinkerScript final { // Temporary state used in processCommands() and assignAddresses() // that must be reinitialized for each call to the above functions, and must // not be used outside of the scope of a call to the above functions. struct AddressState { + AddressState(); uint64_t ThreadBssOffset = 0; OutputSection *OutSec = nullptr; MemoryRegion *MemRegion = nullptr; llvm::DenseMap MemRegionOffset; std::function LMAOffset; - AddressState(const ScriptConfiguration &Opt); }; + llvm::DenseMap NameToOutputSection; void assignSymbol(SymbolAssignment *Cmd, bool InSec); @@ -243,7 +223,7 @@ public: OutputSection *createOutputSection(StringRef Name, StringRef Location); OutputSection *getOrCreateOutputSection(StringRef Name); - bool hasPhdrsCommands() { return !Opt.PhdrsCommands.empty(); } + bool hasPhdrsCommands() { return !PhdrsCommands.empty(); } uint64_t getDot() { return Dot; } void discard(ArrayRef V); @@ -265,8 +245,23 @@ public: void addSymbol(SymbolAssignment *Cmd); void processCommands(OutputSectionFactory &Factory); - // Parsed linker script configurations are set to this struct. - ScriptConfiguration Opt; + // SECTIONS command list. + std::vector Commands; + + // PHDRS command list. + std::vector PhdrsCommands; + + bool HasSections = false; + + // List of section patterns specified with KEEP commands. They will + // be kept even if they are unused and --gc-sections is specified. + std::vector KeptSections; + + // A map from memory region name to a memory region descriptor. + llvm::DenseMap MemoryRegions; + + // A list of symbols referenced by the script. + std::vector ReferencedSymbols; }; extern LinkerScript *Script; diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp index e710374e430b..b737eac800b8 100644 --- a/lld/ELF/MarkLive.cpp +++ b/lld/ELF/MarkLive.cpp @@ -229,7 +229,7 @@ template static void doGcSections() { MarkSymbol(Symtab->find(Config->Fini)); for (StringRef S : Config->Undefined) MarkSymbol(Symtab->find(S)); - for (StringRef S : Script->Opt.ReferencedSymbols) + for (StringRef S : Script->ReferencedSymbols) MarkSymbol(Symtab->find(S)); // Preserve externally-visible symbols if the symbols defined by this diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp index 58d1455a62c1..944e29fbbc4a 100644 --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -234,7 +234,7 @@ void ScriptParser::readLinkerScript() { continue; if (Tok == "ASSERT") { - Script->Opt.Commands.push_back(readAssert()); + Script->Commands.push_back(readAssert()); } else if (Tok == "ENTRY") { readEntry(); } else if (Tok == "EXTERN") { @@ -262,7 +262,7 @@ void ScriptParser::readLinkerScript() { } else if (Tok == "VERSION") { readVersion(); } else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok)) { - Script->Opt.Commands.push_back(Cmd); + Script->Commands.push_back(Cmd); } else { setError("unknown directive: " + Tok); } @@ -407,7 +407,7 @@ void ScriptParser::readPhdrs() { setError("unexpected header attribute: " + next()); } - Script->Opt.PhdrsCommands.push_back(Cmd); + Script->PhdrsCommands.push_back(Cmd); } } @@ -418,11 +418,11 @@ void ScriptParser::readRegionAlias() { StringRef Name = next(); expect(")"); - if (Script->Opt.MemoryRegions.count(Alias)) + if (Script->MemoryRegions.count(Alias)) setError("redefinition of memory region '" + Alias + "'"); - if (!Script->Opt.MemoryRegions.count(Name)) + if (!Script->MemoryRegions.count(Name)) setError("memory region '" + Name + "' is not defined"); - Script->Opt.MemoryRegions[Alias] = Script->Opt.MemoryRegions[Name]; + Script->MemoryRegions[Alias] = Script->MemoryRegions[Name]; } void ScriptParser::readSearchDir() { @@ -434,7 +434,7 @@ void ScriptParser::readSearchDir() { } void ScriptParser::readSections() { - Script->Opt.HasSections = true; + Script->HasSections = true; // -no-rosegment is used to avoid placing read only non-executable sections in // their own segment. We do the same if SECTIONS command is present in linker @@ -451,7 +451,7 @@ void ScriptParser::readSections() { else Cmd = readOutputSectionDescription(Tok); } - Script->Opt.Commands.push_back(Cmd); + Script->Commands.push_back(Cmd); } } @@ -572,7 +572,7 @@ ScriptParser::readInputSectionDescription(StringRef Tok) { StringRef FilePattern = next(); InputSectionDescription *Cmd = readInputSectionRules(FilePattern); expect(")"); - Script->Opt.KeptSections.push_back(Cmd); + Script->KeptSections.push_back(Cmd); return Cmd; } return readInputSectionRules(Tok); @@ -1013,9 +1013,9 @@ Expr ScriptParser::readPrimary() { } if (Tok == "LENGTH") { StringRef Name = readParenLiteral(); - if (Script->Opt.MemoryRegions.count(Name) == 0) + if (Script->MemoryRegions.count(Name) == 0) setError("memory region not defined: " + Name); - return [=] { return Script->Opt.MemoryRegions[Name]->Length; }; + return [=] { return Script->MemoryRegions[Name]->Length; }; } if (Tok == "LOADADDR") { StringRef Name = readParenLiteral(); @@ -1027,9 +1027,9 @@ Expr ScriptParser::readPrimary() { } if (Tok == "ORIGIN") { StringRef Name = readParenLiteral(); - if (Script->Opt.MemoryRegions.count(Name) == 0) + if (Script->MemoryRegions.count(Name) == 0) setError("memory region not defined: " + Name); - return [=] { return Script->Opt.MemoryRegions[Name]->Origin; }; + return [=] { return Script->MemoryRegions[Name]->Origin; }; } if (Tok == "SEGMENT_START") { expect("("); @@ -1061,7 +1061,7 @@ Expr ScriptParser::readPrimary() { // Tok is a symbol name. if (!isValidCIdentifier(Tok)) setError("malformed number: " + Tok); - Script->Opt.ReferencedSymbols.push_back(Tok); + Script->ReferencedSymbols.push_back(Tok); return [=] { return Script->getSymbolValue(Location, Tok); }; } @@ -1261,11 +1261,11 @@ void ScriptParser::readMemory() { uint64_t Length = readMemoryAssignment("LENGTH", "len", "l"); // Add the memory region to the region map. - if (Script->Opt.MemoryRegions.count(Name)) + if (Script->MemoryRegions.count(Name)) setError("region '" + Name + "' already defined"); MemoryRegion *MR = make(); *MR = {Name, Origin, Length, Flags, NegFlags}; - Script->Opt.MemoryRegions[Name] = MR; + Script->MemoryRegions[Name] = MR; } } diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 0cc506eddf6f..cdc2c0e53952 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -161,7 +161,7 @@ template void Writer::run() { addReservedSymbols(); // Create output sections. - if (Script->Opt.HasSections) { + if (Script->HasSections) { // If linker script contains SECTIONS commands, let it create sections. Script->processCommands(Factory); @@ -466,7 +466,7 @@ template void Writer::copyLocalSymbols() { template void Writer::addSectionSymbols() { // Create one STT_SECTION symbol for each output section we might // have a relocation with. - for (BaseCommand *Base : Script->Opt.Commands) { + for (BaseCommand *Base : Script->Commands) { auto *Sec = dyn_cast(Base); if (!Sec) continue; @@ -813,7 +813,7 @@ template void Writer::addReservedSymbols() { addOptionalRegular(Name, Out::ElfHeader, 0, STV_HIDDEN); // If linker script do layout we do not need to create any standart symbols. - if (Script->Opt.HasSections) + if (Script->HasSections) return; auto Add = [](StringRef S, int64_t Pos) { @@ -849,7 +849,7 @@ static void sortBySymbolsOrder() { // Sort sections by priority. DenseMap SectionOrder = buildSectionOrder(); - for (BaseCommand *Base : Script->Opt.Commands) + for (BaseCommand *Base : Script->Commands) if (auto *Sec = dyn_cast(Base)) Sec->sort([&](InputSectionBase *S) { return SectionOrder.lookup(S); }); } @@ -876,8 +876,7 @@ template void Writer::createSections() { Factory.addInputSec(IS, getOutputSectionName(IS->Name))) Vec.push_back(Sec); - Script->Opt.Commands.insert(Script->Opt.Commands.begin(), Vec.begin(), - Vec.end()); + Script->Commands.insert(Script->Commands.begin(), Vec.begin(), Vec.end()); Script->fabricateDefaultCommands(); sortBySymbolsOrder(); @@ -1052,15 +1051,15 @@ template void Writer::sortSections() { if (Config->Relocatable) return; - for (BaseCommand *Base : Script->Opt.Commands) + for (BaseCommand *Base : Script->Commands) if (auto *Sec = dyn_cast(Base)) Sec->SortRank = getSectionRank(Sec); - if (!Script->Opt.HasSections) { + if (!Script->HasSections) { // We know that all the OutputSections are contiguous in // this case. - auto E = Script->Opt.Commands.end(); - auto I = Script->Opt.Commands.begin(); + auto E = Script->Commands.end(); + auto I = Script->Commands.begin(); auto IsSection = [](BaseCommand *Base) { return isa(Base); }; I = std::find_if(I, E, IsSection); E = std::find_if(llvm::make_reverse_iterator(E), @@ -1101,7 +1100,7 @@ template void Writer::sortSections() { // a PT_LOAD. // // There is some ambiguity as to where exactly a new entry should be - // inserted, because Opt.Commands contains not only output section + // inserted, because Commands contains not only output section // commands but also other types of commands such as symbol assignment // expressions. There's no correct answer here due to the lack of the // formal specification of the linker script. We use heuristics to @@ -1109,8 +1108,8 @@ template void Writer::sortSections() { // after another commands. For the details, look at shouldSkip // function. - auto I = Script->Opt.Commands.begin(); - auto E = Script->Opt.Commands.end(); + auto I = Script->Commands.begin(); + auto E = Script->Commands.end(); auto NonScriptI = std::find_if(I, E, [](BaseCommand *Base) { if (auto *Sec = dyn_cast(Base)) return Sec->Live && Sec->SectionIndex == INT_MAX; @@ -1241,7 +1240,7 @@ template void Writer::finalizeSections() { // addresses of each section by section name. Add such symbols. if (!Config->Relocatable) { addStartEndSymbols(); - for (BaseCommand *Base : Script->Opt.Commands) + for (BaseCommand *Base : Script->Commands) if (auto *Sec = dyn_cast(Base)) addStartStopSymbols(Sec); } @@ -1305,7 +1304,7 @@ template void Writer::finalizeSections() { // Now that we have the final list, create a list of all the // OutputSections for convenience. - for (BaseCommand *Base : Script->Opt.Commands) + for (BaseCommand *Base : Script->Commands) if (auto *Sec = dyn_cast(Base)) OutputSections.push_back(Sec); @@ -1356,7 +1355,7 @@ template void Writer::finalizeSections() { InX::Dynamic}, [](SyntheticSection *SS) { SS->finalizeContents(); }); - if (!Script->Opt.HasSections && !Config->Relocatable) + if (!Script->HasSections && !Config->Relocatable) fixSectionAlignments(); // Some architectures use small displacements for jump instructions. @@ -1441,7 +1440,7 @@ void Writer::addStartStopSymbols(OutputSection *Sec) { } template OutputSection *Writer::findSection(StringRef Name) { - for (BaseCommand *Base : Script->Opt.Commands) + for (BaseCommand *Base : Script->Commands) if (auto *Sec = dyn_cast(Base)) if (Sec->Name == Name) return Sec; @@ -1682,7 +1681,7 @@ template void Writer::assignFileOffsets() { for (OutputSection *Sec : OutputSections) { Off = setOffset(Sec, Off); - if (Script->Opt.HasSections) + if (Script->HasSections) continue; // If this is a last section of the last executable segment and that // segment is the last loadable segment, align the offset of the @@ -1861,7 +1860,7 @@ static void fillTrap(uint8_t *I, uint8_t *End) { // We'll leave other pages in segments as-is because the rest will be // overwritten by output sections. template void Writer::writeTrapInstr() { - if (Script->Opt.HasSections) + if (Script->HasSections) return; // Fill the last page.