[lld] dd6412c - [WebAssembly][lld] Exclude COMDAT sections

Derek Schuff via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 10 17:49:39 PST 2020


Author: Derek Schuff
Date: 2020-12-10T17:47:41-08:00
New Revision: dd6412c05c1039e582a970da1aee62cdde75c892

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

LOG: [WebAssembly][lld] Exclude COMDAT sections

Allow exclusion/discarding of custom sections with COMDAT groups.
It piggybacks on the existing COMDAT-handling code, but applies to custom sections as well.

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

Added: 
    lld/test/wasm/Inputs/comdat1.s
    lld/test/wasm/Inputs/comdat2.s
    lld/test/wasm/comdat-sections.s

Modified: 
    lld/wasm/InputChunks.h
    lld/wasm/InputFiles.cpp
    lld/wasm/OutputSections.cpp
    lld/wasm/Writer.cpp

Removed: 
    


################################################################################
diff  --git a/lld/test/wasm/Inputs/comdat1.s b/lld/test/wasm/Inputs/comdat1.s
new file mode 100644
index 000000000000..ff988ccef20f
--- /dev/null
+++ b/lld/test/wasm/Inputs/comdat1.s
@@ -0,0 +1,13 @@
+        .text
+        .section .text.foo,"G",@,foo,comdat
+        .globl foo
+        .type foo, at function
+foo:
+        .functype foo () -> ()
+        return
+        end_function
+
+        .section .debug_foo,"G",@,foo,comdat
+        .int32 1
+        .section .debug_foo,"G",@,duplicate,comdat
+        .int64 123

diff  --git a/lld/test/wasm/Inputs/comdat2.s b/lld/test/wasm/Inputs/comdat2.s
new file mode 100644
index 000000000000..f498fdd105d6
--- /dev/null
+++ b/lld/test/wasm/Inputs/comdat2.s
@@ -0,0 +1,13 @@
+        .text
+        .section .text.foo,"G",@,foo,comdat
+        .globl foo
+        .type foo, at function
+foo:
+        .functype foo () -> ()
+        return
+        end_function
+
+        .section .debug_foo,"G",@,foo,comdat
+        .int32 2
+        .section .debug_foo,"G",@,duplicate,comdat
+        .int64 234

diff  --git a/lld/test/wasm/comdat-sections.s b/lld/test/wasm/comdat-sections.s
new file mode 100644
index 000000000000..fc8d2ded1980
--- /dev/null
+++ b/lld/test/wasm/comdat-sections.s
@@ -0,0 +1,22 @@
+# RUN: llvm-mc -triple=wasm32 -filetype=obj %p/Inputs/comdat1.s -o %t1.o
+# RUN: llvm-mc -triple=wasm32 -filetype=obj %p/Inputs/comdat2.s -o %t2.o
+# RUN: llvm-mc -triple=wasm32 -filetype=obj %s -o %t.o
+# RUN: wasm-ld  -o %t.wasm %t.o %t1.o %t2.o
+# RUN: obj2yaml %t.wasm | FileCheck %s
+
+
+        .globl  _start
+        .type  _start, at function
+_start:
+        .functype _start () -> ()
+        call foo
+        end_function
+
+        .functype foo () -> ()
+
+
+# Check that we got 1 copy of each of the .debug_foo sections from the 2 object
+# files, and that they came from the same object.
+# CHECK:  - Type:            CUSTOM
+# CHECK-NEXT:    Name:            .debug_foo
+# CHECK-NEXT:    Payload:         010000007B00000000000000

