mib updated this revision to Diff 494107.
mib added a comment.

Small fixes


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139252/new/

https://reviews.llvm.org/D139252

Files:
  lldb/bindings/python/python-swigsafecast.swig
  lldb/bindings/python/python-wrapper.swig
  lldb/examples/python/scripted_process/scripted_platform.py
  lldb/include/lldb/API/SBAttachInfo.h
  lldb/include/lldb/API/SBDebugger.h
  lldb/include/lldb/API/SBLaunchInfo.h
  lldb/include/lldb/API/SBProcess.h
  lldb/include/lldb/API/SBTarget.h
  lldb/include/lldb/Interpreter/ScriptInterpreter.h
  lldb/include/lldb/Interpreter/ScriptedPlatformInterface.h
  lldb/source/Interpreter/ScriptInterpreter.cpp
  lldb/source/Plugins/Platform/CMakeLists.txt
  lldb/source/Plugins/Platform/scripted/CMakeLists.txt
  lldb/source/Plugins/Platform/scripted/ScriptedPlatform.cpp
  lldb/source/Plugins/Platform/scripted/ScriptedPlatform.h
  lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
  lldb/source/Plugins/Process/scripted/ScriptedProcess.h
  lldb/source/Plugins/Process/scripted/ScriptedThread.cpp
  lldb/source/Plugins/Process/scripted/ScriptedThread.h
  lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
  
lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.h
  lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h
  lldb/test/API/functionalities/scripted_platform/my_scripted_platform.py
  lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp

Index: lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
===================================================================
--- lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
+++ lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
@@ -139,6 +139,26 @@
   return nullptr;
 }
 
+void *lldb_private::LLDBSWIGPython_CastPyObjectToSBProcess(PyObject *data) {
+  return nullptr;
+}
+
+void *lldb_private::LLDBSWIGPython_CastPyObjectToSBDebugger(PyObject *data) {
+  return nullptr;
+}
+
+void *lldb_private::LLDBSWIGPython_CastPyObjectToSBTarget(PyObject *data) {
+  return nullptr;
+}
+
+void *lldb_private::LLDBSWIGPython_CastPyObjectToSBAttachInfo(PyObject *data) {
+  return nullptr;
+}
+
+void *lldb_private::LLDBSWIGPython_CastPyObjectToSBLaunchInfo(PyObject *data) {
+  return nullptr;
+}
+
 void *lldb_private::LLDBSWIGPython_CastPyObjectToSBError(PyObject *data) {
   return nullptr;
 }
Index: lldb/test/API/functionalities/scripted_platform/my_scripted_platform.py
===================================================================
--- lldb/test/API/functionalities/scripted_platform/my_scripted_platform.py
+++ lldb/test/API/functionalities/scripted_platform/my_scripted_platform.py
@@ -23,6 +23,9 @@
     def get_process_info(self, pid):
         return self.processes[pid]
 
+    def attach_to_process(self, attach_info, target, debugger, error):
+        return None
+
     def launch_process(self, launch_info):
         return lldb.SBError()
 
Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h
@@ -117,6 +117,22 @@
     return python::ToSWIGWrapper(arg);
   }
 
