Refactor how we decide which sections to sort.

This is a bit more verbose, but it has a few advantages.

The logic on what to do with special sections like .init_array is not
duplicated. Before we would need keep isKnownNonreorderableSection in
sync.

I think with this the call graph based sorting can be implemented by
"just" returning a new order from buildSectionOrder.

llvm-svn: 324744
This commit is contained in:
Rafael Espindola 2018-02-09 16:09:22 +00:00
parent 5cd92ead72
commit ecfd73457c
1 changed files with 33 additions and 28 deletions

View File

@ -1048,40 +1048,45 @@ static DenseMap<SectionBase *, int> buildSectionOrder() {
return SectionOrder; return SectionOrder;
} }
static bool isKnownNonreorderableSection(const OutputSection *OS) { static void sortSection(OutputSection *Sec,
return llvm::StringSwitch<bool>(OS->Name) const DenseMap<SectionBase *, int> &Order) {
.Cases(".init", ".fini", ".init_array", ".fini_array", ".ctors", if (!Sec->Live)
".dtors", true) return;
.Default(false); StringRef Name = Sec->Name;
// Sort input sections by section name suffixes for
// __attribute__((init_priority(N))).
if (Name == ".init_array" || Name == ".fini_array") {
if (!Script->HasSectionsCommand)
Sec->sortInitFini();
return;
}
// Sort input sections by the special rule for .ctors and .dtors.
if (Name == ".ctors" || Name == ".dtors") {
if (!Script->HasSectionsCommand)
Sec->sortCtorsDtors();
return;
}
// Never sort these.
if (Name == ".init" || Name == ".fini")
return;
// Sort input sections by priority using the list provided
// by --symbol-ordering-file.
if (!Order.empty())
Sec->sort([&](InputSectionBase *S) { return Order.lookup(S); });
} }
// If no layout was provided by linker script, we want to apply default // If no layout was provided by linker script, we want to apply default
// sorting for special input sections. This also handles --symbol-ordering-file. // sorting for special input sections. This also handles --symbol-ordering-file.
template <class ELFT> void Writer<ELFT>::sortInputSections() { template <class ELFT> void Writer<ELFT>::sortInputSections() {
// Sort input sections by priority using the list provided // Build the order once since it is expensive.
// by --symbol-ordering-file.
DenseMap<SectionBase *, int> Order = buildSectionOrder(); DenseMap<SectionBase *, int> Order = buildSectionOrder();
if (!Order.empty()) for (BaseCommand *Base : Script->SectionCommands)
for (BaseCommand *Base : Script->SectionCommands) if (auto *Sec = dyn_cast<OutputSection>(Base))
if (auto *Sec = dyn_cast<OutputSection>(Base)) sortSection(Sec, Order);
if (Sec->Live && !isKnownNonreorderableSection(Sec))
Sec->sort([&](InputSectionBase *S) { return Order.lookup(S); });
if (Script->HasSectionsCommand)
return;
// Sort input sections by section name suffixes for
// __attribute__((init_priority(N))).
if (OutputSection *Sec = findSection(".init_array"))
Sec->sortInitFini();
if (OutputSection *Sec = findSection(".fini_array"))
Sec->sortInitFini();
// Sort input sections by the special rule for .ctors and .dtors.
if (OutputSection *Sec = findSection(".ctors"))
Sec->sortCtorsDtors();
if (OutputSection *Sec = findSection(".dtors"))
Sec->sortCtorsDtors();
} }
template <class ELFT> void Writer<ELFT>::sortSections() { template <class ELFT> void Writer<ELFT>::sortSections() {