]> granicus.if.org Git - llvm/commitdiff
[WebAssembly] Add DataCount section to object files
authorThomas Lively <tlively@google.com>
Fri, 12 Apr 2019 22:27:48 +0000 (22:27 +0000)
committerThomas Lively <tlively@google.com>
Fri, 12 Apr 2019 22:27:48 +0000 (22:27 +0000)
Summary:
This ensures that object files will continue to validate as
WebAssembly modules in the presence of bulk memory operations. Engines
that don't support bulk memory operations will not recognize the
DataCount section and will report validation errors, but that's ok
because object files aren't supposed to be run directly anyway.

Reviewers: aheejin, dschuff, sbc100

Subscribers: jgravelle-google, hiraditya, sunfish, rupprecht, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D60623

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358315 91177308-0d34-0410-b5e6-96231b3b80d8

21 files changed:
include/llvm/Object/Wasm.h
include/llvm/ObjectYAML/WasmYAML.h
lib/MC/WasmObjectWriter.cpp
lib/Object/WasmObjectFile.cpp
lib/ObjectYAML/WasmYAML.cpp
test/MC/WebAssembly/bss.ll
test/MC/WebAssembly/comdat.ll
test/MC/WebAssembly/data-section.s
test/MC/WebAssembly/debug-info.ll
test/MC/WebAssembly/explicit-sections.ll
test/MC/WebAssembly/external-data.ll
test/MC/WebAssembly/external-func-address.ll
test/MC/WebAssembly/global-ctor-dtor.ll
test/MC/WebAssembly/reloc-code.ll
test/MC/WebAssembly/reloc-data.ll
test/MC/WebAssembly/reloc-pic.s
test/MC/WebAssembly/unnamed-data.ll
test/MC/WebAssembly/weak-alias.ll
tools/llvm-readobj/WasmDumper.cpp
tools/obj2yaml/wasm2yaml.cpp
tools/yaml2obj/yaml2wasm.cpp

index 02220dbcf0fb9c3f96286e3f9b172ff80a6f5b01..db1bef38892690044c130090cd2fdfa71c1cdf80 100644 (file)
@@ -247,6 +247,7 @@ private:
   Error parseElemSection(ReadContext &Ctx);
   Error parseCodeSection(ReadContext &Ctx);
   Error parseDataSection(ReadContext &Ctx);
+  Error parseDataCountSection(ReadContext &Ctx);
 
   // Custom section types
   Error parseDylinkSection(ReadContext &Ctx);
@@ -273,6 +274,7 @@ private:
   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;
