Index: lib/MC/WasmObjectWriter.cpp =================================================================== --- lib/MC/WasmObjectWriter.cpp +++ lib/MC/WasmObjectWriter.cpp @@ -306,7 +306,7 @@ ArrayRef Functions); void writeDataSection(); void writeRelocSection(uint32_t SectionIndex, StringRef Name, - ArrayRef Relocations); + std::vector& Relocations); void writeLinkingMetaDataSection( ArrayRef SymbolInfos, ArrayRef> InitFuncs, @@ -892,19 +892,31 @@ void WasmObjectWriter::writeRelocSection( uint32_t SectionIndex, StringRef Name, - ArrayRef Relocations) { + std::vector& 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); Index: lib/Object/WasmObjectFile.cpp =================================================================== --- lib/Object/WasmObjectFile.cpp +++ lib/Object/WasmObjectFile.cpp @@ -602,10 +602,15 @@ WasmSection& Section = Sections[SectionIndex]; uint32_t RelocCount = readVaruint32(Ctx); uint32_t EndOffset = Section.Content.size(); + uint32_t PreviousOffset = 0; while (RelocCount--) { wasm::WasmRelocation Reloc = {}; Reloc.Type = readVaruint32(Ctx); Reloc.Offset = readVaruint32(Ctx); + if (Reloc.Offset < PreviousOffset) + return make_error("Relocations not in offset order", + object_error::parse_failed); + PreviousOffset = Reloc.Offset; Reloc.Index = readVaruint32(Ctx); switch (Reloc.Type) { case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB: