https://github.com/rchamala updated 
https://github.com/llvm/llvm-project/pull/183675

>From df5cc9d38ac7e0a044382ab83097461af967afed Mon Sep 17 00:00:00 2001
From: Rahul Reddy Chamala <[email protected]>
Date: Thu, 26 Feb 2026 14:55:33 -0800
Subject: [PATCH 1/2] [lldb] Add LocateSourceFile callback to SymbolLocator
 plugin interface

Add a LocateSourceFile callback slot to the SymbolLocator plugin
interface and wire it into source file resolution via
LineEntry::ApplyFileMappings.

This is NFC for existing plugins: Default and DebugSymbols use the
default nullptr, and Debuginfod passes an explicit nullptr since
DebuggerInitialize follows it in the argument list.

The new callback takes (ModuleSP, FileSpec) with no TargetSP, following
the global plugin model. When a SymbolLocator plugin provides a
LocateSourceFile implementation, it is called before the existing
target.source-map resolution path in ApplyFileMappings.

The ApplyFileMappings signature gains a `const Address &address`
parameter so the implementation can extract the ModuleSP from the
address. All four call sites (Module.cpp, StackFrame.cpp,
StackFrameList.cpp, ThreadPlanStepRange.cpp) are updated accordingly.
---
 lldb/include/lldb/Core/PluginManager.h        |  4 ++++
 lldb/include/lldb/Symbol/LineEntry.h          |  2 +-
 lldb/include/lldb/lldb-private-interfaces.h   |  2 ++
 lldb/source/Core/Module.cpp                   |  2 +-
 lldb/source/Core/PluginManager.cpp            | 22 +++++++++++++++++--
 .../Debuginfod/SymbolLocatorDebuginfod.cpp    |  2 +-
 lldb/source/Symbol/LineEntry.cpp              | 19 +++++++++++++++-
 lldb/source/Target/StackFrame.cpp             |  2 +-
 lldb/source/Target/StackFrameList.cpp         |  3 ++-
 lldb/source/Target/ThreadPlanStepRange.cpp    |  4 ++--
 10 files changed, 52 insertions(+), 10 deletions(-)

diff --git a/lldb/include/lldb/Core/PluginManager.h 
b/lldb/include/lldb/Core/PluginManager.h
index 4d116f52460ff..3fd3e6177afa0 100644
--- a/lldb/include/lldb/Core/PluginManager.h
+++ b/lldb/include/lldb/Core/PluginManager.h
@@ -455,6 +455,7 @@ class PluginManager {
       SymbolLocatorDownloadObjectAndSymbolFile download_object_symbol_file =
           nullptr,
       SymbolLocatorFindSymbolFileInBundle find_symbol_file_in_bundle = nullptr,
+      SymbolLocatorLocateSourceFile locate_source_file = nullptr,
       DebuggerInitializeCallback debugger_init_callback = nullptr);
 
   static bool UnregisterPlugin(SymbolLocatorCreateInstance create_callback);
@@ -479,6 +480,9 @@ class PluginManager {
                                          const UUID *uuid,
                                          const ArchSpec *arch);
 
