Reland "[WebAssembly] Add support for naming wasm data segments"

Add adds support for naming data segments.  This is useful
useful linkers so that they can merge similar sections.

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

llvm-svn: 313795
diff --git a/llvm/tools/llvm-readobj/WasmDumper.cpp b/llvm/tools/llvm-readobj/WasmDumper.cpp
index 88fcbf6..3bff4b8 100644
--- a/llvm/tools/llvm-readobj/WasmDumper.cpp
+++ b/llvm/tools/llvm-readobj/WasmDumper.cpp
@@ -148,7 +148,7 @@
     const WasmSection &WasmSec = Obj->getWasmSection(Section);
     DictScope SectionD(W, "Section");
     W.printEnum("Type", WasmSec.Type, makeArrayRef(WasmSectionTypes));
-    W.printNumber("Size", (uint64_t)WasmSec.Content.size());
+    W.printNumber("Size", static_cast<uint64_t>(WasmSec.Content.size()));
     W.printNumber("Offset", WasmSec.Offset);
     switch (WasmSec.Type) {
     case wasm::WASM_SEC_CUSTOM:
@@ -160,6 +160,19 @@
           W.printNumber("DataAlignment", LinkingData.DataAlignment);
       }
       break;
+    case wasm::WASM_SEC_DATA: {
+      ListScope Group(W, "Segments");
+      for (const WasmSegment &Segment : Obj->dataSegments()) {
+        const wasm::WasmDataSegment& Seg = Segment.Data;
+        DictScope Group(W, "Segment");
+        if (!Seg.Name.empty())
+          W.printString("Name", Seg.Name);
+        W.printNumber("Size", static_cast<uint64_t>(Seg.Content.size()));
+        if (Seg.Offset.Opcode == wasm::WASM_OPCODE_I32_CONST)
+          W.printNumber("Offset", Seg.Offset.Value.Int32);
+      }
+      break;
+    }
     case wasm::WASM_SEC_MEMORY:
       ListScope Group(W, "Memories");
       for (const wasm::WasmLimits &Memory : Obj->memories()) {
diff --git a/llvm/tools/obj2yaml/wasm2yaml.cpp b/llvm/tools/obj2yaml/wasm2yaml.cpp
index a1da4b6..8b2a0ad 100644
--- a/llvm/tools/obj2yaml/wasm2yaml.cpp
+++ b/llvm/tools/obj2yaml/wasm2yaml.cpp
@@ -70,6 +70,16 @@
     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) {
@@ -234,7 +244,7 @@
     }
     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;
diff --git a/llvm/tools/yaml2obj/yaml2wasm.cpp b/llvm/tools/yaml2obj/yaml2wasm.cpp
index 0bd8829..9dd7564 100644
--- a/llvm/tools/yaml2obj/yaml2wasm.cpp
+++ b/llvm/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;
 }