+  python::PythonObject Transform(lldb::TargetSP arg) {
+    return python::ToSWIGWrapper(arg);
+  }
+
+  python::PythonObject Transform(lldb::DebuggerSP arg) {
+    return python::ToSWIGWrapper(arg);
+  }
+
+  python::PythonObject Transform(lldb::ProcessAttachInfoSP arg) {
+    return python::ToSWIGWrapper(arg);
+  }
+
+  python::PythonObject Transform(lldb::ProcessLaunchInfoSP arg) {
+    return python::ToSWIGWrapper(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!
@@ -198,6 +214,29 @@
 Status ScriptedPythonInterface::ExtractValueFromPythonObject<Status>(
     python::PythonObject &p, Status &error);
 
+template <>
+lldb::ProcessSP
+ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::ProcessSP>(
+    python::PythonObject &p, Status &error);
+
+template <>
+lldb::DebuggerSP
+ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::DebuggerSP>(
+    python::PythonObject &p, Status &error);
+
+template <>
+lldb::TargetSP
+ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::TargetSP>(
+    python::PythonObject &p, Status &error);
+
+template <>
+lldb::ProcessAttachInfoSP ScriptedPythonInterface::ExtractValueFromPythonObject<
+    lldb::ProcessAttachInfoSP>(python::PythonObject &p, Status &error);
+
+template <>
+lldb::ProcessLaunchInfoSP ScriptedPythonInterface::ExtractValueFromPythonObject<
+    lldb::ProcessLaunchInfoSP>(python::PythonObject &p, Status &error);
+
 template <>
 lldb::DataExtractorSP
 ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::DataExtractorSP>(
Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp
@@ -71,6 +71,81 @@
   return m_interpreter.GetDataExtractorFromSBData(*sb_data);
 }
 
+template <>
+lldb::ProcessSP
+ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::ProcessSP>(
+    python::PythonObject &p, Status &error) {
+  lldb::SBProcess *sb_process = reinterpret_cast<lldb::SBProcess *>(
+      LLDBSWIGPython_CastPyObjectToSBProcess(p.get()));
+
+  if (!sb_process) {
+    error.SetErrorString("Couldn't cast lldb::SBProcess to lldb::ProcessSP.");
+    return nullptr;
+  }
+
+  return m_interpreter.GetOpaqueTypeFromSBProcess(*sb_process);
+}
+
+template <>
+lldb::DebuggerSP
+ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::DebuggerSP>(
+    python::PythonObject &p, Status &error) {
+  lldb::SBDebugger *sb_debugger = reinterpret_cast<lldb::SBDebugger *>(
+      LLDBSWIGPython_CastPyObjectToSBDebugger(p.get()));
+
+  if (!sb_debugger) {
+    error.SetErrorString("Couldn't cast lldb::SBDebugger to lldb::DebuggerSP.");
+    return nullptr;
+  }
+
+  return m_interpreter.GetOpaqueTypeFromSBDebugger(*sb_debugger);
+}
+
+template <>
+lldb::TargetSP
+ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::TargetSP>(
+    python::PythonObject &p, Status &error) {
+  lldb::SBTarget *sb_target = reinterpret_cast<lldb::SBTarget *>(
+      LLDBSWIGPython_CastPyObjectToSBTarget(p.get()));
+
+  if (!sb_target) {
+    error.SetErrorString("Couldn't cast lldb::SBTarget to lldb::TargetSP.");
+    return nullptr;
+  }
+
+  return m_interpreter.GetOpaqueTypeFromSBTarget(*sb_target);
+}
+
+template <>
+lldb::ProcessAttachInfoSP ScriptedPythonInterface::ExtractValueFromPythonObject<
+    lldb::ProcessAttachInfoSP>(python::PythonObject &p, Status &error) {
+  lldb::SBAttachInfo *sb_attach_info = reinterpret_cast<lldb::SBAttachInfo *>(
+      LLDBSWIGPython_CastPyObjectToSBAttachInfo(p.get()));
+
+  if (!sb_attach_info) {
+    error.SetErrorString(
+        "Couldn't cast lldb::SBAttachInfo to lldb::ProcessAttachInfoSP.");
+    return nullptr;
+  }
+
+  return m_interpreter.GetOpaqueTypeFromSBAttachInfo(*sb_attach_info);
+}
+
+template <>
+lldb::ProcessLaunchInfoSP ScriptedPythonInterface::ExtractValueFromPythonObject<
+    lldb::ProcessLaunchInfoSP>(python::PythonObject &p, Status &error) {
+  lldb::SBLaunchInfo *sb_launch_info = reinterpret_cast<lldb::SBLaunchInfo *>(
+      LLDBSWIGPython_CastPyObjectToSBLaunchInfo(p.get()));
+
+  if (!sb_launch_info) {
+    error.SetErrorString(
+        "Couldn't cast lldb::SBLaunchInfo to lldb::ProcessLaunchInfoSP.");
+    return nullptr;
+  }
+
+  return m_interpreter.GetOpaqueTypeFromSBLaunchInfo(*sb_launch_info);
+}
+
 template <>
 std::optional<MemoryRegionInfo>
 ScriptedPythonInterface::ExtractValueFromPythonObject<
Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.h
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.h
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.h
@@ -32,7 +32,10 @@
 
   StructuredData::DictionarySP GetProcessInfo(lldb::pid_t) override;
 
-  Status AttachToProcess(lldb::ProcessAttachInfoSP attach_info) override;
+  lldb::ProcessSP AttachToProcess(lldb::ProcessAttachInfoSP attach_info_sp,
+                                  lldb::TargetSP target_sp,
+                                  lldb::DebuggerSP debugger_sp,
+                                  Status &error) override;
 
   Status LaunchProcess(lldb::ProcessLaunchInfoSP launch_info) override;
 
Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.cpp
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.cpp
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.cpp
@@ -89,16 +89,29 @@
   return dict_sp;
 }
 
-Status ScriptedPlatformPythonInterface::AttachToProcess(
-    ProcessAttachInfoSP attach_info) {
-  // FIXME: Pass `attach_info` to method call
-  return GetStatusFromMethod("attach_to_process");
+lldb::ProcessSP ScriptedPlatformPythonInterface::AttachToProcess(
+    lldb::ProcessAttachInfoSP attach_info_sp, lldb::TargetSP target_sp,
+    lldb::DebuggerSP debugger_sp, Status &error) {
+  Status py_error;
+  ProcessSP process_sp =
+      Dispatch<ProcessSP>("attach_to_process", py_error, attach_info_sp,
+                          target_sp, debugger_sp, error);
+
+  if (!process_sp || error.Fail()) {
+    return ScriptedInterface::ErrorWithMessage<ProcessSP>(
+        LLVM_PRETTY_FUNCTION,
+        llvm::Twine("Null or invalid object (" +
+                    llvm::Twine(error.AsCString()) + llvm::Twine(")."))
+            .str(),
+        error);
+  }
+
+  return process_sp;
 }
 
 Status ScriptedPlatformPythonInterface::LaunchProcess(
-    ProcessLaunchInfoSP launch_info) {
-  // FIXME: Pass `launch_info` to method call
-  return GetStatusFromMethod("launch_process");
+    ProcessLaunchInfoSP launch_info_sp) {
+  return GetStatusFromMethod("launch_process", launch_info_sp);
 }
 
 Status ScriptedPlatformPythonInterface::KillProcess(lldb::pid_t pid) {
Index: lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
+++ lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
@@ -76,7 +76,8 @@
 PythonObject ToSWIGWrapper(lldb::ExecutionContextRefSP ctx_sp);
 PythonObject ToSWIGWrapper(const TypeSummaryOptions &summary_options);
 PythonObject ToSWIGWrapper(const SymbolContext &sym_ctx);
-
+PythonObject ToSWIGWrapper(lldb::ProcessAttachInfoSP attach_info_sp);
+PythonObject ToSWIGWrapper(lldb::ProcessLaunchInfoSP launch_info_sp);
 PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBValue> value_sb);
 PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBStream> stream_sb);
 PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBStructuredData> data_sb);
