Index: ELF/LinkerScript.h =================================================================== --- ELF/LinkerScript.h +++ ELF/LinkerScript.h @@ -227,6 +227,7 @@ public: OutputSection *createOutputSection(StringRef Name, StringRef Location); OutputSection *getOrCreateOutputSection(StringRef Name); + OutputSection *getOutputSection(StringRef Name); bool hasPhdrsCommands() { return !PhdrsCommands.empty(); } uint64_t getDot() { return Dot; } Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -102,6 +102,13 @@ return CmdRef; } +OutputSection *LinkerScript::getOutputSection(StringRef Name) { + OutputSection *Sec = NameToOutputSection.lookup(Name); + if (!Sec || Sec->Location.empty()) + return nullptr; + return Sec; +} + void LinkerScript::setDot(Expr E, const Twine &Loc, bool InSec) { uint64_t Val = E().getValue(); if (Val < Dot && InSec) @@ -446,19 +453,9 @@ make(".", Expr, "")); } -static OutputSection *findByName(ArrayRef Vec, - StringRef Name) { - for (BaseCommand *Base : Vec) - if (auto *Sec = dyn_cast(Base)) - if (Sec->Name == Name) - return Sec; - return nullptr; -} - // Add sections that didn't match any sections command. void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) { - unsigned End = SectionCommands.size(); - + std::vector V; for (InputSectionBase *S : InputSections) { if (!S->Live || S->Parent) continue; @@ -466,16 +463,16 @@ StringRef Name = getOutputSectionName(S->Name); log(toString(S) + " is being placed in '" + Name + "'"); - if (OutputSection *Sec = - findByName(makeArrayRef(SectionCommands).slice(0, End), Name)) { + if (OutputSection *Sec = getOutputSection(Name)) { Sec->addSection(cast(S)); continue; } if (OutputSection *OS = Factory.addInputSec(S, Name)) - SectionCommands.push_back(OS); + V.push_back(OS); assert(S->getOutputSection()->SectionIndex == INT_MAX); } + SectionCommands.insert(SectionCommands.end(), V.begin(), V.end()); } uint64_t LinkerScript::advance(uint64_t Size, unsigned Alignment) { Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -78,7 +78,6 @@ void addStartEndSymbols(); void addStartStopSymbols(OutputSection *Sec); uint64_t getEntryAddr(); - OutputSection *findSection(StringRef Name); std::vector Phdrs; @@ -870,10 +869,10 @@ Script->fabricateDefaultCommands(); sortBySymbolsOrder(); - sortInitFini(findSection(".init_array")); - sortInitFini(findSection(".fini_array")); - sortCtorsDtors(findSection(".ctors")); - sortCtorsDtors(findSection(".dtors")); + sortInitFini(Script->getOutputSection(".init_array")); + sortInitFini(Script->getOutputSection(".fini_array")); + sortCtorsDtors(Script->getOutputSection(".ctors")); + sortCtorsDtors(Script->getOutputSection(".dtors")); } // This function generates assignments for predefined symbols (e.g. _end or @@ -930,7 +929,7 @@ } if (ElfSym::Bss) - ElfSym::Bss->Section = findSection(".bss"); + ElfSym::Bss->Section = Script->getOutputSection(".bss"); // Setup MIPS _gp_disp/__gnu_local_gp symbols which should // be equal to the _gp symbol's value. @@ -1220,10 +1219,10 @@ // Create output section objects and add them to OutputSections. template void Writer::finalizeSections() { - Out::DebugInfo = findSection(".debug_info"); - Out::PreinitArray = findSection(".preinit_array"); - Out::InitArray = findSection(".init_array"); - Out::FiniArray = findSection(".fini_array"); + Out::DebugInfo = Script->getOutputSection(".debug_info"); + Out::PreinitArray = Script->getOutputSection(".preinit_array"); + Out::InitArray = Script->getOutputSection(".init_array"); + Out::FiniArray = Script->getOutputSection(".fini_array"); // The linker needs to define SECNAME_start, SECNAME_end and SECNAME_stop // symbols for sections, so that the runtime can get the start and end @@ -1384,7 +1383,7 @@ template void Writer::addPredefinedSections() { // ARM ABI requires .ARM.exidx to be terminated by some piece of data. // We have the terminater synthetic section class. Add that at the end. - OutputSection *Cmd = findSection(".ARM.exidx"); + OutputSection *Cmd = Script->getOutputSection(".ARM.exidx"); if (!Cmd || !Cmd->Live || Config->Relocatable) return; @@ -1413,7 +1412,7 @@ Define("__init_array_start", "__init_array_end", Out::InitArray); Define("__fini_array_start", "__fini_array_end", Out::FiniArray); - if (OutputSection *Sec = findSection(".ARM.exidx")) + if (OutputSection *Sec = Script->getOutputSection(".ARM.exidx")) Define("__exidx_start", "__exidx_end", Sec); } @@ -1431,14 +1430,6 @@ addOptionalRegular(Saver.save("__stop_" + S), Sec, -1, STV_DEFAULT); } -template OutputSection *Writer::findSection(StringRef Name) { - for (BaseCommand *Base : Script->SectionCommands) - if (auto *Sec = dyn_cast(Base)) - if (Sec->Name == Name) - return Sec; - return nullptr; -} - static bool needsPtLoad(OutputSection *Sec) { if (!(Sec->Flags & SHF_ALLOC)) return false; @@ -1476,7 +1467,7 @@ AddHdr(PT_PHDR, PF_R)->add(Out::ProgramHeaders); // PT_INTERP must be the second entry if exists. - if (OutputSection *Cmd = findSection(".interp")) + if (OutputSection *Cmd = Script->getOutputSection(".interp")) AddHdr(PT_INTERP, Cmd->getPhdrFlags())->add(Cmd); // Add the first PT_LOAD segment for regular output sections. @@ -1537,7 +1528,7 @@ // PT_OPENBSD_RANDOMIZE is an OpenBSD-specific feature. That makes // the dynamic linker fill the segment with random data. - if (OutputSection *Cmd = findSection(".openbsd.randomdata")) + if (OutputSection *Cmd = Script->getOutputSection(".openbsd.randomdata")) AddHdr(PT_OPENBSD_RANDOMIZE, Cmd->getPhdrFlags())->add(Cmd); // PT_GNU_STACK is a special section to tell the loader to make the @@ -1739,7 +1730,7 @@ return Addr; // Case 4 - if (OutputSection *Sec = findSection(".text")) { + if (OutputSection *Sec = Script->getOutputSection(".text")) { if (Config->WarnMissingEntry) warn("cannot find entry symbol " + Config->Entry + "; defaulting to 0x" + utohexstr(Sec->Addr)); @@ -1885,7 +1876,7 @@ // PPC64 needs to process relocations in the .opd section // before processing relocations in code-containing sections. - if (auto *OpdCmd = findSection(".opd")) { + if (auto *OpdCmd = Script->getOutputSection(".opd")) { Out::Opd = OpdCmd; Out::OpdBuf = Buf + Out::Opd->Offset; OpdCmd->template writeTo(Buf + Out::Opd->Offset);