[llvm-branch-commits] [llvm] 9a72d3e - [WebAssembly] Add support for named data sections in wasm binaries

Sam Clegg via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Dec 9 13:06:10 PST 2020


Author: Sam Clegg
Date: 2020-12-09T12:57:07-08:00
New Revision: 9a72d3e3e456ffa9cfb4e0b2c2e81da78bb15dd3

URL: https://github.com/llvm/llvm-project/commit/9a72d3e3e456ffa9cfb4e0b2c2e81da78bb15dd3
DIFF: https://github.com/llvm/llvm-project/commit/9a72d3e3e456ffa9cfb4e0b2c2e81da78bb15dd3.diff

LOG: [WebAssembly] Add support for named data sections in wasm binaries

Followup to https://reviews.llvm.org/D91769 which added support
for names globals.

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

Added: 
    

Modified: 
    lld/test/wasm/call-indirect.ll
    lld/test/wasm/data-segment-merging.ll
    lld/test/wasm/gc-sections.ll
    lld/test/wasm/local-symbols.ll
    lld/test/wasm/locals-duplicate.test
    lld/test/wasm/map-file.s
    lld/test/wasm/signature-mismatch.ll
    lld/test/wasm/weak-symbols.s
    lld/wasm/SyntheticSections.cpp
    lld/wasm/SyntheticSections.h
    lld/wasm/Writer.cpp
    llvm/include/llvm/BinaryFormat/Wasm.h
    llvm/include/llvm/ObjectYAML/WasmYAML.h
    llvm/lib/Object/WasmObjectFile.cpp
    llvm/lib/ObjectYAML/WasmEmitter.cpp
    llvm/lib/ObjectYAML/WasmYAML.cpp
    llvm/tools/obj2yaml/wasm2yaml.cpp

Removed: 
    


