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

>From 3184d77439fa8fa4766307e7ae8d1b5884f701da Mon Sep 17 00:00:00 2001
From: satya janga <[email protected]>
Date: Fri, 21 Aug 2026 13:55:59 -0700
Subject: [PATCH] [lldb] Prefer readers with detailed debug information

Rank symbol-file readers that provide line tables associated with compile 
units, blocks, local variables, or types ahead of readers that provide only 
information obtainable from an object symbol table. Preserve the existing 
ability-mask ordering within each category.
---
 lldb/include/lldb/Symbol/SymbolFile.h   |  8 ++-
 lldb/source/Symbol/SymbolFile.cpp       | 17 +++++-
 lldb/unittests/Symbol/LineTableTest.cpp | 71 +++++++++++++++++++++----
 3 files changed, 83 insertions(+), 13 deletions(-)

diff --git a/lldb/include/lldb/Symbol/SymbolFile.h 
b/lldb/include/lldb/Symbol/SymbolFile.h
index ae6504c016d7b..97a6b69ad3af2 100644
--- a/lldb/include/lldb/Symbol/SymbolFile.h
+++ b/lldb/include/lldb/Symbol/SymbolFile.h
@@ -95,8 +95,12 @@ class SymbolFile : public PluginInterface {
   /// trying to figure out which symbol file plug-in will get used
   /// for a given object file. The plug-in that responds with the
   /// best mix of "SymbolFile::Abilities" bits set, will get chosen to
-  /// be the symbol file parser. This allows each plug-in to check for
-  /// sections that contain data a symbol file plug-in would need. For
+  /// be the symbol file parser. Plug-ins that provide detailed debug
+  /// information such as line tables associated with compile units, blocks,
+  /// local variables, or types are preferred over plug-ins that provide only
+  /// information obtainable from an object file's symbol table. This allows
+  /// each plug-in to check for sections that contain data a symbol file 
plug-in
+  /// would need. For
   /// example the DWARF plug-in requires DWARF sections in a file that
   /// contain debug information. If the DWARF plug-in doesn't find
   /// these sections, it won't respond with many ability bits set, and
diff --git a/lldb/source/Symbol/SymbolFile.cpp 
b/lldb/source/Symbol/SymbolFile.cpp
index 0ef139b1d453a..43ba160961072 100644
--- a/lldb/source/Symbol/SymbolFile.cpp
+++ b/lldb/source/Symbol/SymbolFile.cpp
@@ -23,6 +23,7 @@
 #include "lldb/lldb-private.h"
 
 #include <future>
+#include <utility>
 
 using namespace lldb_private;
 using namespace lldb;
@@ -30,6 +31,19 @@ using namespace lldb;
 char SymbolFile::ID;
 char SymbolFileCommon::ID;
 
+static std::pair<bool, uint32_t> GetSymbolFileRank(uint32_t abilities) {
+  constexpr uint32_t detailed_info = SymbolFile::Blocks |
+                                     SymbolFile::LocalVariables |
+                                     SymbolFile::VariableTypes;
+  constexpr uint32_t usable_line_tables =
+      SymbolFile::CompileUnits | SymbolFile::LineTables;
+  const bool has_usable_line_tables =
+      (abilities & usable_line_tables) == usable_line_tables;
+  return {has_usable_line_tables ||
+              static_cast<bool>(abilities & detailed_info),
+          abilities};
+}
+
 void SymbolFile::PreloadSymbols() {
   // No-op for most implementations.
 }
@@ -65,7 +79,8 @@ SymbolFile *SymbolFile::FindPlugin(ObjectFileSP objfile_sp) {
 
       if (curr_symfile_up) {
         const uint32_t sym_file_abilities = curr_symfile_up->GetAbilities();
-        if (sym_file_abilities > best_symfile_abilities) {
+        if (GetSymbolFileRank(sym_file_abilities) >
+            GetSymbolFileRank(best_symfile_abilities)) {
           best_symfile_abilities = sym_file_abilities;
           best_symfile_up.reset(curr_symfile_up.release());
           // If any symbol file parser has all of the abilities, then we should
diff --git a/lldb/unittests/Symbol/LineTableTest.cpp 
b/lldb/unittests/Symbol/LineTableTest.cpp
index 80f2f219d0e81..4b25629ec1bd7 100644
--- a/lldb/unittests/Symbol/LineTableTest.cpp
+++ b/lldb/unittests/Symbol/LineTableTest.cpp
@@ -35,10 +35,19 @@ class FakeSymbolFile : public SymbolFile {
   /// \}
 
   static void Initialize() {
-    PluginManager::RegisterPlugin("FakeSymbolFile", "", CreateInstance,
-                                  DebuggerInitialize);
+    PluginManager::RegisterPlugin("LineTableFakeSymbolFile", "",
+                                  CreateLineTableInstance, DebuggerInitialize);
+    PluginManager::RegisterPlugin("SymbolOnlyFakeSymbolFile", "",
+                                  CreateSymbolOnlyInstance, 
DebuggerInitialize);
+  }
+  static void Terminate() {
+    PluginManager::UnregisterPlugin(CreateSymbolOnlyInstance);
+    PluginManager::UnregisterPlugin(CreateLineTableInstance);
+  }
+
+  static void SetLineTableAbilities(uint32_t abilities) {
+    g_line_table_abilities = abilities;
   }
-  static void Terminate() { PluginManager::UnregisterPlugin(CreateInstance); }
 
   void InjectCompileUnit(std::unique_ptr<CompileUnit> cu_up) {
     m_cu_sp = std::move(cu_up);
@@ -48,14 +57,19 @@ class FakeSymbolFile : public SymbolFile {
   /// LLVM RTTI support.
   static char ID;
 
-  static SymbolFile *CreateInstance(ObjectFileSP objfile_sp) {
-    return new FakeSymbolFile(std::move(objfile_sp));
+  static SymbolFile *CreateLineTableInstance(ObjectFileSP objfile_sp) {
+    return new FakeSymbolFile(std::move(objfile_sp), "LineTableFakeSymbolFile",
+                              g_line_table_abilities);
+  }
+  static SymbolFile *CreateSymbolOnlyInstance(ObjectFileSP objfile_sp) {
+    return new FakeSymbolFile(std::move(objfile_sp), 
"SymbolOnlyFakeSymbolFile",
+                              Functions | GlobalVariables);
   }
   static void DebuggerInitialize(Debugger &) {}
 
-  StringRef GetPluginName() override { return "FakeSymbolFile"; }
-  uint32_t GetAbilities() override { return UINT32_MAX; }
-  uint32_t CalculateAbilities() override { return UINT32_MAX; }
+  StringRef GetPluginName() override { return m_plugin_name; }
+  uint32_t GetAbilities() override { return m_abilities; }
+  uint32_t CalculateAbilities() override { return m_abilities; }
   uint32_t GetNumCompileUnits() override { return 1; }
   CompUnitSP GetCompileUnitAtIndex(uint32_t) override { return m_cu_sp; }
   Symtab *GetSymtab(bool can_create = true) override { return nullptr; }
@@ -109,11 +123,16 @@ class FakeSymbolFile : public SymbolFile {
   }
   TypeSP CopyType(const TypeSP &) override { return nullptr; }
 
-  FakeSymbolFile(ObjectFileSP objfile_sp)
-      : m_objfile_sp(std::move(objfile_sp)) {}
+  FakeSymbolFile(ObjectFileSP objfile_sp, StringRef plugin_name,
+                 uint32_t abilities)
+      : m_objfile_sp(std::move(objfile_sp)), m_plugin_name(plugin_name),
+        m_abilities(abilities) {}
 
   ObjectFileSP m_objfile_sp;
   CompUnitSP m_cu_sp;
+  StringRef m_plugin_name;
+  uint32_t m_abilities;
+  inline static uint32_t g_line_table_abilities = CompileUnits | LineTables;
 };
 
 struct FakeModuleFixture {
@@ -124,6 +143,13 @@ struct FakeModuleFixture {
 };
 
 class LineTableTest : public testing::Test {
+protected:
+  void SetUp() override {
+    FakeSymbolFile::SetLineTableAbilities(SymbolFile::CompileUnits |
+                                          SymbolFile::LineTables);
+  }
+
+private:
   SubsystemRAII<ObjectFileELF, FakeSymbolFile> subsystems;
 };
 
@@ -190,6 +216,31 @@ CreateFakeModule(std::vector<LineTable::Sequence> 
line_sequences) {
                            std::move(text_sp), line_table};
 }
 
+TEST_F(LineTableTest, FindPluginPrefersLineTablesWithCompileUnits) {
+  llvm::Expected<FakeModuleFixture> fixture = CreateFakeModule({});
+  ASSERT_THAT_EXPECTED(fixture, llvm::Succeeded());
+
+  SymbolFile *symbol_file = fixture->module_sp->GetSymbolFile();
+  ASSERT_NE(symbol_file, nullptr);
+  EXPECT_EQ(symbol_file->GetPluginName(), "LineTableFakeSymbolFile");
+  EXPECT_EQ(
+      symbol_file->GetAbilities(),
+      static_cast<uint32_t>(SymbolFile::CompileUnits | 
SymbolFile::LineTables));
+}
+
+TEST_F(LineTableTest, FindPluginDoesNotPreferLineTablesWithoutCompileUnits) {
+  FakeSymbolFile::SetLineTableAbilities(SymbolFile::LineTables);
+  llvm::Expected<FakeModuleFixture> fixture = CreateFakeModule({});
+  ASSERT_THAT_EXPECTED(fixture, llvm::Succeeded());
+
+  SymbolFile *symbol_file = fixture->module_sp->GetSymbolFile();
+  ASSERT_NE(symbol_file, nullptr);
+  EXPECT_EQ(symbol_file->GetPluginName(), "SymbolOnlyFakeSymbolFile");
+  EXPECT_EQ(symbol_file->GetAbilities(),
+            static_cast<uint32_t>(SymbolFile::Functions |
+                                  SymbolFile::GlobalVariables));
+}
+
 TEST_F(LineTableTest, lower_bound) {
   LineSequenceBuilder builder;
   builder.Entry(0);

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

Reply via email to