[llvm] [bolt] Resolve duplicated symbols name through versioning (PR #203223)
Alexey Moksyakov via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 11 02:43:49 PDT 2026
https://github.com/yavtuk created https://github.com/llvm/llvm-project/pull/203223
Related to [PR](https://github.com/llvm/llvm-project/pull/201082)
>From 1b1d45848e0dd5450659a662fabfa176cda9d211 Mon Sep 17 00:00:00 2001
From: yavtuk <yavtuk at ya.ru>
Date: Thu, 11 Jun 2026 12:33:40 +0300
Subject: [PATCH] [bolt] Resolve duplicated symbols name through versioning
---
bolt/lib/Rewrite/RewriteInstance.cpp | 33 ++++++++++++++++++++-
bolt/test/duplicate_symbols.test | 44 ++++++++++++++++++++++++++++
2 files changed, 76 insertions(+), 1 deletion(-)
create mode 100644 bolt/test/duplicate_symbols.test
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 9364e32939982..f4898b01a2528 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -933,6 +933,34 @@ void RewriteInstance::discoverFileObjects() {
return false;
};
+
+ // read dynamic symbols name and version
+ DenseMap<uint64_t, std::string> DynSymNames;
+ Expected<std::vector<VersionEntry>> SymbolVersionOrErr =
+ InputFile->readDynsymVersions();
+ if (SymbolVersionOrErr && !SymbolVersionOrErr->empty()) {
+ ArrayRef<VersionEntry> SymbolVersions = *SymbolVersionOrErr;
+ for (const SymbolRef &Symbol : InputFile->getDynamicSymbolIterators()) {
+ const uint64_t SymAddress = cantFail(Symbol.getAddress());
+ if (!isSymbolInMemory(Symbol) || !SymAddress)
+ continue;
+ Expected<StringRef> NameOrError = Symbol.getName();
+ if (!NameOrError) {
+ consumeError(NameOrError.takeError());
+ continue;
+ }
+ StringRef SymbolName = *NameOrError;
+ if (SymbolName.empty())
+ continue;
+ const VersionEntry &Ver =
+ SymbolVersions[Symbol.getRawDataRefImpl().d.b - 1];
+ if (Ver.Name.empty())
+ continue;
+ DynSymNames[SymAddress] =
+ SymbolName.str() + (Ver.IsVerDef ? "@@" : "@") + Ver.Name;
+ }
+ }
+
for (const SymbolRef &Symbol : InputFile->symbols())
if (isSymbolInMemory(Symbol)) {
SymbolInfo SymInfo{cantFail(Symbol.getAddress()), Symbol};
@@ -1034,7 +1062,10 @@ void RewriteInstance::discoverFileObjects() {
if (SymbolType == SymbolRef::ST_File)
continue;
- StringRef SymName = cantFail(Symbol.getName(), "cannot get symbol name");
+ StringRef SymName =
+ DynSymNames.find(SymbolAddress) != DynSymNames.end()
+ ? DynSymNames[SymbolAddress]
+ : cantFail(Symbol.getName(), "cannot get symbol name");
if (SymbolAddress == 0) {
if (opts::Verbosity >= 1 && SymbolType == SymbolRef::ST_Function)
BC->errs() << "BOLT-WARNING: function with 0 address seen\n";
diff --git a/bolt/test/duplicate_symbols.test b/bolt/test/duplicate_symbols.test
new file mode 100644
index 0000000000000..5047c7d496c0f
--- /dev/null
+++ b/bolt/test/duplicate_symbols.test
@@ -0,0 +1,44 @@
+## 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 --check-prefix=CHECK-SHARED
+
+# CHECK-SHARED-NOT: bad input binary, global symbol "foo" is not unique
+
+## 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: not llvm-bolt %t.exe -o %t.exe.bolt 2>&1 | FileCheck %s --check-prefix=CHECK-STATIC
+
+# CHECK-STATIC: 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
\ No newline at end of file
More information about the llvm-commits
mailing list