uint32_t MemoryIndex;
WasmInitExpr Offset;
ArrayRef<uint8_t> Content;
+ StringRef Name;
};
struct WasmElemSegment {
WASM_SYMBOL_INFO = 0x2,
WASM_DATA_SIZE = 0x3,
WASM_DATA_ALIGNMENT = 0x4,
+ WASM_SEGMENT_NAMES = 0x5,
};
enum : unsigned {
return C && C->Name == "linking";
}
- std::vector<SymbolInfo> SymbolInfos;
uint32_t DataSize;
uint32_t DataAlignment;
+ std::vector<SymbolInfo> SymbolInfos;
+ std::vector<NameEntry> SegmentNames;
};
struct TypeSection : Section {
// wasm data segment.
struct WasmDataSegment {
MCSectionWasm *Section;
+ StringRef Name;
uint32_t Offset;
SmallVector<char, 4> Data;
};
uint32_t NumFuncImports);
void writeCodeRelocSection();
void writeDataRelocSection();
- void writeLinkingMetaDataSection(uint32_t DataSize, uint32_t DataAlignment,
+ void writeLinkingMetaDataSection(ArrayRef<WasmDataSegment> Segments,
+ uint32_t DataSize, uint32_t DataAlignment,
ArrayRef<StringRef> WeakSymbols,
bool HasStackPointer,
uint32_t StackPointerGlobal);
}
void WasmObjectWriter::writeLinkingMetaDataSection(
- uint32_t DataSize, uint32_t DataAlignment, ArrayRef<StringRef> WeakSymbols,
+ ArrayRef<WasmDataSegment> Segments, uint32_t DataSize,
+ uint32_t DataAlignment, ArrayRef<StringRef> WeakSymbols,
bool HasStackPointer, uint32_t StackPointerGlobal) {
SectionBookkeeping Section;
startSection(Section, wasm::WASM_SEC_CUSTOM, "linking");
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);
}
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);
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.
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<GenericBinaryError>("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;
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) {
@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
+; CHECK-NEXT: ...
--- /dev/null
+; RUN: llc -mtriple wasm32-unknown-unknown-wasm -filetype=obj %s -o - | obj2yaml | FileCheck %s
+
+@g0 = global i8* null, align 4
+
+; CHECK: - Type: DATA
+; CHECK-NEXT: Segments:
+; CHECK-NEXT: - SectionOffset: 6
+; CHECK-NEXT: MemoryIndex: 0
+; CHECK-NEXT: Offset:
+; CHECK-NEXT: Opcode: I32_CONST
+; CHECK-NEXT: Value: 0
+; CHECK-NEXT: Content: '00000000'
+; CHECK-NEXT: - Type: CUSTOM
+; CHECK-NEXT: Name: linking
+; CHECK-NEXT: DataSize: 4
+; CHECK-NEXT: DataAlignment: 4
+; CHECK-NEXT: SegmentNames:
+; CHECK-NEXT: - Index: 0
+; CHECK-NEXT: Name: .bss.g0
+; CHECK-NEXT: ...
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 24
; CHECK-NEXT: Content: '08000000'
+
+; CHECK: - Type: CUSTOM
+; CHECK-NEXT: Name: linking
+; CHECK-NEXT: DataSize: 28
+; CHECK-NEXT: DataAlignment: 8
+; CHECK-NEXT: SegmentNames:
+; CHECK-NEXT: - Index: 0
+; CHECK-NEXT: Name: .data.global0
+; CHECK-NEXT: - Index: 1
+; CHECK-NEXT: Name: .sec1
+; CHECK-NEXT: - Index: 2
+; CHECK-NEXT: Name: .sec2
+; CHECK-NEXT: ...
; 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: ...
; CHECK-NEXT: Flags: 1
; CHECK-NEXT: - Name: bar_alias
; CHECK-NEXT: Flags: 1
+; CHECK-NEXT: SegmentNames:
+; CHECK-NEXT: - Index: 0
+; CHECK-NEXT: Name: .data.bar
+; CHECK-NEXT: - Index: 1
+; CHECK-NEXT: Name: .data.bar_alias_address
; CHECK-NEXT: ...
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: Offset: 0
+WASM-NEXT: }
+WASM-NEXT: ]
WASM-NEXT: }
WASM-NEXT: Section {
WASM-NEXT: Type: CUSTOM (0x0)
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());
+ if (Segment.Data.Offset.Opcode == wasm::WASM_OPCODE_I32_CONST)
+ W.printNumber("Offset", Segment.Data.Offset.Value.Int32);
+ }
+ break;
+ }
case wasm::WASM_SEC_MEMORY:
ListScope Group(W, "Memories");
for (const wasm::WasmLimits &Memory : Obj->memories()) {
CustomSec = std::move(NameSec);
} else if (WasmSec.Name == "linking") {
std::unique_ptr<WasmYAML::LinkingSection> LinkingSec = make_unique<WasmYAML::LinkingSection>();
+ 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) {
}
case wasm::WASM_SEC_DATA: {
auto DataSec = make_unique<WasmYAML::DataSection>();
- for (auto &Segment : Obj.dataSegments()) {
+ for (const object::WasmSegment &Segment : Obj.dataSegments()) {
WasmYAML::DataSegment Seg;
Seg.SectionOffset = Segment.SectionOffset;
Seg.MemoryIndex = Segment.Data.MemoryIndex;
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;
}