llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: None (rchamala)

<details>
<summary>Changes</summary>

## Summary                                                        
                                                                    
  Adds a new `SymbolLocatorScripted` plugin that allows Python scripts to 
implement custom symbol and source file resolution logic. This enables 
downstream users to build custom symbol servers, source file remapping, and 
build artifact resolution entirely in Python.
                                                                    
  ### Changes

  - Adds `LocateSourceFile()` to the SymbolLocator plugin interface, called 
during source path resolution with a fully loaded `ModuleSP`, so the plugin has 
access to the module's UUID, file paths, and symbols.
  - Adds `SymbolLocatorScripted` plugin that delegates all four SymbolLocator 
methods (`LocateExecutableObjectFile`, `LocateExecutableSymbolFile`, 
`DownloadObjectAndSymbolFile`, `LocateSourceFile`) to a user-provided Python 
class.
  - Adds `ScriptedSymbolLocatorPythonInterface` to bridge C++ calls to Python, 
with proper GIL management and error handling.
  - Results for `LocateSourceFile` are cached per (module UUID, source file) 
pair.
  - The Python class is configured via: `settings set 
plugin.symbol-locator.scripted.script-class module.ClassName`

  ### Python class interface

  ```python
  class MyLocator:
      def __init__(self, exe_ctx, args): ...
      def locate_source_file(self, module, original_source_file):
  ...
      def locate_executable_object_file(self, module_spec): ...
      def locate_executable_symbol_file(self, module_spec,
  default_search_paths): ...
      def download_object_and_symbol_file(self, module_spec,
  force_lookup, copy_executable): ...
```

  ### Test plan
```
  Added TestScriptedSymbolLocator.py with 3 test cases:
  - test_locate_source_file — verifies the locator resolves source
  files, receives a valid SBModule with UUID, and remaps paths correctly
  - test_locate_source_file_none_fallthrough — verifies returning
  None falls through to default LLDB resolution, and that having no script
  class set works normally
  - test_invalid_script_class — verifies graceful handling of
  invalid class names without crashing
```

---

Patch is 56.37 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/181334.diff


29 Files Affected:

- (modified) lldb/include/lldb/Core/PluginManager.h (+4) 
- (added) 
lldb/include/lldb/Interpreter/Interfaces/ScriptedSymbolLocatorInterface.h (+57) 
- (modified) lldb/include/lldb/Interpreter/ScriptInterpreter.h (+6) 
- (modified) lldb/include/lldb/Symbol/LineEntry.h (+1-1) 
- (modified) lldb/include/lldb/lldb-forward.h (+3) 
- (modified) lldb/include/lldb/lldb-private-interfaces.h (+2) 
- (modified) lldb/source/Core/Module.cpp (+1-1) 
- (modified) lldb/source/Core/PluginManager.cpp (+20-2) 
- (modified) 
lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt (+1-2) 
- (modified) 
lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h
 (+1) 
- (modified) 
lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
 (+4) 
- (added) 
lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedSymbolLocatorPythonInterface.cpp
 (+278) 
- (added) 
lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedSymbolLocatorPythonInterface.h
 (+69) 
- (modified) 
lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp (+5) 
- (modified) 
lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h 
(+5-2) 
- (modified) lldb/source/Plugins/SymbolLocator/CMakeLists.txt (+1) 
- (modified) 
lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.cpp (+1-1) 
- (added) lldb/source/Plugins/SymbolLocator/Scripted/CMakeLists.txt (+24) 
- (added) lldb/source/Plugins/SymbolLocator/Scripted/SymbolLocatorScripted.cpp 
(+271) 
- (added) lldb/source/Plugins/SymbolLocator/Scripted/SymbolLocatorScripted.h 
(+57) 
- (added) 
lldb/source/Plugins/SymbolLocator/Scripted/SymbolLocatorScriptedProperties.td 
(+7) 
- (modified) lldb/source/Symbol/LineEntry.cpp (+21-1) 
- (modified) lldb/source/Target/StackFrame.cpp (+1-1) 
- (modified) lldb/source/Target/StackFrameList.cpp (+2-1) 
- (modified) lldb/source/Target/ThreadPlanStepRange.cpp (+5-5) 
- (added) lldb/test/API/functionalities/scripted_symbol_locator/Makefile (+4) 
- (added) 
lldb/test/API/functionalities/scripted_symbol_locator/TestScriptedSymbolLocator.py
 (+156) 
- (added) lldb/test/API/functionalities/scripted_symbol_locator/main.c (+5) 
- (added) 
lldb/test/API/functionalities/scripted_symbol_locator/source_locator.py (+53) 


