[llvm] 0a39106 - [WebAssembly] Add Object and ObjectWriter support for wasm COMDAT sections

Derek Schuff via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 7 12:14:09 PST 2020


Author: Derek Schuff
Date: 2020-12-07T12:12:44-08:00
New Revision: 0a391060f16dc3e10bcb0b02036073021c414006

URL: https://github.com/llvm/llvm-project/commit/0a391060f16dc3e10bcb0b02036073021c414006
DIFF: https://github.com/llvm/llvm-project/commit/0a391060f16dc3e10bcb0b02036073021c414006.diff

LOG: [WebAssembly] Add Object and ObjectWriter support for wasm COMDAT sections

Allow sections to be placed into COMDAT groups, in addtion to functions and data
segments.

Also make section symbols unnamed, which allows sections with identical names
(section names are independent of their section symbols, but previously we
gave the symbols the same name as their sections, which results in collisions
when sections are identically-named).

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

Added: 
    llvm/test/MC/WebAssembly/comdat-sections.ll

Modified: 
    llvm/include/llvm/BinaryFormat/Wasm.h
    llvm/include/llvm/Object/Wasm.h
    llvm/lib/MC/MCContext.cpp
    llvm/lib/MC/MCObjectFileInfo.cpp
    llvm/lib/MC/WasmObjectWriter.cpp
    llvm/lib/Object/WasmObjectFile.cpp
    llvm/lib/ObjectYAML/WasmYAML.cpp
    llvm/test/DebugInfo/WebAssembly/dwarf-headers.ll
    llvm/tools/obj2yaml/wasm2yaml.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/BinaryFormat/Wasm.h b/llvm/include/llvm/BinaryFormat/Wasm.h
index d93587593ac3..760ddf5a2368 100644
--- a/llvm/include/llvm/BinaryFormat/Wasm.h
+++ b/llvm/include/llvm/BinaryFormat/Wasm.h
@@ -330,6 +330,8 @@ enum : unsigned {
 enum : unsigned {
   WASM_COMDAT_DATA = 0x0,
   WASM_COMDAT_FUNCTION = 0x1,
+  // GLOBAL, EVENT, and TABLE are in here but LLVM doesn't use them yet.
+  WASM_COMDAT_SECTION = 0x5,
 };
 
 // Kind codes used in the custom "linking" section in the WASM_SYMBOL_TABLE

diff  --git a/llvm/include/llvm/Object/Wasm.h b/llvm/include/llvm/Object/Wasm.h
index e5091f5a8552..089046d7d42f 100644
--- a/llvm/include/llvm/Object/Wasm.h
+++ b/llvm/include/llvm/Object/Wasm.h
@@ -108,6 +108,7 @@ struct WasmSection {
   uint32_t Type = 0;         // Section type (See below)
   uint32_t Offset = 0;       // Offset with in the file
   StringRef Name;            // Section name (User-defined sections only)
+  uint32_t Comdat = UINT32_MAX; // From the "comdat info" section
   ArrayRef<uint8_t> Content; // Section content
   std::vector<wasm::WasmRelocation> Relocations; // Relocations for this section
 };

diff  --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index 8b2925157ba5..fe84283a9112 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -644,7 +644,7 @@ MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind Kind,
 
   StringRef CachedName = Entry.first.SectionName;
 
-  MCSymbol *Begin = createSymbol(CachedName, false, false);
+  MCSymbol *Begin = createSymbol(CachedName, true, false);
   cast<MCSymbolWasm>(Begin)->setType(wasm::WASM_SYMBOL_TYPE_SECTION);
 
   MCSectionWasm *Result = new (WasmAllocator.Allocate())

diff  --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index a67e4b33a33b..af1d7c099668 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -974,9 +974,6 @@ MCSection *MCObjectFileInfo::getDwarfComdatSection(const char *Name,
     return Ctx->getELFSection(Name, ELF::SHT_PROGBITS, ELF::SHF_GROUP, 0,
                               utostr(Hash));
   case Triple::Wasm:
-    // FIXME: When using dwarf 5, the .debug_info section is used for type units
-    // but that section already exists, so attempting to get it as a comdate
-    // section triggers an assert.
     return Ctx->getWasmSection(Name, SectionKind::getMetadata(), utostr(Hash),
                                MCContext::GenericSectionID);
   case Triple::MachO:

diff  --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp
index 211f0de3d242..77df4acfe11a 100644
--- a/llvm/lib/MC/WasmObjectWriter.cpp
+++ b/llvm/lib/MC/WasmObjectWriter.cpp
@@ -1421,6 +1421,16 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
         continue;
       }
 
+      // Custom sections can also belong to COMDAT groups. In this case the
+      // decriptor's "index" field is the section index (in the final object
+      // file), but that is not known until after layout, so it must be fixed up
+      // later
+      if (const MCSymbolWasm *C = Section.getGroup()) {
+        Comdats[C->getName()].emplace_back(
+            WasmComdatEntry{wasm::WASM_COMDAT_SECTION,
+                            static_cast<uint32_t>(CustomSections.size())});
+      }
+
       CustomSections.emplace_back(Name, &Section);
     }
   }