diff  --git a/lld/wasm/InputChunks.h b/lld/wasm/InputChunks.h
index ba4e2a591074..9082d1dada5f 100644
--- a/lld/wasm/InputChunks.h
+++ b/lld/wasm/InputChunks.h
@@ -221,7 +221,7 @@ class InputSection : public InputChunk {
 
   StringRef getName() const override { return section.Name; }
   StringRef getDebugName() const override { return StringRef(); }
-  uint32_t getComdat() const override { return UINT32_MAX; }
+  uint32_t getComdat() const override { return section.Comdat; }
 
 protected:
   ArrayRef<uint8_t> data() const override { return section.Content; }

diff  --git a/lld/wasm/InputFiles.cpp b/lld/wasm/InputFiles.cpp
index 2b3c2591058c..68a9472819e4 100644
--- a/lld/wasm/InputFiles.cpp
+++ b/lld/wasm/InputFiles.cpp
@@ -341,6 +341,12 @@ void ObjFile::parse(bool ignoreComdats) {
     }
   }
 
+  ArrayRef<StringRef> comdats = wasmObj->linkingData().Comdats;
+  for (StringRef comdat : comdats) {
+    bool isNew = ignoreComdats || symtab->addComdat(comdat);
+    keptComdats.push_back(isNew);
+  }
+
   uint32_t sectionIndex = 0;
 
   // Bool for each symbol, true if called directly.  This allows us to implement
@@ -360,7 +366,9 @@ void ObjFile::parse(bool ignoreComdats) {
       assert(!dataSection);
       dataSection = §ion;
     } else if (section.Type == WASM_SEC_CUSTOM) {
-      customSections.emplace_back(make<InputSection>(section, this));
+      auto *customSec = make<InputSection>(section, this);
+      customSec->discarded = isExcludedByComdat(customSec);
+      customSections.emplace_back(customSec);
       customSections.back()->setRelocations(section.Relocations);
       customSectionsByIndex[sectionIndex] = customSections.back();
     }
@@ -374,11 +382,6 @@ void ObjFile::parse(bool ignoreComdats) {
   typeMap.resize(getWasmObj()->types().size());
   typeIsUsed.resize(getWasmObj()->types().size(), false);
 
-  ArrayRef<StringRef> comdats = wasmObj->linkingData().Comdats;
-  for (StringRef comdat : comdats) {
-    bool isNew = ignoreComdats || symtab->addComdat(comdat);
-    keptComdats.push_back(isNew);
-  }
 
   // Populate `Segments`.
   for (const WasmSegment &s : wasmObj->dataSegments()) {
@@ -487,6 +490,10 @@ Symbol *ObjFile::createDefined(const WasmSymbol &sym) {
   case WASM_SYMBOL_TYPE_SECTION: {
     InputSection *section = customSectionsByIndex[sym.Info.ElementIndex];
     assert(sym.isBindingLocal());
+    // Need to return null if discarded here? data and func only do that when
+    // binding is not local.
+    if (section->discarded)
+      return nullptr;
     return make<SectionSymbol>(flags, section, this);
   }
   case WASM_SYMBOL_TYPE_EVENT: {

diff  --git a/lld/wasm/OutputSections.cpp b/lld/wasm/OutputSections.cpp
index 89f51ec467b1..1af448dcea74 100644
--- a/lld/wasm/OutputSections.cpp
+++ b/lld/wasm/OutputSections.cpp
@@ -239,6 +239,7 @@ void CustomSection::finalizeContents() {
   os.flush();
 
   for (InputSection *section : inputSections) {
+    assert(!section->discarded);
     section->outputSec = this;
     section->outputOffset = payloadSize;
     payloadSize += section->getSize();

diff  --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp
index 3f255966f8db..c95b92504634 100644
--- a/lld/wasm/Writer.cpp
+++ b/lld/wasm/Writer.cpp
@@ -120,6 +120,9 @@ void Writer::calculateCustomSections() {
   bool stripDebug = config->stripDebug || config->stripAll;
   for (ObjFile *file : symtab->objectFiles) {
     for (InputSection *section : file->customSections) {
+      // Exclude COMDAT sections that are not selected for inclusion
+      if (section->discarded)
+        continue;
       StringRef name = section->getName();
       // These custom sections are known the linker and synthesized rather than
       // blindly copied.


        


More information about the llvm-commits mailing list