xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1be691f3bSpatrick //===-- ScriptedProcessPythonInterface.cpp --------------------------------===//
2be691f3bSpatrick //
3be691f3bSpatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4be691f3bSpatrick // See https://llvm.org/LICENSE.txt for license information.
5be691f3bSpatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6be691f3bSpatrick //
7be691f3bSpatrick //===----------------------------------------------------------------------===//
8be691f3bSpatrick 
9be691f3bSpatrick #include "lldb/Host/Config.h"
10*f6aab3d8Srobert #include "lldb/Utility/Log.h"
11*f6aab3d8Srobert #include "lldb/Utility/Status.h"
12be691f3bSpatrick #include "lldb/lldb-enumerations.h"
13be691f3bSpatrick 
14be691f3bSpatrick #if LLDB_ENABLE_PYTHON
15be691f3bSpatrick 
16be691f3bSpatrick // LLDB Python header must be included first
17be691f3bSpatrick #include "lldb-python.h"
18be691f3bSpatrick 
19be691f3bSpatrick #include "SWIGPythonBridge.h"
20be691f3bSpatrick #include "ScriptInterpreterPythonImpl.h"
21be691f3bSpatrick #include "ScriptedProcessPythonInterface.h"
22*f6aab3d8Srobert #include "ScriptedThreadPythonInterface.h"
23*f6aab3d8Srobert #include <optional>
24be691f3bSpatrick 
25be691f3bSpatrick using namespace lldb;
26be691f3bSpatrick using namespace lldb_private;
27be691f3bSpatrick using namespace lldb_private::python;
28be691f3bSpatrick using Locker = ScriptInterpreterPythonImpl::Locker;
29be691f3bSpatrick 
ScriptedProcessPythonInterface(ScriptInterpreterPythonImpl & interpreter)30*f6aab3d8Srobert ScriptedProcessPythonInterface::ScriptedProcessPythonInterface(
31*f6aab3d8Srobert     ScriptInterpreterPythonImpl &interpreter)
32*f6aab3d8Srobert     : ScriptedProcessInterface(), ScriptedPythonInterface(interpreter) {}
33*f6aab3d8Srobert 
CreatePluginObject(llvm::StringRef class_name,ExecutionContext & exe_ctx,StructuredData::DictionarySP args_sp,StructuredData::Generic * script_obj)34be691f3bSpatrick StructuredData::GenericSP ScriptedProcessPythonInterface::CreatePluginObject(
35*f6aab3d8Srobert     llvm::StringRef class_name, ExecutionContext &exe_ctx,
36*f6aab3d8Srobert     StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) {
37be691f3bSpatrick   if (class_name.empty())
38be691f3bSpatrick     return {};
39be691f3bSpatrick 
40*f6aab3d8Srobert   StructuredDataImpl args_impl(args_sp);
41be691f3bSpatrick   std::string error_string;
42be691f3bSpatrick 
43be691f3bSpatrick   Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
44be691f3bSpatrick                  Locker::FreeLock);
45be691f3bSpatrick 
46*f6aab3d8Srobert   lldb::ExecutionContextRefSP exe_ctx_ref_sp =
47*f6aab3d8Srobert       std::make_shared<ExecutionContextRef>(exe_ctx);
48*f6aab3d8Srobert 
49*f6aab3d8Srobert   PythonObject ret_val = LLDBSwigPythonCreateScriptedObject(
50*f6aab3d8Srobert       class_name.str().c_str(), m_interpreter.GetDictionaryName(),
51*f6aab3d8Srobert       exe_ctx_ref_sp, args_impl, error_string);
52be691f3bSpatrick 
53be691f3bSpatrick   m_object_instance_sp =
54*f6aab3d8Srobert       StructuredData::GenericSP(new StructuredPythonObject(std::move(ret_val)));
55be691f3bSpatrick 
56be691f3bSpatrick   return m_object_instance_sp;
57be691f3bSpatrick }
58be691f3bSpatrick 
Launch()59be691f3bSpatrick Status ScriptedProcessPythonInterface::Launch() {
60be691f3bSpatrick   return GetStatusFromMethod("launch");
61be691f3bSpatrick }
62be691f3bSpatrick 
Resume()63be691f3bSpatrick Status ScriptedProcessPythonInterface::Resume() {
64be691f3bSpatrick   return GetStatusFromMethod("resume");
65be691f3bSpatrick }
66be691f3bSpatrick 
ShouldStop()67be691f3bSpatrick bool ScriptedProcessPythonInterface::ShouldStop() {
68*f6aab3d8Srobert   Status error;
69*f6aab3d8Srobert   StructuredData::ObjectSP obj = Dispatch("is_alive", error);
70be691f3bSpatrick 
71*f6aab3d8Srobert   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
72*f6aab3d8Srobert     return {};
73be691f3bSpatrick 
74*f6aab3d8Srobert   return obj->GetBooleanValue();
75be691f3bSpatrick }
76be691f3bSpatrick 
Stop()77be691f3bSpatrick Status ScriptedProcessPythonInterface::Stop() {
78be691f3bSpatrick   return GetStatusFromMethod("stop");
79be691f3bSpatrick }
80be691f3bSpatrick 
81*f6aab3d8Srobert std::optional<MemoryRegionInfo>
GetMemoryRegionContainingAddress(lldb::addr_t address,Status & error)82be691f3bSpatrick ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress(
83*f6aab3d8Srobert     lldb::addr_t address, Status &error) {
84*f6aab3d8Srobert   auto mem_region = Dispatch<std::optional<MemoryRegionInfo>>(
85*f6aab3d8Srobert       "get_memory_region_containing_address", error, address);
86*f6aab3d8Srobert 
87*f6aab3d8Srobert   if (error.Fail()) {
88*f6aab3d8Srobert     return ErrorWithMessage<MemoryRegionInfo>(LLVM_PRETTY_FUNCTION,
89*f6aab3d8Srobert                                               error.AsCString(), error);
90*f6aab3d8Srobert   }
91*f6aab3d8Srobert 
92*f6aab3d8Srobert   return mem_region;
93*f6aab3d8Srobert }
94*f6aab3d8Srobert 
GetThreadsInfo()95*f6aab3d8Srobert StructuredData::DictionarySP ScriptedProcessPythonInterface::GetThreadsInfo() {
96*f6aab3d8Srobert   Status error;
97*f6aab3d8Srobert   StructuredData::DictionarySP dict =
98*f6aab3d8Srobert       Dispatch<StructuredData::DictionarySP>("get_threads_info", error);
99*f6aab3d8Srobert 
100*f6aab3d8Srobert   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error))
101*f6aab3d8Srobert     return {};
102*f6aab3d8Srobert 
103*f6aab3d8Srobert   return dict;
104be691f3bSpatrick }
105be691f3bSpatrick 
106be691f3bSpatrick StructuredData::DictionarySP
GetThreadWithID(lldb::tid_t tid)107be691f3bSpatrick ScriptedProcessPythonInterface::GetThreadWithID(lldb::tid_t tid) {
108*f6aab3d8Srobert   Status error;
109*f6aab3d8Srobert   StructuredData::ObjectSP obj = Dispatch("get_thread_with_id", error, tid);
110*f6aab3d8Srobert 
111*f6aab3d8Srobert   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
112*f6aab3d8Srobert     return {};
113*f6aab3d8Srobert 
114*f6aab3d8Srobert   StructuredData::DictionarySP dict{obj->GetAsDictionary()};
115*f6aab3d8Srobert 
116*f6aab3d8Srobert   return dict;
117be691f3bSpatrick }
118be691f3bSpatrick 
119be691f3bSpatrick StructuredData::DictionarySP
GetRegistersForThread(lldb::tid_t tid)120be691f3bSpatrick ScriptedProcessPythonInterface::GetRegistersForThread(lldb::tid_t tid) {
121be691f3bSpatrick   // TODO: Implement
122*f6aab3d8Srobert   return {};
123be691f3bSpatrick }
124be691f3bSpatrick 
ReadMemoryAtAddress(lldb::addr_t address,size_t size,Status & error)125be691f3bSpatrick lldb::DataExtractorSP ScriptedProcessPythonInterface::ReadMemoryAtAddress(
126be691f3bSpatrick     lldb::addr_t address, size_t size, Status &error) {
127*f6aab3d8Srobert   Status py_error;
128*f6aab3d8Srobert   lldb::DataExtractorSP data_sp = Dispatch<lldb::DataExtractorSP>(
129*f6aab3d8Srobert       "read_memory_at_address", py_error, address, size, error);
130be691f3bSpatrick 
131*f6aab3d8Srobert   // If there was an error on the python call, surface it to the user.
132*f6aab3d8Srobert   if (py_error.Fail())
133*f6aab3d8Srobert     error = py_error;
134be691f3bSpatrick 
135*f6aab3d8Srobert   return data_sp;
136be691f3bSpatrick }
137be691f3bSpatrick 
GetLoadedImages()138*f6aab3d8Srobert StructuredData::ArraySP ScriptedProcessPythonInterface::GetLoadedImages() {
139*f6aab3d8Srobert   Status error;
140*f6aab3d8Srobert   StructuredData::ArraySP array =
141*f6aab3d8Srobert       Dispatch<StructuredData::ArraySP>("get_loaded_images", error);
142be691f3bSpatrick 
143*f6aab3d8Srobert   if (!array || !array->IsValid() || error.Fail()) {
144*f6aab3d8Srobert     return ScriptedInterface::ErrorWithMessage<StructuredData::ArraySP>(
145*f6aab3d8Srobert         LLVM_PRETTY_FUNCTION,
146*f6aab3d8Srobert         llvm::Twine("Null or invalid object (" +
147*f6aab3d8Srobert                     llvm::Twine(error.AsCString()) + llvm::Twine(")."))
148*f6aab3d8Srobert             .str(),
149*f6aab3d8Srobert         error);
150be691f3bSpatrick   }
151be691f3bSpatrick 
152*f6aab3d8Srobert   return array;
153be691f3bSpatrick }
154be691f3bSpatrick 
GetProcessID()155be691f3bSpatrick lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() {
156*f6aab3d8Srobert   Status error;
157*f6aab3d8Srobert   StructuredData::ObjectSP obj = Dispatch("get_process_id", error);
158*f6aab3d8Srobert 
159*f6aab3d8Srobert   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
160*f6aab3d8Srobert     return LLDB_INVALID_PROCESS_ID;
161*f6aab3d8Srobert 
162*f6aab3d8Srobert   return obj->GetIntegerValue(LLDB_INVALID_PROCESS_ID);
163be691f3bSpatrick }
164be691f3bSpatrick 
IsAlive()165be691f3bSpatrick bool ScriptedProcessPythonInterface::IsAlive() {
166*f6aab3d8Srobert   Status error;
167*f6aab3d8Srobert   StructuredData::ObjectSP obj = Dispatch("is_alive", error);
168be691f3bSpatrick 
169*f6aab3d8Srobert   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
170*f6aab3d8Srobert     return {};
171be691f3bSpatrick 
172*f6aab3d8Srobert   return obj->GetBooleanValue();
173*f6aab3d8Srobert }
174*f6aab3d8Srobert 
175*f6aab3d8Srobert std::optional<std::string>
GetScriptedThreadPluginName()176*f6aab3d8Srobert ScriptedProcessPythonInterface::GetScriptedThreadPluginName() {
177*f6aab3d8Srobert   Status error;
178*f6aab3d8Srobert   StructuredData::ObjectSP obj = Dispatch("get_scripted_thread_plugin", error);
179*f6aab3d8Srobert 
180*f6aab3d8Srobert   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
181*f6aab3d8Srobert     return {};
182*f6aab3d8Srobert 
183*f6aab3d8Srobert   return obj->GetStringValue().str();
184*f6aab3d8Srobert }
185*f6aab3d8Srobert 
186*f6aab3d8Srobert lldb::ScriptedThreadInterfaceSP
CreateScriptedThreadInterface()187*f6aab3d8Srobert ScriptedProcessPythonInterface::CreateScriptedThreadInterface() {
188*f6aab3d8Srobert   return std::make_shared<ScriptedThreadPythonInterface>(m_interpreter);
189*f6aab3d8Srobert }
190*f6aab3d8Srobert 
GetMetadata()191*f6aab3d8Srobert StructuredData::DictionarySP ScriptedProcessPythonInterface::GetMetadata() {
192*f6aab3d8Srobert   Status error;
193*f6aab3d8Srobert   StructuredData::DictionarySP dict =
194*f6aab3d8Srobert       Dispatch<StructuredData::DictionarySP>("get_process_metadata", error);
195*f6aab3d8Srobert 
196*f6aab3d8Srobert   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error))
197*f6aab3d8Srobert     return {};
198*f6aab3d8Srobert 
199*f6aab3d8Srobert   return dict;
200be691f3bSpatrick }
201be691f3bSpatrick 
202be691f3bSpatrick #endif
203