@@ -1799,9 +1809,17 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
     DataSectionIndex = writeDataSection(Layout);
   }
 
-  for (auto &CustomSection : CustomSections) {
-    writeCustomSection(CustomSection, Asm, Layout);
+  // The Sections in the COMDAT list have placeholder indices (their index among
+  // custom sections, rather than among all sections). Fix them up here.
+  for (auto &Group : Comdats) {
+    for (auto &Entry : Group.second) {
+      if (Entry.Kind == wasm::WASM_COMDAT_SECTION) {
+        Entry.Index += SectionCount;
+      }
+    }
   }
+  for (auto &CustomSection : CustomSections)
+    writeCustomSection(CustomSection, Asm, Layout);
 
   if (Mode != DwoMode::DwoOnly) {
     writeLinkingMetaDataSection(SymbolInfos, InitFuncs, Comdats);

diff  --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp
index eb1f3983b578..7c8abcbd76fa 100644
--- a/llvm/lib/Object/WasmObjectFile.cpp
+++ b/llvm/lib/Object/WasmObjectFile.cpp
@@ -745,6 +745,15 @@ Error WasmObjectFile::parseLinkingSectionComdat(ReadContext &Ctx) {
                                                 object_error::parse_failed);
         getDefinedFunction(Index).Comdat = ComdatIndex;
         break;
+      case wasm::WASM_COMDAT_SECTION:
+        if (Index >= Sections.size())
+          return make_error<GenericBinaryError>(
+              "COMDAT section index out of range", object_error::parse_failed);
+        if (Sections[Index].Type != wasm::WASM_SEC_CUSTOM)
+          return make_error<GenericBinaryError>(
+              "Non-custom section in a COMDAT", object_error::parse_failed);
+        Sections[Index].Comdat = ComdatIndex;
+        break;
       }
     }
   }

diff  --git a/llvm/lib/ObjectYAML/WasmYAML.cpp b/llvm/lib/ObjectYAML/WasmYAML.cpp
index 5898ece19667..a6ad5c3e0b8d 100644
--- a/llvm/lib/ObjectYAML/WasmYAML.cpp
+++ b/llvm/lib/ObjectYAML/WasmYAML.cpp
@@ -472,6 +472,7 @@ void ScalarEnumerationTraits<WasmYAML::ComdatKind>::enumeration(
 #define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_COMDAT_##X);
   ECase(FUNCTION);
   ECase(DATA);
+  ECase(SECTION);
 #undef ECase
 }
 

diff  --git a/llvm/test/DebugInfo/WebAssembly/dwarf-headers.ll b/llvm/test/DebugInfo/WebAssembly/dwarf-headers.ll
index fa244d99735d..b2be5487b9cd 100644
--- a/llvm/test/DebugInfo/WebAssembly/dwarf-headers.ll
+++ b/llvm/test/DebugInfo/WebAssembly/dwarf-headers.ll
@@ -8,17 +8,15 @@
 ; RUN:     | llvm-dwarfdump -v - | FileCheck %s --check-prefix=O-4
 ; RUN: llvm-dwarfdump -v %t.dwo | FileCheck %s --check-prefix=DWO-4
 
