[lld] wasm-ld: Add allow-multiple-definition flag (PR #97699)

via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 4 02:22:48 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lld

@llvm/pr-subscribers-lld-wasm

Author: None (mzukovec)

<details>
<summary>Changes</summary>

Add `allow-multiple-definition` flag to `wasm-ld`. This follows the ELF linker logic. In case of duplication, the first symbol met is used.

This PR resolves the #<!-- -->97543 

---
Full diff: https://github.com/llvm/llvm-project/pull/97699.diff


6 Files Affected:

- (added) lld/test/wasm/Inputs/allow-multiple-definition.s (+6) 
- (added) lld/test/wasm/allow-multiple-definition.s (+39) 
- (modified) lld/wasm/Config.h (+1) 
- (modified) lld/wasm/Driver.cpp (+3) 
- (modified) lld/wasm/Options.td (+4) 
- (modified) lld/wasm/SymbolTable.cpp (+8-3) 


``````````diff
diff --git a/lld/test/wasm/Inputs/allow-multiple-definition.s b/lld/test/wasm/Inputs/allow-multiple-definition.s
new file mode 100644
index 0000000000000..7a5577cb12791
--- /dev/null
+++ b/lld/test/wasm/Inputs/allow-multiple-definition.s
@@ -0,0 +1,6 @@
+  .hidden foo
+  .globl  foo
+foo:
+  .functype foo () -> (i32)
+  i32.const 1
+  end_function
diff --git a/lld/test/wasm/allow-multiple-definition.s b/lld/test/wasm/allow-multiple-definition.s
new file mode 100644
index 0000000000000..605ed4965b15b
--- /dev/null
+++ b/lld/test/wasm/allow-multiple-definition.s
@@ -0,0 +1,39 @@
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %s -o %t1
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %p/Inputs/allow-multiple-definition.s -o %t2
+# RUN: llvm-objdump --no-print-imm-hex -d %t1 | FileCheck --check-prefix=DEF1 %s
+# RUN: llvm-objdump --no-print-imm-hex -d %t2 | FileCheck --check-prefix=DEF2 %s
+# RUN: not wasm-ld -o %t.wasm %t1 %t2 2>&1 | FileCheck --check-prefix=DUP1 %s
+# RUN: not wasm-ld -o %t.wasm %t2 %t1 2>&1 | FileCheck --check-prefix=DUP2 %s
+# RUN: wasm-ld --allow-multiple-definition %t1 %t2 -o %t3
+# RUN: llvm-objdump --no-print-imm-hex -d %t3 | FileCheck --check-prefix=RES12 %s
+# RUN: wasm-ld --allow-multiple-definition %t2 %t1 -o %t4
+# RUN: llvm-objdump --no-print-imm-hex -d %t4 | FileCheck --check-prefix=RES21 %s
+
+
+# DUP1: duplicate symbol: foo
+# DUP2: duplicate symbol: foo
+
+# DEF1: i32.const 0
+# DEF2: i32.const 1
+
+# RES12: i32.const 0
+# RES21: i32.const 1
+
+# inputs contain different constants for function foo return.
+# Tests below checks that order of files in command line
+# affects on what symbol will be used.
+# If flag allow-multiple-definition is enabled the first
+# meet symbol should be used.
+
+  .hidden foo
+  .globl  foo
+foo:
+  .functype foo () -> (i32)
+  i32.const 0
+  end_function
+
+	.globl _start
+_start:
+	.functype	_start () -> (i32)
+	call foo
+	end_function
\ No newline at end of file
diff --git a/lld/wasm/Config.h b/lld/wasm/Config.h
index d0ffa83d111e0..f36300cf21e32 100644
--- a/lld/wasm/Config.h
+++ b/lld/wasm/Config.h
@@ -43,6 +43,7 @@ enum class BuildIdKind { None, Fast, Sha1, Hexstring, Uuid };
 // and such fields have the same name as the corresponding options.
 // Most fields are initialized by the driver.
 struct Configuration {
+  bool allowMultipleDefinition;
   bool bsymbolic;
   bool checkFeatures;
   bool compressRelocations;
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index d099689911fc6..3bc64b1ae387d 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -467,6 +467,9 @@ getBuildId(opt::InputArgList &args) {
 
 // Initializes Config members by the command line options.
 static void readConfigs(opt::InputArgList &args) {
+  config->allowMultipleDefinition =
+      args.hasFlag(OPT_allow_multiple_definition,
+                   OPT_no_allow_multiple_definition, false);
   config->bsymbolic = args.hasArg(OPT_Bsymbolic);
   config->checkFeatures =
       args.hasFlag(OPT_check_features, OPT_no_check_features, true);
diff --git a/lld/wasm/Options.td b/lld/wasm/Options.td
index 7e954822ef642..dc08ae6f81310 100644
--- a/lld/wasm/Options.td
+++ b/lld/wasm/Options.td
@@ -42,6 +42,10 @@ def Bdynamic: F<"Bdynamic">, HelpText<"Link against shared libraries">;
 
 def Bstatic: F<"Bstatic">, HelpText<"Do not link against shared libraries (default)">;
 
+defm allow_multiple_definition: B<"allow-multiple-definition",
+    "Allow multiple definitions",
+    "Do not allow multiple definitions (default)">;
+
 def build_id: F<"build-id">, HelpText<"Alias for --build-id=fast">;
 
 def build_id_eq: J<"build-id=">, HelpText<"Generate build ID note">,
diff --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp
index 081f811cd139d..e50706d7c8a19 100644
--- a/lld/wasm/SymbolTable.cpp
+++ b/lld/wasm/SymbolTable.cpp
@@ -310,9 +310,14 @@ static bool shouldReplace(const Symbol *existing, InputFile *newFile,
   }
 
   // Neither symbol is week. They conflict.
-  error("duplicate symbol: " + toString(*existing) + "\n>>> defined in " +
-        toString(existing->getFile()) + "\n>>> defined in " +
-        toString(newFile));
+  std::string msg = "duplicate symbol: " + toString(*existing) +
+                    "\n>>> defined in " + toString(existing->getFile()) +
+                    "\n>>> defined in " + toString(newFile);
+  if (config->allowMultipleDefinition) {
+    warn(msg);
+    return false;
+  }
+  error(msg);
   return true;
 }
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/97699


More information about the llvm-commits mailing list