[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