From 1e7ea802fea6139a1ddf92f4d52fe9742bc98762 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Wed, 12 Jul 2017 00:24:54 +0000 Subject: [PATCH] [WebAssembly] Expose the offset of each data segment Summary: This allows tools like lld that process relocations to apply data relocation correctly. This information is required because relocation are stored as section offset. Subscribers: jfb, dschuff, jgravelle-google, aheejin Differential Revision: https://reviews.llvm.org/D35234 llvm-svn: 307741 --- include/llvm/BinaryFormat/Wasm.h | 2 +- include/llvm/Object/Wasm.h | 12 ++++++++---- include/llvm/ObjectYAML/WasmYAML.h | 3 ++- lib/Object/WasmObjectFile.cpp | 10 ++++++---- lib/ObjectYAML/WasmYAML.cpp | 3 ++- test/MC/WebAssembly/external-data.ll | 3 ++- test/MC/WebAssembly/unnamed-data.ll | 3 ++- test/ObjectYAML/wasm/data_section.yaml | 5 +++-- tools/obj2yaml/wasm2yaml.cpp | 7 ++++--- tools/yaml2obj/yaml2wasm.cpp | 2 +- 10 files changed, 31 insertions(+), 19 deletions(-) diff --git a/include/llvm/BinaryFormat/Wasm.h b/include/llvm/BinaryFormat/Wasm.h index 4cb373a0b70..23e30b7a868 100644 --- a/include/llvm/BinaryFormat/Wasm.h +++ b/include/llvm/BinaryFormat/Wasm.h @@ -94,7 +94,7 @@ struct WasmFunction { }; struct WasmDataSegment { - uint32_t Index; + uint32_t MemoryIndex; WasmInitExpr Offset; ArrayRef Content; }; diff --git a/include/llvm/Object/Wasm.h b/include/llvm/Object/Wasm.h index f1c140cf97c..07ee4a4d6c4 100644 --- a/include/llvm/Object/Wasm.h +++ b/include/llvm/Object/Wasm.h @@ -69,8 +69,7 @@ public: #endif }; -class WasmSection { -public: +struct WasmSection { WasmSection() = default; uint32_t Type = 0; // Section type (See below) @@ -80,6 +79,11 @@ public: std::vector Relocations; // Relocations for this section }; +struct WasmSegment { + uint32_t SectionOffset; + wasm::WasmDataSegment Data; +}; + class WasmObjectFile : public ObjectFile { public: @@ -110,7 +114,7 @@ public: return ElemSegments; } - const std::vector& dataSegments() const { + const std::vector& dataSegments() const { return DataSegments; } @@ -210,7 +214,7 @@ private: std::vector Imports; std::vector Exports; std::vector ElemSegments; - std::vector DataSegments; + std::vector DataSegments; std::vector Functions; std::vector Symbols; ArrayRef CodeSection; diff --git a/include/llvm/ObjectYAML/WasmYAML.h b/include/llvm/ObjectYAML/WasmYAML.h index 6bf08d340ee..709ad8ec3b7 100644 --- a/include/llvm/ObjectYAML/WasmYAML.h +++ b/include/llvm/ObjectYAML/WasmYAML.h @@ -98,7 +98,8 @@ struct Relocation { }; struct DataSegment { - uint32_t Index; + uint32_t MemoryIndex; + uint32_t SectionOffset; wasm::WasmInitExpr Offset; yaml::BinaryRef Content; }; diff --git a/lib/Object/WasmObjectFile.cpp b/lib/Object/WasmObjectFile.cpp index 3c675aa71b9..7f80bf0b83a 100644 --- a/lib/Object/WasmObjectFile.cpp +++ b/lib/Object/WasmObjectFile.cpp @@ -675,15 +675,17 @@ Error WasmObjectFile::parseElemSection(const uint8_t *Ptr, const uint8_t *End) { } Error WasmObjectFile::parseDataSection(const uint8_t *Ptr, const uint8_t *End) { + const uint8_t *Start = Ptr; uint32_t Count = readVaruint32(Ptr); DataSegments.reserve(Count); while (Count--) { - wasm::WasmDataSegment Segment; - Segment.Index = readVaruint32(Ptr); - if (Error Err = readInitExpr(Segment.Offset, Ptr)) + WasmSegment Segment; + Segment.Data.MemoryIndex = readVaruint32(Ptr); + if (Error Err = readInitExpr(Segment.Data.Offset, Ptr)) return Err; uint32_t Size = readVaruint32(Ptr); - Segment.Content = ArrayRef(Ptr, Size); + Segment.Data.Content = ArrayRef(Ptr, Size); + Segment.SectionOffset = Ptr - Start; Ptr += Size; DataSegments.push_back(Segment); } diff --git a/lib/ObjectYAML/WasmYAML.cpp b/lib/ObjectYAML/WasmYAML.cpp index 2040efdc9d1..6a68cd265ad 100644 --- a/lib/ObjectYAML/WasmYAML.cpp +++ b/lib/ObjectYAML/WasmYAML.cpp @@ -345,7 +345,8 @@ void MappingTraits::mapping(IO &IO, void MappingTraits::mapping( IO &IO, WasmYAML::DataSegment &Segment) { - IO.mapRequired("Index", Segment.Index); + IO.mapOptional("SectionOffset", Segment.SectionOffset); + IO.mapRequired("MemoryIndex", Segment.MemoryIndex); IO.mapRequired("Offset", Segment.Offset); IO.mapRequired("Content", Segment.Content); } diff --git a/test/MC/WebAssembly/external-data.ll b/test/MC/WebAssembly/external-data.ll index 6914736ac67..b8c97453413 100644 --- a/test/MC/WebAssembly/external-data.ll +++ b/test/MC/WebAssembly/external-data.ll @@ -13,7 +13,8 @@ ; CHECK: Index: 0 ; CHECK: Offset: 0x0000000E ; CHECK: Segments: -; CHECK: - Index: 0 +; CHECK: - SectionOffset: 6 +; CHECK: MemoryIndex: 0 ; CHECK: Offset: ; CHECK: Opcode: I32_CONST ; CHECK: Value: 0 diff --git a/test/MC/WebAssembly/unnamed-data.ll b/test/MC/WebAssembly/unnamed-data.ll index fd985088c1d..fa0ff966a79 100644 --- a/test/MC/WebAssembly/unnamed-data.ll +++ b/test/MC/WebAssembly/unnamed-data.ll @@ -46,7 +46,8 @@ ; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x0000001E ; CHECK-NEXT: Segments: -; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: - SectionOffset: 6 +; CHECK-NEXT: MemoryIndex: 0 ; CHECK-NEXT: Offset: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 0 diff --git a/test/ObjectYAML/wasm/data_section.yaml b/test/ObjectYAML/wasm/data_section.yaml index b8c65abbff9..521aa540278 100644 --- a/test/ObjectYAML/wasm/data_section.yaml +++ b/test/ObjectYAML/wasm/data_section.yaml @@ -8,7 +8,7 @@ Sections: - Initial: 0x00000003 - Type: DATA Segments: - - Index: 0 + - MemoryIndex: 0 Offset: Opcode: I32_CONST Value: 4 @@ -38,7 +38,8 @@ Sections: # CHECK-NEXT: Offset: 0x00000006 # CHECK-NEXT: Addend: -6 # CHECK-NEXT: Segments: -# CHECK-NEXT: - Index: 0 +# CHECK-NEXT: - SectionOffset: 6 +# CHECK-NEXT: MemoryIndex: 0 # CHECK-NEXT: Offset: # CHECK-NEXT: Opcode: I32_CONST # CHECK-NEXT: Value: 4 diff --git a/tools/obj2yaml/wasm2yaml.cpp b/tools/obj2yaml/wasm2yaml.cpp index 1df6afcf3c4..a1da4b6a748 100644 --- a/tools/obj2yaml/wasm2yaml.cpp +++ b/tools/obj2yaml/wasm2yaml.cpp @@ -236,9 +236,10 @@ ErrorOr WasmDumper::dump() { auto DataSec = make_unique(); for (auto &Segment : Obj.dataSegments()) { WasmYAML::DataSegment Seg; - Seg.Index = Segment.Index; - Seg.Offset = Segment.Offset; - Seg.Content = yaml::BinaryRef(Segment.Content); + Seg.SectionOffset = Segment.SectionOffset; + Seg.MemoryIndex = Segment.Data.MemoryIndex; + Seg.Offset = Segment.Data.Offset; + Seg.Content = yaml::BinaryRef(Segment.Data.Content); DataSec->Segments.push_back(Seg); } S = std::move(DataSec); diff --git a/tools/yaml2obj/yaml2wasm.cpp b/tools/yaml2obj/yaml2wasm.cpp index 110700d40c3..059ec5f9edc 100644 --- a/tools/yaml2obj/yaml2wasm.cpp +++ b/tools/yaml2obj/yaml2wasm.cpp @@ -338,7 +338,7 @@ int WasmWriter::writeSectionContent(raw_ostream &OS, WasmYAML::DataSection &Section) { encodeULEB128(Section.Segments.size(), OS); for (auto &Segment : Section.Segments) { - encodeULEB128(Segment.Index, OS); + encodeULEB128(Segment.MemoryIndex, OS); writeInitExpr(Segment.Offset, OS); encodeULEB128(Segment.Content.binary_size(), OS); Segment.Content.writeAsBinary(OS);