[Lldb-commits] [lldb] [lldb] Prefer readers with detailed debug information (PR #218030)

satyanarayana reddy janga via lldb-commits lldb-commits at lists.llvm.org
Sat Sep 26 12:14:18 PDT 2026


https://github.com/satyajanga updated https://github.com/llvm/llvm-project/pull/218030

>From 502f4e37439e8e2771363e0e29788da61f0a67c8 Mon Sep 17 00:00:00 2001
From: satya janga <satyajanga at fb.com>
Date: Fri, 21 Aug 2026 13:55:59 -0700
Subject: [PATCH 1/3] [lldb] Prefer readers with detailed debug information

Add a Symbols ability for object-file symbol data and make SymbolFileSymtab advertise it instead of claiming full Functions or GlobalVariables.

Order the ability bits so the existing numeric comparison prefers richer debug information. In particular, CompileUnits plus LineTables outranks Symbols plus CompileUnits.

Add focused coverage for plugin selection and SymbolFileSymtab abilities.
---
 lldb/include/lldb/Symbol/SymbolFile.h         | 24 +++--
 .../SymbolFile/Symtab/SymbolFileSymtab.cpp    | 13 +--
 lldb/unittests/Symbol/CMakeLists.txt          |  1 +
 lldb/unittests/Symbol/SymbolFileTest.cpp      | 95 +++++++++++++++++++
 lldb/unittests/Symbol/SymtabTest.cpp          |  5 +
 5 files changed, 123 insertions(+), 15 deletions(-)
 create mode 100644 lldb/unittests/Symbol/SymbolFileTest.cpp

diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h
index b49c5ae230062..8174661b446b3 100644
--- a/lldb/include/lldb/Symbol/SymbolFile.h
+++ b/lldb/include/lldb/Symbol/SymbolFile.h
@@ -64,16 +64,22 @@ class SymbolFile : public PluginInterface {
   // Each symbol file can claim to support one or more symbol file abilities.
   // These get returned from SymbolFile::GetAbilities(). These help us to
   // determine which plug-in will be best to load the debug information found
-  // in files.
+  // in files. The values are ordered so that a simple numeric comparison
+  // prefers detailed debug information over data read directly from an object
+  // file's symbol table.
   enum Abilities {
-    CompileUnits = (1u << 0),
-    LineTables = (1u << 1),
-    Functions = (1u << 2),
-    Blocks = (1u << 3),
-    GlobalVariables = (1u << 4),
-    LocalVariables = (1u << 5),
-    VariableTypes = (1u << 6),
-    kAllAbilities = ((1u << 7) - 1u)
+    Symbols = (1u << 0),
+    CompileUnits = (1u << 1),
+    LineTables = (1u << 2),
+    Functions = (1u << 3),
+    Blocks = (1u << 4),
+    GlobalVariables = (1u << 5),
+    LocalVariables = (1u << 6),
+    VariableTypes = (1u << 7),
+    // All detailed debug-information abilities. Symbols is excluded because
+    // it describes information from the object file's symbol table.
+    kAllAbilities = CompileUnits | LineTables | Functions | Blocks |
+        GlobalVariables | LocalVariables | VariableTypes
   };
 
   static SymbolFile *FindPlugin(lldb::ObjectFileSP objfile_sp);
diff --git a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
index 9c298374101fa..57fe9090aa694 100644
--- a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
+++ b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
@@ -60,9 +60,13 @@ uint32_t SymbolFileSymtab::CalculateAbilities() {
   if (m_objfile_sp) {
     const Symtab *symtab = m_objfile_sp->GetSymtab();
     if (symtab) {
-      // The snippet of code below will get the indexes the module symbol table
-      // entries that are code, data, or function related (debug info), sort
-      // them by value (address) and dump the sorted symbols.
+      // Get the indexes of source, code, data, and function-related entries in
+      // the module symbol table. Only source-file entries provide a genuine
+      // debug-info ability. Code and data entries remain available as symbols
+      // but are not equivalent to debug-info functions or global variables.
+      if (symtab->GetNumSymbols() > 0)
+        abilities |= Symbols;
+
       if (symtab->AppendSymbolIndexesWithType(eSymbolTypeSourceFile,
                                               m_source_indexes)) {
         abilities |= CompileUnits;
@@ -72,20 +76,17 @@ uint32_t SymbolFileSymtab::CalculateAbilities() {
               eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny,
               m_func_indexes)) {
         symtab->SortSymbolIndexesByValue(m_func_indexes, true);
-        abilities |= Functions;
       }
 
       if (symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugNo,
                                               Symtab::eVisibilityAny,
                                               m_code_indexes)) {
         symtab->SortSymbolIndexesByValue(m_code_indexes, true);
-        abilities |= Functions;
       }
 
       if (symtab->AppendSymbolIndexesWithType(eSymbolTypeData,
                                               m_data_indexes)) {
         symtab->SortSymbolIndexesByValue(m_data_indexes, true);
-        abilities |= GlobalVariables;
       }
 
       lldb_private::Symtab::IndexCollection objc_class_indexes;
diff --git a/lldb/unittests/Symbol/CMakeLists.txt b/lldb/unittests/Symbol/CMakeLists.txt
index 0fdbc9d72445e..c3aa38e36a5c4 100644
--- a/lldb/unittests/Symbol/CMakeLists.txt
+++ b/lldb/unittests/Symbol/CMakeLists.txt
@@ -5,6 +5,7 @@ add_lldb_unittest(SymbolTests
   MangledTest.cpp
   PostfixExpressionTest.cpp
   SymbolLocatorTest.cpp
+  SymbolFileTest.cpp
   SymbolTest.cpp
   SymtabTest.cpp
   SymStoreTest.cpp
diff --git a/lldb/unittests/Symbol/SymbolFileTest.cpp b/lldb/unittests/Symbol/SymbolFileTest.cpp
new file mode 100644
index 0000000000000..9c14e637990a9
--- /dev/null
+++ b/lldb/unittests/Symbol/SymbolFileTest.cpp
@@ -0,0 +1,95 @@
+//===-- SymbolFileTest.cpp -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
+#include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"
+#include "TestingSupport/SubsystemRAII.h"
+#include "TestingSupport/TestUtilities.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "gtest/gtest.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+namespace {
+
+class FakeSymbolFile : public SymbolFileSymtab {
+public:
+  static void Initialize() {
+    PluginManager::RegisterPlugin("SymbolOnlyFakeSymbolFile", "",
+                                  CreateSymbolOnlyInstance);
+    PluginManager::RegisterPlugin("LineTableFakeSymbolFile", "",
+                                  CreateLineTableInstance);
+    PluginManager::RegisterPlugin("SymtabLikeFakeSymbolFile", "",
+                                  CreateSymtabInstance);
+  }
+
+  static void Terminate() {
+    PluginManager::UnregisterPlugin(CreateSymtabInstance);
+    PluginManager::UnregisterPlugin(CreateLineTableInstance);
+    PluginManager::UnregisterPlugin(CreateSymbolOnlyInstance);
+  }
+
+  llvm::StringRef GetPluginName() override { return m_plugin_name; }
+  uint32_t CalculateAbilities() override { return m_abilities; }
+
+private:
+  FakeSymbolFile(ObjectFileSP objfile_sp, llvm::StringRef plugin_name,
+                 uint32_t abilities)
+      : SymbolFileSymtab(std::move(objfile_sp)), m_plugin_name(plugin_name),
+        m_abilities(abilities) {}
+
+  static SymbolFile *CreateSymbolOnlyInstance(ObjectFileSP objfile_sp) {
+    return new FakeSymbolFile(std::move(objfile_sp), "SymbolOnlyFakeSymbolFile",
+                              Symbols);
+  }
+
+  static SymbolFile *CreateSymtabInstance(ObjectFileSP objfile_sp) {
+    return new FakeSymbolFile(std::move(objfile_sp), "SymtabLikeFakeSymbolFile",
+                              Symbols | CompileUnits);
+  }
+
+  static SymbolFile *CreateLineTableInstance(ObjectFileSP objfile_sp) {
+    return new FakeSymbolFile(std::move(objfile_sp), "LineTableFakeSymbolFile",
+                              CompileUnits | LineTables);
+  }
+
+  llvm::StringRef m_plugin_name;
+  uint32_t m_abilities;
+};
+
+class SymbolFileTest : public testing::Test {
+  SubsystemRAII<ObjectFileELF, FakeSymbolFile> subsystems;
+};
+
+TEST_F(SymbolFileTest, FindPluginPrefersLineTablesOverSymbols) {
+  llvm::Expected<TestFile> file = TestFile::fromYaml(R"(
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_EXEC
+  Machine: EM_386
+)");
+  ASSERT_THAT_EXPECTED(file, llvm::Succeeded());
+
+  auto module_sp = std::make_shared<Module>(file->moduleSpec());
+  ObjectFile *object_file = module_sp->GetObjectFile();
+  ASSERT_NE(object_file, nullptr);
+
+  std::unique_ptr<SymbolFile> symbol_file(
+      SymbolFile::FindPlugin(object_file->shared_from_this()));
+  ASSERT_NE(symbol_file, nullptr);
+  EXPECT_EQ(symbol_file->GetPluginName(), "LineTableFakeSymbolFile");
+  EXPECT_EQ(
+      symbol_file->GetAbilities(),
+      static_cast<uint32_t>(SymbolFile::CompileUnits | SymbolFile::LineTables));
+}
+
+} // namespace
diff --git a/lldb/unittests/Symbol/SymtabTest.cpp b/lldb/unittests/Symbol/SymtabTest.cpp
index fda92e4044919..dba75c0f6e1f6 100644
--- a/lldb/unittests/Symbol/SymtabTest.cpp
+++ b/lldb/unittests/Symbol/SymtabTest.cpp
@@ -739,6 +739,11 @@ TEST_F(SymtabTest, TestSymbolFileCreatedOnDemand) {
   // And we should be able to get it again once it has been created.
   Symtab *cached_module_symtab = module_sp->GetSymtab(/*can_create=*/false);
   ASSERT_EQ(module_symtab, cached_module_symtab);
+
+  SymbolFile *symbol_file = module_sp->GetSymbolFile();
+  ASSERT_NE(symbol_file, nullptr);
+  EXPECT_EQ(symbol_file->GetAbilities(),
+            static_cast<uint32_t>(SymbolFile::Symbols));
 }
 
 TEST_F(SymtabTest, TestSymbolTableCreatedOnDemand) {

>From a4a66e203d32cb0321a91b89cdc00753d9a53bea Mon Sep 17 00:00:00 2001
From: satya janga <satyajanga at fb.com>
Date: Sat, 26 Sep 2026 09:43:27 -0700
Subject: [PATCH 2/3] [lldb] Address symbol-file selection review feedback

---
 lldb/include/lldb/Symbol/SymbolFile.h         | 11 +++++-----
 .../SymbolFile/Symtab/SymbolFileSymtab.cpp    |  6 ++---
 lldb/unittests/Symbol/SymbolFileTest.cpp      |  2 +-
 lldb/unittests/Symbol/SymtabTest.cpp          | 22 +++++++++++++++++++
 4 files changed, 31 insertions(+), 10 deletions(-)

diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h
index f7e4208e232e0..8323998573755 100644
--- a/lldb/include/lldb/Symbol/SymbolFile.h
+++ b/lldb/include/lldb/Symbol/SymbolFile.h
@@ -64,9 +64,8 @@ class SymbolFile : public PluginInterface {
   // Each symbol file can claim to support one or more symbol file abilities.
   // These get returned from SymbolFile::GetAbilities(). These help us to
   // determine which plug-in will be best to load the debug information found
-  // in files. The values are ordered so that a simple numeric comparison
-  // prefers detailed debug information over data read directly from an object
-  // file's symbol table.
+  // in files. Symbols is the least-significant bit so a plug-in reporting any
+  // other ability ranks ahead of one reporting only Symbols.
   enum Abilities {
     Symbols = (1u << 0),
     CompileUnits = (1u << 1),
@@ -76,10 +75,10 @@ class SymbolFile : public PluginInterface {
     GlobalVariables = (1u << 5),
     LocalVariables = (1u << 6),
     VariableTypes = (1u << 7),
-    // All detailed debug-information abilities. Symbols is excluded because
-    // it describes information from the object file's symbol table.
+    /// All detailed debug-information abilities. Symbols is excluded because
+    /// it describes information from the object file's symbol table.
     kAllAbilities = CompileUnits | LineTables | Functions | Blocks |
-        GlobalVariables | LocalVariables | VariableTypes
+                    GlobalVariables | LocalVariables | VariableTypes
   };
 
   static SymbolFile *FindPlugin(lldb::ObjectFileSP objfile_sp);
diff --git a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
index 57fe9090aa694..1d17743d7dc6a 100644
--- a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
+++ b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
@@ -60,13 +60,13 @@ uint32_t SymbolFileSymtab::CalculateAbilities() {
   if (m_objfile_sp) {
     const Symtab *symtab = m_objfile_sp->GetSymtab();
     if (symtab) {
+      if (symtab->GetNumSymbols() > 0)
+        abilities |= Symbols;
+
       // Get the indexes of source, code, data, and function-related entries in
       // the module symbol table. Only source-file entries provide a genuine
       // debug-info ability. Code and data entries remain available as symbols
       // but are not equivalent to debug-info functions or global variables.
-      if (symtab->GetNumSymbols() > 0)
-        abilities |= Symbols;
-
       if (symtab->AppendSymbolIndexesWithType(eSymbolTypeSourceFile,
                                               m_source_indexes)) {
         abilities |= CompileUnits;
diff --git a/lldb/unittests/Symbol/SymbolFileTest.cpp b/lldb/unittests/Symbol/SymbolFileTest.cpp
index 9c14e637990a9..db899f1f86460 100644
--- a/lldb/unittests/Symbol/SymbolFileTest.cpp
+++ b/lldb/unittests/Symbol/SymbolFileTest.cpp
@@ -1,4 +1,4 @@
-//===-- SymbolFileTest.cpp -----------------------------------------------===//
+//===----------------------------------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/unittests/Symbol/SymtabTest.cpp b/lldb/unittests/Symbol/SymtabTest.cpp
index dba75c0f6e1f6..dfb2258b847e0 100644
--- a/lldb/unittests/Symbol/SymtabTest.cpp
+++ b/lldb/unittests/Symbol/SymtabTest.cpp
@@ -716,6 +716,12 @@ TEST_F(SymtabTest, TestSymbolFileCreatedOnDemand) {
     Address:         0x0000000000400180
     AddressAlign:    0x0000000000000010
     Content:         554889E58B042500106000890425041060005DC3
+  - Name:            .data
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    Address:         0x0000000000601000
+    AddressAlign:    0x0000000000000004
+    Content:         2F000000
 Symbols:
   - Name:            _start
     Type:            STT_FUNC
@@ -723,6 +729,12 @@ TEST_F(SymtabTest, TestSymbolFileCreatedOnDemand) {
     Value:           0x0000000000400180
     Size:            0x0000000000000014
     Binding:         STB_GLOBAL
+  - Name:            global_data
+    Type:            STT_OBJECT
+    Section:         .data
+    Value:           0x0000000000601000
+    Size:            0x0000000000000004
+    Binding:         STB_GLOBAL
 ...
 )");
   ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
@@ -735,6 +747,14 @@ TEST_F(SymtabTest, TestSymbolFileCreatedOnDemand) {
   // But it should be created on demand.
   module_symtab = module_sp->GetSymtab(/*can_create=*/true);
   ASSERT_NE(module_symtab, nullptr);
+  ASSERT_NE(module_symtab->FindFirstSymbolWithNameAndType(
+                ConstString("_start"), eSymbolTypeCode, Symtab::eDebugAny,
+                Symtab::eVisibilityAny),
+            nullptr);
+  ASSERT_NE(module_symtab->FindFirstSymbolWithNameAndType(
+                ConstString("global_data"), eSymbolTypeData, Symtab::eDebugAny,
+                Symtab::eVisibilityAny),
+            nullptr);
 
   // And we should be able to get it again once it has been created.
   Symtab *cached_module_symtab = module_sp->GetSymtab(/*can_create=*/false);
@@ -742,6 +762,8 @@ TEST_F(SymtabTest, TestSymbolFileCreatedOnDemand) {
 
   SymbolFile *symbol_file = module_sp->GetSymbolFile();
   ASSERT_NE(symbol_file, nullptr);
+  EXPECT_EQ(symbol_file->GetPluginName(),
+            SymbolFileSymtab::GetPluginNameStatic());
   EXPECT_EQ(symbol_file->GetAbilities(),
             static_cast<uint32_t>(SymbolFile::Symbols));
 }

>From f83961b68e11dd4338bc391c33d046535aaffcec Mon Sep 17 00:00:00 2001
From: satya janga <satyajanga at fb.com>
Date: Sat, 26 Sep 2026 11:52:55 -0700
Subject: [PATCH 3/3] [lldb] Fix SymbolFile ability formatting

---
 lldb/include/lldb/Symbol/SymbolFile.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h
index 8323998573755..f00c5d220b39a 100644
--- a/lldb/include/lldb/Symbol/SymbolFile.h
+++ b/lldb/include/lldb/Symbol/SymbolFile.h
@@ -78,7 +78,7 @@ class SymbolFile : public PluginInterface {
     /// All detailed debug-information abilities. Symbols is excluded because
     /// it describes information from the object file's symbol table.
     kAllAbilities = CompileUnits | LineTables | Functions | Blocks |
-                    GlobalVariables | LocalVariables | VariableTypes
+        GlobalVariables | LocalVariables | VariableTypes
   };
 
   static SymbolFile *FindPlugin(lldb::ObjectFileSP objfile_sp);



More information about the lldb-commits mailing list