+  static FileSpec LocateSourceFile(const lldb::ModuleSP &module_sp,
+                                   const FileSpec &original_source_file);
+
   // Trace
   static bool RegisterPlugin(
       llvm::StringRef name, llvm::StringRef description,
diff --git a/lldb/include/lldb/Symbol/LineEntry.h 
b/lldb/include/lldb/Symbol/LineEntry.h
index adf2e989e3e34..e023eda6d89a4 100644
--- a/lldb/include/lldb/Symbol/LineEntry.h
+++ b/lldb/include/lldb/Symbol/LineEntry.h
@@ -128,7 +128,7 @@ struct LineEntry {
   ///
   /// \param[in] target_sp
   ///     Shared pointer to the target this LineEntry belongs to.
-  void ApplyFileMappings(lldb::TargetSP target_sp);
+  void ApplyFileMappings(lldb::TargetSP target_sp, const Address &address);
 
   /// Helper to access the file.
   const FileSpec &GetFile() const { return file_sp->GetSpecOnly(); }
diff --git a/lldb/include/lldb/lldb-private-interfaces.h 
b/lldb/include/lldb/lldb-private-interfaces.h
index a87e01769c555..6d71b8d671b71 100644
--- a/lldb/include/lldb/lldb-private-interfaces.h
+++ b/lldb/include/lldb/lldb-private-interfaces.h
@@ -110,6 +110,8 @@ typedef std::optional<FileSpec> 
(*SymbolLocatorLocateExecutableSymbolFile)(
 typedef bool (*SymbolLocatorDownloadObjectAndSymbolFile)(
     ModuleSpec &module_spec, Status &error, bool force_lookup,
     bool copy_executable);
+typedef std::optional<FileSpec> (*SymbolLocatorLocateSourceFile)(
+    const lldb::ModuleSP &module_sp, const FileSpec &original_source_file);
 using BreakpointHitCallback =
     std::function<bool(void *baton, StoppointCallbackContext *context,
                        lldb::user_id_t break_id, lldb::user_id_t 
break_loc_id)>;
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index 659190833c20d..fc17daf86a901 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -476,7 +476,7 @@ uint32_t Module::ResolveSymbolContextForAddress(
           symfile->ResolveSymbolContext(so_addr, resolve_scope, sc);
 
       if ((resolve_scope & eSymbolContextLineEntry) && sc.line_entry.IsValid())
-        sc.line_entry.ApplyFileMappings(sc.target_sp);
+        sc.line_entry.ApplyFileMappings(sc.target_sp, so_addr);
     }
 
     // Resolve the symbol if requested, but don't re-look it up if we've
diff --git a/lldb/source/Core/PluginManager.cpp 
b/lldb/source/Core/PluginManager.cpp
index 64130d700a006..5b8bcc7cc68ef 100644
--- a/lldb/source/Core/PluginManager.cpp
+++ b/lldb/source/Core/PluginManager.cpp
@@ -1476,18 +1476,21 @@ struct SymbolLocatorInstance
       SymbolLocatorLocateExecutableSymbolFile locate_executable_symbol_file,
       SymbolLocatorDownloadObjectAndSymbolFile download_object_symbol_file,
       SymbolLocatorFindSymbolFileInBundle find_symbol_file_in_bundle,
+      SymbolLocatorLocateSourceFile locate_source_file,
       DebuggerInitializeCallback debugger_init_callback)
       : PluginInstance<SymbolLocatorCreateInstance>(
             name, description, create_callback, debugger_init_callback),
         locate_executable_object_file(locate_executable_object_file),
         locate_executable_symbol_file(locate_executable_symbol_file),
         download_object_symbol_file(download_object_symbol_file),
-        find_symbol_file_in_bundle(find_symbol_file_in_bundle) {}
+        find_symbol_file_in_bundle(find_symbol_file_in_bundle),
+        locate_source_file(locate_source_file) {}
 
   SymbolLocatorLocateExecutableObjectFile locate_executable_object_file;
   SymbolLocatorLocateExecutableSymbolFile locate_executable_symbol_file;
   SymbolLocatorDownloadObjectAndSymbolFile download_object_symbol_file;
   SymbolLocatorFindSymbolFileInBundle find_symbol_file_in_bundle;
+  SymbolLocatorLocateSourceFile locate_source_file;
 };
 typedef PluginInstances<SymbolLocatorInstance> SymbolLocatorInstances;
 
@@ -1503,11 +1506,12 @@ bool PluginManager::RegisterPlugin(
     SymbolLocatorLocateExecutableSymbolFile locate_executable_symbol_file,
     SymbolLocatorDownloadObjectAndSymbolFile download_object_symbol_file,
     SymbolLocatorFindSymbolFileInBundle find_symbol_file_in_bundle,
+    SymbolLocatorLocateSourceFile locate_source_file,
     DebuggerInitializeCallback debugger_init_callback) {
   return GetSymbolLocatorInstances().RegisterPlugin(
       name, description, create_callback, locate_executable_object_file,
       locate_executable_symbol_file, download_object_symbol_file,
-      find_symbol_file_in_bundle, debugger_init_callback);
+      find_symbol_file_in_bundle, locate_source_file, debugger_init_callback);
 }
 
 bool PluginManager::UnregisterPlugin(
@@ -1591,6 +1595,20 @@ FileSpec PluginManager::FindSymbolFileInBundle(const 
FileSpec &symfile_bundle,
   return {};
 }
 
+FileSpec PluginManager::LocateSourceFile(const lldb::ModuleSP &module_sp,
+                                         const FileSpec &original_source_file) 
{
+  auto instances = GetSymbolLocatorInstances().GetSnapshot();
+  for (auto &instance : instances) {
+    if (instance.locate_source_file) {
+      std::optional<FileSpec> result =
+          instance.locate_source_file(module_sp, original_source_file);
+      if (result)
+        return *result;
+    }
+  }
+  return {};
+}
+
 #pragma mark Trace
 
 struct TraceInstance
diff --git 
a/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.cpp 
b/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.cpp
index a09bb356e3a8c..bdef57f0671e1 100644
--- a/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.cpp
+++ b/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.cpp
@@ -111,7 +111,7 @@ void SymbolLocatorDebuginfod::Initialize() {
     PluginManager::RegisterPlugin(
         GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance,
         LocateExecutableObjectFile, LocateExecutableSymbolFile, nullptr,
-        nullptr, SymbolLocatorDebuginfod::DebuggerInitialize);
+        nullptr, nullptr, SymbolLocatorDebuginfod::DebuggerInitialize);
     llvm::HTTPClient::initialize();
   });
 }
diff --git a/lldb/source/Symbol/LineEntry.cpp b/lldb/source/Symbol/LineEntry.cpp
index dcfbac8789863..fc03e004b58fb 100644
--- a/lldb/source/Symbol/LineEntry.cpp
+++ b/lldb/source/Symbol/LineEntry.cpp
@@ -7,6 +7,9 @@
 
//===----------------------------------------------------------------------===//
 
 #include "lldb/Symbol/LineEntry.h"
+#include "lldb/Core/Address.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
 #include "lldb/Symbol/CompileUnit.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
@@ -242,8 +245,22 @@ AddressRange LineEntry::GetSameLineContiguousAddressRange(
   return complete_line_range;
 }
 
