[Lldb-commits] [lldb] [lldb/Plugins] Introduce Scripted Platform Plugin (PR #99814)

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Tue Jul 23 07:30:45 PDT 2024


================
@@ -0,0 +1,305 @@
+//===-- 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) {
+  return llvm::is_contained(g_supported_script_languages, language);
+}
+
+ScriptedPlatformInterface &ScriptedPlatform::GetInterface() const {
+  return *m_interface_up;
+}
+
+lldb::PlatformSP ScriptedPlatform::CreateInstance(bool force,
+                                                  const ArchSpec *arch) {
+  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})",
+              __PRETTY_FUNCTION__, force ? "true" : "false", arch_name,
+              triple_cstr);
+  }
+
+  return std::make_shared<ScriptedPlatform>();
+}
+
+ScriptedPlatform::ScriptedPlatform() : Platform(false) {}
+
+llvm::Error ScriptedPlatform::SetupScriptedObject() {
+
+  auto error_with_message = [](llvm::StringRef message) -> llvm::Error {
+    Status error;
+    ScriptedInterface::ErrorWithMessage<bool>(LLVM_PRETTY_FUNCTION, message,
+                                              error, LLDBLog::Platform);
+    return error.ToError();
+  };
+
+  Debugger &debugger = m_metadata->GetDebugger();
+
+  if (!IsScriptLanguageSupported(debugger.GetScriptLanguage()))
+    return error_with_message("Debugger language not supported");
+
+  ScriptInterpreter *interpreter = debugger.GetScriptInterpreter();
+  if (!interpreter)
+    return error_with_message("Debugger has no Script Interpreter");
+
+  // Create platform instance interface
+  m_interface_up = interpreter->CreateScriptedPlatformInterface();
+  if (!m_interface_up)
+    return error_with_message(
+        "Script interpreter couldn't create Scripted Process Interface");
+
+  const ScriptedMetadata scripted_metadata = m_metadata->GetScriptedMetadata();
+
+  ExecutionContext e(&debugger.GetSelectedOrDummyTarget());
+  auto obj_or_err = GetInterface().CreatePluginObject(
+      scripted_metadata.GetClassName(), e, scripted_metadata.GetArgsSP());
+
+  if (!obj_or_err) {
+    llvm::consumeError(obj_or_err.takeError());
+    return error_with_message("Failed to create script object.");
+  }
+
+  StructuredData::GenericSP object_sp = *obj_or_err;
+  if (!object_sp || !object_sp->IsValid())
+    return error_with_message("Failed to create valid script object");
+
+  m_hostname = GetHostPlatform()->GetHostname();
+  return llvm::Error::success();
+}
+
+ScriptedPlatform::~ScriptedPlatform() {}
+
+llvm::Error ScriptedPlatform::ReloadMetadata() {
+  if (!m_metadata)
+    return llvm::createStringError(
+        "Scripted Platform has no platform metadata.");
+  return SetupScriptedObject();
+}
+
+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) {
----------------
labath wrote:

This doesn't seem right. Normally a platform should "know" which architectures it supports without having access to any specific process. In this case, that would probably mean calling out to python so that the plugin author can specify those. `process_host_arch` was only added to disambiguate some cases (and I don't remember what those cases were, but I think it had something to do with macos simulator platforms). This may be fine for now, but we probably shouldn't rely on this implementation...

https://github.com/llvm/llvm-project/pull/99814


More information about the lldb-commits mailing list