-; TODO: enable testing for dwarf v5 with type units
-; (See the FIXME in MCObjectFileInfo::getDwarfComdatSection)
-; RU N: llc -dwarf-version=5 -generate-type-units \
-; RU N:     -filetype=obj -O0 -mtriple= < %s \
-; RU N:     | llvm-dwarfdump -v - | FileCheck %s --check-prefix=SINGLE-5
-
-; RU N: llc -split-dwarf-file=foo.dwo -split-dwarf-output=%t.dwo \
-; RU N:     -dwarf-version=5 -generate-type-units \
-; RU N:     -filetype=obj -O0 -mtriple= < %s \
-; RU N:     | llvm-dwarfdump -v - | FileCheck %s --check-prefix=O-5
-; RU N: llvm-dwarfdump -v %t.dwo | FileCheck %s --check-prefix=DWO-5
+; RUN: llc -dwarf-version=5 -generate-type-units \
+; RUN:     -filetype=obj -O0 -mtriple= < %s \
+; RUN:     | llvm-dwarfdump -v - | FileCheck %s --check-prefix=SINGLE-5
+
+; RUN: llc -split-dwarf-file=foo.dwo -split-dwarf-output=%t.dwo \
+; RUN:     -dwarf-version=5 -generate-type-units \
+; RUN:     -filetype=obj -O0 -mtriple= < %s \
+; RUN:     | llvm-dwarfdump -v - | FileCheck %s --check-prefix=O-5
+; RUN: llvm-dwarfdump -v %t.dwo | FileCheck %s --check-prefix=DWO-5
 
 ; This test is derived from test/CodeGen/X86/dwarf-headers.ll
 

diff  --git a/llvm/test/MC/WebAssembly/comdat-sections.ll b/llvm/test/MC/WebAssembly/comdat-sections.ll
new file mode 100644
index 000000000000..75381ff6f904
--- /dev/null
+++ b/llvm/test/MC/WebAssembly/comdat-sections.ll
@@ -0,0 +1,37 @@
+; RUN: llc -dwarf-version=4 -generate-type-units \
+; RUN:     -filetype=obj -O0 -mtriple=wasm32-unknown-unknown < %s \
+; RUN:     | obj2yaml | FileCheck %s
+
+
+; CHECK:     Comdats:
+; CHECK:      - Name:            '4721183873463917179'
+; CHECK:        Entries:
+; CHECK:          - Kind:            SECTION
+; CHECK:            Index:           3
+
+; ModuleID = 't.cpp'
+source_filename = "t.cpp"
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown-wasm"
+
+%struct.S = type { i32 }
+
+ at s = global %struct.S zeroinitializer, align 4, !dbg !0
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!10, !11}
+!llvm.ident = !{!12}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "s", scope: !2, file: !3, line: 5, type: !6, isLocal: false, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 5.0.0 (trunk 295942)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5)
+!3 = !DIFile(filename: "t.cpp", directory: "/home/probinson/projects/scratch")
+!4 = !{}
+!5 = !{!0}
+!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S", file: !3, line: 1, size: 32, elements: !7, identifier: "_ZTS1S")
+!7 = !{!8}
+!8 = !DIDerivedType(tag: DW_TAG_member, name: "s1", scope: !6, file: !3, line: 2, baseType: !9, size: 32)
+!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!10 = !{i32 2, !"Dwarf Version", i32 4}
+!11 = !{i32 2, !"Debug Info Version", i32 3}
+!12 = !{!"clang version 5.0.0 (trunk 295942)"}

diff  --git a/llvm/tools/obj2yaml/wasm2yaml.cpp b/llvm/tools/obj2yaml/wasm2yaml.cpp
index d47b7bee199b..91855c30653d 100644
--- a/llvm/tools/obj2yaml/wasm2yaml.cpp
+++ b/llvm/tools/obj2yaml/wasm2yaml.cpp
@@ -107,6 +107,14 @@ WasmDumper::dumpCustomSection(const WasmSection &WasmSec) {
       }
       SegmentIndex++;
     }
+    uint32_t SectionIndex = 0;
+    for (const auto &Sec : Obj.sections()) {
+      const WasmSection &WasmSec = Obj.getWasmSection(Sec);
+      if (WasmSec.Comdat != UINT32_MAX)
+        LinkingSec->Comdats[WasmSec.Comdat].Entries.emplace_back(
+            WasmYAML::ComdatEntry{wasm::WASM_COMDAT_SECTION, SectionIndex});
+      SectionIndex++;
+    }
 
     uint32_t SymbolIndex = 0;
     for (const wasm::WasmSymbolInfo &Symbol : Obj.linkingData().SymbolTable) {


        


More information about the llvm-commits mailing list