@@ -88,6 +89,11 @@
 } // namespace python
 
 void *LLDBSWIGPython_CastPyObjectToSBData(PyObject *data);
+void *LLDBSWIGPython_CastPyObjectToSBProcess(PyObject *data);
+void *LLDBSWIGPython_CastPyObjectToSBDebugger(PyObject *data);
+void *LLDBSWIGPython_CastPyObjectToSBTarget(PyObject *data);
+void *LLDBSWIGPython_CastPyObjectToSBAttachInfo(PyObject *data);
+void *LLDBSWIGPython_CastPyObjectToSBLaunchInfo(PyObject *data);
 void *LLDBSWIGPython_CastPyObjectToSBError(PyObject *data);
 void *LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data);
 void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *data);
Index: lldb/source/Plugins/Process/scripted/ScriptedThread.h
===================================================================
--- lldb/source/Plugins/Process/scripted/ScriptedThread.h
+++ lldb/source/Plugins/Process/scripted/ScriptedThread.h
@@ -61,7 +61,11 @@
   StructuredData::ObjectSP FetchThreadExtendedInfo() override;
 
 private:
-  void CheckInterpreterAndScriptObject() const;
+  inline void CheckInterpreterAndScriptObject() const {
+    assert(m_script_object_sp && "Invalid Script Object.");
+    assert(GetInterface() && "Invalid Scripted Thread Interface.");
+  }
+
   lldb::ScriptedThreadInterfaceSP GetInterface() const;
 
   ScriptedThread(const ScriptedThread &) = delete;
Index: lldb/source/Plugins/Process/scripted/ScriptedThread.cpp
===================================================================
--- lldb/source/Plugins/Process/scripted/ScriptedThread.cpp
+++ lldb/source/Plugins/Process/scripted/ScriptedThread.cpp
@@ -23,11 +23,6 @@
 using namespace lldb;
 using namespace lldb_private;
 
-void ScriptedThread::CheckInterpreterAndScriptObject() const {
-  lldbassert(m_script_object_sp && "Invalid Script Object.");
-  lldbassert(GetInterface() && "Invalid Scripted Thread Interface.");
-}
-
 llvm::Expected<std::shared_ptr<ScriptedThread>>
 ScriptedThread::Create(ScriptedProcess &process,
                        StructuredData::Generic *script_object) {
Index: lldb/source/Plugins/Process/scripted/ScriptedProcess.h
===================================================================
--- lldb/source/Plugins/Process/scripted/ScriptedProcess.h
+++ lldb/source/Plugins/Process/scripted/ScriptedProcess.h
@@ -91,15 +91,18 @@
 private:
   friend class ScriptedThread;
 
-  void CheckInterpreterAndScriptObject() const;
+  inline void CheckInterpreterAndScriptObject() const {
+    lldbassert(m_interpreter && "Invalid Script Interpreter.");
+    lldbassert(m_script_object_sp && "Invalid Script Object.");
+  }
+
   ScriptedProcessInterface &GetInterface() const;
+
   static bool IsScriptLanguageSupported(lldb::ScriptLanguage language);
 
-  // Member variables.
   const ScriptedMetadata m_scripted_metadata;
   lldb_private::ScriptInterpreter *m_interpreter = nullptr;
   lldb_private::StructuredData::ObjectSP m_script_object_sp = nullptr;
-  //@}
 };
 
 } // namespace lldb_private
Index: lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
===================================================================
--- lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
+++ lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
@@ -50,11 +50,6 @@
   return llvm::is_contained(supported_languages, language);
 }
 
