135653324SMed Ismail Bennani //===-- ScriptedProcessPythonInterface.cpp --------------------------------===// 235653324SMed Ismail Bennani // 335653324SMed Ismail Bennani // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 435653324SMed Ismail Bennani // See https://llvm.org/LICENSE.txt for license information. 535653324SMed Ismail Bennani // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 635653324SMed Ismail Bennani // 735653324SMed Ismail Bennani //===----------------------------------------------------------------------===// 835653324SMed Ismail Bennani 935653324SMed Ismail Bennani #include "lldb/Core/PluginManager.h" 1035653324SMed Ismail Bennani #include "lldb/Host/Config.h" 1135653324SMed Ismail Bennani #include "lldb/Utility/Log.h" 1235653324SMed Ismail Bennani #include "lldb/Utility/Status.h" 1335653324SMed Ismail Bennani #include "lldb/lldb-enumerations.h" 1435653324SMed Ismail Bennani 1535653324SMed Ismail Bennani #if LLDB_ENABLE_PYTHON 1635653324SMed Ismail Bennani 1735653324SMed Ismail Bennani // clang-format off 1835653324SMed Ismail Bennani // LLDB Python header must be included first 1935653324SMed Ismail Bennani #include "../lldb-python.h" 2035653324SMed Ismail Bennani 2135653324SMed Ismail Bennani #include "../SWIGPythonBridge.h" 2235653324SMed Ismail Bennani #include "../ScriptInterpreterPythonImpl.h" 2335653324SMed Ismail Bennani #include "ScriptedThreadPythonInterface.h" 2435653324SMed Ismail Bennani #include "ScriptedProcessPythonInterface.h" 2535653324SMed Ismail Bennani 2635653324SMed Ismail Bennani // Included in this position to prevent redefinition of pid_t on Windows. 2735653324SMed Ismail Bennani #include "lldb/Target/Process.h" 2835653324SMed Ismail Bennani //clang-format off 2935653324SMed Ismail Bennani 3035653324SMed Ismail Bennani #include <optional> 3135653324SMed Ismail Bennani 3235653324SMed Ismail Bennani using namespace lldb; 3335653324SMed Ismail Bennani using namespace lldb_private; 3435653324SMed Ismail Bennani using namespace lldb_private::python; 3535653324SMed Ismail Bennani using Locker = ScriptInterpreterPythonImpl::Locker; 3635653324SMed Ismail Bennani 3735653324SMed Ismail Bennani ScriptedProcessPythonInterface::ScriptedProcessPythonInterface( 3835653324SMed Ismail Bennani ScriptInterpreterPythonImpl &interpreter) 3935653324SMed Ismail Bennani : ScriptedProcessInterface(), ScriptedPythonInterface(interpreter) {} 4035653324SMed Ismail Bennani 4135653324SMed Ismail Bennani llvm::Expected<StructuredData::GenericSP> 4235653324SMed Ismail Bennani ScriptedProcessPythonInterface::CreatePluginObject( 4335653324SMed Ismail Bennani llvm::StringRef class_name, ExecutionContext &exe_ctx, 4435653324SMed Ismail Bennani StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) { 4535653324SMed Ismail Bennani ExecutionContextRefSP exe_ctx_ref_sp = 4635653324SMed Ismail Bennani std::make_shared<ExecutionContextRef>(exe_ctx); 4735653324SMed Ismail Bennani StructuredDataImpl sd_impl(args_sp); 4835653324SMed Ismail Bennani return ScriptedPythonInterface::CreatePluginObject(class_name, script_obj, 4935653324SMed Ismail Bennani exe_ctx_ref_sp, sd_impl); 5035653324SMed Ismail Bennani } 5135653324SMed Ismail Bennani 5235653324SMed Ismail Bennani StructuredData::DictionarySP ScriptedProcessPythonInterface::GetCapabilities() { 5335653324SMed Ismail Bennani Status error; 5435653324SMed Ismail Bennani StructuredData::DictionarySP dict = 5535653324SMed Ismail Bennani Dispatch<StructuredData::DictionarySP>("get_capabilities", error); 5635653324SMed Ismail Bennani 5735653324SMed Ismail Bennani if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, 5835653324SMed Ismail Bennani error)) 5935653324SMed Ismail Bennani return {}; 6035653324SMed Ismail Bennani 6135653324SMed Ismail Bennani return dict; 6235653324SMed Ismail Bennani } 6335653324SMed Ismail Bennani 6435653324SMed Ismail Bennani Status 6535653324SMed Ismail Bennani ScriptedProcessPythonInterface::Attach(const ProcessAttachInfo &attach_info) { 6635653324SMed Ismail Bennani lldb::ProcessAttachInfoSP attach_info_sp = 6735653324SMed Ismail Bennani std::make_shared<ProcessAttachInfo>(attach_info); 6835653324SMed Ismail Bennani return GetStatusFromMethod("attach", attach_info_sp); 6935653324SMed Ismail Bennani } 7035653324SMed Ismail Bennani 7135653324SMed Ismail Bennani Status ScriptedProcessPythonInterface::Launch() { 7235653324SMed Ismail Bennani return GetStatusFromMethod("launch"); 7335653324SMed Ismail Bennani } 7435653324SMed Ismail Bennani 7535653324SMed Ismail Bennani Status ScriptedProcessPythonInterface::Resume() { 7635653324SMed Ismail Bennani // When calling ScriptedProcess.Resume from lldb we should always stop. 7735653324SMed Ismail Bennani return GetStatusFromMethod("resume", /*should_stop=*/true); 7835653324SMed Ismail Bennani } 7935653324SMed Ismail Bennani 8035653324SMed Ismail Bennani std::optional<MemoryRegionInfo> 8135653324SMed Ismail Bennani ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress( 8235653324SMed Ismail Bennani lldb::addr_t address, Status &error) { 8335653324SMed Ismail Bennani auto mem_region = Dispatch<std::optional<MemoryRegionInfo>>( 8435653324SMed Ismail Bennani "get_memory_region_containing_address", error, address); 8535653324SMed Ismail Bennani 8635653324SMed Ismail Bennani if (error.Fail()) { 8735653324SMed Ismail Bennani return ErrorWithMessage<MemoryRegionInfo>(LLVM_PRETTY_FUNCTION, 8835653324SMed Ismail Bennani error.AsCString(), error); 8935653324SMed Ismail Bennani } 9035653324SMed Ismail Bennani 9135653324SMed Ismail Bennani return mem_region; 9235653324SMed Ismail Bennani } 9335653324SMed Ismail Bennani 9435653324SMed Ismail Bennani StructuredData::DictionarySP ScriptedProcessPythonInterface::GetThreadsInfo() { 9535653324SMed Ismail Bennani Status error; 9635653324SMed Ismail Bennani StructuredData::DictionarySP dict = 9735653324SMed Ismail Bennani Dispatch<StructuredData::DictionarySP>("get_threads_info", error); 9835653324SMed Ismail Bennani 9935653324SMed Ismail Bennani if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, 10035653324SMed Ismail Bennani error)) 10135653324SMed Ismail Bennani return {}; 10235653324SMed Ismail Bennani 10335653324SMed Ismail Bennani return dict; 10435653324SMed Ismail Bennani } 10535653324SMed Ismail Bennani 10635653324SMed Ismail Bennani bool ScriptedProcessPythonInterface::CreateBreakpoint(lldb::addr_t addr, 10735653324SMed Ismail Bennani Status &error) { 10835653324SMed Ismail Bennani Status py_error; 10935653324SMed Ismail Bennani StructuredData::ObjectSP obj = 11035653324SMed Ismail Bennani Dispatch("create_breakpoint", py_error, addr, error); 11135653324SMed Ismail Bennani 11235653324SMed Ismail Bennani // If there was an error on the python call, surface it to the user. 11335653324SMed Ismail Bennani if (py_error.Fail()) 114*b798f4bdSAdrian Prantl error = std::move(py_error); 11535653324SMed Ismail Bennani 11635653324SMed Ismail Bennani if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, 11735653324SMed Ismail Bennani error)) 11835653324SMed Ismail Bennani return {}; 11935653324SMed Ismail Bennani 12035653324SMed Ismail Bennani return obj->GetBooleanValue(); 12135653324SMed Ismail Bennani } 12235653324SMed Ismail Bennani 12335653324SMed Ismail Bennani lldb::DataExtractorSP ScriptedProcessPythonInterface::ReadMemoryAtAddress( 12435653324SMed Ismail Bennani lldb::addr_t address, size_t size, Status &error) { 12535653324SMed Ismail Bennani Status py_error; 12635653324SMed Ismail Bennani lldb::DataExtractorSP data_sp = Dispatch<lldb::DataExtractorSP>( 12735653324SMed Ismail Bennani "read_memory_at_address", py_error, address, size, error); 12835653324SMed Ismail Bennani 12935653324SMed Ismail Bennani // If there was an error on the python call, surface it to the user. 13035653324SMed Ismail Bennani if (py_error.Fail()) 131*b798f4bdSAdrian Prantl error = std::move(py_error); 13235653324SMed Ismail Bennani 13335653324SMed Ismail Bennani return data_sp; 13435653324SMed Ismail Bennani } 13535653324SMed Ismail Bennani 13635653324SMed Ismail Bennani lldb::offset_t ScriptedProcessPythonInterface::WriteMemoryAtAddress( 13735653324SMed Ismail Bennani lldb::addr_t addr, lldb::DataExtractorSP data_sp, Status &error) { 13835653324SMed Ismail Bennani Status py_error; 13935653324SMed Ismail Bennani StructuredData::ObjectSP obj = 14035653324SMed Ismail Bennani Dispatch("write_memory_at_address", py_error, addr, data_sp, error); 14135653324SMed Ismail Bennani 14235653324SMed Ismail Bennani if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, 14335653324SMed Ismail Bennani error)) 14435653324SMed Ismail Bennani return LLDB_INVALID_OFFSET; 14535653324SMed Ismail Bennani 14635653324SMed Ismail Bennani // If there was an error on the python call, surface it to the user. 14735653324SMed Ismail Bennani if (py_error.Fail()) 148*b798f4bdSAdrian Prantl error = std::move(py_error); 14935653324SMed Ismail Bennani 15035653324SMed Ismail Bennani return obj->GetUnsignedIntegerValue(LLDB_INVALID_OFFSET); 15135653324SMed Ismail Bennani } 15235653324SMed Ismail Bennani 15335653324SMed Ismail Bennani StructuredData::ArraySP ScriptedProcessPythonInterface::GetLoadedImages() { 15435653324SMed Ismail Bennani Status error; 15535653324SMed Ismail Bennani StructuredData::ArraySP array = 15635653324SMed Ismail Bennani Dispatch<StructuredData::ArraySP>("get_loaded_images", error); 15735653324SMed Ismail Bennani 15835653324SMed Ismail Bennani if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, array, 15935653324SMed Ismail Bennani error)) 16035653324SMed Ismail Bennani return {}; 16135653324SMed Ismail Bennani 16235653324SMed Ismail Bennani return array; 16335653324SMed Ismail Bennani } 16435653324SMed Ismail Bennani 16535653324SMed Ismail Bennani lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() { 16635653324SMed Ismail Bennani Status error; 16735653324SMed Ismail Bennani StructuredData::ObjectSP obj = Dispatch("get_process_id", error); 16835653324SMed Ismail Bennani 16935653324SMed Ismail Bennani if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, 17035653324SMed Ismail Bennani error)) 17135653324SMed Ismail Bennani return LLDB_INVALID_PROCESS_ID; 17235653324SMed Ismail Bennani 17335653324SMed Ismail Bennani return obj->GetUnsignedIntegerValue(LLDB_INVALID_PROCESS_ID); 17435653324SMed Ismail Bennani } 17535653324SMed Ismail Bennani 17635653324SMed Ismail Bennani bool ScriptedProcessPythonInterface::IsAlive() { 17735653324SMed Ismail Bennani Status error; 17835653324SMed Ismail Bennani StructuredData::ObjectSP obj = Dispatch("is_alive", error); 17935653324SMed Ismail Bennani 18035653324SMed Ismail Bennani if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, 18135653324SMed Ismail Bennani error)) 18235653324SMed Ismail Bennani return {}; 18335653324SMed Ismail Bennani 18435653324SMed Ismail Bennani return obj->GetBooleanValue(); 18535653324SMed Ismail Bennani } 18635653324SMed Ismail Bennani 18735653324SMed Ismail Bennani std::optional<std::string> 18835653324SMed Ismail Bennani ScriptedProcessPythonInterface::GetScriptedThreadPluginName() { 18935653324SMed Ismail Bennani Status error; 19035653324SMed Ismail Bennani StructuredData::ObjectSP obj = Dispatch("get_scripted_thread_plugin", error); 19135653324SMed Ismail Bennani 19235653324SMed Ismail Bennani if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, 19335653324SMed Ismail Bennani error)) 19435653324SMed Ismail Bennani return {}; 19535653324SMed Ismail Bennani 19635653324SMed Ismail Bennani return obj->GetStringValue().str(); 19735653324SMed Ismail Bennani } 19835653324SMed Ismail Bennani 19935653324SMed Ismail Bennani lldb::ScriptedThreadInterfaceSP 20035653324SMed Ismail Bennani ScriptedProcessPythonInterface::CreateScriptedThreadInterface() { 20135653324SMed Ismail Bennani return m_interpreter.CreateScriptedThreadInterface(); 20235653324SMed Ismail Bennani } 20335653324SMed Ismail Bennani 20435653324SMed Ismail Bennani StructuredData::DictionarySP ScriptedProcessPythonInterface::GetMetadata() { 20535653324SMed Ismail Bennani Status error; 20635653324SMed Ismail Bennani StructuredData::DictionarySP dict = 20735653324SMed Ismail Bennani Dispatch<StructuredData::DictionarySP>("get_process_metadata", error); 20835653324SMed Ismail Bennani 20935653324SMed Ismail Bennani if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, 21035653324SMed Ismail Bennani error)) 21135653324SMed Ismail Bennani return {}; 21235653324SMed Ismail Bennani 21335653324SMed Ismail Bennani return dict; 21435653324SMed Ismail Bennani } 21535653324SMed Ismail Bennani 21635653324SMed Ismail Bennani void ScriptedProcessPythonInterface::Initialize() { 21735653324SMed Ismail Bennani const std::vector<llvm::StringRef> ci_usages = { 21835653324SMed Ismail Bennani "process attach -C <script-name> [-k key -v value ...]", 21935653324SMed Ismail Bennani "process launch -C <script-name> [-k key -v value ...]"}; 22035653324SMed Ismail Bennani const std::vector<llvm::StringRef> api_usages = { 22135653324SMed Ismail Bennani "SBAttachInfo.SetScriptedProcessClassName", 22235653324SMed Ismail Bennani "SBAttachInfo.SetScriptedProcessDictionary", 22335653324SMed Ismail Bennani "SBTarget.Attach", 22435653324SMed Ismail Bennani "SBLaunchInfo.SetScriptedProcessClassName", 22535653324SMed Ismail Bennani "SBLaunchInfo.SetScriptedProcessDictionary", 22635653324SMed Ismail Bennani "SBTarget.Launch"}; 22735653324SMed Ismail Bennani PluginManager::RegisterPlugin( 22835653324SMed Ismail Bennani GetPluginNameStatic(), llvm::StringRef("Mock process state"), 22935653324SMed Ismail Bennani CreateInstance, eScriptLanguagePython, {ci_usages, api_usages}); 23035653324SMed Ismail Bennani } 23135653324SMed Ismail Bennani 23235653324SMed Ismail Bennani void ScriptedProcessPythonInterface::Terminate() { 23335653324SMed Ismail Bennani PluginManager::UnregisterPlugin(CreateInstance); 23435653324SMed Ismail Bennani } 23535653324SMed Ismail Bennani 23635653324SMed Ismail Bennani #endif 237