1344a3780SDimitry Andric //===-- ScriptedProcessPythonInterface.cpp --------------------------------===//
2344a3780SDimitry Andric //
3344a3780SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4344a3780SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5344a3780SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6344a3780SDimitry Andric //
7344a3780SDimitry Andric //===----------------------------------------------------------------------===//
8344a3780SDimitry Andric
9344a3780SDimitry Andric #include "lldb/Host/Config.h"
107fa27ce4SDimitry Andric #if LLDB_ENABLE_PYTHON
117fa27ce4SDimitry Andric // LLDB Python header must be included first
12b1c73532SDimitry Andric #include "../lldb-python.h"
137fa27ce4SDimitry Andric #endif
147fa27ce4SDimitry Andric #include "lldb/Target/Process.h"
15c0981da4SDimitry Andric #include "lldb/Utility/Log.h"
16e3b55780SDimitry Andric #include "lldb/Utility/Status.h"
17344a3780SDimitry Andric #include "lldb/lldb-enumerations.h"
18344a3780SDimitry Andric
19344a3780SDimitry Andric #if LLDB_ENABLE_PYTHON
20344a3780SDimitry Andric
21b1c73532SDimitry Andric #include "../SWIGPythonBridge.h"
22b1c73532SDimitry Andric #include "../ScriptInterpreterPythonImpl.h"
23344a3780SDimitry Andric #include "ScriptedProcessPythonInterface.h"
24c0981da4SDimitry Andric #include "ScriptedThreadPythonInterface.h"
25e3b55780SDimitry Andric #include <optional>
26344a3780SDimitry Andric
27344a3780SDimitry Andric using namespace lldb;
28344a3780SDimitry Andric using namespace lldb_private;
29344a3780SDimitry Andric using namespace lldb_private::python;
30344a3780SDimitry Andric using Locker = ScriptInterpreterPythonImpl::Locker;
31344a3780SDimitry Andric
ScriptedProcessPythonInterface(ScriptInterpreterPythonImpl & interpreter)32c0981da4SDimitry Andric ScriptedProcessPythonInterface::ScriptedProcessPythonInterface(
33c0981da4SDimitry Andric ScriptInterpreterPythonImpl &interpreter)
34c0981da4SDimitry Andric : ScriptedProcessInterface(), ScriptedPythonInterface(interpreter) {}
35c0981da4SDimitry Andric
36b1c73532SDimitry Andric llvm::Expected<StructuredData::GenericSP>
CreatePluginObject(llvm::StringRef class_name,ExecutionContext & exe_ctx,StructuredData::DictionarySP args_sp,StructuredData::Generic * script_obj)37b1c73532SDimitry Andric ScriptedProcessPythonInterface::CreatePluginObject(
38c0981da4SDimitry Andric llvm::StringRef class_name, ExecutionContext &exe_ctx,
396f8fc217SDimitry Andric StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) {
40b1c73532SDimitry Andric ExecutionContextRefSP exe_ctx_ref_sp =
41e3b55780SDimitry Andric std::make_shared<ExecutionContextRef>(exe_ctx);
42b1c73532SDimitry Andric StructuredDataImpl sd_impl(args_sp);
43b1c73532SDimitry Andric return ScriptedPythonInterface::CreatePluginObject(class_name, script_obj,
44b1c73532SDimitry Andric exe_ctx_ref_sp, sd_impl);
45344a3780SDimitry Andric }
46344a3780SDimitry Andric
GetCapabilities()477fa27ce4SDimitry Andric StructuredData::DictionarySP ScriptedProcessPythonInterface::GetCapabilities() {
487fa27ce4SDimitry Andric Status error;
497fa27ce4SDimitry Andric StructuredData::DictionarySP dict =
507fa27ce4SDimitry Andric Dispatch<StructuredData::DictionarySP>("get_capabilities", error);
517fa27ce4SDimitry Andric
52ac9a064cSDimitry Andric if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict,
53ac9a064cSDimitry Andric error))
547fa27ce4SDimitry Andric return {};
557fa27ce4SDimitry Andric
567fa27ce4SDimitry Andric return dict;
577fa27ce4SDimitry Andric }
587fa27ce4SDimitry Andric
597fa27ce4SDimitry Andric Status
Attach(const ProcessAttachInfo & attach_info)607fa27ce4SDimitry Andric ScriptedProcessPythonInterface::Attach(const ProcessAttachInfo &attach_info) {
617fa27ce4SDimitry Andric lldb::ProcessAttachInfoSP attach_info_sp =
627fa27ce4SDimitry Andric std::make_shared<ProcessAttachInfo>(attach_info);
637fa27ce4SDimitry Andric return GetStatusFromMethod("attach", attach_info_sp);
647fa27ce4SDimitry Andric }
657fa27ce4SDimitry Andric
Launch()66344a3780SDimitry Andric Status ScriptedProcessPythonInterface::Launch() {
67344a3780SDimitry Andric return GetStatusFromMethod("launch");
68344a3780SDimitry Andric }
69344a3780SDimitry Andric
Resume()70344a3780SDimitry Andric Status ScriptedProcessPythonInterface::Resume() {
717fa27ce4SDimitry Andric // When calling ScriptedProcess.Resume from lldb we should always stop.
727fa27ce4SDimitry Andric return GetStatusFromMethod("resume", /*should_stop=*/true);
73344a3780SDimitry Andric }
74344a3780SDimitry Andric
75e3b55780SDimitry Andric std::optional<MemoryRegionInfo>
GetMemoryRegionContainingAddress(lldb::addr_t address,Status & error)76344a3780SDimitry Andric ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress(
77c0981da4SDimitry Andric lldb::addr_t address, Status &error) {
78e3b55780SDimitry Andric auto mem_region = Dispatch<std::optional<MemoryRegionInfo>>(
79c0981da4SDimitry Andric "get_memory_region_containing_address", error, address);
80c0981da4SDimitry Andric
81c0981da4SDimitry Andric if (error.Fail()) {
82c0981da4SDimitry Andric return ErrorWithMessage<MemoryRegionInfo>(LLVM_PRETTY_FUNCTION,
83c0981da4SDimitry Andric error.AsCString(), error);
84c0981da4SDimitry Andric }
85c0981da4SDimitry Andric
86c0981da4SDimitry Andric return mem_region;
87344a3780SDimitry Andric }
88344a3780SDimitry Andric
GetThreadsInfo()896f8fc217SDimitry Andric StructuredData::DictionarySP ScriptedProcessPythonInterface::GetThreadsInfo() {
906f8fc217SDimitry Andric Status error;
916f8fc217SDimitry Andric StructuredData::DictionarySP dict =
926f8fc217SDimitry Andric Dispatch<StructuredData::DictionarySP>("get_threads_info", error);
936f8fc217SDimitry Andric
94ac9a064cSDimitry Andric if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict,
95ac9a064cSDimitry Andric error))
966f8fc217SDimitry Andric return {};
976f8fc217SDimitry Andric
986f8fc217SDimitry Andric return dict;
996f8fc217SDimitry Andric }
1006f8fc217SDimitry Andric
CreateBreakpoint(lldb::addr_t addr,Status & error)1017fa27ce4SDimitry Andric bool ScriptedProcessPythonInterface::CreateBreakpoint(lldb::addr_t addr,
1027fa27ce4SDimitry Andric Status &error) {
1037fa27ce4SDimitry Andric Status py_error;
1047fa27ce4SDimitry Andric StructuredData::ObjectSP obj =
1057fa27ce4SDimitry Andric Dispatch("create_breakpoint", py_error, addr, error);
1067fa27ce4SDimitry Andric
1077fa27ce4SDimitry Andric // If there was an error on the python call, surface it to the user.
1087fa27ce4SDimitry Andric if (py_error.Fail())
1097fa27ce4SDimitry Andric error = py_error;
110c0981da4SDimitry Andric
111ac9a064cSDimitry Andric if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
112ac9a064cSDimitry Andric error))
113c0981da4SDimitry Andric return {};
114c0981da4SDimitry Andric
1157fa27ce4SDimitry Andric return obj->GetBooleanValue();
116344a3780SDimitry Andric }
117344a3780SDimitry Andric
ReadMemoryAtAddress(lldb::addr_t address,size_t size,Status & error)118344a3780SDimitry Andric lldb::DataExtractorSP ScriptedProcessPythonInterface::ReadMemoryAtAddress(
119344a3780SDimitry Andric lldb::addr_t address, size_t size, Status &error) {
120e3b55780SDimitry Andric Status py_error;
121e3b55780SDimitry Andric lldb::DataExtractorSP data_sp = Dispatch<lldb::DataExtractorSP>(
122e3b55780SDimitry Andric "read_memory_at_address", py_error, address, size, error);
123e3b55780SDimitry Andric
124e3b55780SDimitry Andric // If there was an error on the python call, surface it to the user.
125e3b55780SDimitry Andric if (py_error.Fail())
126e3b55780SDimitry Andric error = py_error;
127e3b55780SDimitry Andric
128e3b55780SDimitry Andric return data_sp;
129344a3780SDimitry Andric }
130344a3780SDimitry Andric
WriteMemoryAtAddress(lldb::addr_t addr,lldb::DataExtractorSP data_sp,Status & error)1317fa27ce4SDimitry Andric lldb::offset_t ScriptedProcessPythonInterface::WriteMemoryAtAddress(
1327fa27ce4SDimitry Andric lldb::addr_t addr, lldb::DataExtractorSP data_sp, Status &error) {
1337fa27ce4SDimitry Andric Status py_error;
1347fa27ce4SDimitry Andric StructuredData::ObjectSP obj =
1357fa27ce4SDimitry Andric Dispatch("write_memory_at_address", py_error, addr, data_sp, error);
1367fa27ce4SDimitry Andric
137ac9a064cSDimitry Andric if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
138ac9a064cSDimitry Andric error))
1397fa27ce4SDimitry Andric return LLDB_INVALID_OFFSET;
1407fa27ce4SDimitry Andric
1417fa27ce4SDimitry Andric // If there was an error on the python call, surface it to the user.
1427fa27ce4SDimitry Andric if (py_error.Fail())
1437fa27ce4SDimitry Andric error = py_error;
1447fa27ce4SDimitry Andric
1457fa27ce4SDimitry Andric return obj->GetUnsignedIntegerValue(LLDB_INVALID_OFFSET);
1467fa27ce4SDimitry Andric }
1477fa27ce4SDimitry Andric
GetLoadedImages()148145449b1SDimitry Andric StructuredData::ArraySP ScriptedProcessPythonInterface::GetLoadedImages() {
149145449b1SDimitry Andric Status error;
150145449b1SDimitry Andric StructuredData::ArraySP array =
151145449b1SDimitry Andric Dispatch<StructuredData::ArraySP>("get_loaded_images", error);
152145449b1SDimitry Andric
153ac9a064cSDimitry Andric if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, array,
154ac9a064cSDimitry Andric error))
1557fa27ce4SDimitry Andric return {};
156145449b1SDimitry Andric
157145449b1SDimitry Andric return array;
158344a3780SDimitry Andric }
159344a3780SDimitry Andric
GetProcessID()160344a3780SDimitry Andric lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() {
161c0981da4SDimitry Andric Status error;
162c0981da4SDimitry Andric StructuredData::ObjectSP obj = Dispatch("get_process_id", error);
163c0981da4SDimitry Andric
164ac9a064cSDimitry Andric if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
165ac9a064cSDimitry Andric error))
166c0981da4SDimitry Andric return LLDB_INVALID_PROCESS_ID;
167c0981da4SDimitry Andric
1687fa27ce4SDimitry Andric return obj->GetUnsignedIntegerValue(LLDB_INVALID_PROCESS_ID);
169344a3780SDimitry Andric }
170344a3780SDimitry Andric
IsAlive()171344a3780SDimitry Andric bool ScriptedProcessPythonInterface::IsAlive() {
172c0981da4SDimitry Andric Status error;
173c0981da4SDimitry Andric StructuredData::ObjectSP obj = Dispatch("is_alive", error);
174344a3780SDimitry Andric
175ac9a064cSDimitry Andric if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
176ac9a064cSDimitry Andric error))
177c0981da4SDimitry Andric return {};
178344a3780SDimitry Andric
179c0981da4SDimitry Andric return obj->GetBooleanValue();
180c0981da4SDimitry Andric }
181c0981da4SDimitry Andric
182e3b55780SDimitry Andric std::optional<std::string>
GetScriptedThreadPluginName()183c0981da4SDimitry Andric ScriptedProcessPythonInterface::GetScriptedThreadPluginName() {
184c0981da4SDimitry Andric Status error;
185c0981da4SDimitry Andric StructuredData::ObjectSP obj = Dispatch("get_scripted_thread_plugin", error);
186c0981da4SDimitry Andric
187ac9a064cSDimitry Andric if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
188ac9a064cSDimitry Andric error))
189c0981da4SDimitry Andric return {};
190c0981da4SDimitry Andric
191c0981da4SDimitry Andric return obj->GetStringValue().str();
192c0981da4SDimitry Andric }
193c0981da4SDimitry Andric
194c0981da4SDimitry Andric lldb::ScriptedThreadInterfaceSP
CreateScriptedThreadInterface()1956f8fc217SDimitry Andric ScriptedProcessPythonInterface::CreateScriptedThreadInterface() {
196b1c73532SDimitry Andric return m_interpreter.CreateScriptedThreadInterface();
197344a3780SDimitry Andric }
198344a3780SDimitry Andric
GetMetadata()199e3b55780SDimitry Andric StructuredData::DictionarySP ScriptedProcessPythonInterface::GetMetadata() {
200e3b55780SDimitry Andric Status error;
201e3b55780SDimitry Andric StructuredData::DictionarySP dict =
202e3b55780SDimitry Andric Dispatch<StructuredData::DictionarySP>("get_process_metadata", error);
203e3b55780SDimitry Andric
204ac9a064cSDimitry Andric if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict,
205ac9a064cSDimitry Andric error))
206e3b55780SDimitry Andric return {};
207e3b55780SDimitry Andric
208e3b55780SDimitry Andric return dict;
209e3b55780SDimitry Andric }
210e3b55780SDimitry Andric
211344a3780SDimitry Andric #endif
212