[WebAssembly] Ensure relocation entries are ordered by offset
wasm-lld expects relocation entries to be sorted by offset. In most
cases llvm produces them in order, but the CODE section (which combines
many MCSections) is an exception because we order the functions in
Symbol order, not in section order. What is more, its not clear weather
`recordRelocation` is guaranteed to be called in offset order so this
sort of most likely needed in the general case too.
Differential Revision: https://reviews.llvm.org/D51065
llvm-svn: 340423
diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp
index 5a979d3..f6c5a87 100644
--- a/llvm/lib/MC/WasmObjectWriter.cpp
+++ b/llvm/lib/MC/WasmObjectWriter.cpp
@@ -306,7 +306,7 @@
ArrayRef<WasmFunction> Functions);
void writeDataSection();
void writeRelocSection(uint32_t SectionIndex, StringRef Name,
- ArrayRef<WasmRelocationEntry> Relocations);
+ std::vector<WasmRelocationEntry>& Relocations);
void writeLinkingMetaDataSection(
ArrayRef<wasm::WasmSymbolInfo> SymbolInfos,
ArrayRef<std::pair<uint16_t, uint32_t>> InitFuncs,
@@ -892,19 +892,31 @@
void WasmObjectWriter::writeRelocSection(
uint32_t SectionIndex, StringRef Name,
- ArrayRef<WasmRelocationEntry> Relocations) {
+ std::vector<WasmRelocationEntry>& Relocs) {
// See: https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md
// for descriptions of the reloc sections.
- if (Relocations.empty())
+ if (Relocs.empty())
return;
+ // First, ensure the relocations are sorted in offset order. In general they
+ // should already be sorted since `recordRelocation` is called in offset
+ // order, but for the code section we combine many MC sections into single
+ // wasm section, and this order is determined by the order of Asm.Symbols()
+ // not the sections order.
+ std::stable_sort(
+ Relocs.begin(), Relocs.end(),
+ [](const WasmRelocationEntry &A, const WasmRelocationEntry &B) {
+ return (A.Offset + A.FixupSection->getSectionOffset()) <
+ (B.Offset + B.FixupSection->getSectionOffset());
+ });
+
SectionBookkeeping Section;
startCustomSection(Section, std::string("reloc.") + Name.str());
encodeULEB128(SectionIndex, W.OS);
- encodeULEB128(Relocations.size(), W.OS);
- for (const WasmRelocationEntry& RelEntry : Relocations) {
+ encodeULEB128(Relocs.size(), W.OS);
+ for (const WasmRelocationEntry& RelEntry : Relocs) {
uint64_t Offset = RelEntry.Offset +
RelEntry.FixupSection->getSectionOffset();
uint32_t Index = getRelocationIndexValue(RelEntry);