xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp (revision be691f3bb6417f04a68938fadbcaee2d5795e764)
1*be691f3bSpatrick //===-- ScriptedProcessPythonInterface.cpp --------------------------------===//
2*be691f3bSpatrick //
3*be691f3bSpatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*be691f3bSpatrick // See https://llvm.org/LICENSE.txt for license information.
5*be691f3bSpatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*be691f3bSpatrick //
7*be691f3bSpatrick //===----------------------------------------------------------------------===//
8*be691f3bSpatrick 
9*be691f3bSpatrick #include "lldb/Host/Config.h"
10*be691f3bSpatrick #include "lldb/lldb-enumerations.h"
11*be691f3bSpatrick 
12*be691f3bSpatrick #if LLDB_ENABLE_PYTHON
13*be691f3bSpatrick 
14*be691f3bSpatrick // LLDB Python header must be included first
15*be691f3bSpatrick #include "lldb-python.h"
16*be691f3bSpatrick 
17*be691f3bSpatrick #include "SWIGPythonBridge.h"
18*be691f3bSpatrick #include "ScriptInterpreterPythonImpl.h"
19*be691f3bSpatrick #include "ScriptedProcessPythonInterface.h"
20*be691f3bSpatrick 
21*be691f3bSpatrick using namespace lldb;
22*be691f3bSpatrick using namespace lldb_private;
23*be691f3bSpatrick using namespace lldb_private::python;
24*be691f3bSpatrick using Locker = ScriptInterpreterPythonImpl::Locker;
25*be691f3bSpatrick 
26*be691f3bSpatrick StructuredData::GenericSP ScriptedProcessPythonInterface::CreatePluginObject(
27*be691f3bSpatrick     const llvm::StringRef class_name, lldb::TargetSP target_sp,
28*be691f3bSpatrick     StructuredData::DictionarySP args_sp) {
29*be691f3bSpatrick   if (class_name.empty())
30*be691f3bSpatrick     return {};
31*be691f3bSpatrick 
32*be691f3bSpatrick   std::string error_string;
33*be691f3bSpatrick   StructuredDataImpl *args_impl = nullptr;
34*be691f3bSpatrick   if (args_sp) {
35*be691f3bSpatrick     args_impl = new StructuredDataImpl();
36*be691f3bSpatrick     args_impl->SetObjectSP(args_sp);
37*be691f3bSpatrick   }
38*be691f3bSpatrick 
39*be691f3bSpatrick   void *ret_val;
40*be691f3bSpatrick 
41*be691f3bSpatrick   {
42*be691f3bSpatrick 
43*be691f3bSpatrick     Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
44*be691f3bSpatrick                    Locker::FreeLock);
45*be691f3bSpatrick 
46*be691f3bSpatrick     ret_val = LLDBSwigPythonCreateScriptedProcess(
47*be691f3bSpatrick         class_name.str().c_str(), m_interpreter.GetDictionaryName(), target_sp,
48*be691f3bSpatrick         args_impl, error_string);
49*be691f3bSpatrick   }
50*be691f3bSpatrick 
51*be691f3bSpatrick   m_object_instance_sp =
52*be691f3bSpatrick       StructuredData::GenericSP(new StructuredPythonObject(ret_val));
53*be691f3bSpatrick 
54*be691f3bSpatrick   return m_object_instance_sp;
55*be691f3bSpatrick }
56*be691f3bSpatrick 
57*be691f3bSpatrick Status ScriptedProcessPythonInterface::Launch() {
58*be691f3bSpatrick   return GetStatusFromMethod("launch");
59*be691f3bSpatrick }
60*be691f3bSpatrick 
61*be691f3bSpatrick Status ScriptedProcessPythonInterface::Resume() {
62*be691f3bSpatrick   return GetStatusFromMethod("resume");
63*be691f3bSpatrick }
64*be691f3bSpatrick 
65*be691f3bSpatrick bool ScriptedProcessPythonInterface::ShouldStop() {
66*be691f3bSpatrick   llvm::Optional<unsigned long long> should_stop =
67*be691f3bSpatrick       GetGenericInteger("should_stop");
68*be691f3bSpatrick 
69*be691f3bSpatrick   if (!should_stop)
70*be691f3bSpatrick     return false;
71*be691f3bSpatrick 
72*be691f3bSpatrick   return static_cast<bool>(*should_stop);
73*be691f3bSpatrick }
74*be691f3bSpatrick 
75*be691f3bSpatrick Status ScriptedProcessPythonInterface::Stop() {
76*be691f3bSpatrick   return GetStatusFromMethod("stop");
77*be691f3bSpatrick }
78*be691f3bSpatrick 
79*be691f3bSpatrick Status ScriptedProcessPythonInterface::GetStatusFromMethod(
80*be691f3bSpatrick     llvm::StringRef method_name) {
81*be691f3bSpatrick   Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
82*be691f3bSpatrick                  Locker::FreeLock);
83*be691f3bSpatrick 
84*be691f3bSpatrick   if (!m_object_instance_sp)
85*be691f3bSpatrick     return Status("Python object ill-formed.");
86*be691f3bSpatrick 
87*be691f3bSpatrick   if (!m_object_instance_sp)
88*be691f3bSpatrick     return Status("Cannot convert Python object to StructuredData::Generic.");
89*be691f3bSpatrick   PythonObject implementor(PyRefType::Borrowed,
90*be691f3bSpatrick                            (PyObject *)m_object_instance_sp->GetValue());
91*be691f3bSpatrick 
92*be691f3bSpatrick   if (!implementor.IsAllocated())
93*be691f3bSpatrick     return Status("Python implementor not allocated.");
94*be691f3bSpatrick 
95*be691f3bSpatrick   PythonObject pmeth(
96*be691f3bSpatrick       PyRefType::Owned,
97*be691f3bSpatrick       PyObject_GetAttrString(implementor.get(), method_name.str().c_str()));
98*be691f3bSpatrick 
99*be691f3bSpatrick   if (PyErr_Occurred())
100*be691f3bSpatrick     PyErr_Clear();
101*be691f3bSpatrick 
102*be691f3bSpatrick   if (!pmeth.IsAllocated())
103*be691f3bSpatrick     return Status("Python method not allocated.");
104*be691f3bSpatrick 
105*be691f3bSpatrick   if (PyCallable_Check(pmeth.get()) == 0) {
106*be691f3bSpatrick     if (PyErr_Occurred())
107*be691f3bSpatrick       PyErr_Clear();
108*be691f3bSpatrick     return Status("Python method not callable.");
109*be691f3bSpatrick   }
110*be691f3bSpatrick 
111*be691f3bSpatrick   if (PyErr_Occurred())
112*be691f3bSpatrick     PyErr_Clear();
113*be691f3bSpatrick 
114*be691f3bSpatrick   PythonObject py_return(PyRefType::Owned,
115*be691f3bSpatrick                          PyObject_CallMethod(implementor.get(),
116*be691f3bSpatrick                                              method_name.str().c_str(),
117*be691f3bSpatrick                                              nullptr));
118*be691f3bSpatrick 
119*be691f3bSpatrick   if (PyErr_Occurred()) {
120*be691f3bSpatrick     PyErr_Print();
121*be691f3bSpatrick     PyErr_Clear();
122*be691f3bSpatrick     return Status("Python method could not be called.");
123*be691f3bSpatrick   }
124*be691f3bSpatrick 
125*be691f3bSpatrick   if (PyObject *py_ret_ptr = py_return.get()) {
126*be691f3bSpatrick     lldb::SBError *sb_error =
127*be691f3bSpatrick         (lldb::SBError *)LLDBSWIGPython_CastPyObjectToSBError(py_ret_ptr);
128*be691f3bSpatrick 
129*be691f3bSpatrick     if (!sb_error)
130*be691f3bSpatrick       return Status("Couldn't cast lldb::SBError to lldb::Status.");
131*be691f3bSpatrick 
132*be691f3bSpatrick     Status status = m_interpreter.GetStatusFromSBError(*sb_error);
133*be691f3bSpatrick 
134*be691f3bSpatrick     if (status.Fail())
135*be691f3bSpatrick       return Status("error: %s", status.AsCString());
136*be691f3bSpatrick 
137*be691f3bSpatrick     return status;
138*be691f3bSpatrick   }
139*be691f3bSpatrick 
140*be691f3bSpatrick   return Status("Returned object is null.");
141*be691f3bSpatrick }
142*be691f3bSpatrick 
143*be691f3bSpatrick llvm::Optional<unsigned long long>
144*be691f3bSpatrick ScriptedProcessPythonInterface::GetGenericInteger(llvm::StringRef method_name) {
145*be691f3bSpatrick   Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
146*be691f3bSpatrick                  Locker::FreeLock);
147*be691f3bSpatrick 
148*be691f3bSpatrick   if (!m_object_instance_sp)
149*be691f3bSpatrick     return llvm::None;
150*be691f3bSpatrick 
151*be691f3bSpatrick   if (!m_object_instance_sp)
152*be691f3bSpatrick     return llvm::None;
153*be691f3bSpatrick   PythonObject implementor(PyRefType::Borrowed,
154*be691f3bSpatrick                            (PyObject *)m_object_instance_sp->GetValue());
155*be691f3bSpatrick 
156*be691f3bSpatrick   if (!implementor.IsAllocated())
157*be691f3bSpatrick     return llvm::None;
158*be691f3bSpatrick 
159*be691f3bSpatrick   PythonObject pmeth(
160*be691f3bSpatrick       PyRefType::Owned,
161*be691f3bSpatrick       PyObject_GetAttrString(implementor.get(), method_name.str().c_str()));
162*be691f3bSpatrick 
163*be691f3bSpatrick   if (PyErr_Occurred())
164*be691f3bSpatrick     PyErr_Clear();
165*be691f3bSpatrick 
166*be691f3bSpatrick   if (!pmeth.IsAllocated())
167*be691f3bSpatrick     return llvm::None;
168*be691f3bSpatrick 
169*be691f3bSpatrick   if (PyCallable_Check(pmeth.get()) == 0) {
170*be691f3bSpatrick     if (PyErr_Occurred())
171*be691f3bSpatrick       PyErr_Clear();
172*be691f3bSpatrick     return llvm::None;
173*be691f3bSpatrick   }
174*be691f3bSpatrick 
175*be691f3bSpatrick   if (PyErr_Occurred())
176*be691f3bSpatrick     PyErr_Clear();
177*be691f3bSpatrick 
178*be691f3bSpatrick   PythonObject py_return(PyRefType::Owned,
179*be691f3bSpatrick                          PyObject_CallMethod(implementor.get(),
180*be691f3bSpatrick                                              method_name.str().c_str(),
181*be691f3bSpatrick                                              nullptr));
182*be691f3bSpatrick 
183*be691f3bSpatrick   if (PyErr_Occurred()) {
184*be691f3bSpatrick     PyErr_Print();
185*be691f3bSpatrick     PyErr_Clear();
186*be691f3bSpatrick   }
187*be691f3bSpatrick 
188*be691f3bSpatrick   if (!py_return.get())
189*be691f3bSpatrick     return llvm::None;
190*be691f3bSpatrick 
191*be691f3bSpatrick   llvm::Expected<unsigned long long> size = py_return.AsUnsignedLongLong();
192*be691f3bSpatrick   // FIXME: Handle error.
193*be691f3bSpatrick   if (!size)
194*be691f3bSpatrick     return llvm::None;
195*be691f3bSpatrick 
196*be691f3bSpatrick   return *size;
197*be691f3bSpatrick }
198*be691f3bSpatrick 
199*be691f3bSpatrick lldb::MemoryRegionInfoSP
200*be691f3bSpatrick ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress(
201*be691f3bSpatrick     lldb::addr_t address) {
202*be691f3bSpatrick   // TODO: Implement
203*be691f3bSpatrick   return nullptr;
204*be691f3bSpatrick }
205*be691f3bSpatrick 
206*be691f3bSpatrick StructuredData::DictionarySP
207*be691f3bSpatrick ScriptedProcessPythonInterface::GetThreadWithID(lldb::tid_t tid) {
208*be691f3bSpatrick   // TODO: Implement
209*be691f3bSpatrick   return nullptr;
210*be691f3bSpatrick }
211*be691f3bSpatrick 
212*be691f3bSpatrick StructuredData::DictionarySP
213*be691f3bSpatrick ScriptedProcessPythonInterface::GetRegistersForThread(lldb::tid_t tid) {
214*be691f3bSpatrick   // TODO: Implement
215*be691f3bSpatrick   return nullptr;
216*be691f3bSpatrick }
217*be691f3bSpatrick 
218*be691f3bSpatrick lldb::DataExtractorSP ScriptedProcessPythonInterface::ReadMemoryAtAddress(
219*be691f3bSpatrick     lldb::addr_t address, size_t size, Status &error) {
220*be691f3bSpatrick   Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
221*be691f3bSpatrick                  Locker::FreeLock);
222*be691f3bSpatrick 
223*be691f3bSpatrick   auto error_with_message = [&error](llvm::StringRef message) {
224*be691f3bSpatrick     error.SetErrorString(message);
225*be691f3bSpatrick     return nullptr;
226*be691f3bSpatrick   };
227*be691f3bSpatrick 
228*be691f3bSpatrick   static char callee_name[] = "read_memory_at_address";
229*be691f3bSpatrick   std::string param_format = GetPythonValueFormatString(address);
230*be691f3bSpatrick   param_format += GetPythonValueFormatString(size);
231*be691f3bSpatrick 
232*be691f3bSpatrick   if (!m_object_instance_sp)
233*be691f3bSpatrick     return error_with_message("Python object ill-formed.");
234*be691f3bSpatrick 
235*be691f3bSpatrick   if (!m_object_instance_sp)
236*be691f3bSpatrick     return error_with_message("Python method not callable.");
237*be691f3bSpatrick 
238*be691f3bSpatrick   PythonObject implementor(PyRefType::Borrowed,
239*be691f3bSpatrick                            (PyObject *)m_object_instance_sp->GetValue());
240*be691f3bSpatrick 
241*be691f3bSpatrick   if (!implementor.IsAllocated())
242*be691f3bSpatrick     return error_with_message("Python implementor not allocated.");
243*be691f3bSpatrick 
244*be691f3bSpatrick   PythonObject pmeth(PyRefType::Owned,
245*be691f3bSpatrick                      PyObject_GetAttrString(implementor.get(), callee_name));
246*be691f3bSpatrick 
247*be691f3bSpatrick   if (PyErr_Occurred())
248*be691f3bSpatrick     PyErr_Clear();
249*be691f3bSpatrick 
250*be691f3bSpatrick   if (!pmeth.IsAllocated())
251*be691f3bSpatrick     return error_with_message("Python method not allocated.");
252*be691f3bSpatrick 
253*be691f3bSpatrick   if (PyCallable_Check(pmeth.get()) == 0) {
254*be691f3bSpatrick     if (PyErr_Occurred())
255*be691f3bSpatrick       PyErr_Clear();
256*be691f3bSpatrick     return error_with_message("Python method not callable.");
257*be691f3bSpatrick   }
258*be691f3bSpatrick 
259*be691f3bSpatrick   if (PyErr_Occurred())
260*be691f3bSpatrick     PyErr_Clear();
261*be691f3bSpatrick 
262*be691f3bSpatrick   PythonObject py_return(PyRefType::Owned,
263*be691f3bSpatrick                          PyObject_CallMethod(implementor.get(), callee_name,
264*be691f3bSpatrick                                              param_format.c_str(), address,
265*be691f3bSpatrick                                              size));
266*be691f3bSpatrick 
267*be691f3bSpatrick   if (PyErr_Occurred()) {
268*be691f3bSpatrick     PyErr_Print();
269*be691f3bSpatrick     PyErr_Clear();
270*be691f3bSpatrick     return error_with_message("Python method could not be called.");
271*be691f3bSpatrick   }
272*be691f3bSpatrick 
273*be691f3bSpatrick   if (PyObject *py_ret_ptr = py_return.get()) {
274*be691f3bSpatrick     lldb::SBData *sb_data =
275*be691f3bSpatrick         (lldb::SBData *)LLDBSWIGPython_CastPyObjectToSBData(py_ret_ptr);
276*be691f3bSpatrick 
277*be691f3bSpatrick     if (!sb_data)
278*be691f3bSpatrick       return error_with_message(
279*be691f3bSpatrick           "Couldn't cast lldb::SBData to lldb::DataExtractor.");
280*be691f3bSpatrick 
281*be691f3bSpatrick     return m_interpreter.GetDataExtractorFromSBData(*sb_data);
282*be691f3bSpatrick   }
283*be691f3bSpatrick 
284*be691f3bSpatrick   return error_with_message("Returned object is null.");
285*be691f3bSpatrick }
286*be691f3bSpatrick 
287*be691f3bSpatrick StructuredData::DictionarySP ScriptedProcessPythonInterface::GetLoadedImages() {
288*be691f3bSpatrick   // TODO: Implement
289*be691f3bSpatrick   return nullptr;
290*be691f3bSpatrick }
291*be691f3bSpatrick 
292*be691f3bSpatrick lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() {
293*be691f3bSpatrick   llvm::Optional<unsigned long long> pid = GetGenericInteger("get_process_id");
294*be691f3bSpatrick   return (!pid) ? LLDB_INVALID_PROCESS_ID : *pid;
295*be691f3bSpatrick }
296*be691f3bSpatrick 
297*be691f3bSpatrick bool ScriptedProcessPythonInterface::IsAlive() {
298*be691f3bSpatrick   llvm::Optional<unsigned long long> is_alive = GetGenericInteger("is_alive");
299*be691f3bSpatrick 
300*be691f3bSpatrick   if (!is_alive)
301*be691f3bSpatrick     return false;
302*be691f3bSpatrick 
303*be691f3bSpatrick   return static_cast<bool>(*is_alive);
304*be691f3bSpatrick }
305*be691f3bSpatrick 
306*be691f3bSpatrick #endif
307