-void ScriptedProcess::CheckInterpreterAndScriptObject() const {
-  lldbassert(m_interpreter && "Invalid Script Interpreter.");
-  lldbassert(m_script_object_sp && "Invalid Script Object.");
-}
-
 lldb::ProcessSP ScriptedProcess::CreateInstance(lldb::TargetSP target_sp,
                                                 lldb::ListenerSP listener_sp,
                                                 const FileSpec *file,
Index: lldb/source/Plugins/Platform/scripted/ScriptedPlatform.h
===================================================================
--- /dev/null
+++ lldb/source/Plugins/Platform/scripted/ScriptedPlatform.h
@@ -0,0 +1,86 @@
+//===-- ScriptedPlatform.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_SOURCE_PLUGINS_SCRIPTED_PLATFORM_H
+#define LLDB_SOURCE_PLUGINS_SCRIPTED_PLATFORM_H
+
+#include "lldb/Interpreter/ScriptedMetadata.h"
+#include "lldb/Target/Platform.h"
+
+namespace lldb_private {
+
+class ScriptedPlatform : public Platform {
+public:
+  ScriptedPlatform(Debugger *debugger,
+                   const ScriptedMetadata *scripted_metadata, Status &error);
+
+  ~ScriptedPlatform() override;
+
+  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch,
+                                         const Debugger *debugger,
+                                         const ScriptedMetadata *metadata);
+
+  static void Initialize();
+
+  static void Terminate();
+
+  static llvm::StringRef GetPluginNameStatic() { return "scripted-platform"; }
+
+  static llvm::StringRef GetDescriptionStatic() {
+    return "Scripted Platform plug-in.";
+  }
+
+  llvm::StringRef GetDescription() override { return GetDescriptionStatic(); }
+
+  llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
+
+  std::vector<ArchSpec>
+  GetSupportedArchitectures(const ArchSpec &process_host_arch) override;
+
+  bool IsConnected() const override { return true; }
+
+  lldb::ProcessSP Attach(lldb_private::ProcessAttachInfo &attach_info,
+                         lldb_private::Debugger &debugger,
+                         lldb_private::Target *target,
+                         lldb_private::Status &error) override;
+
+  uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info,
+                         ProcessInstanceInfoList &proc_infos) override;
+
+  bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info) override;
+
+  Status LaunchProcess(ProcessLaunchInfo &launch_info) override;
+
+  Status KillProcess(const lldb::pid_t pid) override;
+
+  void CalculateTrapHandlerSymbolNames() override {}
+
+private:
+  inline void CheckInterpreterAndScriptObject() const {
+    assert(m_interpreter && "Invalid Script Interpreter.");
+    assert(m_script_object_sp && "Invalid Script Object.");
+  }
+
+  ScriptedPlatform(const ScriptedPlatform &) = delete;
+  const ScriptedPlatform &operator=(const ScriptedPlatform &) = delete;
+
+  ScriptedPlatformInterface &GetInterface() const;
+
+  llvm::Expected<ProcessInstanceInfo>
+  ParseProcessInfo(StructuredData::Dictionary &dict, lldb::pid_t pid) const;
+
+  static bool IsScriptLanguageSupported(lldb::ScriptLanguage language);
+
+  const ScriptedMetadata *m_scripted_metadata = nullptr;
+  lldb_private::ScriptInterpreter *m_interpreter = nullptr;
+  lldb_private::StructuredData::ObjectSP m_script_object_sp = nullptr;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_SCRIPTED_PLATFORM_H
Index: lldb/source/Plugins/Platform/scripted/ScriptedPlatform.cpp
===================================================================
--- /dev/null
+++ lldb/source/Plugins/Platform/scripted/ScriptedPlatform.cpp
@@ -0,0 +1,290 @@
+//===-- ScriptedPlatform.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 "ScriptedPlatform.h"
+
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Interpreter/ScriptInterpreter.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Utility/LLDBLog.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+LLDB_PLUGIN_DEFINE(ScriptedPlatform)
+
+static uint32_t g_initialize_count = 0;
+
+static constexpr lldb::ScriptLanguage g_supported_script_languages[] = {
+    ScriptLanguage::eScriptLanguagePython,
+};
+
+bool ScriptedPlatform::IsScriptLanguageSupported(
+    lldb::ScriptLanguage language) {
+  llvm::ArrayRef<lldb::ScriptLanguage> supported_languages =
+      llvm::makeArrayRef(g_supported_script_languages);
+
+  return llvm::is_contained(supported_languages, language);
+}
+
+ScriptedPlatformInterface &ScriptedPlatform::GetInterface() const {
+  return m_interpreter->GetScriptedPlatformInterface();
+}
+
+lldb::PlatformSP
+ScriptedPlatform::CreateInstance(bool force, const ArchSpec *arch,
+                                 const Debugger *debugger,
+                                 const ScriptedMetadata *metadata) {
+  Log *log = GetLog(LLDBLog::Platform);
+  if (log) {
+    const char *arch_name;
+    if (arch && arch->GetArchitectureName())
+      arch_name = arch->GetArchitectureName();
+    else
+      arch_name = "<null>";
+
+    const char *triple_cstr =
+        arch ? arch->GetTriple().getTriple().c_str() : "<null>";
+
+    LLDB_LOGF(log,
+              "ScriptedPlatform::%s(force=%s, arch={%s,%s}, debugger=%" PRIxPTR
+              ")",
+              __PRETTY_FUNCTION__, force ? "true" : "false", arch_name,
+              triple_cstr, (uintptr_t)debugger);
+  }
+
+  if (!debugger || !IsScriptLanguageSupported(debugger->GetScriptLanguage()))
+    return {};
+
+  if (!metadata)
+    return {};
+
+  Status error;
+  std::shared_ptr<ScriptedPlatform> scripted_platform_sp =
+      std::make_shared<ScriptedPlatform>(const_cast<Debugger *>(debugger),
+                                         metadata, error);
+
+  if (error.Success())
+    return scripted_platform_sp;
+
+  LLDB_LOGF(log, "ScriptedPlatform::%s() aborting creation of platform",
+            __PRETTY_FUNCTION__);
+
+  return {};
+}
+
+ScriptedPlatform::ScriptedPlatform(Debugger *debugger,
+                                   const ScriptedMetadata *scripted_metadata,
+                                   Status &error)
+    : Platform(false), m_scripted_metadata(scripted_metadata) {
+  if (!debugger) {
+    error.SetErrorStringWithFormat("ScriptedPlatform::%s () - ERROR: %s",
+                                   __FUNCTION__, "Invalid debugger");
+    return;
+  }
+
+  m_interpreter = debugger->GetScriptInterpreter();
+
+  if (!m_interpreter) {
+    error.SetErrorStringWithFormat("ScriptedPlatform::%s () - ERROR: %s",
+                                   __FUNCTION__,
+                                   "Debugger has no Script Interpreter");
+    return;
+  }
+
+  ExecutionContext e;
+
+  StructuredData::GenericSP object_sp = GetInterface().CreatePluginObject(
+      m_scripted_metadata->GetClassName(), e, m_scripted_metadata->GetArgsSP());
+
+  if (!object_sp || !object_sp->IsValid()) {
+    error.SetErrorStringWithFormat("ScriptedPlatform::%s () - ERROR: %s",
+                                   __FUNCTION__,
+                                   "Failed to create valid script object");
+    return;
+  }
+
+  m_hostname = GetHostPlatform()->GetHostname();
+  m_script_object_sp = object_sp;
+}
+
+ScriptedPlatform::~ScriptedPlatform() {}
+
+void ScriptedPlatform::Initialize() {
+  if (g_initialize_count++ == 0) {
+    // NOTE: This should probably be using the driving process platform
+    PluginManager::RegisterPlugin(ScriptedPlatform::GetPluginNameStatic(),
+                                  ScriptedPlatform::GetDescriptionStatic(),
+                                  ScriptedPlatform::CreateInstance);
+  }
+}
+
+void ScriptedPlatform::Terminate() {
+  if (g_initialize_count > 0) {
+    if (--g_initialize_count == 0) {
+      PluginManager::UnregisterPlugin(ScriptedPlatform::CreateInstance);
+    }
+  }
+}
+
+std::vector<ArchSpec>
+ScriptedPlatform::GetSupportedArchitectures(const ArchSpec &process_host_arch) {
+  std::vector<ArchSpec> result;
+  result.push_back(process_host_arch);
+  return result;
+}
+
+lldb::ProcessSP
+ScriptedPlatform::Attach(lldb_private::ProcessAttachInfo &attach_info,
+                         lldb_private::Debugger &debugger,
+                         lldb_private::Target *target, // Can be nullptr, if
+                                                       // nullptr create a new
+                                                       // target, else use
+                                                       // existing one
+                         lldb_private::Status &error) {
+  lldb::ProcessAttachInfoSP attach_info_sp =
+      std::make_shared<ProcessAttachInfo>(attach_info);
+
+  if (!target) {
+    target = &debugger.GetSelectedOrDummyTarget();
+  }
+
+  ProcessSP process_sp =
+      GetInterface().AttachToProcess(attach_info_sp, target->shared_from_this(),
+                                     debugger.shared_from_this(), error);
+  if (!process_sp || error.Fail())
+    return {};
+  return process_sp;
+}
+
+llvm::Expected<ProcessInstanceInfo>
+ScriptedPlatform::ParseProcessInfo(StructuredData::Dictionary &dict,
+                                   lldb::pid_t pid) const {
+  if (!dict.HasKey("name"))
+    return llvm::make_error<llvm::StringError>(
+        "No 'arch' key in process info dictionary.",
+        llvm::inconvertibleErrorCode());
+  if (!dict.HasKey("arch"))
+    return llvm::make_error<llvm::StringError>(
+        "No 'arch' key in process info dictionary.",
+        llvm::inconvertibleErrorCode());
+
+  llvm::StringRef result;
+  if (!dict.GetValueForKeyAsString("name", result))
+    return llvm::make_error<llvm::StringError>(
+        "Couldn't extract 'name' key from process info dictionary.",
+        llvm::inconvertibleErrorCode());
+  std::string name = result.str();
+
+  if (!dict.GetValueForKeyAsString("arch", result))
+    return llvm::make_error<llvm::StringError>(
+        "Couldn't extract 'arch' key from process info dictionary.",
+        llvm::inconvertibleErrorCode());
+  const ArchSpec arch(result.data());
+  if (!arch.IsValid())
+    return llvm::make_error<llvm::StringError>(
+        "Invalid 'arch' key in process info dictionary.",
+        llvm::inconvertibleErrorCode());
+
+  ProcessInstanceInfo proc_info = ProcessInstanceInfo(name.c_str(), arch, pid);
+
+  lldb::pid_t parent = LLDB_INVALID_PROCESS_ID;
+  if (dict.GetValueForKeyAsInteger("parent", parent))
+    proc_info.SetParentProcessID(parent);
+
+  uint32_t uid = UINT32_MAX;
+  if (dict.GetValueForKeyAsInteger("uid", uid))
+    proc_info.SetEffectiveUserID(uid);
+
+  uint32_t gid = UINT32_MAX;
+  if (dict.GetValueForKeyAsInteger("gid", gid))
+    proc_info.SetEffectiveGroupID(gid);
+
+  return proc_info;
+}
+
+uint32_t
+ScriptedPlatform::FindProcesses(const ProcessInstanceInfoMatch &match_info,
+                                ProcessInstanceInfoList &proc_infos) {
+  CheckInterpreterAndScriptObject();
+  StructuredData::DictionarySP dict_sp = GetInterface().ListProcesses();
+
+  Status error;
+  if (!dict_sp)
+    return ScriptedInterface::ErrorWithMessage<uint32_t>(
+        LLVM_PRETTY_FUNCTION, "Failed to get scripted platform processes.",
+        error, LLDBLog::Platform);
+
+  auto parse_process_info = [this, &proc_infos](ConstString key,
+                                                StructuredData::Object *val) {
+    if (!val)
+      return false;
+
+    StructuredData::Dictionary *dict = val->GetAsDictionary();
+
+    if (!dict || !dict->IsValid())
+      return false;
+
+    lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
+    if (!llvm::to_integer(key.GetStringRef(), pid))
+      return false;
+
+    auto proc_info_or_error = ParseProcessInfo(*dict, pid);
+
+    if (llvm::Error e = proc_info_or_error.takeError()) {
+      LLDB_LOGF(GetLog(LLDBLog::Platform), "%s ERROR = %s",
+                LLVM_PRETTY_FUNCTION, llvm::toString(std::move(e)).c_str());
+      return false;
+    }
+
+    if (!proc_info_or_error) {
+      llvm::consumeError(proc_info_or_error.takeError());
+      return false;
+    }
+
+    proc_infos.push_back(*proc_info_or_error);
+    return true;
+  };
+
+  dict_sp->ForEach(parse_process_info);
+
+  // TODO: Use match_info to filter through processes
+  return proc_infos.size();
+}
+
+bool ScriptedPlatform::GetProcessInfo(lldb::pid_t pid,
+                                      ProcessInstanceInfo &proc_info) {
+  if (pid == LLDB_INVALID_PROCESS_ID)
+    return false;
+
+  StructuredData::DictionarySP dict_sp = GetInterface().GetProcessInfo(pid);
+
+  if (!dict_sp || !dict_sp->IsValid())
+    return false;
+
+  auto proc_info_or_error = ParseProcessInfo(*dict_sp.get(), pid);
+
+  if (!proc_info_or_error) {
+    llvm::consumeError(proc_info_or_error.takeError());
+    return false;
+  }
+
+  proc_info = *proc_info_or_error;
+  return true;
+}
+
+Status ScriptedPlatform::LaunchProcess(ProcessLaunchInfo &launch_info) {
+  return GetInterface().LaunchProcess();
+}
+
+Status ScriptedPlatform::KillProcess(const lldb::pid_t pid) {
+  return GetInterface().KillProcess(pid);
+}
Index: lldb/source/Plugins/Platform/scripted/CMakeLists.txt
===================================================================
--- /dev/null
+++ lldb/source/Plugins/Platform/scripted/CMakeLists.txt
@@ -0,0 +1,8 @@
+add_lldb_library(lldbPluginScriptedPlatform PLUGIN
+  ScriptedPlatform.cpp
+
+  LINK_LIBS
+    lldbCore
+    lldbTarget
+    lldbUtility
+  )
Index: lldb/source/Plugins/Platform/CMakeLists.txt
===================================================================
--- lldb/source/Plugins/Platform/CMakeLists.txt
+++ lldb/source/Plugins/Platform/CMakeLists.txt
@@ -6,5 +6,6 @@
 add_subdirectory(NetBSD)
 add_subdirectory(OpenBSD)
 add_subdirectory(POSIX)