``````````diff
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/Interpreter/Interfaces/ScriptedSymbolLocatorInterface.h 
b/lldb/include/lldb/Interpreter/Interfaces/ScriptedSymbolLocatorInterface.h
new file mode 100644
index 0000000000000..a9edb23d164c0
--- /dev/null
+++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedSymbolLocatorInterface.h
@@ -0,0 +1,57 @@
+//===-- ScriptedSymbolLocatorInterface.h -------------------------*- C++
+//-*-===//
+//
+// 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/Core/StructuredDataImpl.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<ModuleSpec>
+  LocateExecutableObjectFile(const ModuleSpec &module_spec, Status &error) {
+    return {};
+  }
+
+  virtual std::optional<FileSpec>
+  LocateExecutableSymbolFile(const ModuleSpec &module_spec,
+                             const FileSpecList &default_search_paths,
+                             Status &error) {
+    return {};
+  }
+
+  virtual bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
+                                           Status &error, bool force_lookup,
+                                           bool copy_executable) {
+    return false;
+  }
+
+  virtual std::optional<FileSpec>
+  LocateSourceFile(const lldb::ModuleSP &module_sp,
+                   const FileSpec &original_source_file, Status &error) {
+    return {};
+  }
+};
+} // 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..bbd669fd767d3 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"
@@ -545,6 +546,11 @@ class ScriptInterpreter : public PluginInterface {
     return {};
   }
 
