Split LinkerScript::createSections.

createSections is getting longer, so it is probably time to split.

Differential Revision: https://reviews.llvm.org/D22730

llvm-svn: 276538
This commit is contained in:
Rui Ueyama 2016-07-24 01:06:18 +00:00
parent 58ad17df0f
commit 01151e9c24
2 changed files with 43 additions and 21 deletions

View File

@ -261,26 +261,15 @@ std::vector<OutputSectionBase<ELFT> *>
LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) { LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
typedef const std::unique_ptr<ObjectFile<ELFT>> ObjectFile; typedef const std::unique_ptr<ObjectFile<ELFT>> ObjectFile;
std::vector<OutputSectionBase<ELFT> *> Result; std::vector<OutputSectionBase<ELFT> *> Result;
DenseSet<OutputSectionBase<ELFT> *> Removed;
// Add input section to output section. If there is no output section yet, // Add input section to output section. If there is no output section yet,
// then create it and add to output section list. // then create it and add to output section list.
auto AddInputSec = [&](InputSectionBase<ELFT> *C, StringRef Name, auto AddInputSec = [&](InputSectionBase<ELFT> *C, StringRef Name) {
ConstraintKind Constraint) {
OutputSectionBase<ELFT> *Sec; OutputSectionBase<ELFT> *Sec;
bool IsNew; bool IsNew;
std::tie(Sec, IsNew) = Factory.create(C, Name); std::tie(Sec, IsNew) = Factory.create(C, Name);
if (IsNew) if (IsNew)
Result.push_back(Sec); 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); Sec->addSection(C);
}; };
@ -306,7 +295,7 @@ LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
if (OutCmd->Name == "/DISCARD/") if (OutCmd->Name == "/DISCARD/")
S->Live = false; S->Live = false;
else else
AddInputSec(S, OutCmd->Name, OutCmd->Constraint); AddInputSec(S, OutCmd->Name);
} }
} }
} }
@ -318,18 +307,48 @@ LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
for (InputSectionBase<ELFT> *S : F->getSections()) { for (InputSectionBase<ELFT> *S : F->getSections()) {
if (!isDiscarded(S)) { if (!isDiscarded(S)) {
if (!S->OutSec) if (!S->OutSec)
AddInputSec(S, getOutputSectionName(S), NoConstraint); AddInputSec(S, getOutputSectionName(S));
} else } else
reportDiscarded(S, F); reportDiscarded(S, F);
} }
// Remove from the output all the sections which did not met the constraints. // Remove from the output all the sections which did not meet
Result.erase(std::remove_if(Result.begin(), Result.end(), // the optional constraints.
[&](OutputSectionBase<ELFT> *Sec) { return filter(Result);
return Removed.count(Sec); }
}),
Result.end()); // Process ONLY_IF_RO and ONLY_IF_RW.
return Result; template <class ELFT>
std::vector<OutputSectionBase<ELFT> *>
LinkerScript<ELFT>::filter(std::vector<OutputSectionBase<ELFT> *> &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<BaseCommand> &Base : Opt.Commands) {
auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get());
if (!Cmd)
continue;
OutputSectionBase<ELFT> *Sec = *It;
switch (Cmd->Constraint) {
case ConstraintKind::NoConstraint:
++It;
continue;
case ConstraintKind::ReadOnly:
if (Sec->getFlags() & SHF_WRITE)
break;
++It;
continue;
case ConstraintKind::ReadWrite:
if (!(Sec->getFlags() & SHF_WRITE))
break;
++It;
continue;
}
Sections.erase(It);
}
return Sections;
} }
template <class ELFT> template <class ELFT>

View File

@ -130,6 +130,9 @@ private:
// "ScriptConfig" is a bit too long, so define a short name for it. // "ScriptConfig" is a bit too long, so define a short name for it.
ScriptConfiguration &Opt = *ScriptConfig; ScriptConfiguration &Opt = *ScriptConfig;
std::vector<OutputSectionBase<ELFT> *>
filter(std::vector<OutputSectionBase<ELFT> *> &Sections);
int getSectionIndex(StringRef Name); int getSectionIndex(StringRef Name);
std::vector<size_t> getPhdrIndicesForSection(StringRef Name); std::vector<size_t> getPhdrIndicesForSection(StringRef Name);
void dispatchAssignment(SymbolAssignment *Cmd); void dispatchAssignment(SymbolAssignment *Cmd);