+add_subdirectory(Scripted)
 add_subdirectory(QemuUser)
 add_subdirectory(Windows)
Index: lldb/source/Interpreter/ScriptInterpreter.cpp
===================================================================
--- lldb/source/Interpreter/ScriptInterpreter.cpp
+++ lldb/source/Interpreter/ScriptInterpreter.cpp
@@ -82,6 +82,32 @@
   return data.m_opaque_sp;
 }
 
+lldb::ProcessSP ScriptInterpreter::GetOpaqueTypeFromSBProcess(
+    const lldb::SBProcess &process) const {
+  return process.m_opaque_wp.lock();
+}
+
+lldb::DebuggerSP ScriptInterpreter::GetOpaqueTypeFromSBDebugger(
+    const lldb::SBDebugger &debugger) const {
+  return debugger.m_opaque_sp;
+}
+
+lldb::TargetSP ScriptInterpreter::GetOpaqueTypeFromSBTarget(
+    const lldb::SBTarget &target) const {
+  return target.m_opaque_sp;
+}
+
+lldb::ProcessAttachInfoSP ScriptInterpreter::GetOpaqueTypeFromSBAttachInfo(
+    const lldb::SBAttachInfo &attach_info) const {
+  return attach_info.m_opaque_sp;
+}
+
+lldb::ProcessLaunchInfoSP ScriptInterpreter::GetOpaqueTypeFromSBLaunchInfo(
+    const lldb::SBLaunchInfo &launch_info) const {
+  return std::make_shared<ProcessLaunchInfo>(
+      *reinterpret_cast<ProcessLaunchInfo *>(launch_info.m_opaque_sp.get()));
+}
+
 Status
 ScriptInterpreter::GetStatusFromSBError(const lldb::SBError &error) const {
   if (error.m_opaque_up)
Index: lldb/include/lldb/Interpreter/ScriptedPlatformInterface.h
===================================================================
--- lldb/include/lldb/Interpreter/ScriptedPlatformInterface.h
+++ lldb/include/lldb/Interpreter/ScriptedPlatformInterface.h
@@ -32,8 +32,11 @@
     return {};
   }
 
