[lld] [lld][Wasm] Do not emit relocs against dead symbols (PR #129346)

Derek Schuff via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 28 17:54:34 PST 2025


https://github.com/dschuff updated https://github.com/llvm/llvm-project/pull/129346

>From 8436f5a0a0b4c96c011e1b1533a133b683b4d996 Mon Sep 17 00:00:00 2001
From: Derek Schuff <dschuff at chromium.org>
Date: Mon, 24 Feb 2025 15:02:19 -0800
Subject: [PATCH 1/2] [lld][Wasm] Do not emit relocs against dead symbols

When emitting relocs with linked output (i.e. --emit-relocs)
skip relocs against dead symbols (which donot appear in the output)
and do not emit them.
---
 lld/test/wasm/emit-relocs.s | 15 +++++++++++++++
 lld/wasm/InputChunks.cpp    | 15 +++++++++++++++
 lld/wasm/InputChunks.h      |  1 +
 lld/wasm/OutputSections.cpp |  2 +-
 lld/wasm/OutputSections.h   |  1 +
 lld/wasm/Symbols.cpp        |  2 +-
 6 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/lld/test/wasm/emit-relocs.s b/lld/test/wasm/emit-relocs.s
index bd136ba810b5e..385344cb23321 100644
--- a/lld/test/wasm/emit-relocs.s
+++ b/lld/test/wasm/emit-relocs.s
@@ -27,6 +27,12 @@ foo:
   .int32  0
   .size   foo, 4
 
+.section .debug_info,"",@
+.p2align 2
+.int32 unused_function
+.int32 _start
+.int32 0
+
 # CHECK:        - Type:            CODE
 # CHECK-NEXT:     Relocations:
 # CHECK-NEXT:       - Type:            R_WASM_FUNCTION_INDEX_LEB
@@ -42,6 +48,15 @@ foo:
 # CHECK-NEXT:           Value:           1024
 # CHECK-NEXT:         Content:         '00000000'
 
+# There should be a single relocation in this section (just the live symbol)
+# CHECK-NEXT:  - Type:            CUSTOM
+# CHECK-NEXT:    Relocations:
+# CHECK-NEXT:      - Type:            R_WASM_FUNCTION_OFFSET_I32
+# CHECK-NEXT:        Index:           0
+# CHECK-NEXT:        Offset:          0x4
+# CHECK-NEXT:    Name:            .debug_info
+# CHECK-NEXT:    Payload:         FFFFFFFF0200000000000000
+
 # CHECK:        - Type:            CUSTOM
 # CHECK-NEXT:     Name:            linking
 # CHECK-NEXT:     Version:         2
diff --git a/lld/wasm/InputChunks.cpp b/lld/wasm/InputChunks.cpp
index ccdc92f5c8d71..0558f64aa7c42 100644
--- a/lld/wasm/InputChunks.cpp
+++ b/lld/wasm/InputChunks.cpp
@@ -167,6 +167,19 @@ void InputChunk::relocate(uint8_t *buf) const {
   }
 }
 
+static bool relocIsLive(const WasmRelocation& rel, ObjFile* file) {
+  return rel.Type == R_WASM_TYPE_INDEX_LEB ||
+    file->getSymbol(rel.Index)->isLive();
+}
+
+size_t InputChunk::getNumLiveRelocations() const {
+  size_t result = 0;
+  for (const WasmRelocation& rel : relocations) {
+    if (relocIsLive(rel, file)) result ++;
+  }
+  return result;
+}
+
 // Copy relocation entries to a given output stream.
 // This function is used only when a user passes "-r". For a regular link,
 // we consume relocations instead of copying them to an output file.
