From: Rui Ueyama Date: Mon, 25 Jul 2016 21:30:00 +0000 (+0000) Subject: Re-commit "Split LinkerScript::createSections". X-Git-Tag: llvmorg-4.0.0-rc1~14241 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3c291e1aa2dc264f481ba29e68429b74770eadc2;p=platform%2Fupstream%2Fllvm.git Re-commit "Split LinkerScript::createSections". Re-commit r276543 with a fix for buildbots. llvm-svn: 276693 --- diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 403bff9..9ccc27d 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -79,26 +79,15 @@ std::vector *> LinkerScript::createSections(OutputSectionFactory &Factory) { typedef const std::unique_ptr> ObjectFile; std::vector *> Result; - DenseSet *> Removed; // Add input section to output section. If there is no output section yet, // then create it and add to output section list. - auto AddInputSec = [&](InputSectionBase *C, StringRef Name, - ConstraintKind Constraint) { + auto AddInputSec = [&](InputSectionBase *C, StringRef Name) { OutputSectionBase *Sec; bool IsNew; std::tie(Sec, IsNew) = Factory.create(C, Name); if (IsNew) Result.push_back(Sec); - if ((!(C->getSectionHdr()->sh_flags & SHF_WRITE)) && - Constraint == ReadWrite) { - Removed.insert(Sec); - return; - } - if ((C->getSectionHdr()->sh_flags & SHF_WRITE) && Constraint == ReadOnly) { - Removed.insert(Sec); - return; - } Sec->addSection(C); }; @@ -124,7 +113,7 @@ LinkerScript::createSections(OutputSectionFactory &Factory) { if (OutCmd->Name == "/DISCARD/") S->Live = false; else - AddInputSec(S, OutCmd->Name, OutCmd->Constraint); + AddInputSec(S, OutCmd->Name); } } } @@ -136,18 +125,46 @@ LinkerScript::createSections(OutputSectionFactory &Factory) { for (InputSectionBase *S : F->getSections()) { if (!isDiscarded(S)) { if (!S->OutSec) - AddInputSec(S, getOutputSectionName(S), NoConstraint); + AddInputSec(S, getOutputSectionName(S)); } else reportDiscarded(S, F); } - // Remove from the output all the sections which did not met the constraints. - Result.erase(std::remove_if(Result.begin(), Result.end(), - [&](OutputSectionBase *Sec) { - return Removed.count(Sec); - }), - Result.end()); - return Result; + // Remove from the output all the sections which did not meet + // the optional constraints. + return filter(Result); +} + +// Process ONLY_IF_RO and ONLY_IF_RW. +template +std::vector *> +LinkerScript::filter(std::vector *> &Sections) { + // Sections and OutputSectionCommands are parallel arrays. + // In this loop, we remove output sections if they don't satisfy + // requested properties. + auto It = Sections.begin(); + for (const std::unique_ptr &Base : Opt.Commands) { + auto *Cmd = dyn_cast(Base.get()); + if (!Cmd || Cmd->Name == "/DISCARD/") + continue; + + if (Cmd->Constraint == ConstraintKind::NoConstraint) { + ++It; + continue; + } + + OutputSectionBase *Sec = *It; + bool Writable = (Sec->getFlags() & SHF_WRITE); + bool RO = (Cmd->Constraint == ConstraintKind::ReadOnly); + bool RW = (Cmd->Constraint == ConstraintKind::ReadWrite); + + if ((RO && Writable) || (RW && !Writable)) { + Sections.erase(It); + continue; + } + ++It; + } + return Sections; } template diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h index c83dbf0..8f8b293 100644 --- a/lld/ELF/LinkerScript.h +++ b/lld/ELF/LinkerScript.h @@ -134,6 +134,9 @@ private: // "ScriptConfig" is a bit too long, so define a short name for it. ScriptConfiguration &Opt = *ScriptConfig; + std::vector *> + filter(std::vector *> &Sections); + int getSectionIndex(StringRef Name); std::vector getPhdrIndices(StringRef SectionName); void dispatchAssignment(SymbolAssignment *Cmd);