-  virtual Status AttachToProcess(lldb::ProcessAttachInfoSP attach_info) {
-    return Status("ScriptedPlatformInterface cannot attach to a process");
+  virtual lldb::ProcessSP
+  AttachToProcess(lldb::ProcessAttachInfoSP attach_info_sp,
+                  lldb::TargetSP target_sp, lldb::DebuggerSP debugger_sp,
+                  Status &error) {
+    return {};
   }
 
   virtual Status LaunchProcess(lldb::ProcessLaunchInfoSP launch_info) {
Index: lldb/include/lldb/Interpreter/ScriptInterpreter.h
===================================================================
--- lldb/include/lldb/Interpreter/ScriptInterpreter.h
+++ lldb/include/lldb/Interpreter/ScriptInterpreter.h
@@ -9,9 +9,14 @@
 #ifndef LLDB_INTERPRETER_SCRIPTINTERPRETER_H
 #define LLDB_INTERPRETER_SCRIPTINTERPRETER_H
 
+#include "lldb/API/SBAttachInfo.h"
 #include "lldb/API/SBData.h"
+#include "lldb/API/SBDebugger.h"
 #include "lldb/API/SBError.h"
+#include "lldb/API/SBLaunchInfo.h"
 #include "lldb/API/SBMemoryRegionInfo.h"
+#include "lldb/API/SBProcess.h"
+#include "lldb/API/SBTarget.h"
 #include "lldb/Breakpoint/BreakpointOptions.h"
 #include "lldb/Core/PluginInterface.h"
 #include "lldb/Core/SearchFilter.h"
@@ -583,6 +588,20 @@
 
   Status GetStatusFromSBError(const lldb::SBError &error) const;
 
+  lldb::ProcessSP
+  GetOpaqueTypeFromSBProcess(const lldb::SBProcess &process) const;
+
+  lldb::DebuggerSP
+  GetOpaqueTypeFromSBDebugger(const lldb::SBDebugger &debugger) const;
+
+  lldb::TargetSP GetOpaqueTypeFromSBTarget(const lldb::SBTarget &target) const;
+
+  lldb::ProcessAttachInfoSP
+  GetOpaqueTypeFromSBAttachInfo(const lldb::SBAttachInfo &attach_info) const;
+
+  lldb::ProcessLaunchInfoSP
+  GetOpaqueTypeFromSBLaunchInfo(const lldb::SBLaunchInfo &launch_info) const;
+
   std::optional<MemoryRegionInfo> GetOpaqueTypeFromSBMemoryRegionInfo(
       const lldb::SBMemoryRegionInfo &mem_region) const;
 
Index: lldb/include/lldb/API/SBTarget.h
===================================================================
--- lldb/include/lldb/API/SBTarget.h
+++ lldb/include/lldb/API/SBTarget.h
@@ -22,6 +22,10 @@
 #include "lldb/API/SBValue.h"
 #include "lldb/API/SBWatchpoint.h"
 
+namespace lldb_private {
+class ScriptInterpreter;
+}
+
 namespace lldb {
 
 class SBPlatform;
@@ -880,6 +884,8 @@
   friend class SBValue;
   friend class SBVariablesOptions;
 
+  friend class lldb_private::ScriptInterpreter;
+
   // Constructors are private, use static Target::Create function to create an
   // instance of this class.
 
Index: lldb/include/lldb/API/SBProcess.h
===================================================================
--- lldb/include/lldb/API/SBProcess.h
+++ lldb/include/lldb/API/SBProcess.h
@@ -16,6 +16,10 @@
 #include "lldb/API/SBTarget.h"
 #include <cstdio>
 
+namespace lldb_private {
+class ScriptInterpreter;
+}
+
 namespace lldb {
 
 class SBEvent;
@@ -437,6 +441,8 @@
   friend class SBValue;
   friend class lldb_private::QueueImpl;
 
+  friend class lldb_private::ScriptInterpreter;
+
   lldb::ProcessSP GetSP() const;
 
   void SetSP(const lldb::ProcessSP &process_sp);
Index: lldb/include/lldb/API/SBLaunchInfo.h
===================================================================
--- lldb/include/lldb/API/SBLaunchInfo.h
+++ lldb/include/lldb/API/SBLaunchInfo.h
@@ -13,6 +13,7 @@
 
 namespace lldb_private {
 class SBLaunchInfoImpl;
+class ScriptInterpreter;
 }
 
 namespace lldb {
@@ -183,6 +184,8 @@
   friend class SBPlatform;
   friend class SBTarget;
 
+  friend class lldb_private::ScriptInterpreter;
+
   const lldb_private::ProcessLaunchInfo &ref() const;
   void set_ref(const lldb_private::ProcessLaunchInfo &info);
 
Index: lldb/include/lldb/API/SBDebugger.h
===================================================================
--- lldb/include/lldb/API/SBDebugger.h
+++ lldb/include/lldb/API/SBDebugger.h
@@ -14,6 +14,10 @@
 #include "lldb/API/SBDefines.h"
 #include "lldb/API/SBPlatform.h"
 
+namespace lldb_private {
+class ScriptInterpreter;
+}
+
 namespace lldb {
 
 class LLDB_API SBInputReader {
@@ -428,6 +432,8 @@
   friend class SBTarget;
   friend class SBTrace;
 
+  friend class lldb_private::ScriptInterpreter;
+
   lldb::SBTarget FindTargetWithLLDBProcess(const lldb::ProcessSP &processSP);
 
   void reset(const lldb::DebuggerSP &debugger_sp);
Index: lldb/include/lldb/API/SBAttachInfo.h
===================================================================
--- lldb/include/lldb/API/SBAttachInfo.h
+++ lldb/include/lldb/API/SBAttachInfo.h
@@ -11,6 +11,10 @@
 
 #include "lldb/API/SBDefines.h"
 
+namespace lldb_private {
+class ScriptInterpreter;
+}
+
 namespace lldb {
 
 class SBTarget;
@@ -167,6 +171,8 @@
 protected:
   friend class SBTarget;
 
+  friend class lldb_private::ScriptInterpreter;
+
   lldb_private::ProcessAttachInfo &ref();
 
   ProcessAttachInfoSP m_opaque_sp;
Index: lldb/examples/python/scripted_process/scripted_platform.py
===================================================================
--- lldb/examples/python/scripted_process/scripted_platform.py
+++ lldb/examples/python/scripted_process/scripted_platform.py
@@ -60,14 +60,17 @@
         pass
 
     @abstractmethod
-    def attach_to_process(self, attach_info):
+    def attach_to_process(self, attach_info, target, debugger, error):
         """ Attach to a process.
 
         Args:
             attach_info (lldb.SBAttachInfo): The information related to attach to a process.
+            target (lldb.SBTarget): The optional target that we are trying to attach to.
+            debugger (lldb.SBDebugger): The debugger instance.
+            error (lldb.SBError): A status object notifying if the attach succeeded.
 
         Returns:
-            lldb.SBError: A status object notifying if the attach succeeded.
+            lldb.SBProcess: The process that the platform attached to, or None.
         """
         pass
 
Index: lldb/bindings/python/python-wrapper.swig
===================================================================
--- lldb/bindings/python/python-wrapper.swig
+++ lldb/bindings/python/python-wrapper.swig
@@ -716,6 +716,66 @@
   return sb_ptr;
 }
 
+void *lldb_private::LLDBSWIGPython_CastPyObjectToSBProcess(PyObject * data) {
+  lldb::SBProcess *sb_ptr = nullptr;
+
+  int valid_cast =
+      SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBProcess, 0);
+
+  if (valid_cast == -1)
+    return NULL;
+
+  return sb_ptr;
+}
+
+void *lldb_private::LLDBSWIGPython_CastPyObjectToSBDebugger(PyObject * data) {
+  lldb::SBDebugger *sb_ptr = nullptr;
+
+  int valid_cast =
+      SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBDebugger, 0);
+
+  if (valid_cast == -1)
+    return NULL;
+
+  return sb_ptr;
+}
+
+void *lldb_private::LLDBSWIGPython_CastPyObjectToSBTarget(PyObject * data) {
+  lldb::SBTarget *sb_ptr = nullptr;
+
+  int valid_cast =
+      SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBTarget, 0);
+
+  if (valid_cast == -1)
+    return NULL;
+
+  return sb_ptr;
+}
+
+void *lldb_private::LLDBSWIGPython_CastPyObjectToSBAttachInfo(PyObject * data) {
+  lldb::SBAttachInfo *sb_ptr = nullptr;
+
+  int valid_cast =
+      SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBAttachInfo, 0);
+
+  if (valid_cast == -1)
+    return NULL;
+
+  return sb_ptr;
+}
+
+void *lldb_private::LLDBSWIGPython_CastPyObjectToSBLaunchInfo(PyObject * data) {
+  lldb::SBLaunchInfo *sb_ptr = nullptr;
+
+  int valid_cast =
+      SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBLaunchInfo, 0);
+
+  if (valid_cast == -1)
+    return NULL;
+
+  return sb_ptr;
+}
+
 void *lldb_private::LLDBSWIGPython_CastPyObjectToSBError(PyObject * data) {
   lldb::SBError *sb_ptr = nullptr;
 
Index: lldb/bindings/python/python-swigsafecast.swig
===================================================================
--- lldb/bindings/python/python-swigsafecast.swig
+++ lldb/bindings/python/python-swigsafecast.swig
@@ -93,6 +93,16 @@
                       SWIGTYPE_p_lldb__SBSymbolContext);
 }
 
+PythonObject ToSWIGWrapper(lldb::ProcessLaunchInfoSP launch_info_sp) {
+  return ToSWIGHelper(new lldb::ProcessLaunchInfoSP(std::move(launch_info_sp)),
+                      SWIGTYPE_p_lldb__SBLaunchInfo);
+}
+
+PythonObject ToSWIGWrapper(lldb::ProcessAttachInfoSP attach_info_sp) {
+  return ToSWIGHelper(new lldb::ProcessAttachInfoSP(std::move(attach_info_sp)),
+                      SWIGTYPE_p_lldb__SBAttachInfo);
+}
+
 ScopedPythonObject<lldb::SBCommandReturnObject>
 ToSWIGWrapper(CommandReturnObject &cmd_retobj) {
   return ScopedPythonObject<lldb::SBCommandReturnObject>(
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to