@@ -179,6 +192,8 @@ void InputChunk::writeRelocations(raw_ostream &os) const {
                     << " offset=" << Twine(off) << "\n");
 
   for (const WasmRelocation &rel : relocations) {
+    if (!relocIsLive(rel, file))
+      continue;
     writeUleb128(os, rel.Type, "reloc type");
     writeUleb128(os, rel.Offset + off, "reloc offset");
     writeUleb128(os, file->calcNewIndex(rel), "reloc index");
diff --git a/lld/wasm/InputChunks.h b/lld/wasm/InputChunks.h
index f545449e1246f..1fe78d76631f1 100644
--- a/lld/wasm/InputChunks.h
+++ b/lld/wasm/InputChunks.h
@@ -77,6 +77,7 @@ class InputChunk {
   uint32_t getInputSectionOffset() const { return inputSectionOffset; }
 
   size_t getNumRelocations() const { return relocations.size(); }
+  size_t getNumLiveRelocations() const;
   void writeRelocations(llvm::raw_ostream &os) const;
   bool generateRelocationCode(raw_ostream &os) const;
 
diff --git a/lld/wasm/OutputSections.cpp b/lld/wasm/OutputSections.cpp
index d679d1e676479..5038cd8ea965b 100644
--- a/lld/wasm/OutputSections.cpp
+++ b/lld/wasm/OutputSections.cpp
@@ -274,7 +274,7 @@ void CustomSection::writeTo(uint8_t *buf) {
 uint32_t CustomSection::getNumRelocations() const {
   uint32_t count = 0;
   for (const InputChunk *inputSect : inputSections)
-    count += inputSect->getNumRelocations();
+    count += inputSect->getNumLiveRelocations();
   return count;
 }
 
diff --git a/lld/wasm/OutputSections.h b/lld/wasm/OutputSections.h
index fcc8cf45dc73b..4b0329dd16cf2 100644
--- a/lld/wasm/OutputSections.h
+++ b/lld/wasm/OutputSections.h
@@ -41,6 +41,7 @@ class OutputSection {
   virtual void writeTo(uint8_t *buf) = 0;
   virtual void finalizeContents() = 0;
   virtual uint32_t getNumRelocations() const { return 0; }
+  virtual uint32_t getNumLiveRelocations() const { return getNumRelocations(); }
   virtual void writeRelocations(raw_ostream &os) const {}
 
   std::string header;
diff --git a/lld/wasm/Symbols.cpp b/lld/wasm/Symbols.cpp
index a687fd6d6c4ef..09f110d0885f6 100644
--- a/lld/wasm/Symbols.cpp
+++ b/lld/wasm/Symbols.cpp
@@ -183,7 +183,7 @@ void Symbol::markLive() {
 }
 
 uint32_t Symbol::getOutputSymbolIndex() const {
-  assert(outputSymbolIndex != INVALID_INDEX);
+  assert(outputSymbolIndex != INVALID_INDEX || !isLive());
   return outputSymbolIndex;
 }
 

>From d295ede36dee9fbd32524a7700af0f7aa9518063 Mon Sep 17 00:00:00 2001
From: Derek Schuff <dschuff at chromium.org>
Date: Sat, 1 Mar 2025 01:54:19 +0000
Subject: [PATCH 2/2] clang-format

---
 lld/wasm/InputChunks.cpp | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/lld/wasm/InputChunks.cpp b/lld/wasm/InputChunks.cpp
index 0558f64aa7c42..7a8409ffc2dd9 100644
--- a/lld/wasm/InputChunks.cpp
+++ b/lld/wasm/InputChunks.cpp
@@ -167,15 +167,16 @@ void InputChunk::relocate(uint8_t *buf) const {
   }
 }
 
-static bool relocIsLive(const WasmRelocation& rel, ObjFile* file) {
+static bool relocIsLive(const WasmRelocation &rel, ObjFile *file) {
   return rel.Type == R_WASM_TYPE_INDEX_LEB ||
-    file->getSymbol(rel.Index)->isLive();
+         file->getSymbol(rel.Index)->isLive();
 }
 
 size_t InputChunk::getNumLiveRelocations() const {
   size_t result = 0;
-  for (const WasmRelocation& rel : relocations) {
-    if (relocIsLive(rel, file)) result ++;
+  for (const WasmRelocation &rel : relocations) {
+    if (relocIsLive(rel, file))
+      result++;
   }
   return result;
 }



More information about the llvm-commits mailing list