[WebAssembly] Sort output data sections to place .bss last
Summary:
This was always the intended behavior, but had not been
implemented. This ordering is important for Emscripten when generating
.mem files while compiling to JS, since only zeros at the end of
initialized memory can be dropped.
Fixes https://github.com/emscripten-core/emscripten/issues/8999
Reviewers: sbc100
Subscribers: dschuff, jgravelle-google, aheejin, sunfish, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D67736
llvm-svn: 372284
diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp
index 58d585b..c4a87be 100644
--- a/lld/wasm/Writer.cpp
+++ b/lld/wasm/Writer.cpp
@@ -263,7 +263,6 @@
memoryPtr += 4;
}
- // TODO: Add .bss space here.
if (WasmSym::dataEnd)
WasmSym::dataEnd->setVirtualAddress(memoryPtr);
@@ -667,7 +666,7 @@
OutputSegment *&s = segmentMap[name];
if (s == nullptr) {
LLVM_DEBUG(dbgs() << "new segment: " << name << "\n");
- s = make<OutputSegment>(name, segments.size());
+ s = make<OutputSegment>(name);
if (config->sharedMemory || name == ".tdata")
s->initFlags = WASM_SEGMENT_IS_PASSIVE;
segments.push_back(s);
@@ -676,6 +675,24 @@
LLVM_DEBUG(dbgs() << "added data: " << name << ": " << s->size << "\n");
}
}
+
+ // Sort segments by type, placing .bss last
+ std::stable_sort(segments.begin(), segments.end(),
+ [](const OutputSegment *a, const OutputSegment *b) {
+ auto order = [](StringRef name) {
+ return StringSwitch<int>(name)
+ .StartsWith(".rodata", 0)
+ .StartsWith(".data", 1)
+ .StartsWith(".tdata", 2)
+ .StartsWith(".bss", 4)
+ .Default(3);
+ };
+ return order(a->name) < order(b->name);
+ });
+
+ for (size_t i = 0; i < segments.size(); ++i) {
+ segments[i]->index = i;
+ }
}
static void createFunction(DefinedFunction *func, StringRef bodyContent) {