[Lldb-commits] [lldb] [lldb] Prefer exact address match when looking up symbol by address (PR #172055)
Augusto Noronha via lldb-commits
lldb-commits at lists.llvm.org
Fri Dec 12 10:25:18 PST 2025
https://github.com/augusto2112 updated https://github.com/llvm/llvm-project/pull/172055
>From 274d5d0b46ce6881e6e19e5e95372ec586c7f0f1 Mon Sep 17 00:00:00 2001
From: Augusto Noronha <anoronha at apple.com>
Date: Fri, 12 Dec 2025 09:43:09 -0800
Subject: [PATCH 1/2] [lldb] Prefer exact address match when looking up symbol
by address
The current behavior will pick the first symbol that contains the
address, this causes LLDB to pick the wrong symbol when looking for
swift reflection metadata on Linux, as in that case it is valid for a
symbol to completely encompass another one.
Instead, this function should prefer the symbol which is an exact, if
it exists. As a bonus, this should also be faster in the vast majority
of the cases, as we probably query symbols by their exact address most
of the time.
rdar://166344740
---
lldb/source/Core/Module.cpp | 24 ++++++++-------
lldb/unittests/Core/ModuleTest.cpp | 47 ++++++++++++++++++++++++++++++
2 files changed, 60 insertions(+), 11 deletions(-)
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index 466340b0e0990..a543d44e25c4a 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -494,17 +494,19 @@ uint32_t Module::ResolveSymbolContextForAddress(
!(resolved_flags & eSymbolContextSymbol)) {
Symtab *symtab = symfile->GetSymtab();
if (symtab && so_addr.IsSectionOffset()) {
- Symbol *matching_symbol = nullptr;
-
- symtab->ForEachSymbolContainingFileAddress(
- so_addr.GetFileAddress(),
- [&matching_symbol](Symbol *symbol) -> bool {
- if (symbol->GetType() != eSymbolTypeInvalid) {
- matching_symbol = symbol;
- return false; // Stop iterating
- }
- return true; // Keep iterating
- });
+ addr_t file_address = so_addr.GetFileAddress();
+ Symbol *matching_symbol = symtab->FindSymbolAtFileAddress(file_address);
+
+ if (!matching_symbol) {
+ symtab->ForEachSymbolContainingFileAddress(
+ file_address, [&matching_symbol](Symbol *symbol) -> bool {
+ if (symbol->GetType() != eSymbolTypeInvalid) {
+ matching_symbol = symbol;
+ return false; // Stop iterating
+ }
+ return true; // Keep iterating
+ });
+ }
sc.symbol = matching_symbol;
if (!sc.symbol && resolve_scope & eSymbolContextFunction &&
!(resolved_flags & eSymbolContextFunction)) {
diff --git a/lldb/unittests/Core/ModuleTest.cpp b/lldb/unittests/Core/ModuleTest.cpp
index 011554d1b0939..bcaeede367bdd 100644
--- a/lldb/unittests/Core/ModuleTest.cpp
+++ b/lldb/unittests/Core/ModuleTest.cpp
@@ -123,3 +123,50 @@ TEST(ModuleTest, FindFunctionsCppMangledName) {
ASSERT_EQ(name, "std::vector<int>::size()");
ASSERT_EQ(result.GetLanguage(), eLanguageTypeC_plus_plus);
}
+
+TEST(ModuleTest, ResolveSymbolContextForAddressExactMatch) {
+ // Test that ResolveSymbolContextForAddress prefers exact symbol matches
+ // over symbols that merely contain the address.
+ SubsystemRAII<FileSystem, HostInfo, ObjectFileELF, SymbolFileSymtab>
+ subsystems;
+
+ auto ExpectedFile = TestFile::fromYaml(R"(
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_DYN
+ Machine: EM_X86_64
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1000
+ AddressAlign: 0x10
+ Size: 0x200
+Symbols:
+ - Name: outer_function
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x1000
+ Size: 0x100
+ - Name: inner_function
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x1050
+ Size: 0x10
+...
+)");
+ ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
+
+ auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());
+
+ Address addr(module_sp->GetSectionList()->GetSectionAtIndex(0), 0x50);
+ SymbolContext sc;
+ uint32_t resolved =
+ module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextSymbol, sc);
+
+ ASSERT_TRUE(resolved & eSymbolContextSymbol);
+ ASSERT_NE(sc.symbol, nullptr);
+ EXPECT_STREQ(sc.symbol->GetName().GetCString(), "inner_function");
+}
>From a0c2f31e382b049de3259455d312c36fe7fcfa14 Mon Sep 17 00:00:00 2001
From: Augusto Noronha <anoronha at apple.com>
Date: Fri, 12 Dec 2025 10:25:06 -0800
Subject: [PATCH 2/2] Check for invalid symbol
---
lldb/source/Core/Module.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index a543d44e25c4a..5586d994a50b3 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -497,7 +497,8 @@ uint32_t Module::ResolveSymbolContextForAddress(
addr_t file_address = so_addr.GetFileAddress();
Symbol *matching_symbol = symtab->FindSymbolAtFileAddress(file_address);
- if (!matching_symbol) {
+ if (!matching_symbol ||
+ matching_symbol->GetType() == eSymbolTypeInvalid) {
symtab->ForEachSymbolContainingFileAddress(
file_address, [&matching_symbol](Symbol *symbol) -> bool {
if (symbol->GetType() != eSymbolTypeInvalid) {
More information about the lldb-commits
mailing list