[lld] f1969b7 - [lld/mac] Fix nondeterminism in output section ordering
Nico Weber via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 28 15:41:43 PDT 2021
Author: Nico Weber
Date: 2021-06-28T18:41:33-04:00
New Revision: f1969b74a7e70623129872d69caba4759df47fb0
URL: https://github.com/llvm/llvm-project/commit/f1969b74a7e70623129872d69caba4759df47fb0
DIFF: https://github.com/llvm/llvm-project/commit/f1969b74a7e70623129872d69caba4759df47fb0.diff
LOG: [lld/mac] Fix nondeterminism in output section ordering
The two different thread_local_regular sections (__thread_data and
more_thread_data) had nondeterminstic ordering for two reasons:
1. https://reviews.llvm.org/D102972 changed concatOutputSections
from MapVector to DenseMap, so when we iterate it to make
output segments, we would add the two sections to the __DATA
output segment in nondeterministic order.
2. The same change also moved the two stable_sort()s for segments
and sections to sort(). Since sections with assigned priority
(such as TLV data) have the same priority for all sections,
this is incorrect -- we must use stable_sort() so that the
initial (input-order-based) order remains.
As a side effect, we now (deterministically) put the __common
section in front of __bss (while previously we happened to
put it after it). (__common and __bss are both zerofill so
both have order INT_MAX, but common symbols are added to
inputSections before normal sections are collected.)
Makes lld/test/MachO/tlv.s and lld/test/MachO/tlv-dylib.s pass with
LLVM_ENABLE_EXPENSIVE_CHECKS=ON.
Differential Revision: https://reviews.llvm.org/D105054
Added:
Modified:
lld/MachO/OutputSegment.cpp
lld/MachO/Writer.cpp
lld/test/MachO/tlv-dylib.s
Removed:
################################################################################
diff --git a/lld/MachO/OutputSegment.cpp b/lld/MachO/OutputSegment.cpp
index 77aa50cd0304..8a050c4a7627 100644
--- a/lld/MachO/OutputSegment.cpp
+++ b/lld/MachO/OutputSegment.cpp
@@ -140,10 +140,15 @@ static int sectionOrder(OutputSection *osec) {
}
void OutputSegment::sortOutputSections() {
- llvm::sort(sections, compareByOrder<OutputSection *>(sectionOrder));
+ // Must be stable_sort() to keep special sections such as
+ // S_THREAD_LOCAL_REGULAR in input order.
+ llvm::stable_sort(sections, compareByOrder<OutputSection *>(sectionOrder));
}
void macho::sortOutputSegments() {
+ // sort() instead of stable_sort() is fine because segmentOrder() is
+ // name-based and getOrCreateOutputSegment() makes there's only a single
+ // segment for every name.
llvm::sort(outputSegments, compareByOrder<OutputSegment *>(segmentOrder));
}
diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp
index 9dca3416875b..ffe5668a877b 100644
--- a/lld/MachO/Writer.cpp
+++ b/lld/MachO/Writer.cpp
@@ -79,7 +79,10 @@ class Writer {
LCUuid *uuidCommand = nullptr;
OutputSegment *linkEditSegment = nullptr;
- DenseMap<NamePair, ConcatOutputSection *> concatOutputSections;
+
+ // Output sections are added to output segments in iteration order
+ // of ConcatOutputSection, so must have deterministic iteration order.
+ MapVector<NamePair, ConcatOutputSection *> concatOutputSections;
};
// LC_DYLD_INFO_ONLY stores the offsets of symbol import/export information.
diff --git a/lld/test/MachO/tlv-dylib.s b/lld/test/MachO/tlv-dylib.s
index dc6bdef1433e..8a179ffc3490 100644
--- a/lld/test/MachO/tlv-dylib.s
+++ b/lld/test/MachO/tlv-dylib.s
@@ -74,21 +74,21 @@
# FLAGS-NEXT: reloff 0
# FLAGS-NEXT: nreloc 0
# FLAGS-NEXT: type S_THREAD_LOCAL_ZEROFILL
-# FLAGS: sectname __bss
+# FLAGS: sectname __common
# FLAGS-NEXT: segname __DATA
# FLAGS-NEXT: addr
-# FLAGS-NEXT: size 0x0000000000002000
+# FLAGS-NEXT: size 0x0000000000004000
# FLAGS-NEXT: offset 0
-# FLAGS-NEXT: align 2^0 (1)
+# FLAGS-NEXT: align 2^14 (16384)
# FLAGS-NEXT: reloff 0
# FLAGS-NEXT: nreloc 0
# FLAGS-NEXT: type S_ZEROFILL
-# FLAGS: sectname __common
+# FLAGS: sectname __bss
# FLAGS-NEXT: segname __DATA
# FLAGS-NEXT: addr
-# FLAGS-NEXT: size 0x0000000000004000
+# FLAGS-NEXT: size 0x0000000000002000
# FLAGS-NEXT: offset 0
-# FLAGS-NEXT: align 2^14 (16384)
+# FLAGS-NEXT: align 2^0 (1)
# FLAGS-NEXT: reloff 0
# FLAGS-NEXT: nreloc 0
# FLAGS-NEXT: type S_ZEROFILL
More information about the llvm-commits
mailing list