[lld] 7599e98 - [lld-macho][nfc] Remove unnecessary parameterization of section sort
Jez Ng via llvm-commits
llvm-commits at lists.llvm.org
Tue May 25 11:58:47 PDT 2021
Author: Jez Ng
Date: 2021-05-25T14:58:30-04:00
New Revision: 7599e98ab7904dce34ea208009f00e87d9d965fb
URL: https://github.com/llvm/llvm-project/commit/7599e98ab7904dce34ea208009f00e87d9d965fb
DIFF: https://github.com/llvm/llvm-project/commit/7599e98ab7904dce34ea208009f00e87d9d965fb.diff
LOG: [lld-macho][nfc] Remove unnecessary parameterization of section sort
As @alexshap pointed out [here](https://reviews.llvm.org/D102972#inline-975208),
it's a bit confusing to have the option to sort OutputSections with any
comparator when in practice we only use one.
Reviewed By: #lld-macho, alexshap, thakis
Differential Revision: https://reviews.llvm.org/D102974
Added:
Modified:
lld/MachO/OutputSegment.cpp
lld/MachO/OutputSegment.h
lld/MachO/Writer.cpp
Removed:
################################################################################
diff --git a/lld/MachO/OutputSegment.cpp b/lld/MachO/OutputSegment.cpp
index 3989d83d2a24..fda47ed3942f 100644
--- a/lld/MachO/OutputSegment.cpp
+++ b/lld/MachO/OutputSegment.cpp
@@ -13,6 +13,7 @@
#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Memory.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/BinaryFormat/MachO.h"
using namespace llvm;
@@ -60,6 +61,87 @@ void OutputSegment::addOutputSection(OutputSection *osec) {
osec->align = sectAlign.align;
}
+template <typename T, typename F> static auto compareByOrder(F ord) {
+ return [=](T a, T b) { return ord(a) < ord(b); };
+}
+
+static int segmentOrder(OutputSegment *seg) {
+ return StringSwitch<int>(seg->name)
+ .Case(segment_names::pageZero, -4)
+ .Case(segment_names::text, -3)
+ .Case(segment_names::dataConst, -2)
+ .Case(segment_names::data, -1)
+ .Case(segment_names::llvm, std::numeric_limits<int>::max() - 1)
+ // Make sure __LINKEDIT is the last segment (i.e. all its hidden
+ // sections must be ordered after other sections).
+ .Case(segment_names::linkEdit, std::numeric_limits<int>::max())
+ .Default(seg->inputOrder);
+}
+
+static int sectionOrder(OutputSection *osec) {
+ StringRef segname = osec->parent->name;
+ // Sections are uniquely identified by their segment + section name.
+ if (segname == segment_names::text) {
+ return StringSwitch<int>(osec->name)
+ .Case(section_names::header, -4)
+ .Case(section_names::text, -3)
+ .Case(section_names::stubs, -2)
+ .Case(section_names::stubHelper, -1)
+ .Case(section_names::unwindInfo, std::numeric_limits<int>::max() - 1)
+ .Case(section_names::ehFrame, std::numeric_limits<int>::max())
+ .Default(osec->inputOrder);
+ } else if (segname == segment_names::data ||
+ segname == segment_names::dataConst) {
+ // For each thread spawned, dyld will initialize its TLVs by copying the
+ // address range from the start of the first thread-local data section to
+ // the end of the last one. We therefore arrange these sections contiguously
+ // to minimize the amount of memory used. Additionally, since zerofill
+ // sections must be at the end of their segments, and since TLV data
+ // sections can be zerofills, we end up putting all TLV data sections at the
+ // end of the segment.
+ switch (sectionType(osec->flags)) {
+ case S_THREAD_LOCAL_REGULAR:
+ return std::numeric_limits<int>::max() - 2;
+ case S_THREAD_LOCAL_ZEROFILL:
+ return std::numeric_limits<int>::max() - 1;
+ case S_ZEROFILL:
+ return std::numeric_limits<int>::max();
+ default:
+ return StringSwitch<int>(osec->name)
+ .Case(section_names::got, -3)
+ .Case(section_names::lazySymbolPtr, -2)
+ .Case(section_names::const_, -1)
+ .Default(osec->inputOrder);
+ }
+ } else if (segname == segment_names::linkEdit) {
+ return StringSwitch<int>(osec->name)
+ .Case(section_names::rebase, -9)
+ .Case(section_names::binding, -8)
+ .Case(section_names::weakBinding, -7)
+ .Case(section_names::lazyBinding, -6)
+ .Case(section_names::export_, -5)
+ .Case(section_names::functionStarts, -4)
+ .Case(section_names::symbolTable, -3)
+ .Case(section_names::indirectSymbolTable, -2)
+ .Case(section_names::stringTable, -1)
+ .Case(section_names::codeSignature, std::numeric_limits<int>::max())
+ .Default(osec->inputOrder);
+ }
+ // ZeroFill sections must always be the at the end of their segments,
+ // otherwise subsequent sections may get overwritten with zeroes at runtime.
+ if (sectionType(osec->flags) == S_ZEROFILL)
+ return std::numeric_limits<int>::max();
+ return osec->inputOrder;
+}
+
+void OutputSegment::sortOutputSections() {
+ llvm::sort(sections, compareByOrder<OutputSection *>(sectionOrder));
+}
+
+void macho::sortOutputSegments() {
+ llvm::sort(outputSegments, compareByOrder<OutputSegment *>(segmentOrder));
+}
+
static DenseMap<StringRef, OutputSegment *> nameToOutputSegment;
std::vector<OutputSegment *> macho::outputSegments;
diff --git a/lld/MachO/OutputSegment.h b/lld/MachO/OutputSegment.h
index 80d2d73794b2..e5d87ba0a4e0 100644
--- a/lld/MachO/OutputSegment.h
+++ b/lld/MachO/OutputSegment.h
@@ -42,10 +42,7 @@ class OutputSegment {
const OutputSection *lastSection() const { return sections.back(); }
void addOutputSection(OutputSection *os);
- void sortOutputSections(
- llvm::function_ref<bool(OutputSection *, OutputSection *)> comparator) {
- llvm::sort(sections, comparator);
- }
+ void sortOutputSections();
const std::vector<OutputSection *> &getSections() const { return sections; }
size_t numNonHiddenSections() const;
@@ -65,6 +62,8 @@ class OutputSegment {
extern std::vector<OutputSegment *> outputSegments;
+void sortOutputSegments();
+
OutputSegment *getOrCreateOutputSegment(StringRef name);
} // namespace macho
diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp
index 3dcf360bf6e5..aa5f60ff57d0 100644
--- a/lld/MachO/Writer.cpp
+++ b/lld/MachO/Writer.cpp
@@ -755,94 +755,19 @@ static DenseMap<const InputSection *, size_t> buildInputSectionPriorities() {
return sectionPriorities;
}
-static int segmentOrder(OutputSegment *seg) {
- return StringSwitch<int>(seg->name)
- .Case(segment_names::pageZero, -4)
- .Case(segment_names::text, -3)
- .Case(segment_names::dataConst, -2)
- .Case(segment_names::data, -1)
- .Case(segment_names::llvm, std::numeric_limits<int>::max() - 1)
- // Make sure __LINKEDIT is the last segment (i.e. all its hidden
- // sections must be ordered after other sections).
- .Case(segment_names::linkEdit, std::numeric_limits<int>::max())
- .Default(seg->inputOrder);
-}
-
-static int sectionOrder(OutputSection *osec) {
- StringRef segname = osec->parent->name;
- // Sections are uniquely identified by their segment + section name.
- if (segname == segment_names::text) {
- return StringSwitch<int>(osec->name)
- .Case(section_names::header, -4)
- .Case(section_names::text, -3)
- .Case(section_names::stubs, -2)
- .Case(section_names::stubHelper, -1)
- .Case(section_names::unwindInfo, std::numeric_limits<int>::max() - 1)
- .Case(section_names::ehFrame, std::numeric_limits<int>::max())
- .Default(osec->inputOrder);
- } else if (segname == segment_names::data ||
- segname == segment_names::dataConst) {
- // For each thread spawned, dyld will initialize its TLVs by copying the
- // address range from the start of the first thread-local data section to
- // the end of the last one. We therefore arrange these sections contiguously
- // to minimize the amount of memory used. Additionally, since zerofill
- // sections must be at the end of their segments, and since TLV data
- // sections can be zerofills, we end up putting all TLV data sections at the
- // end of the segment.
- switch (sectionType(osec->flags)) {
- case S_THREAD_LOCAL_REGULAR:
- return std::numeric_limits<int>::max() - 2;
- case S_THREAD_LOCAL_ZEROFILL:
- return std::numeric_limits<int>::max() - 1;
- case S_ZEROFILL:
- return std::numeric_limits<int>::max();
- default:
- return StringSwitch<int>(osec->name)
- .Case(section_names::got, -3)
- .Case(section_names::lazySymbolPtr, -2)
- .Case(section_names::const_, -1)
- .Default(osec->inputOrder);
- }
- } else if (segname == segment_names::linkEdit) {
- return StringSwitch<int>(osec->name)
- .Case(section_names::rebase, -9)
- .Case(section_names::binding, -8)
- .Case(section_names::weakBinding, -7)
- .Case(section_names::lazyBinding, -6)
- .Case(section_names::export_, -5)
- .Case(section_names::functionStarts, -4)
- .Case(section_names::symbolTable, -3)
- .Case(section_names::indirectSymbolTable, -2)
- .Case(section_names::stringTable, -1)
- .Case(section_names::codeSignature, std::numeric_limits<int>::max())
- .Default(osec->inputOrder);
- }
- // ZeroFill sections must always be the at the end of their segments,
- // otherwise subsequent sections may get overwritten with zeroes at runtime.
- if (sectionType(osec->flags) == S_ZEROFILL)
- return std::numeric_limits<int>::max();
- return osec->inputOrder;
-}
-
-template <typename T, typename F>
-static std::function<bool(T, T)> compareByOrder(F ord) {
- return [=](T a, T b) { return ord(a) < ord(b); };
-}
-
// Sorting only can happen once all outputs have been collected. Here we sort
// segments, output sections within each segment, and input sections within each
// output segment.
static void sortSegmentsAndSections() {
TimeTraceScope timeScope("Sort segments and sections");
-
- llvm::sort(outputSegments, compareByOrder<OutputSegment *>(segmentOrder));
+ sortOutputSegments();
DenseMap<const InputSection *, size_t> isecPriorities =
buildInputSectionPriorities();
uint32_t sectionIndex = 0;
for (OutputSegment *seg : outputSegments) {
- seg->sortOutputSections(compareByOrder<OutputSection *>(sectionOrder));
+ seg->sortOutputSections();
for (OutputSection *osec : seg->getSections()) {
// Now that the output sections are sorted, assign the final
// output section indices.
More information about the llvm-commits
mailing list