+  virtual lldb::ScriptedSymbolLocatorInterfaceSP
+  CreateScriptedSymbolLocatorInterface() {
+    return {};
+  }
+
   virtual lldb::ScriptedThreadPlanInterfaceSP
   CreateScriptedThreadPlanInterface() {
     return {};
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-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/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/ScriptInterpreter/Python/Interfaces/CMakeLists.txt 
b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt
index 50569cdefaafa..ddffff08095fb 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt
@@ -26,6 +26,7 @@ add_lldb_library(lldbPluginScriptInterpreterPythonInterfaces 
PLUGIN
   ScriptedFrameProviderPythonInterface.cpp
   ScriptedPlatformPythonInterface.cpp
   ScriptedProcessPythonInterface.cpp
+  ScriptedSymbolLocatorPythonInterface.cpp
   ScriptedPythonInterface.cpp
   ScriptedStopHookPythonInterface.cpp
   ScriptedBreakpointPythonInterface.cpp
@@ -42,5 +43,3 @@ add_lldb_library(lldbPluginScriptInterpreterPythonInterfaces 
PLUGIN
     ${Python3_LIBRARIES}
     ${LLDB_LIBEDIT_LIBS}
   )
-
-
diff --git 
a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h
 
b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h
index 721902ec1e253..52827d01b2495 100644
--- 
a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h
+++ 
b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h
@@ -22,6 +22,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.h
 
b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
index 4aadee584b2e2..82e6f239a3b68 100644
--- 
a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
+++ 
b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
@@ -632,6 +632,10 @@ class ScriptedPythonInterface : virtual public 
ScriptedInterface {
     return python::SWIGBridge::ToSWIGWrapper(arg);
   }
 
+  python::PythonObject Transform(lldb::ModuleSP arg) {
+    return python::SWIGBridge::ToSWIGWrapper(arg);
+  }
+
   python::PythonObject Transform(Event *arg) {
     return python::SWIGBridge::ToSWIGWrapper(arg);
   }
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..f0027bb7d386c
--- /dev/null
+++ 
b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedSymbolLocatorPythonInterface.cpp
@@ -0,0 +1,278 @@
+//===-- ScriptedSymbolLocatorPythonInterface.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 "lldb/Host/Config.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/lldb-enumerations.h"
+
+#if LLDB_ENABLE_PYTHON
+
+// 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"
+
+#include "lldb/API/SBFileSpec.h"
+#include "lldb/API/SBModuleSpec.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::python;
+using Locker = ScriptInterpreterPythonImpl::Locker;
+
+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);
+}
+
+/// Helper to convert an internal ModuleSpec to a Python SBModuleSpec object.
+/// Must be called with the GIL held.
+static PythonObject ToSWIGModuleSpec(const ModuleSpec &module_spec) {
+  // Build an SBModuleSpec using public API setters since the constructor
+  // from ModuleSpec is private.
+  SBModuleSpec sb_module_spec;
+
+  const UUID &uuid = module_spec.GetUUID();
+  if (uuid.IsValid())
+    sb_module_spec.SetUUIDBytes(uuid.GetBytes().data(), 
uuid.GetBytes().size());
+
+  const FileSpec &file = module_spec.GetFileSpec();
+  if (file)
+    sb_module_spec.SetFileSpec(SBFileSpec(file.GetPath().c_str(), false));
+
+  const FileSpec &platform_file = module_spec.GetPlatformFileSpec();
+  if (platform_file)
+    sb_module_spec.SetPlatformFileSpec(
+        SBFileSpec(platform_file.GetPath().c_str(), false));
+
+  const FileSpec &symbol_file = module_spec.GetSymbolFileSpec();
+  if (symbol_file)
+    sb_module_spec.SetSymbolFileSpec(
+        SBFileSpec(symbol_file.GetPath().c_str(), false));
+
+  const ArchSpec &arch = module_spec.GetArchitecture();
+  if (arch.IsValid())
+    sb_module_spec.SetTriple(arch.GetTriple().getTriple().c_str());
+
+  ConstString object_name = module_spec.GetObjectName();
+  if (object_name)
+    sb_module_spec.SetObjectName(object_name.GetCString());
+
+  sb_module_spec.SetObjectOffset(module_spec.GetObjectOffset());
+  sb_module_spec.SetObjectSize(module_spec.GetObjectSize());
+
+  return SWIGBridge::ToSWIGWrapper(
+      std::make_unique<SBModuleSpec>(sb_module_spec));
+}
+
+/// Helper to convert an internal FileSpec to a Python SBFileSpec object.
+/// Must be called with the GIL held.
+static PythonObject ToSWIGFileSpec(const FileSpec &file_spec) {
+  return SWIGBridge::ToSWIGWrapper(
+      std::make_unique<SBFileSpec>(file_spec.GetPath().c_str(), false));
+}
+
+std::optional<ModuleSpec>
+ScriptedSymbolLocatorPythonInterface::LocateExecutableObjectFile(
+    const ModuleSpec &module_spec, Status &error) {
+  if (!m_object_instance_sp)
+    return {};
+
+  // Acquire the GIL before creating any Python objects.
+  Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
+                 Locker::FreeLock);
+
+  PythonObject implementor(PyRefType::Borrowed,
+                           (PyObject *)m_object_instance_sp->GetValue());
+  if (!implementor.IsAllocated())
+    return {};
+
+  PythonObject py_module_spec = ToSWIGModuleSpec(module_spec);
+
+  auto expected =
+      implementor.CallMethod("locate_executable_object_file", py_module_spec);
+  if (!expected) {
+    // Consume the PythonException while the GIL is held. Converting to string
+    // forces PythonException destruction before the GIL is released.
+    std::string msg = llvm::toString(expected.takeError());
+    error = Status(msg);
+    return {};
+  }
+
+  PythonObject py_return = std::move(*expected);
+  if (!py_return.IsAllocated() || py_return.IsNone())
+    return {};
+
+  auto obj = py_return.CreateStructuredObject();
+  if (!obj)
+    return {};
+
+  llvm::StringRef value = obj->GetStringValue();
+  if (value.empty())
+    return {};
+
+  ModuleSpec result_spec(module_spec);
+  result_spec.GetFileSpec().SetPath(value);
+  return result_spec;
+}
+
+std::optional<FileSpec>
+ScriptedSymbolLocatorPythonInterface::LocateExecutableSymbolFile(
+    const ModuleSpec &module_spec, const FileSpecList &default_search_paths,
+    Status &error) {
+  if (!m_object_instance_sp)
+    return {};
+
+  // Acquire the GIL before creating any Python objects.
+  Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
+                 Locker::FreeLock);
+
+  PythonObject implementor(PyRefType::Borrowed,
+                           (PyObject *)m_object_instance_sp->GetValue());
+  if (!implementor.IsAllocated())
+    return {};
+
+  PythonObject py_module_spec = ToSWIGModuleSpec(module_spec);
+
+  // Convert FileSpecList to a Python list of SBFileSpec.
+  PythonList py_paths(default_search_paths.GetSize());
+  for (size_t i = 0; i < default_search_paths.GetSize(); i++) {
+    py_paths.SetItemAtIndex(
+        i, ToSWIGFileSpec(default_search_paths.GetFileSpecAtIndex(i)));
+  }
+
+  auto expected = implementor.CallMethod("locate_executable_symbol_file",
+                                         py_module_spec, py_paths);
+  if (!expected) {
+    std::string msg = llvm::toString(expected.takeError());
+    error = Status(msg);
+    return {};
+  }
+
+  PythonObject py_return = std::move(*expected);
+  if (!py_return.IsAllocated() || py_return.IsNone())
+    return {};
+
+  auto obj = py_return.CreateStructuredObject();
+  if (!obj)
+    return {};
+
+  llvm::StringRef value = obj->GetStringValue();
+  if (value.empty())
+    return {};
+
+  FileSpec file_spec;
+  file_spec.SetPath(value);
+  return file_spec;
+}
+
+bool ScriptedSymbolLocatorPythonInterface::DownloadObjectAndSymbolFile(
+    ModuleSpec &module_spec, Status &error, bool force_lookup,
+    bool copy_executable) {
+  if (!m_object_instance_sp)
+    return false;
+
+  // Acquire the GIL before creating any Python objects.
+  Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
+                 Locker::FreeLock);
+
+  PythonObject implementor(PyRefType::Borrowed,
+                           (PyObject *)m_object_instance_sp->GetValue());
+  if (!implementor.IsAllocated())
+    return false;
+
+  PythonObject py_module_spec = ToSWIGModuleSpec(module_spec);
+
+  auto expected = implementor.CallMet...
[truncated]

``````````

</details>


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

Reply via email to