[llvm] [BOLT] Ignore duplicate global symbols (PR #201082)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 2 03:20:39 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-bolt
Author: Jinjie Huang (Jinjie-Huang)
<details>
<summary>Changes</summary>
Background:
Version tag is a commonly used feature in dynamic libraries. However, this often results in the generation of multiple symbols with the exact same name but pointing to different real addresses within the symbol table, which triggers BOLT's "bad input binary" error.
Furthermore, a similar issue occurs when .symver is used within a static archive (.a) and linked into a main executable(I have provided examples covering these scenarios in the test cases).
Proposed Solution:
This patch uniquifies these duplicate-named symbols and marks them as ignored(since simply uniquifying them might confuse the usage of `getBinaryDataByName()`).
---
Full diff: https://github.com/llvm/llvm-project/pull/201082.diff
2 Files Affected:
- (modified) bolt/lib/Rewrite/RewriteInstance.cpp (+13-3)
- (added) bolt/test/duplicate_symbols.test (+42)
``````````diff
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 4a2d83cbf8706..b4311f6932702 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -1027,6 +1027,8 @@ void RewriteInstance::discoverFileObjects() {
if (SymbolType == SymbolRef::ST_File)
continue;
+ bool IsDuplicate = false;
+
StringRef SymName = cantFail(Symbol.getName(), "cannot get symbol name");
if (SymbolAddress == 0) {
if (opts::Verbosity >= 1 && SymbolType == SymbolRef::ST_Function)
@@ -1080,11 +1082,16 @@ void RewriteInstance::discoverFileObjects() {
// Ignore duplicate entry - possibly a bug in the linker
continue;
}
- BC->errs() << "BOLT-ERROR: bad input binary, global symbol \"" << Name
+ BC->errs() << "BOLT-WARNING: bad input binary, global symbol \"" << Name
<< "\" is not unique\n";
- exit(1);
+ UniqueName = NR.uniquify(Name);
+ IsDuplicate = true;
+ if (BinaryFunction *FirstBF =
+ BC->getBinaryFunctionAtAddress(BD->getAddress()))
+ FirstBF->setIgnored();
+ } else {
+ UniqueName = Name;
}
- UniqueName = Name;
} else {
// If we have a local file name, we should create 2 variants for the
// function name. The reason is that perf profile might have been
@@ -1322,6 +1329,9 @@ void RewriteInstance::discoverFileObjects() {
if (!AlternativeName.empty())
BF->addAlternativeName(AlternativeName);
+ if (IsDuplicate)
+ BF->setIgnored();
+
registerName(SymbolSize);
PreviousFunction = BF;
}
diff --git a/bolt/test/duplicate_symbols.test b/bolt/test/duplicate_symbols.test
new file mode 100644
index 0000000000000..cf5c55b3869b9
--- /dev/null
+++ b/bolt/test/duplicate_symbols.test
@@ -0,0 +1,42 @@
+## Verify that BOLT can correctly process binaries with duplicate symbols.
+
+# REQUIRES: system-linux
+
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t.o
+
+## Shared library with the duplicate symbol "foo", which requires a version script.
+# RUN: echo "VERS_1 { global: foo; }; VERS_2 { global: foo; } VERS_1;" > %t.map
+# RUN: ld.lld %t.o -o %t.so -shared --version-script %t.map
+# RUN: llvm-bolt %t.so -o %t.so.bolt 2>&1 | FileCheck %s
+
+## Main executable with the duplicate symbol "foo",
+## linked from a static object/archive without needing a version script.
+# RUN: ld.lld %t.o -o %t.exe
+# RUN: llvm-bolt %t.exe -o %t.exe.bolt 2>&1 | FileCheck %s
+
+# CHECK: BOLT-WARNING: bad input binary, global symbol "foo" is not unique
+
+.text
+.globl _start
+.type _start, @function
+_start:
+ call foo_v1
+ call foo_v2
+ ret
+.size _start, .-_start
+
+.globl foo_v1
+.type foo_v1, @function
+foo_v1:
+ nop
+ nop
+.size foo_v1, .-foo_v1
+
+.globl foo_v2
+.type foo_v2, @function
+foo_v2:
+ ret
+.size foo_v2, .-foo_v2
+
+.symver foo_v1, foo at VERS_1
+.symver foo_v2, foo@@VERS_2
``````````
</details>
https://github.com/llvm/llvm-project/pull/201082
More information about the llvm-commits
mailing list