Index: include/llvm/BinaryFormat/Wasm.h =================================================================== --- include/llvm/BinaryFormat/Wasm.h +++ include/llvm/BinaryFormat/Wasm.h @@ -97,6 +97,7 @@ uint32_t MemoryIndex; WasmInitExpr Offset; ArrayRef Content; + StringRef Name; }; struct WasmElemSegment { @@ -184,6 +185,7 @@ WASM_SYMBOL_INFO = 0x2, WASM_DATA_SIZE = 0x3, WASM_DATA_ALIGNMENT = 0x4, + WASM_SEGMENT_NAMES = 0x5, }; enum : unsigned { Index: include/llvm/ObjectYAML/WasmYAML.h =================================================================== --- include/llvm/ObjectYAML/WasmYAML.h +++ include/llvm/ObjectYAML/WasmYAML.h @@ -160,9 +160,10 @@ return C && C->Name == "linking"; } - std::vector SymbolInfos; uint32_t DataSize; uint32_t DataAlignment; + std::vector SymbolInfos; + std::vector SegmentNames; }; struct TypeSection : Section { Index: lib/MC/WasmObjectWriter.cpp =================================================================== --- lib/MC/WasmObjectWriter.cpp +++ lib/MC/WasmObjectWriter.cpp @@ -102,6 +102,7 @@ // wasm data segment. struct WasmDataSegment { MCSectionWasm *Section; + StringRef Name; uint32_t Offset; SmallVector Data; }; @@ -279,10 +280,10 @@ uint32_t NumFuncImports); void writeCodeRelocSection(); void writeDataRelocSection(); - void writeLinkingMetaDataSection(uint32_t DataSize, uint32_t DataAlignment, - ArrayRef WeakSymbols, - bool HasStackPointer, - uint32_t StackPointerGlobal); + void writeLinkingMetaDataSection( + const ArrayRef Segments, uint32_t DataSize, + uint32_t DataAlignment, ArrayRef WeakSymbols, + bool HasStackPointer, uint32_t StackPointerGlobal); uint32_t getProvisionalValue(const WasmRelocationEntry &RelEntry); void applyRelocations(ArrayRef Relocations, @@ -921,6 +922,7 @@ } void WasmObjectWriter::writeLinkingMetaDataSection( + const ArrayRef Segments, uint32_t DataSize, uint32_t DataAlignment, ArrayRef WeakSymbols, bool HasStackPointer, uint32_t StackPointerGlobal) { SectionBookkeeping Section; @@ -953,6 +955,14 @@ endSection(SubSection); } + if (Segments.size()) { + startSection(SubSection, wasm::WASM_SEGMENT_NAMES); + encodeULEB128(Segments.size(), getStream()); + for (const WasmDataSegment &Segment : Segments) + writeString(Segment.Name); + endSection(SubSection); + } + endSection(Section); } @@ -1146,6 +1156,7 @@ DataSize = alignTo(DataSize, Section.getAlignment()); DataSegments.emplace_back(); WasmDataSegment &Segment = DataSegments.back(); + Segment.Name = Section.getSectionName(); Segment.Offset = DataSize; Segment.Section = &Section; addData(Segment.Data, Section, DataAlignment); @@ -1307,7 +1318,8 @@ writeNameSection(Functions, Imports, NumFuncImports); writeCodeRelocSection(); writeDataRelocSection(); - writeLinkingMetaDataSection(DataSize, DataAlignment, WeakSymbols, HasStackPointer, StackPointerGlobal); + writeLinkingMetaDataSection(DataSegments, DataSize, DataAlignment, + WeakSymbols, HasStackPointer, StackPointerGlobal); // TODO: Translate the .comment section to the output. // TODO: Translate debug sections to the output. Index: lib/Object/WasmObjectFile.cpp =================================================================== --- lib/Object/WasmObjectFile.cpp +++ lib/Object/WasmObjectFile.cpp @@ -396,6 +396,15 @@ case wasm::WASM_DATA_ALIGNMENT: LinkingData.DataAlignment = readVaruint32(Ptr); break; + case wasm::WASM_SEGMENT_NAMES: { + uint32_t Count = readVaruint32(Ptr); + if (Count > DataSegments.size()) + return make_error("Too many segment names", + object_error::parse_failed); + for (uint32_t i = 0; i < Count; i++) + DataSegments[i].Data.Name = readString(Ptr); + break; + } case wasm::WASM_STACK_POINTER: default: Ptr += Size; Index: lib/ObjectYAML/WasmYAML.cpp =================================================================== --- lib/ObjectYAML/WasmYAML.cpp +++ lib/ObjectYAML/WasmYAML.cpp @@ -60,6 +60,7 @@ IO.mapRequired("DataSize", Section.DataSize); IO.mapRequired("DataAlignment", Section.DataAlignment); IO.mapOptional("SymbolInfo", Section.SymbolInfos); + IO.mapOptional("SegmentNames", Section.SegmentNames); } static void sectionMapping(IO &IO, WasmYAML::CustomSection &Section) { Index: test/MC/WebAssembly/array-fill.ll =================================================================== --- test/MC/WebAssembly/array-fill.ll +++ test/MC/WebAssembly/array-fill.ll @@ -9,6 +9,13 @@ @gBd = hidden global [2 x %struct.bd] [%struct.bd { i8 1 }, %struct.bd { i8 2 }], align 1 -; CHECK: - Type: DATA -; CHECK: Content: '0102' -; CHECK: DataSize: 2 +; CHECK: - Type: DATA +; CHECK: Content: '0102' +; CHECK: - Type: CUSTOM +; CHECK-NEXT: Name: linking +; CHECK-NEXT: DataSize: 2 +; CHECK-NEXT: DataAlignment: 1 +; CHECK-NEXT: SegmentNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: .data + Index: test/MC/WebAssembly/unnamed-data.ll =================================================================== --- test/MC/WebAssembly/unnamed-data.ll +++ test/MC/WebAssembly/unnamed-data.ll @@ -74,4 +74,13 @@ ; CHECK-NEXT: Name: linking ; CHECK-NEXT: DataSize: 28 ; CHECK-NEXT: DataAlignment: 8 +; CHECK-NEXT: SegmentNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: .rodata..L.str1 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Name: .rodata..L.str2 +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Name: .data.a +; CHECK-NEXT: - Index: 3 +; CHECK-NEXT: Name: .data.b ; CHECK-NEXT: ... Index: test/tools/llvm-readobj/sections.test =================================================================== --- test/tools/llvm-readobj/sections.test +++ test/tools/llvm-readobj/sections.test @@ -543,6 +543,11 @@ WASM-NEXT: Type: DATA (0xB) WASM-NEXT: Size: 19 WASM-NEXT: Offset: 154 +WASM-NEXT: Segments [ +WASM-NEXT: Segment { +WASM-NEXT: Size: 13 +WASM-NEXT: } +WASM-NEXT: ] WASM-NEXT: } WASM-NEXT: Section { WASM-NEXT: Type: CUSTOM (0x0) Index: tools/llvm-readobj/WasmDumper.cpp =================================================================== --- tools/llvm-readobj/WasmDumper.cpp +++ tools/llvm-readobj/WasmDumper.cpp @@ -160,6 +160,16 @@ W.printNumber("DataAlignment", LinkingData.DataAlignment); } break; + case wasm::WASM_SEC_DATA: { + ListScope Group(W, "Segments"); + for (const WasmSegment &Segment : Obj->dataSegments()) { + DictScope Group(W, "Segment"); + if (!Segment.Data.Name.empty()) + W.printString("Name", Segment.Data.Name); + W.printNumber("Size", Segment.Data.Content.size()); + } + break; + } case wasm::WASM_SEC_MEMORY: ListScope Group(W, "Memories"); for (const wasm::WasmLimits &Memory : Obj->memories()) { Index: tools/obj2yaml/wasm2yaml.cpp =================================================================== --- tools/obj2yaml/wasm2yaml.cpp +++ tools/obj2yaml/wasm2yaml.cpp @@ -70,6 +70,16 @@ CustomSec = std::move(NameSec); } else if (WasmSec.Name == "linking") { std::unique_ptr LinkingSec = make_unique(); + size_t Index = 0; + for (const object::WasmSegment &Segment : Obj.dataSegments()) { + if (!Segment.Data.Name.empty()) { + WasmYAML::NameEntry NameEntry; + NameEntry.Name = Segment.Data.Name; + NameEntry.Index = Index; + LinkingSec->SegmentNames.push_back(NameEntry); + } + Index++; + } for (const object::SymbolRef& Sym: Obj.symbols()) { const object::WasmSymbol Symbol = Obj.getWasmSymbol(Sym); if (Symbol.Flags != 0) { @@ -234,7 +244,7 @@ } case wasm::WASM_SEC_DATA: { auto DataSec = make_unique(); - for (auto &Segment : Obj.dataSegments()) { + for (const object::WasmSegment &Segment : Obj.dataSegments()) { WasmYAML::DataSegment Seg; Seg.SectionOffset = Segment.SectionOffset; Seg.MemoryIndex = Segment.Data.MemoryIndex; Index: tools/yaml2obj/yaml2wasm.cpp =================================================================== --- tools/yaml2obj/yaml2wasm.cpp +++ tools/yaml2obj/yaml2wasm.cpp @@ -157,6 +157,17 @@ SubSection.Done(); } + + // SEGMENT_NAMES subsection + if (Section.SegmentNames.size()) { + encodeULEB128(wasm::WASM_SEGMENT_NAMES, OS); + encodeULEB128(Section.SegmentNames.size(), SubSection.GetStream()); + for (const WasmYAML::NameEntry &NameEntry : Section.SegmentNames) { + encodeULEB128(NameEntry.Index, SubSection.GetStream()); + writeStringRef(NameEntry.Name, SubSection.GetStream()); + } + SubSection.Done(); + } return 0; }