index 60ed1aae1bd8791dd88088fa9d953fbe025fc087..2411dc7ac17d8420420dbc878804e9814509950d 100644 (file)
@@ -379,6 +379,16 @@ struct DataSection : Section {
   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;
index 636770959182755eee69e7767e5cb8cc4210521f..2994772c519e0b1bae84897e6cc547f65fd73dba 100644 (file)
@@ -326,6 +326,7 @@ private:
   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();
@@ -849,6 +850,16 @@ void WasmObjectWriter::writeElemSection(ArrayRef<uint32_t> TableElems) {
   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) {
@@ -1600,6 +1611,7 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
   writeEventSection(Events);
   writeExportSection(Exports);
   writeElemSection(TableElems);
+  writeDataCountSection();
   writeCodeSection(Asm, Layout, Functions);
   writeDataSection();
   for (auto &CustomSection : CustomSections)
index 16645002a6d698de0a5dce3d0f53258e44ba18ad..167b8c25c2ba2ac8bda1d7c9e289d53323f51ad5 100644 (file)
@@ -316,6 +316,8 @@ Error WasmObjectFile::parseSection(WasmSection &Sec) {
     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);
@@ -1201,6 +1203,9 @@ Error WasmObjectFile::parseElemSection(ReadContext &Ctx) {
 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;
@@ -1234,6 +1239,11 @@ Error WasmObjectFile::parseDataSection(ReadContext &Ctx) {
   return Error::success();
 }
 
+Error WasmObjectFile::parseDataCountSection(ReadContext &Ctx) {
+  DataCount = readVaruint32(Ctx);
+  return Error::success();
+}
+
 const wasm::WasmObjectHeader &WasmObjectFile::getHeader() const {
   return Header;
 }
@@ -1399,6 +1409,7 @@ std::error_code WasmObjectFile::getSectionName(DataRefImpl Sec,
     ECase(ELEM);
     ECase(CODE);
     ECase(DATA);
+    ECase(DATACOUNT);
   case wasm::WASM_SEC_CUSTOM:
     Res = S.Name;
     break;
index 3841c5b7712c3c3ac1255a240c0e299ce2fd6bd6..19c7f54aed933b77b4f4382801ae96120abbdfb9 100644 (file)
@@ -153,6 +153,11 @@ static void sectionMapping(IO &IO, WasmYAML::DataSection &Section) {
   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;
@@ -257,6 +262,11 @@ void MappingTraits<std::unique_ptr<WasmYAML::Section>>::mapping(
       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");
   }
@@ -278,6 +288,7 @@ void ScalarEnumerationTraits<WasmYAML::SectionType>::enumeration(
   ECase(ELEM);
   ECase(CODE);
   ECase(DATA);
+  ECase(DATACOUNT);
 #undef ECase
 }
 
index b3d95a161d1f051b52cd4b01f317a8425d5ec675..05b6a6986e119980ba82f2a956df919526cc7308 100644 (file)
@@ -9,7 +9,7 @@ target triple = "wasm32-unknown-unknown"
 @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
index 1890589077690cf19882f08510a96a933afc1351..ecc5e5be27a49f8e85623ee66fb26991a028634c 100644 (file)
@@ -50,6 +50,8 @@ define linkonce_odr i32 @sharedFn() #1 comdat($sharedComdat) {
 ; 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
index d4ddd3d496eff65b249f27c3262badd356823ee0..70d9de2bb934133c25042abaf3a0b4707e254b9b 100644 (file)
@@ -53,6 +53,8 @@ test0:
 # 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
@@ -91,4 +93,3 @@ test0:
 # BIN-NEXT:         Alignment:       0
 # BIN-NEXT:         Flags:           [  ]
 # BIN-NEXT: ...
-
index fe4a4cf698319773543f31baaf27101ced305ff0..d0c49b7c836393cec7658f4d3c33bb9c616e1b36 100644 (file)
 ; 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:]
 
index b94190f81436baf325bd17cfbff711f931ccbae6..ae04051f458e0589739789bf4ac2b5946b6996f9 100644 (file)
@@ -10,7 +10,7 @@ target triple = "wasm32-unknown-unknown"
 @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
index c1ebca69c37f1591b95a4cdb358b5098360e797c..3f2129b86ead3fb3782c95e4adea394e3239c7dc 100644 (file)
@@ -10,7 +10,7 @@ target triple = "wasm32-unknown-unknown"
 @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
index 3a9f03bf9e3ab5e017b2acebc571adedf2e7c0e2..9d3b33592e0b98f36ee6876da5e3171cda6b5659 100644 (file)
@@ -58,7 +58,7 @@ define void @call(i32) {
 ; 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
index df7ff92acffa95db7c5b2008dead4d0f7fbca7e5..f506794467c231a5430bd6bbac6e74c63a3e331c 100644 (file)
@@ -61,6 +61,8 @@ declare void @func3()
 ; 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
index 4180d5f5a73d4b9f87f32b9ef9ee1320ff363f67..c16de2ec2a6ee2d85b58c8723cf60aca9048c413 100644 (file)
@@ -24,7 +24,7 @@ entry:
 
 ; 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
index 2c4b206fe9f55527031dbe835db61e6f8ecc1405..aedaa4e58ff900a52cd9857ee6653580154b07e0 100644 (file)
@@ -13,7 +13,7 @@ target triple = "wasm32-unknown-unknown"
 
 ; 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
index 249cd1fb89a4f27a15c77dd591d47c7df6b67342..5a18554167348447d4cbb898a391d460a06f30f9 100644 (file)
@@ -84,6 +84,8 @@ hidden_func:
 # 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
index e645572fdafd2ee1da3416e4fa169c18338698df..836e3e7b5c15fa2ad739404363ffff80ee589d5e 100644 (file)
@@ -9,7 +9,7 @@ target triple = "wasm32-unknown-unknown"
 @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
index 7abdc79b5691b68cd388e43b0def7b041d953900..20a27edd343a204393acb9b41771513e0bbb5517 100644 (file)
@@ -73,6 +73,8 @@ entry:
 ; 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
index edcd0731553d10e20fccc5758d3bad4efeed1eb5..e232d1124ddfa4b04cbcc35bd039a2c57bd5cbaf 100644 (file)
@@ -32,11 +32,11 @@ static const EnumEntry<unsigned> WasmSymbolTypes[] = {
 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
 };
 
index eacbe621e0ef15955e3fe8364da3897f9205529b..47d984b53fb81265069fd257f63c79c60c5e0a4c 100644 (file)
@@ -353,6 +353,12 @@ ErrorOr<WasmYAML::Object *> WasmDumper::dump() {
       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;
index 322ac0117badd6fad04026368a3f021b773add66..cd07a30b74873692c80cf6d4217770bafc9cd6db 100644 (file)
@@ -43,6 +43,7 @@ private:
   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);
@@ -514,6 +515,12 @@ int WasmWriter::writeSectionContent(raw_ostream &OS,
   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) {
@@ -614,6 +621,9 @@ int WasmWriter::writeWasm(raw_ostream &OS) {
     } 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;