forked from OSchip/llvm-project
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:
parent
58ad17df0f
commit
01151e9c24
|
@ -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>
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue