summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/MC/WasmObjectWriter.cpp22
-rw-r--r--llvm/lib/Object/WasmObjectFile.cpp5
2 files changed, 22 insertions, 5 deletions
diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp
index 5a979d36e81..f6c5a874e7c 100644
--- a/llvm/lib/MC/WasmObjectWriter.cpp
+++ b/llvm/lib/MC/WasmObjectWriter.cpp
@@ -306,7 +306,7 @@ private:
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::writeDataSection() {
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);
diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp
index 1b32ae8afd9..f75dbfc3014 100644
--- a/llvm/lib/Object/WasmObjectFile.cpp
+++ b/llvm/lib/Object/WasmObjectFile.cpp
@@ -602,10 +602,15 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
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<GenericBinaryError>("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:
OpenPOWER on IntegriCloud