Index: include/llvm/MC/MCSectionWasm.h =================================================================== --- include/llvm/MC/MCSectionWasm.h +++ include/llvm/MC/MCSectionWasm.h @@ -26,6 +26,7 @@ /// This represents a section on wasm. class MCSectionWasm final : public MCSection { +private: /// This is the name of the section. The referenced memory is owned by /// TargetLoweringObjectFileWasm's WasmUniqueMap. StringRef SectionName; @@ -40,10 +41,11 @@ const MCSymbolWasm *Group; - // The offset of the MC function section in the wasm code section. + // The offset of the MC function/data section in the wasm code/data section. + // For data relocations the offset is relative to start of the data payload + // itself and does not include the size of the section header. uint64_t SectionOffset; -private: friend class MCContext; MCSectionWasm(StringRef Section, unsigned type, unsigned flags, SectionKind K, const MCSymbolWasm *group, unsigned UniqueID, MCSymbol *Begin) Index: include/llvm/MC/MCWasmObjectWriter.h =================================================================== --- include/llvm/MC/MCWasmObjectWriter.h +++ include/llvm/MC/MCWasmObjectWriter.h @@ -32,12 +32,12 @@ struct WasmRelocationEntry { uint64_t Offset; // Where is the relocation. const MCSymbolWasm *Symbol; // The symbol to relocate with. - uint64_t Addend; // A value to add to the symbol. + int64_t Addend; // A value to add to the symbol. unsigned Type; // The type of the relocation. MCSectionWasm *FixupSection;// The section the relocation is targeting. WasmRelocationEntry(uint64_t Offset, const MCSymbolWasm *Symbol, - uint64_t Addend, unsigned Type, + int64_t Addend, unsigned Type, MCSectionWasm *FixupSection) : Offset(Offset), Symbol(Symbol), Addend(Addend), Type(Type), FixupSection(FixupSection) {} Index: include/llvm/Support/Wasm.h =================================================================== --- include/llvm/Support/Wasm.h +++ include/llvm/Support/Wasm.h @@ -108,7 +108,7 @@ uint32_t Type; // The type of the relocation. int32_t Index; // Index into function to global index space. uint64_t Offset; // Offset from the start of the section. - uint64_t Addend; // A value to add to the symbol. + int64_t Addend; // A value to add to the symbol. }; enum : unsigned { Index: lib/MC/WasmObjectWriter.cpp =================================================================== --- lib/MC/WasmObjectWriter.cpp +++ lib/MC/WasmObjectWriter.cpp @@ -468,16 +468,16 @@ // Write out the portions of the relocation records that the linker will // need to handle. -static void WriteRelocations( - ArrayRef Relocations, - raw_pwrite_stream &Stream, - DenseMap &SymbolIndices) -{ +static void +WriteRelocations(ArrayRef Relocations, + raw_pwrite_stream &Stream, + DenseMap &SymbolIndices, + uint64_t HeaderSize) { for (const WasmRelocationEntry RelEntry : Relocations) { encodeULEB128(RelEntry.Type, Stream); uint64_t Offset = RelEntry.Offset + - RelEntry.FixupSection->getSectionOffset(); + RelEntry.FixupSection->getSectionOffset() + HeaderSize; uint32_t Index = SymbolIndices[RelEntry.Symbol]; int64_t Addend = RelEntry.Addend; @@ -1052,6 +1052,7 @@ } // === Data Section ========================================================== + uint32_t DataSectionHeaderSize = 0; if (!DataBytes.empty()) { startSection(Section, wasm::WASM_SEC_DATA); @@ -1061,11 +1062,12 @@ encodeSLEB128(0, getStream()); // offset write8(wasm::WASM_OPCODE_END); encodeULEB128(DataBytes.size(), getStream()); // size + DataSectionHeaderSize = getStream().tell() - Section.ContentsOffset; writeBytes(DataBytes); // data // Apply fixups. ApplyRelocations(DataRelocations, getStream(), SymbolIndices, - Section.ContentsOffset); + Section.ContentsOffset + DataSectionHeaderSize); endSection(Section); } @@ -1109,7 +1111,7 @@ encodeULEB128(CodeRelocations.size() + TypeIndexFixups.size(), getStream()); - WriteRelocations(CodeRelocations, getStream(), SymbolIndices); + WriteRelocations(CodeRelocations, getStream(), SymbolIndices, 0); WriteTypeRelocations(TypeIndexFixups, TypeIndexFixupTypes, getStream()); endSection(Section); @@ -1123,7 +1125,8 @@ encodeULEB128(DataRelocations.size(), getStream()); - WriteRelocations(DataRelocations, getStream(), SymbolIndices); + WriteRelocations(DataRelocations, getStream(), SymbolIndices, + DataSectionHeaderSize); endSection(Section); } Index: test/MC/WebAssembly/reloc-data.ll =================================================================== --- /dev/null +++ test/MC/WebAssembly/reloc-data.ll @@ -0,0 +1,26 @@ +; RUN: llc -O0 -mtriple wasm32-unknown-unknown-wasm -filetype=obj %s -o - | llvm-readobj -r -expand-relocs | FileCheck %s + +; foo and bar are external and internal symbols. a and b are pointers +; initialized to these locations offset by 2 and -2 elements respecitively. +@foo = external global i32, align 4 +@bar = global i64 7, align 4 +@a = global i32* getelementptr (i32, i32* @foo, i32 2), align 8 +@b = global i64* getelementptr (i64, i64* @bar, i64 -2), align 8 + +; CHECK: Format: WASM +; CHECK: Relocations [ +; CHECK: Section (6) DATA { +; CHECK: Relocation { +; CHECK: Type: R_WEBASSEMBLY_GLOBAL_ADDR_I32 (5) +; CHECK: Offset: 0xE +; CHECK: Index: 0x0 +; CHECK: Addend: 8 +; CHECK: } +; CHECK: Relocation { +; CHECK: Type: R_WEBASSEMBLY_GLOBAL_ADDR_I32 (5) +; CHECK: Offset: 0x16 +; CHECK: Index: 0x1 +; CHECK: Addend: -16 +; CHECK: } +; CHECK: } +; CHECK: ]