Author: Augusto Noronha
Date: 2025-12-17T10:51:14-08:00
New Revision: 208553460a704fc94b5154c0a2145010015b137f

URL: 
https://github.com/llvm/llvm-project/commit/208553460a704fc94b5154c0a2145010015b137f
DIFF: 
https://github.com/llvm/llvm-project/commit/208553460a704fc94b5154c0a2145010015b137f.diff

LOG: [lldb] Prefer exact address match when looking up symbol by address 
(#172055)

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

Added: 
    

Modified: 
    lldb/source/Core/Module.cpp
    lldb/unittests/Core/ModuleTest.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index 617e2d0904e83..0948136f30156 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -496,15 +496,23 @@ uint32_t Module::ResolveSymbolContextForAddress(
       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 *symbol_at_address =
+            symtab->FindSymbolAtFileAddress(file_address);
+        if (symbol_at_address &&
+            symbol_at_address->GetType() != lldb::eSymbolTypeInvalid) {
+          matching_symbol = symbol_at_address;
+        } else {
+          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");
+}


        
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to