Error parseElemSection(ReadContext &Ctx);
Error parseCodeSection(ReadContext &Ctx);
Error parseDataSection(ReadContext &Ctx);
+ Error parseDataCountSection(ReadContext &Ctx);
// Custom section types
Error parseDylinkSection(ReadContext &Ctx);
std::vector<wasm::WasmExport> Exports;
std::vector<wasm::WasmElemSegment> ElemSegments;
std::vector<WasmSegment> DataSegments;
+ llvm::Optional<size_t> DataCount;
std::vector<wasm::WasmFunction> Functions;
std::vector<WasmSymbol> Symbols;
std::vector<wasm::WasmFunctionName> DebugNames;
std::vector<DataSegment> Segments;
};
+struct DataCountSection : Section {
+ DataCountSection() : Section(wasm::WASM_SEC_DATACOUNT) {}
+
+ static bool classof(const Section *S) {
+ return S->Type == wasm::WASM_SEC_DATACOUNT;
+ }
+
+ uint32_t Count;
+};
+
struct Object {
FileHeader Header;
std::vector<std::unique_ptr<Section>> Sections;
void writeFunctionSection(ArrayRef<WasmFunction> Functions);
void writeExportSection(ArrayRef<wasm::WasmExport> Exports);
void writeElemSection(ArrayRef<uint32_t> TableElems);
+ void writeDataCountSection();
void writeCodeSection(const MCAssembler &Asm, const MCAsmLayout &Layout,
ArrayRef<WasmFunction> Functions);
void writeDataSection();
endSection(Section);
}
+void WasmObjectWriter::writeDataCountSection() {
+ if (DataSegments.empty())
+ return;
+
+ SectionBookkeeping Section;
+ startSection(Section, wasm::WASM_SEC_DATACOUNT);
+ encodeULEB128(DataSegments.size(), W.OS);
+ endSection(Section);
+}
+
void WasmObjectWriter::writeCodeSection(const MCAssembler &Asm,
const MCAsmLayout &Layout,
ArrayRef<WasmFunction> Functions) {
writeEventSection(Events);
writeExportSection(Exports);
writeElemSection(TableElems);
+ writeDataCountSection();
writeCodeSection(Asm, Layout, Functions);
writeDataSection();
for (auto &CustomSection : CustomSections)
return parseCodeSection(Ctx);
case wasm::WASM_SEC_DATA:
return parseDataSection(Ctx);
+ case wasm::WASM_SEC_DATACOUNT:
+ return parseDataCountSection(Ctx);
default:
return make_error<GenericBinaryError>("Bad section type",
object_error::parse_failed);
Error WasmObjectFile::parseDataSection(ReadContext &Ctx) {
DataSection = Sections.size();
uint32_t Count = readVaruint32(Ctx);
+ if (DataCount && Count != DataCount.getValue())
+ return make_error<GenericBinaryError>(
+ "Number of data segments does not match DataCount section");
DataSegments.reserve(Count);
while (Count--) {
WasmSegment Segment;
return Error::success();
}
+Error WasmObjectFile::parseDataCountSection(ReadContext &Ctx) {
+ DataCount = readVaruint32(Ctx);
+ return Error::success();
+}
+
const wasm::WasmObjectHeader &WasmObjectFile::getHeader() const {
return Header;
}
ECase(ELEM);
ECase(CODE);
ECase(DATA);
+ ECase(DATACOUNT);
case wasm::WASM_SEC_CUSTOM:
Res = S.Name;
break;
IO.mapRequired("Segments", Section.Segments);
}
+static void sectionMapping(IO &IO, WasmYAML::DataCountSection &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapRequired("Count", Section.Count);
+}
+
void MappingTraits<std::unique_ptr<WasmYAML::Section>>::mapping(
IO &IO, std::unique_ptr<WasmYAML::Section> &Section) {
WasmYAML::SectionType SectionType;
Section.reset(new WasmYAML::DataSection());
sectionMapping(IO, *cast<WasmYAML::DataSection>(Section.get()));
break;
+ case wasm::WASM_SEC_DATACOUNT:
+ if (!IO.outputting())
+ Section.reset(new WasmYAML::DataCountSection());
+ sectionMapping(IO, *cast<WasmYAML::DataCountSection>(Section.get()));
+ break;
default:
llvm_unreachable("Unknown section type");
}
ECase(ELEM);
ECase(CODE);
ECase(DATA);
+ ECase(DATACOUNT);
#undef ECase
}
@foo = global %union.u1 zeroinitializer, align 1
@bar = global %union.u1 zeroinitializer, align 1
-; CHECK: - Type: DATA
+; CHECK: - Type: DATA{{$}}
; CHECK-NEXT: Segments:
; CHECK-NEXT: - SectionOffset: 6
; CHECK-NEXT: InitFlags: 0
; CHECK-NEXT: SigIndex: 0
; CHECK-NEXT: - Type: FUNCTION
; CHECK-NEXT: FunctionTypes: [ 0, 0, 0 ]
+; CHECK-NEXT: - Type: DATACOUNT
+; CHECK-NEXT: Count: 1
; CHECK-NEXT: - Type: CODE
; CHECK-NEXT: Relocations:
; CHECK-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
# BIN-NEXT: Initial: 0x00000000
# BIN-NEXT: - Type: FUNCTION
# BIN-NEXT: FunctionTypes: [ 0 ]
+# BIN-NEXT: - Type: DATACOUNT
+# BIN-NEXT: Count: 1
# BIN-NEXT: - Type: CODE
# BIN-NEXT: Relocations:
# BIN-NEXT: - Type: R_WASM_MEMORY_ADDR_SLEB
# BIN-NEXT: Alignment: 0
# BIN-NEXT: Flags: [ ]
# BIN-NEXT: ...
-
; CHECK-NEXT: Offset: 90
; CHECK-NEXT: }
; CHECK-NEXT: Section {
+; CHECK-NEXT: Type: DATACOUNT (0xC)
+; CHECK-NEXT: Size: 1
+; CHECK-NEXT: Offset: 103
+; CHECK-NEXT: }
+; CHECK-NEXT: Section {
; CHECK-NEXT: Type: CODE (0xA)
; CHECK-NEXT: Size: 4
-; CHECK-NEXT: Offset: 103
+; CHECK-NEXT: Offset: 110
; CHECK-NEXT: }
; CHECK-NEXT: Section {
; CHECK-NEXT: Type: DATA (0xB)
; CHECK-NEXT: Size: 19
-; CHECK-NEXT: Offset: 113
+; CHECK-NEXT: Offset: 120
; CHECK-NEXT: Segments [
; CHECK-NEXT: Segment {
; CHECK-NEXT: Name: .data.foo
; CHECK-NEXT: Section {
; CHECK-NEXT: Type: CUSTOM (0x0)
; CHECK-NEXT: Size: 121
-; CHECK-NEXT: Offset: 138
+; CHECK-NEXT: Offset: 145
; CHECK-NEXT: Name: .debug_str
; CHECK-NEXT: }
; CHECK-NEXT: Section {
; CHECK-NEXT: Type: CUSTOM (0x0)
; CHECK-NEXT: Size: 84
-; CHECK-NEXT: Offset: 276
+; CHECK-NEXT: Offset: 283
; CHECK-NEXT: Name: .debug_abbrev
; CHECK-NEXT: }
; CHECK-NEXT: Section {
; CHECK-NEXT: Type: CUSTOM (0x0)
; CHECK-NEXT: Size: 106
-; CHECK-NEXT: Offset: 380
+; CHECK-NEXT: Offset: 387
; CHECK-NEXT: Name: .debug_info
; CHECK-NEXT: }
; CHECK-NEXT: Section {
; CHECK-NEXT: Type: CUSTOM (0x0)
; CHECK-NEXT: Size: 1
-; CHECK-NEXT: Offset: 504
+; CHECK-NEXT: Offset: 511
; CHECK-NEXT: Name: .debug_macinfo
; CHECK-NEXT: }
; CHECK-NEXT: Section {
; CHECK-NEXT: Type: CUSTOM (0x0)
; CHECK-NEXT: Size: 42
-; CHECK-NEXT: Offset: 526
+; CHECK-NEXT: Offset: 533
; CHECK-NEXT: Name: .debug_pubnames
; CHECK-NEXT: }
; CHECK-NEXT: Section {
; CHECK-NEXT: Type: CUSTOM (0x0)
; CHECK-NEXT: Size: 26
-; CHECK-NEXT: Offset: 590
+; CHECK-NEXT: Offset: 597
; CHECK-NEXT: Name: .debug_pubtypes
; CHECK-NEXT: }
; CHECK-NEXT: Section {
; CHECK-NEXT: Type: CUSTOM (0x0)
; CHECK-NEXT: Size: 57
-; CHECK-NEXT: Offset: 638
+; CHECK-NEXT: Offset: 645
; CHECK-NEXT: Name: .debug_line
; CHECK-NEXT: }
; CHECK-NEXT: Section {
; CHECK-NEXT: Type: CUSTOM (0x0)
; CHECK-NEXT: Size: 88
-; CHECK-NEXT: Offset: 713
+; CHECK-NEXT: Offset: 720
; CHECK-NEXT: Name: linking
; CHECK-NEXT: }
; CHECK-NEXT: Section {
; CHECK-NEXT: Type: CUSTOM (0x0)
; CHECK-NEXT: Size: 9
-; CHECK-NEXT: Offset: 815
+; CHECK-NEXT: Offset: 822
; CHECK-NEXT: Name: reloc.DATA
; CHECK-NEXT: }
; CHECK-NEXT: Section {
; CHECK-NEXT: Type: CUSTOM (0x0)
; CHECK-NEXT: Size: 58
-; CHECK-NEXT: Offset: 841
+; CHECK-NEXT: Offset: 848
; CHECK-NEXT: Name: reloc..debug_info
; CHECK-NEXT: }
; CHECK-NEXT: Section {
; CHECK-NEXT: Type: CUSTOM (0x0)
; CHECK-NEXT: Size: 6
-; CHECK-NEXT: Offset: 923
+; CHECK-NEXT: Offset: 930
; CHECK-NEXT: Name: reloc..debug_pubnames
; CHECK-NEXT: }
; CHECK-NEXT: Section {
; CHECK-NEXT: Type: CUSTOM (0x0)
; CHECK-NEXT: Size: 6
-; CHECK-NEXT: Offset: 957
+; CHECK-NEXT: Offset: 964
; CHECK-NEXT: Name: reloc..debug_pubtypes
; CHECK-NEXT: }
; CHECK-NEXT: Section {
; CHECK-NEXT: Type: CUSTOM (0x0)
; CHECK-NEXT: Size: 6
-; CHECK-NEXT: Offset: 991
+; CHECK-NEXT: Offset: 998
; CHECK-NEXT: Name: reloc..debug_line
; CHECK-NEXT: }
; CHECK-NEXT: Section {
; CHECK-NEXT: Type: CUSTOM (0x0)
; CHECK-NEXT: Size: 77
-; CHECK-NEXT: Offset: 1021
+; CHECK-NEXT: Offset: 1028
; CHECK-NEXT: Name: producers
; CHECK-NEXT: }
; CHECK-NEXT:]
; CHECK-NEXT:Relocations [
-; CHECK-NEXT: Section (6) DATA {
+; CHECK-NEXT: Section (7) DATA {
; CHECK-NEXT: 0x6 R_WASM_MEMORY_ADDR_I32 myextern 0
; CHECK-NEXT: 0xF R_WASM_TABLE_INDEX_I32 f2
; CHECK-NEXT: }
-; CHECK-NEXT: Section (9) .debug_info {
+; CHECK-NEXT: Section (10) .debug_info {
; CHECK-NEXT: 0x6 R_WASM_SECTION_OFFSET_I32 .debug_abbrev 0
; CHECK-NEXT: 0xC R_WASM_SECTION_OFFSET_I32 .debug_str 0
; CHECK-NEXT: 0x12 R_WASM_SECTION_OFFSET_I32 .debug_str 55
; CHECK-NEXT: 0x5B R_WASM_FUNCTION_OFFSET_I32 f2 0
; CHECK-NEXT: 0x63 R_WASM_SECTION_OFFSET_I32 .debug_str 118
; CHECK-NEXT: }
-; CHECK-NEXT: Section (11) .debug_pubnames {
+; CHECK-NEXT: Section (12) .debug_pubnames {
; CHECK-NEXT: 0x6 R_WASM_SECTION_OFFSET_I32 .debug_info 0
; CHECK-NEXT: }
-; CHECK-NEXT: Section (12) .debug_pubtypes {
+; CHECK-NEXT: Section (13) .debug_pubtypes {
; CHECK-NEXT: 0x6 R_WASM_SECTION_OFFSET_I32 .debug_info 0
; CHECK-NEXT: }
-; CHECK-NEXT: Section (13) .debug_line {
+; CHECK-NEXT: Section (14) .debug_line {
; CHECK-NEXT: 0x2B R_WASM_FUNCTION_OFFSET_I32 f2 0
; CHECK-NEXT: }
; CHECK-NEXT:]
; CHECK-NEXT: Flags [ (0x2)
; CHECK-NEXT: BINDING_LOCAL (0x2)
; CHECK-NEXT: ]
-; CHECK-NEXT: ElementIndex: 0x6
+; CHECK-NEXT: ElementIndex: 0x7
; CHECK-NEXT: }
; CHECK-NEXT: Symbol {
; CHECK-NEXT: Name: .debug_abbrev
; CHECK-NEXT: Flags [ (0x2)
; CHECK-NEXT: BINDING_LOCAL (0x2)
; CHECK-NEXT: ]
-; CHECK-NEXT: ElementIndex: 0x7
+; CHECK-NEXT: ElementIndex: 0x8
; CHECK-NEXT: }
; CHECK-NEXT: Symbol {
; CHECK-NEXT: Name: .debug_info
; CHECK-NEXT: Flags [ (0x2)
; CHECK-NEXT: BINDING_LOCAL (0x2)
; CHECK-NEXT: ]
-; CHECK-NEXT: ElementIndex: 0x8
+; CHECK-NEXT: ElementIndex: 0x9
; CHECK-NEXT: }
; CHECK-NEXT: Symbol {
; CHECK-NEXT: Name: .debug_line
; CHECK-NEXT: Flags [ (0x2)
; CHECK-NEXT: BINDING_LOCAL (0x2)
; CHECK-NEXT: ]
-; CHECK-NEXT: ElementIndex: 0xC
+; CHECK-NEXT: ElementIndex: 0xD
; CHECK-NEXT: }
; CHECK-NEXT:]
@global3 = global i32 8, align 8, section ".sec2"
-; CHECK: - Type: DATA
+; CHECK: - Type: DATA{{$}}
; CHECK-NEXT: Segments:
; CHECK-NEXT: - SectionOffset: 6
; CHECK-NEXT: InitFlags: 0
@foo = global i64 7, align 4
@bar = hidden global i32* @myimport, align 4
-; CHECK: - Type: DATA
+; CHECK: - Type: DATA{{$}}
; CHECK-NEXT: Relocations:
; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_I32
; CHECK-NEXT: Index: 2
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 1
; CHECK-NEXT: Functions: [ 1, 2 ]
-; CHECK: - Type: DATA
+; CHECK: - Type: DATA{{$}}
; CHECK-NEXT: Relocations:
; CHECK-NEXT: - Type: R_WASM_TABLE_INDEX_I32
; CHECK-NEXT: Index: 3
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 1
; CHECK-NEXT: Functions: [ 5, 7 ]
+; CHECK-NEXT: - Type: DATACOUNT
+; CHECK-NEXT: Count: 1
; CHECK-NEXT: - Type: CODE
; CHECK-NEXT: Relocations:
; CHECK-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
; CHECK: Format: WASM
; CHECK: Relocations [
-; CHECK-NEXT: Section (4) CODE {
+; CHECK-NEXT: Section (5) CODE {
; CHECK-NEXT: Relocation {
; CHECK-NEXT: Type: R_WASM_MEMORY_ADDR_LEB (3)
; CHECK-NEXT: Offset: 0x9
; CHECK: Format: WASM
; CHECK: Relocations [
-; CHECK-NEXT: Section (2) DATA {
+; CHECK-NEXT: Section (3) DATA {
; CHECK-NEXT: Relocation {
; CHECK-NEXT: Type: R_WASM_MEMORY_ADDR_I32 (5)
; CHECK-NEXT: Offset: 0x13
# CHECK-NEXT: GlobalMutable: true
# CHECK-NEXT: - Type: FUNCTION
# CHECK-NEXT: FunctionTypes: [ 0, 0, 0, 0, 0 ]
+# CHECK-NEXT: - Type: DATACOUNT
+# CHECK-NEXT: Count: 1
# CHECK-NEXT: - Type: CODE
# CHECK-NEXT: Relocations:
# CHECK-NEXT: - Type: R_WASM_GLOBAL_INDEX_LEB
@b = global i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str2, i32 0, i32 0), align 8
-; CHECK: - Type: DATA
+; CHECK: - Type: DATA{{$}}
; CHECK-NEXT: Relocations:
; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_I32
; CHECK-NEXT: Index: 0
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 1
; CHECK-NEXT: Functions: [ 0 ]
+; CHECK-NEXT: - Type: DATACOUNT
+; CHECK-NEXT: Count: 3
; CHECK-NEXT: - Type: CODE
; CHECK-NEXT: Relocations:
; CHECK-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
static const EnumEntry<uint32_t> WasmSectionTypes[] = {
#define ENUM_ENTRY(X) \
{ #X, wasm::WASM_SEC_##X }
- ENUM_ENTRY(CUSTOM), ENUM_ENTRY(TYPE), ENUM_ENTRY(IMPORT),
- ENUM_ENTRY(FUNCTION), ENUM_ENTRY(TABLE), ENUM_ENTRY(MEMORY),
- ENUM_ENTRY(GLOBAL), ENUM_ENTRY(EVENT), ENUM_ENTRY(EXPORT),
- ENUM_ENTRY(START), ENUM_ENTRY(ELEM), ENUM_ENTRY(CODE),
- ENUM_ENTRY(DATA),
+ ENUM_ENTRY(CUSTOM), ENUM_ENTRY(TYPE), ENUM_ENTRY(IMPORT),
+ ENUM_ENTRY(FUNCTION), ENUM_ENTRY(TABLE), ENUM_ENTRY(MEMORY),
+ ENUM_ENTRY(GLOBAL), ENUM_ENTRY(EVENT), ENUM_ENTRY(EXPORT),
+ ENUM_ENTRY(START), ENUM_ENTRY(ELEM), ENUM_ENTRY(CODE),
+ ENUM_ENTRY(DATA), ENUM_ENTRY(DATACOUNT),
#undef ENUM_ENTRY
};
S = std::move(DataSec);
break;
}
+ case wasm::WASM_SEC_DATACOUNT: {
+ auto DataCountSec = make_unique<WasmYAML::DataCountSection>();
+ DataCountSec->Count = Obj.dataSegments().size();
+ S = std::move(DataCountSec);
+ break;
+ }
default:
llvm_unreachable("Unknown section type");
break;
int writeSectionContent(raw_ostream &OS, WasmYAML::ElemSection &Section);
int writeSectionContent(raw_ostream &OS, WasmYAML::CodeSection &Section);
int writeSectionContent(raw_ostream &OS, WasmYAML::DataSection &Section);
+ int writeSectionContent(raw_ostream &OS, WasmYAML::DataCountSection &Section);
// Custom section types
int writeSectionContent(raw_ostream &OS, WasmYAML::DylinkSection &Section);
return 0;
}
+int WasmWriter::writeSectionContent(raw_ostream &OS,
+ WasmYAML::DataCountSection &Section) {
+ encodeULEB128(Section.Count, OS);
+ return 0;
+}
+
int WasmWriter::writeRelocSection(raw_ostream &OS, WasmYAML::Section &Sec,
uint32_t SectionIndex) {
switch (Sec.Type) {
} else if (auto S = dyn_cast<WasmYAML::DataSection>(Sec.get())) {
if (auto Err = writeSectionContent(StringStream, *S))
return Err;
+ } else if (auto S = dyn_cast<WasmYAML::DataCountSection>(Sec.get())) {
+ if (auto Err = writeSectionContent(StringStream, *S))
+ return Err;
} else {
errs() << "Unknown section type: " << Sec->Type << "\n";
return 1;