15f757f3fSDimitry Andric //===-- ScriptedProcessPythonInterface.cpp --------------------------------===// 25f757f3fSDimitry Andric // 35f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 45f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 55f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65f757f3fSDimitry Andric // 75f757f3fSDimitry Andric //===----------------------------------------------------------------------===// 85f757f3fSDimitry Andric 95f757f3fSDimitry Andric #include "lldb/Host/Config.h" 105f757f3fSDimitry Andric #if LLDB_ENABLE_PYTHON 115f757f3fSDimitry Andric // LLDB Python header must be included first 125f757f3fSDimitry Andric #include "../lldb-python.h" 135f757f3fSDimitry Andric #endif 145f757f3fSDimitry Andric #include "lldb/Target/Process.h" 155f757f3fSDimitry Andric #include "lldb/Utility/Log.h" 165f757f3fSDimitry Andric #include "lldb/Utility/Status.h" 175f757f3fSDimitry Andric #include "lldb/lldb-enumerations.h" 185f757f3fSDimitry Andric 195f757f3fSDimitry Andric #if LLDB_ENABLE_PYTHON 205f757f3fSDimitry Andric 215f757f3fSDimitry Andric #include "../SWIGPythonBridge.h" 225f757f3fSDimitry Andric #include "../ScriptInterpreterPythonImpl.h" 235f757f3fSDimitry Andric #include "ScriptedProcessPythonInterface.h" 245f757f3fSDimitry Andric #include "ScriptedThreadPythonInterface.h" 255f757f3fSDimitry Andric #include <optional> 265f757f3fSDimitry Andric 275f757f3fSDimitry Andric using namespace lldb; 285f757f3fSDimitry Andric using namespace lldb_private; 295f757f3fSDimitry Andric using namespace lldb_private::python; 305f757f3fSDimitry Andric using Locker = ScriptInterpreterPythonImpl::Locker; 315f757f3fSDimitry Andric 325f757f3fSDimitry Andric ScriptedProcessPythonInterface::ScriptedProcessPythonInterface( 335f757f3fSDimitry Andric ScriptInterpreterPythonImpl &interpreter) 345f757f3fSDimitry Andric : ScriptedProcessInterface(), ScriptedPythonInterface(interpreter) {} 355f757f3fSDimitry Andric 365f757f3fSDimitry Andric llvm::Expected<StructuredData::GenericSP> 375f757f3fSDimitry Andric ScriptedProcessPythonInterface::CreatePluginObject( 385f757f3fSDimitry Andric llvm::StringRef class_name, ExecutionContext &exe_ctx, 395f757f3fSDimitry Andric StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) { 405f757f3fSDimitry Andric ExecutionContextRefSP exe_ctx_ref_sp = 415f757f3fSDimitry Andric std::make_shared<ExecutionContextRef>(exe_ctx); 425f757f3fSDimitry Andric StructuredDataImpl sd_impl(args_sp); 435f757f3fSDimitry Andric return ScriptedPythonInterface::CreatePluginObject(class_name, script_obj, 445f757f3fSDimitry Andric exe_ctx_ref_sp, sd_impl); 455f757f3fSDimitry Andric } 465f757f3fSDimitry Andric 475f757f3fSDimitry Andric StructuredData::DictionarySP ScriptedProcessPythonInterface::GetCapabilities() { 485f757f3fSDimitry Andric Status error; 495f757f3fSDimitry Andric StructuredData::DictionarySP dict = 505f757f3fSDimitry Andric Dispatch<StructuredData::DictionarySP>("get_capabilities", error); 515f757f3fSDimitry Andric 52*0fca6ea1SDimitry Andric if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, 53*0fca6ea1SDimitry Andric error)) 545f757f3fSDimitry Andric return {}; 555f757f3fSDimitry Andric 565f757f3fSDimitry Andric return dict; 575f757f3fSDimitry Andric } 585f757f3fSDimitry Andric 595f757f3fSDimitry Andric Status 605f757f3fSDimitry Andric ScriptedProcessPythonInterface::Attach(const ProcessAttachInfo &attach_info) { 615f757f3fSDimitry Andric lldb::ProcessAttachInfoSP attach_info_sp = 625f757f3fSDimitry Andric std::make_shared<ProcessAttachInfo>(attach_info); 635f757f3fSDimitry Andric return GetStatusFromMethod("attach", attach_info_sp); 645f757f3fSDimitry Andric } 655f757f3fSDimitry Andric 665f757f3fSDimitry Andric Status ScriptedProcessPythonInterface::Launch() { 675f757f3fSDimitry Andric return GetStatusFromMethod("launch"); 685f757f3fSDimitry Andric } 695f757f3fSDimitry Andric 705f757f3fSDimitry Andric Status ScriptedProcessPythonInterface::Resume() { 715f757f3fSDimitry Andric // When calling ScriptedProcess.Resume from lldb we should always stop. 725f757f3fSDimitry Andric return GetStatusFromMethod("resume", /*should_stop=*/true); 735f757f3fSDimitry Andric } 745f757f3fSDimitry Andric 755f757f3fSDimitry Andric std::optional<MemoryRegionInfo> 765f757f3fSDimitry Andric ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress( 775f757f3fSDimitry Andric lldb::addr_t address, Status &error) { 785f757f3fSDimitry Andric auto mem_region = Dispatch<std::optional<MemoryRegionInfo>>( 795f757f3fSDimitry Andric "get_memory_region_containing_address", error, address); 805f757f3fSDimitry Andric 815f757f3fSDimitry Andric if (error.Fail()) { 825f757f3fSDimitry Andric return ErrorWithMessage<MemoryRegionInfo>(LLVM_PRETTY_FUNCTION, 835f757f3fSDimitry Andric error.AsCString(), error); 845f757f3fSDimitry Andric } 855f757f3fSDimitry Andric 865f757f3fSDimitry Andric return mem_region; 875f757f3fSDimitry Andric } 885f757f3fSDimitry Andric 895f757f3fSDimitry Andric StructuredData::DictionarySP ScriptedProcessPythonInterface::GetThreadsInfo() { 905f757f3fSDimitry Andric Status error; 915f757f3fSDimitry Andric StructuredData::DictionarySP dict = 925f757f3fSDimitry Andric Dispatch<StructuredData::DictionarySP>("get_threads_info", error); 935f757f3fSDimitry Andric 94*0fca6ea1SDimitry Andric if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, 95*0fca6ea1SDimitry Andric error)) 965f757f3fSDimitry Andric return {}; 975f757f3fSDimitry Andric 985f757f3fSDimitry Andric return dict; 995f757f3fSDimitry Andric } 1005f757f3fSDimitry Andric 1015f757f3fSDimitry Andric bool ScriptedProcessPythonInterface::CreateBreakpoint(lldb::addr_t addr, 1025f757f3fSDimitry Andric Status &error) { 1035f757f3fSDimitry Andric Status py_error; 1045f757f3fSDimitry Andric StructuredData::ObjectSP obj = 1055f757f3fSDimitry Andric Dispatch("create_breakpoint", py_error, addr, error); 1065f757f3fSDimitry Andric 1075f757f3fSDimitry Andric // If there was an error on the python call, surface it to the user. 1085f757f3fSDimitry Andric if (py_error.Fail()) 1095f757f3fSDimitry Andric error = py_error; 1105f757f3fSDimitry Andric 111*0fca6ea1SDimitry Andric if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, 112*0fca6ea1SDimitry Andric error)) 1135f757f3fSDimitry Andric return {}; 1145f757f3fSDimitry Andric 1155f757f3fSDimitry Andric return obj->GetBooleanValue(); 1165f757f3fSDimitry Andric } 1175f757f3fSDimitry Andric 1185f757f3fSDimitry Andric lldb::DataExtractorSP ScriptedProcessPythonInterface::ReadMemoryAtAddress( 1195f757f3fSDimitry Andric lldb::addr_t address, size_t size, Status &error) { 1205f757f3fSDimitry Andric Status py_error; 1215f757f3fSDimitry Andric lldb::DataExtractorSP data_sp = Dispatch<lldb::DataExtractorSP>( 1225f757f3fSDimitry Andric "read_memory_at_address", py_error, address, size, error); 1235f757f3fSDimitry Andric 1245f757f3fSDimitry Andric // If there was an error on the python call, surface it to the user. 1255f757f3fSDimitry Andric if (py_error.Fail()) 1265f757f3fSDimitry Andric error = py_error; 1275f757f3fSDimitry Andric 1285f757f3fSDimitry Andric return data_sp; 1295f757f3fSDimitry Andric } 1305f757f3fSDimitry Andric 1315f757f3fSDimitry Andric lldb::offset_t ScriptedProcessPythonInterface::WriteMemoryAtAddress( 1325f757f3fSDimitry Andric lldb::addr_t addr, lldb::DataExtractorSP data_sp, Status &error) { 1335f757f3fSDimitry Andric Status py_error; 1345f757f3fSDimitry Andric StructuredData::ObjectSP obj = 1355f757f3fSDimitry Andric Dispatch("write_memory_at_address", py_error, addr, data_sp, error); 1365f757f3fSDimitry Andric 137*0fca6ea1SDimitry Andric if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, 138*0fca6ea1SDimitry Andric error)) 1395f757f3fSDimitry Andric return LLDB_INVALID_OFFSET; 1405f757f3fSDimitry Andric 1415f757f3fSDimitry Andric // If there was an error on the python call, surface it to the user. 1425f757f3fSDimitry Andric if (py_error.Fail()) 1435f757f3fSDimitry Andric error = py_error; 1445f757f3fSDimitry Andric 1455f757f3fSDimitry Andric return obj->GetUnsignedIntegerValue(LLDB_INVALID_OFFSET); 1465f757f3fSDimitry Andric } 1475f757f3fSDimitry Andric 1485f757f3fSDimitry Andric StructuredData::ArraySP ScriptedProcessPythonInterface::GetLoadedImages() { 1495f757f3fSDimitry Andric Status error; 1505f757f3fSDimitry Andric StructuredData::ArraySP array = 1515f757f3fSDimitry Andric Dispatch<StructuredData::ArraySP>("get_loaded_images", error); 1525f757f3fSDimitry Andric 153*0fca6ea1SDimitry Andric if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, array, 154*0fca6ea1SDimitry Andric error)) 1555f757f3fSDimitry Andric return {}; 1565f757f3fSDimitry Andric 1575f757f3fSDimitry Andric return array; 1585f757f3fSDimitry Andric } 1595f757f3fSDimitry Andric 1605f757f3fSDimitry Andric lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() { 1615f757f3fSDimitry Andric Status error; 1625f757f3fSDimitry Andric StructuredData::ObjectSP obj = Dispatch("get_process_id", error); 1635f757f3fSDimitry Andric 164*0fca6ea1SDimitry Andric if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, 165*0fca6ea1SDimitry Andric error)) 1665f757f3fSDimitry Andric return LLDB_INVALID_PROCESS_ID; 1675f757f3fSDimitry Andric 1685f757f3fSDimitry Andric return obj->GetUnsignedIntegerValue(LLDB_INVALID_PROCESS_ID); 1695f757f3fSDimitry Andric } 1705f757f3fSDimitry Andric 1715f757f3fSDimitry Andric bool ScriptedProcessPythonInterface::IsAlive() { 1725f757f3fSDimitry Andric Status error; 1735f757f3fSDimitry Andric StructuredData::ObjectSP obj = Dispatch("is_alive", error); 1745f757f3fSDimitry Andric 175*0fca6ea1SDimitry Andric if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, 176*0fca6ea1SDimitry Andric error)) 1775f757f3fSDimitry Andric return {}; 1785f757f3fSDimitry Andric 1795f757f3fSDimitry Andric return obj->GetBooleanValue(); 1805f757f3fSDimitry Andric } 1815f757f3fSDimitry Andric 1825f757f3fSDimitry Andric std::optional<std::string> 1835f757f3fSDimitry Andric ScriptedProcessPythonInterface::GetScriptedThreadPluginName() { 1845f757f3fSDimitry Andric Status error; 1855f757f3fSDimitry Andric StructuredData::ObjectSP obj = Dispatch("get_scripted_thread_plugin", error); 1865f757f3fSDimitry Andric 187*0fca6ea1SDimitry Andric if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, 188*0fca6ea1SDimitry Andric error)) 1895f757f3fSDimitry Andric return {}; 1905f757f3fSDimitry Andric 1915f757f3fSDimitry Andric return obj->GetStringValue().str(); 1925f757f3fSDimitry Andric } 1935f757f3fSDimitry Andric 1945f757f3fSDimitry Andric lldb::ScriptedThreadInterfaceSP 1955f757f3fSDimitry Andric ScriptedProcessPythonInterface::CreateScriptedThreadInterface() { 1965f757f3fSDimitry Andric return m_interpreter.CreateScriptedThreadInterface(); 1975f757f3fSDimitry Andric } 1985f757f3fSDimitry Andric 1995f757f3fSDimitry Andric StructuredData::DictionarySP ScriptedProcessPythonInterface::GetMetadata() { 2005f757f3fSDimitry Andric Status error; 2015f757f3fSDimitry Andric StructuredData::DictionarySP dict = 2025f757f3fSDimitry Andric Dispatch<StructuredData::DictionarySP>("get_process_metadata", error); 2035f757f3fSDimitry Andric 204*0fca6ea1SDimitry Andric if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, 205*0fca6ea1SDimitry Andric error)) 2065f757f3fSDimitry Andric return {}; 2075f757f3fSDimitry Andric 2085f757f3fSDimitry Andric return dict; 2095f757f3fSDimitry Andric } 2105f757f3fSDimitry Andric 2115f757f3fSDimitry Andric #endif 212