################################################################################
diff  --git a/lld/test/wasm/call-indirect.ll b/lld/test/wasm/call-indirect.ll
index 84a84710f2ba..4acc1edae4f2 100644
--- a/lld/test/wasm/call-indirect.ll
+++ b/lld/test/wasm/call-indirect.ll
@@ -156,4 +156,7 @@ define void @call_ptr(i64 (i64)* %arg) {
 ; CHECK-NEXT:     GlobalNames:
 ; CHECK-NEXT:       - Index:           0
 ; CHECK-NEXT:         Name:            __stack_pointer
+; CHECK-NEXT:     DataSegmentNames:
+; CHECK-NEXT:       - Index:           0
+; CHECK-NEXT:         Name:            .data
 ; CHECK-NEXT: ...

diff  --git a/lld/test/wasm/data-segment-merging.ll b/lld/test/wasm/data-segment-merging.ll
index bc347d193574..1dee1ccbda29 100644
--- a/lld/test/wasm/data-segment-merging.ll
+++ b/lld/test/wasm/data-segment-merging.ll
@@ -31,7 +31,9 @@
 ; MERGE-NEXT:    GlobalNames:
 ; MERGE-NEXT:      - Index:           0
 ; MERGE-NEXT:        Name:            __stack_pointer
-; MERGE-NOT:       - Index:
+; MERGE-NEXT:    DataSegmentNames:
+; MERGE-NEXT:      - Index:           0
+; MERGE-NEXT:        Name:            .rodata
 
 ; RUN: wasm-ld -no-gc-sections --no-entry --no-merge-data-segments -o %t.separate.wasm %t.o
 ; RUN: obj2yaml %t.separate.wasm | FileCheck %s --check-prefix=SEPARATE
@@ -71,7 +73,9 @@
 ; SEPARATE-NEXT:    GlobalNames:
 ; SEPARATE-NEXT:      - Index:           0
 ; SEPARATE-NEXT:        Name:            __stack_pointer
-; SEPARATE-NOT:       - Index:
+; SEPARATE-NEXT:    DataSegmentNames:
+; SEPARATE-NEXT:      - Index:           0
+; SEPARATE-NEXT:        Name:            .rodata
 
 ; RUN: wasm-ld -no-gc-sections --no-entry --shared-memory --max-memory=131072 -o %t.merged.passive.wasm %t.passive.o
 ; RUN: obj2yaml %t.merged.passive.wasm | FileCheck %s --check-prefix=PASSIVE-MERGE

diff  --git a/lld/test/wasm/gc-sections.ll b/lld/test/wasm/gc-sections.ll
index 8bac2fd07827..de8298697bf1 100644
--- a/lld/test/wasm/gc-sections.ll
+++ b/lld/test/wasm/gc-sections.ll
@@ -87,6 +87,9 @@ entry:
 ; CHECK-NEXT:         Name:            __stack_pointer
 ; CHECK-NEXT:       - Index:           1
 ; CHECK-NEXT:         Name:            used_global
+; CHECK-NEXT:     DataSegmentNames:
+; CHECK-NEXT:       - Index:           0
+; CHECK-NEXT:         Name:            .data
 ; CHECK-NEXT: ...
 
 ; RUN: wasm-ld -print-gc-sections --no-gc-sections -o %t1.no-gc.wasm \
@@ -162,6 +165,9 @@ entry:
 ; NO-GC-NEXT:         Name:            unused_global
 ; NO-GC-NEXT:       - Index:           2
 ; NO-GC-NEXT:         Name:            used_global
+; NO-GC-NEXT:     DataSegmentNames:
+; NO-GC-NEXT:       - Index:           0
+; NO-GC-NEXT:         Name:            .data
 ; NO-GC-NEXT: ...
 
 ; RUN: not wasm-ld --gc-sections --relocatable -o %t1.no-gc.wasm %t.o 2>&1 | FileCheck %s -check-prefix=CHECK-ERROR

diff  --git a/lld/test/wasm/local-symbols.ll b/lld/test/wasm/local-symbols.ll
index d0a520a950a2..13c200d648e9 100644
--- a/lld/test/wasm/local-symbols.ll
+++ b/lld/test/wasm/local-symbols.ll
@@ -97,4 +97,7 @@ entry:
 ; CHECK-NEXT:     GlobalNames:
 ; CHECK-NEXT:       - Index:           0
 ; CHECK-NEXT:         Name:            __stack_pointer
+; CHECK-NEXT:     DataSegmentNames:
+; CHECK-NEXT:       - Index:           0
+; CHECK-NEXT:         Name:            .data
 ; CHECK-NEXT: ...

diff  --git a/lld/test/wasm/locals-duplicate.test b/lld/test/wasm/locals-duplicate.test
index dc6b9c88be29..07abb7485381 100644
--- a/lld/test/wasm/locals-duplicate.test
+++ b/lld/test/wasm/locals-duplicate.test
@@ -212,6 +212,9 @@
 ; CHECK-NEXT:     GlobalNames:
 ; CHECK-NEXT:       - Index:           0
 ; CHECK-NEXT:         Name:            __stack_pointer
+; CHECK-NEXT:     DataSegmentNames:
+; CHECK-NEXT:       - Index:           0
+; CHECK-NEXT:         Name:            .data
 ; CHECK-NEXT: ...
 
 
@@ -546,4 +549,11 @@
 ; RELOC-NEXT:         Name:            get_func2B
 ; RELOC-NEXT:       - Index:           17
 ; RELOC-NEXT:         Name:            get_func3B
+; RELOC-NEXT:     DataSegmentNames:
+; RELOC-NEXT:       - Index:           0
+; RELOC-NEXT:         Name:            .data.colliding_global1
+; RELOC-NEXT:       - Index:           1
+; RELOC-NEXT:         Name:            .data.colliding_global2
+; RELOC-NEXT:       - Index:           2
+; RELOC-NEXT:         Name:            .data.colliding_global3
 ; RELOC-NEXT: ...

diff  --git a/lld/test/wasm/map-file.s b/lld/test/wasm/map-file.s
index e194662ea5d1..a5bd01605695 100644
--- a/lld/test/wasm/map-file.s
+++ b/lld/test/wasm/map-file.s
@@ -40,7 +40,7 @@ somedata:
 # CHECK-NEXT:     400       5a        4         {{.*}}{{/|\\}}map-file.s.tmp1.o:(.data.somedata)
 # CHECK-NEXT:     400       5a        4                 somedata
 # CHECK-NEXT:       -       60       12 CUSTOM(.debug_info)
-# CHECK-NEXT:       -       72       2b CUSTOM(name)
+# CHECK-NEXT:       -       72       35 CUSTOM(name)
 
 # RUN: not wasm-ld %t1.o -o /dev/null -Map=/ 2>&1 \
 # RUN:  | FileCheck -check-prefix=FAIL %s

diff  --git a/lld/test/wasm/signature-mismatch.ll b/lld/test/wasm/signature-mismatch.ll
index 3e42a74d0f05..d5f95b0073c0 100644
--- a/lld/test/wasm/signature-mismatch.ll
+++ b/lld/test/wasm/signature-mismatch.ll
@@ -55,6 +55,9 @@ declare i32 @ret32(i32, i64, i32) local_unnamed_addr
 ; YAML-NEXT:     GlobalNames:
 ; YAML-NEXT:       - Index:           0
 ; YAML-NEXT:         Name:            __stack_pointer
+; YAML-NEXT:     DataSegmentNames:
+; YAML-NEXT:       - Index:           0
+; YAML-NEXT:         Name:            .data
 ; YAML-NEXT: ...
 
 ;      RELOC:     Name:            linking

diff  --git a/lld/test/wasm/weak-symbols.s b/lld/test/wasm/weak-symbols.s
index 41c8a1a38f55..7557dfb5535b 100644
--- a/lld/test/wasm/weak-symbols.s
+++ b/lld/test/wasm/weak-symbols.s
@@ -116,4 +116,7 @@ _start:
 # CHECK-NEXT:     GlobalNames:
 # CHECK-NEXT:       - Index:           0
 # CHECK-NEXT:         Name:            __stack_pointer
+# CHECK-NEXT:     DataSegmentNames:
+# CHECK-NEXT:       - Index:           0
+# CHECK-NEXT:         Name:            .data
 # CHECK-NEXT: ...

diff  --git a/lld/wasm/SyntheticSections.cpp b/lld/wasm/SyntheticSections.cpp
index 3fdcc6252fd9..95a48528db9e 100644
--- a/lld/wasm/SyntheticSections.cpp
+++ b/lld/wasm/SyntheticSections.cpp
@@ -562,6 +562,16 @@ unsigned NameSection::numNamedGlobals() const {
   return numNames;
 }
 
+unsigned NameSection::numNamedDataSegments() const {
+  unsigned numNames = 0;
+
+  for (const OutputSegment *s : segments)
+    if (!s->name.empty())
+      ++numNames;
+
+  return numNames;
+}
+
 // Create the custom "name" section containing debug symbol names.
 void NameSection::writeBody() {
   unsigned count = numNamedFunctions();
@@ -619,6 +629,19 @@ void NameSection::writeBody() {
 
     sub.writeTo(bodyOutputStream);
   }
+
+  count = numNamedDataSegments();
+  if (count) {
+    SubSection sub(WASM_NAMES_DATA_SEGMENT);
+    writeUleb128(sub.os, count, "name count");
+
+    for (OutputSegment *s : segments) {
+      writeUleb128(sub.os, s->index, "global index");
+      writeStr(sub.os, s->name, "segment name");
+    }
+
+    sub.writeTo(bodyOutputStream);
+  }
 }
 
 void ProducersSection::addInfo(const WasmProducerInfo &info) {

diff  --git a/lld/wasm/SyntheticSections.h b/lld/wasm/SyntheticSections.h
index f9ec7f288dbd..56ba66ffc08d 100644
--- a/lld/wasm/SyntheticSections.h
+++ b/lld/wasm/SyntheticSections.h
@@ -296,7 +296,9 @@ class LinkingSection : public SyntheticSection {
 // Create the custom "name" section containing debug symbol names.
 class NameSection : public SyntheticSection {
 public:
-  NameSection() : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, "name") {}
+  NameSection(ArrayRef<OutputSegment *> segments)
+      : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, "name"),
+        segments(segments) {}
   bool isNeeded() const override {
     return !config->stripDebug && !config->stripAll && numNames() > 0;
   }
@@ -304,6 +306,10 @@ class NameSection : public SyntheticSection {
   unsigned numNames() const { return numNamedGlobals() + numNamedFunctions(); }
   unsigned numNamedGlobals() const;
   unsigned numNamedFunctions() const;
+  unsigned numNamedDataSegments() const;
+
+protected:
+  ArrayRef<OutputSegment *> segments;
 };
 
 class ProducersSection : public SyntheticSection {

diff  --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp
index 851a6d366210..dca6c260d429 100644
--- a/lld/wasm/Writer.cpp
+++ b/lld/wasm/Writer.cpp
@@ -1210,7 +1210,7 @@ void Writer::createSyntheticSections() {
   out.elemSec = make<ElemSection>();
   out.dataCountSec = make<DataCountSection>(segments);
   out.linkingSec = make<LinkingSection>(initFunctions, segments);
-  out.nameSec = make<NameSection>();
+  out.nameSec = make<NameSection>(segments);
   out.producersSec = make<ProducersSection>();
   out.targetFeaturesSec = make<TargetFeaturesSection>();
 }

diff  --git a/llvm/include/llvm/BinaryFormat/Wasm.h b/llvm/include/llvm/BinaryFormat/Wasm.h
index 760ddf5a2368..371e9add880f 100644
--- a/llvm/include/llvm/BinaryFormat/Wasm.h
+++ b/llvm/include/llvm/BinaryFormat/Wasm.h
@@ -202,7 +202,8 @@ struct WasmSymbolInfo {
 
 enum class NameType {
   FUNCTION,
-  GLOBAL
+  GLOBAL,
+  DATA_SEGMENT,
 };
 
 struct WasmDebugName {
@@ -313,9 +314,10 @@ enum : uint8_t {
 
 // Kind codes used in the custom "name" section
 enum : unsigned {
-  WASM_NAMES_FUNCTION = 0x1,
-  WASM_NAMES_LOCAL = 0x2,
-  WASM_NAMES_GLOBAL = 0x7,
+  WASM_NAMES_FUNCTION = 1,
+  WASM_NAMES_LOCAL = 2,
+  WASM_NAMES_GLOBAL = 7,
+  WASM_NAMES_DATA_SEGMENT = 9,
 };
 
 // Kind codes used in the custom "linking" section

diff  --git a/llvm/include/llvm/ObjectYAML/WasmYAML.h b/llvm/include/llvm/ObjectYAML/WasmYAML.h
index 28cd56061a3c..80f1b4006205 100644
--- a/llvm/include/llvm/ObjectYAML/WasmYAML.h
+++ b/llvm/include/llvm/ObjectYAML/WasmYAML.h
@@ -222,6 +222,7 @@ struct NameSection : CustomSection {
 
   std::vector<NameEntry> FunctionNames;
   std::vector<NameEntry> GlobalNames;
+  std::vector<NameEntry> DataSegmentNames;
 };
 
 struct LinkingSection : CustomSection {

diff  --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp
index 7c8abcbd76fa..c9b13e4afb4e 100644
--- a/llvm/lib/Object/WasmObjectFile.cpp
+++ b/llvm/lib/Object/WasmObjectFile.cpp
@@ -357,6 +357,7 @@ Error WasmObjectFile::parseDylinkSection(ReadContext &Ctx) {
 Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
   llvm::DenseSet<uint64_t> SeenFunctions;
   llvm::DenseSet<uint64_t> SeenGlobals;
+  llvm::DenseSet<uint64_t> SeenSegments;
   if (FunctionTypes.size() && !SeenCodeSection) {
     return make_error<GenericBinaryError>("Names must come after code section",
                                           object_error::parse_failed);
@@ -368,11 +369,13 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
     const uint8_t *SubSectionEnd = Ctx.Ptr + Size;
     switch (Type) {
     case wasm::WASM_NAMES_FUNCTION:
-    case wasm::WASM_NAMES_GLOBAL: {
+    case wasm::WASM_NAMES_GLOBAL:
+    case wasm::WASM_NAMES_DATA_SEGMENT: {
       uint32_t Count = readVaruint32(Ctx);
       while (Count--) {
         uint32_t Index = readVaruint32(Ctx);
         StringRef Name = readString(Ctx);
+        wasm::NameType nameType = wasm::NameType::FUNCTION;
         if (Type == wasm::WASM_NAMES_FUNCTION) {
           if (!SeenFunctions.insert(Index).second)
             return make_error<GenericBinaryError>(
@@ -383,18 +386,24 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
 
           if (isDefinedFunctionIndex(Index))
             getDefinedFunction(Index).DebugName = Name;
-        } else {
+        } else if (Type == wasm::WASM_NAMES_GLOBAL) {
+          nameType = wasm::NameType::GLOBAL;
           if (!SeenGlobals.insert(Index).second)
             return make_error<GenericBinaryError>("Global named more than once",
                                                   object_error::parse_failed);
           if (!isValidGlobalIndex(Index) || Name.empty())
             return make_error<GenericBinaryError>("Invalid name entry",
                                                   object_error::parse_failed);
+        } else {
+          nameType = wasm::NameType::DATA_SEGMENT;
+          if (!SeenSegments.insert(Index).second)
+            return make_error<GenericBinaryError>(
+                "Segment named more than once", object_error::parse_failed);
+          if (Index > DataSegments.size())
+            return make_error<GenericBinaryError>("Invalid named data segment",
+                                                  object_error::parse_failed);
         }
-        wasm::NameType T = Type == wasm::WASM_NAMES_FUNCTION
-                               ? wasm::NameType::FUNCTION
-                               : wasm::NameType::GLOBAL;
-        DebugNames.push_back(wasm::WasmDebugName{T, Index, Name});
+        DebugNames.push_back(wasm::WasmDebugName{nameType, Index, Name});
       }
       break;
     }

diff  --git a/llvm/lib/ObjectYAML/WasmEmitter.cpp b/llvm/lib/ObjectYAML/WasmEmitter.cpp
index 64498c82232b..d9f820baaaa3 100644
--- a/llvm/lib/ObjectYAML/WasmEmitter.cpp
+++ b/llvm/lib/ObjectYAML/WasmEmitter.cpp
@@ -281,6 +281,19 @@ void WasmWriter::writeSectionContent(raw_ostream &OS,
       writeStringRef(NameEntry.Name, SubSection.getStream());
     }
 
+    SubSection.done();
+  }
+  if (Section.DataSegmentNames.size()) {
+    writeUint8(OS, wasm::WASM_NAMES_DATA_SEGMENT);
+
+    SubSectionWriter SubSection(OS);
+
+    encodeULEB128(Section.DataSegmentNames.size(), SubSection.getStream());
+    for (const WasmYAML::NameEntry &NameEntry : Section.DataSegmentNames) {
+      encodeULEB128(NameEntry.Index, SubSection.getStream());
+      writeStringRef(NameEntry.Name, SubSection.getStream());
+    }
+
     SubSection.done();
   }
 }

diff  --git a/llvm/lib/ObjectYAML/WasmYAML.cpp b/llvm/lib/ObjectYAML/WasmYAML.cpp
index a6ad5c3e0b8d..69c4fd6cf481 100644
--- a/llvm/lib/ObjectYAML/WasmYAML.cpp
+++ b/llvm/lib/ObjectYAML/WasmYAML.cpp
@@ -62,6 +62,7 @@ static void sectionMapping(IO &IO, WasmYAML::NameSection &Section) {
   IO.mapRequired("Name", Section.Name);
   IO.mapOptional("FunctionNames", Section.FunctionNames);
   IO.mapOptional("GlobalNames", Section.GlobalNames);
+  IO.mapOptional("DataSegmentNames", Section.DataSegmentNames);
 }
 
 static void sectionMapping(IO &IO, WasmYAML::LinkingSection &Section) {

diff  --git a/llvm/tools/obj2yaml/wasm2yaml.cpp b/llvm/tools/obj2yaml/wasm2yaml.cpp
index 91855c30653d..205ec1e01638 100644
--- a/llvm/tools/obj2yaml/wasm2yaml.cpp
+++ b/llvm/tools/obj2yaml/wasm2yaml.cpp
@@ -70,9 +70,11 @@ WasmDumper::dumpCustomSection(const WasmSection &WasmSec) {
       NameEntry.Index = Name.Index;
       if (Name.Type == llvm::wasm::NameType::FUNCTION) {
         NameSec->FunctionNames.push_back(NameEntry);
-      } else {
-        assert(Name.Type == llvm::wasm::NameType::GLOBAL);
+      } else if (Name.Type == llvm::wasm::NameType::GLOBAL) {
         NameSec->GlobalNames.push_back(NameEntry);
+      } else {
+        assert(Name.Type == llvm::wasm::NameType::DATA_SEGMENT);
+        NameSec->DataSegmentNames.push_back(NameEntry);
       }
     }
     CustomSec = std::move(NameSec);


        


More information about the llvm-branch-commits mailing list