-void LineEntry::ApplyFileMappings(lldb::TargetSP target_sp) {
+void LineEntry::ApplyFileMappings(lldb::TargetSP target_sp,
+                                  const Address &address) {
   if (target_sp) {
+    // Try SymbolLocator plugins for source file resolution. The plugin
+    // handles the fast path internally (returns immediately when no
+    // scripted locators are registered).
+    lldb::ModuleSP module_sp = address.GetModule();
+    if (module_sp) {
+      FileSpec resolved = PluginManager::LocateSourceFile(
+          module_sp, original_file_sp->GetSpecOnly());
+      if (resolved) {
+        file_sp = std::make_shared<SupportFile>(resolved);
+        return;
+      }
+    }
+
     // Apply any file remappings to our file.
     if (auto new_file_spec = target_sp->GetSourcePathMap().FindFile(
             original_file_sp->GetSpecOnly())) {
diff --git a/lldb/source/Target/StackFrame.cpp 
b/lldb/source/Target/StackFrame.cpp
index 9fb26176e43c0..ec3c3a9b32010 100644
--- a/lldb/source/Target/StackFrame.cpp
+++ b/lldb/source/Target/StackFrame.cpp
@@ -412,7 +412,7 @@ StackFrame::GetSymbolContext(SymbolContextItem 
resolve_scope) {
         if ((resolved & eSymbolContextLineEntry) &&
             !m_sc.line_entry.IsValid()) {
           m_sc.line_entry = sc.line_entry;
-          m_sc.line_entry.ApplyFileMappings(m_sc.target_sp);
+          m_sc.line_entry.ApplyFileMappings(m_sc.target_sp, lookup_addr);
         }
       }
     } else {
diff --git a/lldb/source/Target/StackFrameList.cpp 
b/lldb/source/Target/StackFrameList.cpp
index 825d538e3815b..5c0e5180bf3c9 100644
--- a/lldb/source/Target/StackFrameList.cpp
+++ b/lldb/source/Target/StackFrameList.cpp
@@ -563,7 +563,8 @@ bool StackFrameList::FetchFramesUpTo(uint32_t end_idx,
 
       while (unwind_sc.GetParentOfInlinedScope(
           curr_frame_address, next_frame_sc, next_frame_address)) {
-        next_frame_sc.line_entry.ApplyFileMappings(target_sp);
+        next_frame_sc.line_entry.ApplyFileMappings(target_sp,
+                                                   curr_frame_address);
         behaves_like_zeroth_frame = false;
         StackFrameSP frame_sp(new StackFrame(
             m_thread.shared_from_this(), m_frames.size(), idx,
diff --git a/lldb/source/Target/ThreadPlanStepRange.cpp 
b/lldb/source/Target/ThreadPlanStepRange.cpp
index 3a9deb6f5c6fd..c75bd68d2e4bb 100644
--- a/lldb/source/Target/ThreadPlanStepRange.cpp
+++ b/lldb/source/Target/ThreadPlanStepRange.cpp
@@ -432,8 +432,8 @@ bool ThreadPlanStepRange::SetNextBranchBreakpoint() {
                 std::make_shared<SupportFile>(call_site_file_spec);
             top_most_line_entry.range = range;
             top_most_line_entry.file_sp = std::make_shared<SupportFile>();
-            top_most_line_entry.ApplyFileMappings(
-                GetThread().CalculateTarget());
+            
top_most_line_entry.ApplyFileMappings(GetThread().CalculateTarget(),
+                                                  range.GetBaseAddress());
             if (!top_most_line_entry.file_sp->GetSpecOnly())
               top_most_line_entry.file_sp =
                   top_most_line_entry.original_file_sp;

>From 9952932b304e086583420b7e14cfcc6ac666f8c2 Mon Sep 17 00:00:00 2001
From: Rahul Reddy Chamala <[email protected]>
Date: Thu, 26 Feb 2026 14:59:08 -0800
Subject: [PATCH 2/2] [lldb] Add ScriptedSymbolLocator Python interface bridge

Add the abstract interface, Python bridge, SWIG bindings, and all
plumbing needed for Python classes to implement symbol locator callbacks.

New files:
- ScriptedSymbolLocatorInterface.h: abstract base with all 4 callback
  virtual methods (LocateSourceFile, LocateExecutableObjectFile,
  LocateExecutableSymbolFile, DownloadObjectAndSymbolFile)
- ScriptedSymbolLocatorPythonInterface.h/.cpp: Python interface class
  using Dispatch<FileSpec> for locate_source_file; the remaining 3
  callbacks are no-op stubs pending SBModuleSpec SWIG bridge

Modified files wire up the new interface:
- lldb-forward.h: forward decl + ScriptedSymbolLocatorInterfaceSP typedef
- SBFileSpec.h, SBModule.h: friend class ScriptInterpreter
- ScriptInterpreter.h/.cpp: CreateScriptedSymbolLocatorInterface() virtual,
  GetOpaqueTypeFromSBFileSpec/SBModule helpers
- ScriptedPythonInterface.h/.cpp: Transform(ModuleSP), Transform(string),
  ExtractValueFromPythonObject<FileSpec/ModuleSP> specializations
- SWIGPythonBridge.h + python-wrapper.swig: CastPyObjectToSBFileSpec/SBModule
- CMakeLists, Interfaces registration, ScriptInterpreterPython overrides
- PythonTestSuite.cpp: test stubs for new cast functions
---
 lldb/bindings/python/python-wrapper.swig      | 24 +++++
 lldb/include/lldb/API/SBFileSpec.h            |  5 +
 lldb/include/lldb/API/SBModule.h              |  1 +
 .../ScriptedSymbolLocatorInterface.h          | 52 +++++++++++
 .../lldb/Interpreter/ScriptInterpreter.h      | 10 ++
 lldb/include/lldb/lldb-forward.h              |  3 +
 lldb/source/Interpreter/ScriptInterpreter.cpp | 12 +++
 .../Python/Interfaces/CMakeLists.txt          |  1 +
 .../ScriptInterpreterPythonInterfaces.cpp     |  2 +
 .../ScriptInterpreterPythonInterfaces.h       |  1 +
 .../Interfaces/ScriptedPythonInterface.cpp    | 35 +++++++
 .../Interfaces/ScriptedPythonInterface.h      | 22 +++++
 .../ScriptedSymbolLocatorPythonInterface.cpp  | 92 +++++++++++++++++++
 .../ScriptedSymbolLocatorPythonInterface.h    | 62 +++++++++++++
 .../Python/SWIGPythonBridge.h                 |  2 +
 .../Python/ScriptInterpreterPython.cpp        |  5 +
 .../Python/ScriptInterpreterPythonImpl.h      |  3 +
 .../Python/PythonTestSuite.cpp                | 10 ++
 18 files changed, 342 insertions(+)
 create mode 100644 
lldb/include/lldb/Interpreter/Interfaces/ScriptedSymbolLocatorInterface.h
 create mode 100644 
lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedSymbolLocatorPythonInterface.cpp
 create mode 100644 
lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedSymbolLocatorPythonInterface.h

diff --git a/lldb/bindings/python/python-wrapper.swig 
b/lldb/bindings/python/python-wrapper.swig
index bf59569920470..d6c3a423e1e2c 100644
--- a/lldb/bindings/python/python-wrapper.swig
+++ b/lldb/bindings/python/python-wrapper.swig
@@ -595,6 +595,30 @@ void 
*lldb_private::python::LLDBSWIGPython_CastPyObjectToSBFrameList(PyObject *d
   return sb_ptr;
 }
 
+void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBFileSpec(PyObject 
*data) {
+  lldb::SBFileSpec *sb_ptr = NULL;
+
+  int valid_cast = SWIG_ConvertPtr(data, (void **)&sb_ptr,
+                                   SWIGTYPE_p_lldb__SBFileSpec, 0);
+
+  if (valid_cast == -1)
+    return NULL;
+
+  return sb_ptr;
+}
+
+void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBModule(PyObject 
*data) {
+  lldb::SBModule *sb_ptr = NULL;
+
+  int valid_cast = SWIG_ConvertPtr(data, (void **)&sb_ptr,
+                                   SWIGTYPE_p_lldb__SBModule, 0);
+
+  if (valid_cast == -1)
+    return NULL;
+
+  return sb_ptr;
+}
+
 bool lldb_private::python::SWIGBridge::LLDBSwigPythonCallCommand(
     const char *python_function_name, const char *session_dictionary_name,
     lldb::DebuggerSP debugger, const char *args,
diff --git a/lldb/include/lldb/API/SBFileSpec.h 
b/lldb/include/lldb/API/SBFileSpec.h
index 36641843aabeb..4b0b640dd4dbc 100644
--- a/lldb/include/lldb/API/SBFileSpec.h
+++ b/lldb/include/lldb/API/SBFileSpec.h
@@ -11,6 +11,10 @@
 
 #include "lldb/API/SBDefines.h"
 
+namespace lldb_private {
+class ScriptInterpreter;
+}
+
 namespace lldb {
 
 class LLDB_API SBFileSpec {
@@ -79,6 +83,7 @@ class LLDB_API SBFileSpec {
   friend class SBThread;
   friend class SBTrace;
   friend class SBSaveCoreOptions;
+  friend class lldb_private::ScriptInterpreter;
 
   SBFileSpec(const lldb_private::FileSpec &fspec);
 
diff --git a/lldb/include/lldb/API/SBModule.h b/lldb/include/lldb/API/SBModule.h
index 4009ca1461e51..3e8e5b99f6404 100644
--- a/lldb/include/lldb/API/SBModule.h
+++ b/lldb/include/lldb/API/SBModule.h
@@ -311,6 +311,7 @@ class LLDB_API SBModule {
   friend class SBType;
 
   friend class lldb_private::python::SWIGBridge;
+  friend class lldb_private::ScriptInterpreter;
 
   explicit SBModule(const lldb::ModuleSP &module_sp);
 
diff --git 
a/lldb/include/lldb/Interpreter/Interfaces/ScriptedSymbolLocatorInterface.h 
b/lldb/include/lldb/Interpreter/Interfaces/ScriptedSymbolLocatorInterface.h
new file mode 100644
index 0000000000000..b81c73698d918
--- /dev/null
+++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedSymbolLocatorInterface.h
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_INTERPRETER_INTERFACES_SCRIPTEDSYMBOLLOCATORINTERFACE_H
+#define LLDB_INTERPRETER_INTERFACES_SCRIPTEDSYMBOLLOCATORINTERFACE_H
+
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Interpreter/Interfaces/ScriptedInterface.h"
+#include "lldb/Utility/Status.h"
+
+#include "lldb/lldb-private.h"
+
+#include <optional>
+#include <string>
+
+namespace lldb_private {
+class ScriptedSymbolLocatorInterface : virtual public ScriptedInterface {
+public:
+  virtual llvm::Expected<StructuredData::GenericSP>
+  CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx,
+                     StructuredData::DictionarySP args_sp,
+                     StructuredData::Generic *script_obj = nullptr) = 0;
+
+  virtual std::optional<FileSpec>
+  LocateSourceFile(const lldb::ModuleSP &module_sp,
+                   const FileSpec &original_source_file, Status &error) {
+    return {};
+  }
+
+  virtual std::optional<ModuleSpec>
+  LocateExecutableObjectFile(const ModuleSpec &module_spec, Status &error) {
+    return {};
+  }
+
+  virtual std::optional<FileSpec>
+  LocateExecutableSymbolFile(const ModuleSpec &module_spec, Status &error) {
+    return {};
+  }
+
+  virtual bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
+                                           Status &error) {
+    return false;
+  }
+};
+} // namespace lldb_private
+
+#endif // LLDB_INTERPRETER_INTERFACES_SCRIPTEDSYMBOLLOCATORINTERFACE_H
diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h 
b/lldb/include/lldb/Interpreter/ScriptInterpreter.h
index 557d73a415452..f4d12a64e1e25 100644
--- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h
+++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h
@@ -33,6 +33,7 @@
 #include "lldb/Interpreter/Interfaces/ScriptedFrameProviderInterface.h"
 #include "lldb/Interpreter/Interfaces/ScriptedPlatformInterface.h"
 #include "lldb/Interpreter/Interfaces/ScriptedProcessInterface.h"
+#include "lldb/Interpreter/Interfaces/ScriptedSymbolLocatorInterface.h"
 #include "lldb/Interpreter/Interfaces/ScriptedThreadInterface.h"
 #include "lldb/Interpreter/ScriptObject.h"
 #include "lldb/Symbol/SymbolContext.h"
@@ -567,6 +568,11 @@ class ScriptInterpreter : public PluginInterface {
     return {};
   }
 
+  virtual lldb::ScriptedSymbolLocatorInterfaceSP
+  CreateScriptedSymbolLocatorInterface() {
+    return {};
+  }
+
   virtual StructuredData::ObjectSP
   CreateStructuredDataFromScriptObject(ScriptObject obj) {
     return {};
@@ -612,6 +618,10 @@ class ScriptInterpreter : public PluginInterface {
   lldb::ValueObjectSP
   GetOpaqueTypeFromSBValue(const lldb::SBValue &value) const;
 
+  FileSpec GetOpaqueTypeFromSBFileSpec(const lldb::SBFileSpec &file_spec) 
const;
+
+  lldb::ModuleSP GetOpaqueTypeFromSBModule(const lldb::SBModule &module) const;
+
 protected:
   Debugger &m_debugger;
   lldb::ScriptLanguage m_script_lang;
diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h
index ccfe5efa19e1d..c0f65b09616a3 100644
--- a/lldb/include/lldb/lldb-forward.h
+++ b/lldb/include/lldb/lldb-forward.h
@@ -196,6 +196,7 @@ class ScriptedProcessInterface;
 class ScriptedStopHookInterface;
 class ScriptedThreadInterface;
 class ScriptedThreadPlanInterface;
+class ScriptedSymbolLocatorInterface;
 class ScriptedSyntheticChildren;
 class SearchFilter;
 class Section;
@@ -431,6 +432,8 @@ typedef 
std::shared_ptr<lldb_private::ScriptedThreadPlanInterface>
     ScriptedThreadPlanInterfaceSP;
 typedef std::shared_ptr<lldb_private::ScriptedBreakpointInterface>
     ScriptedBreakpointInterfaceSP;
+typedef std::shared_ptr<lldb_private::ScriptedSymbolLocatorInterface>
+    ScriptedSymbolLocatorInterfaceSP;
 typedef std::shared_ptr<lldb_private::Section> SectionSP;
 typedef std::unique_ptr<lldb_private::SectionList> SectionListUP;
 typedef std::weak_ptr<lldb_private::Section> SectionWP;
diff --git a/lldb/source/Interpreter/ScriptInterpreter.cpp 
b/lldb/source/Interpreter/ScriptInterpreter.cpp
index 5e8478c2670bb..331e1d8377f48 100644
--- a/lldb/source/Interpreter/ScriptInterpreter.cpp
+++ b/lldb/source/Interpreter/ScriptInterpreter.cpp
@@ -7,6 +7,8 @@
 
//===----------------------------------------------------------------------===//
 
 #include "lldb/Interpreter/ScriptInterpreter.h"
+#include "lldb/API/SBFileSpec.h"
+#include "lldb/API/SBModule.h"
 #include "lldb/Core/Debugger.h"
 #include "lldb/Host/ConnectionFileDescriptor.h"
 #include "lldb/Host/Pipe.h"
@@ -172,6 +174,16 @@ ScriptInterpreter::GetOpaqueTypeFromSBValue(const 
lldb::SBValue &value) const {
   return locker.GetLockedSP(*value.m_opaque_sp);
 }
 
+FileSpec ScriptInterpreter::GetOpaqueTypeFromSBFileSpec(
+    const lldb::SBFileSpec &file_spec) const {
+  return file_spec.ref();
+}
+
+lldb::ModuleSP ScriptInterpreter::GetOpaqueTypeFromSBModule(
+    const lldb::SBModule &module) const {
+  return module.GetSP();
+}
+
 lldb::ScriptLanguage
 ScriptInterpreter::StringToLanguage(const llvm::StringRef &language) {
   if (language.equals_insensitive(LanguageToString(eScriptLanguageNone)))
diff --git 
a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt 
b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt
index 50569cdefaafa..026111d92354e 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt
@@ -29,6 +29,7 @@ add_lldb_library(lldbPluginScriptInterpreterPythonInterfaces 
PLUGIN
   ScriptedPythonInterface.cpp
   ScriptedStopHookPythonInterface.cpp
   ScriptedBreakpointPythonInterface.cpp
+  ScriptedSymbolLocatorPythonInterface.cpp
   ScriptedThreadPlanPythonInterface.cpp
   ScriptedThreadPythonInterface.cpp
 
diff --git 
a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.cpp
 
b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.cpp
index 5fbccb67fe173..51c2566513c98 100644
--- 
a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.cpp
+++ 
b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.cpp
@@ -27,6 +27,7 @@ void ScriptInterpreterPythonInterfaces::Initialize() {
   ScriptedProcessPythonInterface::Initialize();
   ScriptedStopHookPythonInterface::Initialize();
   ScriptedBreakpointPythonInterface::Initialize();
+  ScriptedSymbolLocatorPythonInterface::Initialize();
   ScriptedThreadPlanPythonInterface::Initialize();
   ScriptedFrameProviderPythonInterface::Initialize();
 }
@@ -37,6 +38,7 @@ void ScriptInterpreterPythonInterfaces::Terminate() {
   ScriptedProcessPythonInterface::Terminate();
   ScriptedStopHookPythonInterface::Terminate();
   ScriptedBreakpointPythonInterface::Terminate();
+  ScriptedSymbolLocatorPythonInterface::Terminate();
   ScriptedThreadPlanPythonInterface::Terminate();
   ScriptedFrameProviderPythonInterface::Terminate();
 }
diff --git 
a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h
 
b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h
index 58b19760cb8e1..0eec005b87b21 100644
--- 
a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h
+++ 
b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h
@@ -19,6 +19,7 @@
 #include "ScriptedPlatformPythonInterface.h"
 #include "ScriptedProcessPythonInterface.h"
 #include "ScriptedStopHookPythonInterface.h"
+#include "ScriptedSymbolLocatorPythonInterface.h"
 #include "ScriptedThreadPlanPythonInterface.h"
 
 namespace lldb_private {
diff --git 
a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp
 
b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp
index 68aea7d223f7b..eb24fa98c3183 100644
--- 
a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp
+++ 
b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp
@@ -308,3 +308,38 @@ 
ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::ValueObjectListSP>(
 
   return out;
 }
+
+template <>
+FileSpec ScriptedPythonInterface::ExtractValueFromPythonObject<FileSpec>(
+    python::PythonObject &p, Status &error) {
+  if (!p.IsAllocated())
+    return {};
+
+  void *sb_file_spec_ptr =
+      python::LLDBSWIGPython_CastPyObjectToSBFileSpec(p.get());
+  if (!sb_file_spec_ptr) {
+    error = Status::FromErrorString("Couldn't cast to SBFileSpec");
+    return {};
+  }
+
+  auto *sb_file_spec = reinterpret_cast<lldb::SBFileSpec *>(sb_file_spec_ptr);
+  FileSpec result = m_interpreter.GetOpaqueTypeFromSBFileSpec(*sb_file_spec);
+  return result;
+}
+
+template <>
+lldb::ModuleSP
+ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::ModuleSP>(
+    python::PythonObject &p, Status &error) {
+  if (!p.IsAllocated())
+    return {};
+
+  void *sb_module_ptr = python::LLDBSWIGPython_CastPyObjectToSBModule(p.get());
+  if (!sb_module_ptr) {
+    error = Status::FromErrorString("Couldn't cast to SBModule");
+    return {};
+  }
+
+  auto *sb_module = reinterpret_cast<lldb::SBModule *>(sb_module_ptr);
+  return m_interpreter.GetOpaqueTypeFromSBModule(*sb_module);
+}
diff --git 
a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
 
b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
index 055d4dc8707d6..771bc42851da2 100644
--- 
a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
+++ 
b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
@@ -657,6 +657,14 @@ class ScriptedPythonInterface : virtual public 
ScriptedInterface {
     return python::SWIGBridge::ToSWIGWrapper(arg);
   }
 
+  python::PythonObject Transform(lldb::ModuleSP arg) {
+    return python::SWIGBridge::ToSWIGWrapper(arg);
+  }
+
+  python::PythonObject Transform(const std::string &arg) {
+    return python::PythonString(arg);
+  }
+
   template <typename T, typename U>
   void ReverseTransform(T &original_arg, U transformed_arg, Status &error) {
     // If U is not a PythonObject, don't touch it!
@@ -668,6 +676,11 @@ class ScriptedPythonInterface : virtual public 
ScriptedInterface {
     original_arg = ExtractValueFromPythonObject<T>(transformed_arg, error);
   }
 
+  void ReverseTransform(std::string &original_arg,
+                        python::PythonObject transformed_arg, Status &error) {
+    // No-op: string arguments are input-only, no reverse transformation 
needed.
+  }
+
   void ReverseTransform(bool &original_arg,
                         python::PythonObject transformed_arg, Status &error) {
     python::PythonBoolean boolean_arg = python::PythonBoolean(
@@ -825,6 +838,15 @@ lldb::ValueObjectListSP
 ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::ValueObjectListSP>(
     python::PythonObject &p, Status &error);
 
+template <>
+FileSpec ScriptedPythonInterface::ExtractValueFromPythonObject<FileSpec>(
+    python::PythonObject &p, Status &error);
+
+template <>
+lldb::ModuleSP
+ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::ModuleSP>(
+    python::PythonObject &p, Status &error);
+
 } // namespace lldb_private
 
 #endif // 
LLDB_SOURCE_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDPYTHONINTERFACE_H
diff --git 
a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedSymbolLocatorPythonInterface.cpp
 
b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedSymbolLocatorPythonInterface.cpp
new file mode 100644
index 0000000000000..e6ed156674d88
--- /dev/null
+++ 
b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedSymbolLocatorPythonInterface.cpp
@@ -0,0 +1,92 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/lldb-enumerations.h"
+
+// clang-format off
+// LLDB Python header must be included first
+#include "../lldb-python.h"
+//clang-format on
+
+#include "../SWIGPythonBridge.h"
+#include "../ScriptInterpreterPythonImpl.h"
+#include "ScriptedSymbolLocatorPythonInterface.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::python;
+
+ScriptedSymbolLocatorPythonInterface::ScriptedSymbolLocatorPythonInterface(
+    ScriptInterpreterPythonImpl &interpreter)
+    : ScriptedSymbolLocatorInterface(), ScriptedPythonInterface(interpreter) {}
+
+llvm::Expected<StructuredData::GenericSP>
+ScriptedSymbolLocatorPythonInterface::CreatePluginObject(
+    const llvm::StringRef class_name, ExecutionContext &exe_ctx,
+    StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) 
{
+  ExecutionContextRefSP exe_ctx_ref_sp =
+      std::make_shared<ExecutionContextRef>(exe_ctx);
+  StructuredDataImpl sd_impl(args_sp);
+  return ScriptedPythonInterface::CreatePluginObject(class_name, script_obj,
+                                                     exe_ctx_ref_sp, sd_impl);
+}
+
+std::optional<FileSpec> ScriptedSymbolLocatorPythonInterface::LocateSourceFile(
+    const lldb::ModuleSP &module_sp, const FileSpec &original_source_file,
+    Status &error) {
+  std::string source_path = original_source_file.GetPath();
+  lldb::ModuleSP module_copy(module_sp);
+
+  FileSpec file_spec =
+      Dispatch<FileSpec>("locate_source_file", error, module_copy, 
source_path);
+
+  if (error.Fail() || !file_spec)
+    return {};
+
+  return file_spec;
+}
+
+std::optional<ModuleSpec>
+ScriptedSymbolLocatorPythonInterface::LocateExecutableObjectFile(
+    const ModuleSpec &module_spec, Status &error) {
+  // Not yet implemented — requires SBModuleSpec SWIG bridge.
+  return {};
+}
+
+std::optional<FileSpec>
+ScriptedSymbolLocatorPythonInterface::LocateExecutableSymbolFile(
+    const ModuleSpec &module_spec, Status &error) {
+  // Not yet implemented — requires SBModuleSpec SWIG bridge.
+  return {};
+}
+
+bool ScriptedSymbolLocatorPythonInterface::DownloadObjectAndSymbolFile(
+    ModuleSpec &module_spec, Status &error) {
+  // Not yet implemented — requires SBModuleSpec SWIG bridge.
+  return false;
+}
+
+void ScriptedSymbolLocatorPythonInterface::Initialize() {
+  const std::vector<llvm::StringRef> ci_usages = {
+      "target symbols scripted register -C "
+      "<script-class> [-k <key> -v <value> ...]"};
+  const std::vector<llvm::StringRef> api_usages = {
+      "SBDebugger.RegisterScriptedSymbolLocator(class_name, args_dict)"};
+  PluginManager::RegisterPlugin(
+      GetPluginNameStatic(),
+      llvm::StringRef("Scripted symbol locator Python interface"),
+      CreateInstance, eScriptLanguagePython, {ci_usages, api_usages});
+}
+
+void ScriptedSymbolLocatorPythonInterface::Terminate() {
+  PluginManager::UnregisterPlugin(CreateInstance);
+}
diff --git 
a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedSymbolLocatorPythonInterface.h
 
b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedSymbolLocatorPythonInterface.h
new file mode 100644
index 0000000000000..f806dddf1d5a7
--- /dev/null
+++ 
b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedSymbolLocatorPythonInterface.h
@@ -0,0 +1,62 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef 
LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDSYMBOLLOCATORPYTHONINTERFACE_H
+#define 
LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDSYMBOLLOCATORPYTHONINTERFACE_H
+
+#include "lldb/Interpreter/Interfaces/ScriptedSymbolLocatorInterface.h"
+
+#include "ScriptedPythonInterface.h"
+
+namespace lldb_private {
+class ScriptedSymbolLocatorPythonInterface
+    : public ScriptedSymbolLocatorInterface,
+      public ScriptedPythonInterface,
+      public PluginInterface {
+public:
+  ScriptedSymbolLocatorPythonInterface(
+      ScriptInterpreterPythonImpl &interpreter);
+
+  llvm::Expected<StructuredData::GenericSP>
+  CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx,
+                     StructuredData::DictionarySP args_sp,
+                     StructuredData::Generic *script_obj = nullptr) override;
+
+  llvm::SmallVector<AbstractMethodRequirement>
+  GetAbstractMethodRequirements() const override {
+    return llvm::SmallVector<AbstractMethodRequirement>(
+        {{"locate_source_file", 2}});
+  }
+
+  std::optional<FileSpec> LocateSourceFile(const lldb::ModuleSP &module_sp,
+                                           const FileSpec 
&original_source_file,
+                                           Status &error) override;
+
+  std::optional<ModuleSpec>
+  LocateExecutableObjectFile(const ModuleSpec &module_spec,
+                             Status &error) override;
+
+  std::optional<FileSpec>
+  LocateExecutableSymbolFile(const ModuleSpec &module_spec,
+                             Status &error) override;
+
+  bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
+                                   Status &error) override;
+
+  static void Initialize();
+  static void Terminate();
+
+  static llvm::StringRef GetPluginNameStatic() {
+    return "ScriptedSymbolLocatorPythonInterface";
+  }
+
+  llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
+};
+} // namespace lldb_private
+
+#endif // 
LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDSYMBOLLOCATORPYTHONINTERFACE_H
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h 
b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
index 16ad895ee9f26..a8c7564fd5f81 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
@@ -269,6 +269,8 @@ void *LLDBSWIGPython_CastPyObjectToSBValueList(PyObject 
*data);
 void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *data);
 void *LLDBSWIGPython_CastPyObjectToSBExecutionContext(PyObject *data);
 void *LLDBSWIGPython_CastPyObjectToSBFrameList(PyObject *data);
+void *LLDBSWIGPython_CastPyObjectToSBFileSpec(PyObject *data);
+void *LLDBSWIGPython_CastPyObjectToSBModule(PyObject *data);
 } // namespace python
 
 } // namespace lldb_private
diff --git 
a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp 
b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index 3daa24472864e..f11df7c97fc75 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -1513,6 +1513,11 @@ 
ScriptInterpreterPythonImpl::CreateScriptedBreakpointInterface() {
   return std::make_shared<ScriptedBreakpointPythonInterface>(*this);
 }
 
+ScriptedSymbolLocatorInterfaceSP
+ScriptInterpreterPythonImpl::CreateScriptedSymbolLocatorInterface() {
+  return std::make_shared<ScriptedSymbolLocatorPythonInterface>(*this);
+}
+
 ScriptedThreadInterfaceSP
 ScriptInterpreterPythonImpl::CreateScriptedThreadInterface() {
   return std::make_shared<ScriptedThreadPythonInterface>(*this);
diff --git 
a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h 
b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
index f08b2334f9ccb..874f1eca0e1c1 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
@@ -93,6 +93,9 @@ class ScriptInterpreterPythonImpl : public 
ScriptInterpreterPython {
   lldb::ScriptedBreakpointInterfaceSP
   CreateScriptedBreakpointInterface() override;
 
+  lldb::ScriptedSymbolLocatorInterfaceSP
+  CreateScriptedSymbolLocatorInterface() override;
+
   lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() override;
 
   lldb::ScriptedFrameInterfaceSP CreateScriptedFrameInterface() override;
diff --git a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp 
b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
index 5694aeeff3e5b..a669100ea4314 100644
--- a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
+++ b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
@@ -171,6 +171,16 @@ 
lldb_private::python::LLDBSWIGPython_CastPyObjectToSBFrameList(PyObject *data) {
   return nullptr;
 }
 
+void *
+lldb_private::python::LLDBSWIGPython_CastPyObjectToSBFileSpec(PyObject *data) {
+  return nullptr;
+}
+
+void *
+lldb_private::python::LLDBSWIGPython_CastPyObjectToSBModule(PyObject *data) {
+  return nullptr;
+}
+
 lldb::ValueObjectSP
 lldb_private::python::SWIGBridge::LLDBSWIGPython_GetValueObjectSPFromSBValue(
     void *data) {

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

Reply via email to