1 //===-- ScriptedProcessPythonInterface.cpp --------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/Host/Config.h"
10 #include "lldb/Utility/Log.h"
11 #include "lldb/Utility/Logging.h"
12 #include "lldb/lldb-enumerations.h"
13 
14 #if LLDB_ENABLE_PYTHON
15 
16 // LLDB Python header must be included first
17 #include "lldb-python.h"
18 
19 #include "SWIGPythonBridge.h"
20 #include "ScriptInterpreterPythonImpl.h"
21 #include "ScriptedProcessPythonInterface.h"
22 #include "ScriptedThreadPythonInterface.h"
23 
24 using namespace lldb;
25 using namespace lldb_private;
26 using namespace lldb_private::python;
27 using Locker = ScriptInterpreterPythonImpl::Locker;
28 
29 ScriptedProcessPythonInterface::ScriptedProcessPythonInterface(
30     ScriptInterpreterPythonImpl &interpreter)
31     : ScriptedProcessInterface(), ScriptedPythonInterface(interpreter) {}
32 
33 StructuredData::GenericSP ScriptedProcessPythonInterface::CreatePluginObject(
34     llvm::StringRef class_name, ExecutionContext &exe_ctx,
35     StructuredData::DictionarySP args_sp) {
36   if (class_name.empty())
37     return {};
38 
39   TargetSP target_sp = exe_ctx.GetTargetSP();
40   StructuredDataImpl *args_impl = nullptr;
41   if (args_sp) {
42     args_impl = new StructuredDataImpl();
43     args_impl->SetObjectSP(args_sp);
44   }
45   std::string error_string;
46 
47   Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
48                  Locker::FreeLock);
49 
50   void *ret_val = LLDBSwigPythonCreateScriptedProcess(
51       class_name.str().c_str(), m_interpreter.GetDictionaryName(), target_sp,
52       args_impl, error_string);
53 
54   if (!ret_val)
55     return {};
56 
57   m_object_instance_sp =
58       StructuredData::GenericSP(new StructuredPythonObject(ret_val));
59 
60   return m_object_instance_sp;
61 }
62 
63 Status ScriptedProcessPythonInterface::Launch() {
64   return GetStatusFromMethod("launch");
65 }
66 
67 Status ScriptedProcessPythonInterface::Resume() {
68   return GetStatusFromMethod("resume");
69 }
70 
71 bool ScriptedProcessPythonInterface::ShouldStop() {
72   Status error;
73   StructuredData::ObjectSP obj = Dispatch("is_alive", error);
74 
75   if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error))
76     return {};
77 
78   return obj->GetBooleanValue();
79 }
80 
81 Status ScriptedProcessPythonInterface::Stop() {
82   return GetStatusFromMethod("stop");
83 }
84 
85 lldb::MemoryRegionInfoSP
86 ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress(
87     lldb::addr_t address) {
88   // TODO: Implement
89   return {};
90 }
91 
92 StructuredData::DictionarySP
93 ScriptedProcessPythonInterface::GetThreadWithID(lldb::tid_t tid) {
94   Status error;
95   StructuredData::ObjectSP obj = Dispatch("get_thread_with_id", error, tid);
96 
97   if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error))
98     return {};
99 
100   StructuredData::DictionarySP dict{obj->GetAsDictionary()};
101 
102   return dict;
103 }
104 
105 StructuredData::DictionarySP
106 ScriptedProcessPythonInterface::GetRegistersForThread(lldb::tid_t tid) {
107   // TODO: Implement
108   return {};
109 }
110 
111 lldb::DataExtractorSP ScriptedProcessPythonInterface::ReadMemoryAtAddress(
112     lldb::addr_t address, size_t size, Status &error) {
113   return Dispatch<lldb::DataExtractorSP>("read_memory_at_address", error,
114                                          address, size);
115 }
116 
117 StructuredData::DictionarySP ScriptedProcessPythonInterface::GetLoadedImages() {
118   // TODO: Implement
119   return {};
120 }
121 
122 lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() {
123   Status error;
124   StructuredData::ObjectSP obj = Dispatch("get_process_id", error);
125 
126   if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error))
127     return LLDB_INVALID_PROCESS_ID;
128 
129   return obj->GetIntegerValue(LLDB_INVALID_PROCESS_ID);
130 }
131 
132 bool ScriptedProcessPythonInterface::IsAlive() {
133   Status error;
134   StructuredData::ObjectSP obj = Dispatch("is_alive", error);
135 
136   if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error))
137     return {};
138 
139   return obj->GetBooleanValue();
140 }
141 
142 llvm::Optional<std::string>
143 ScriptedProcessPythonInterface::GetScriptedThreadPluginName() {
144   Status error;
145   StructuredData::ObjectSP obj = Dispatch("get_scripted_thread_plugin", error);
146 
147   if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error))
148     return {};
149 
150   return obj->GetStringValue().str();
151 }
152 
153 lldb::ScriptedThreadInterfaceSP
154 ScriptedProcessPythonInterface::GetScriptedThreadInterface() {
155   if (!m_scripted_thread_interface_sp)
156     m_scripted_thread_interface_sp =
157         std::make_shared<ScriptedThreadPythonInterface>(m_interpreter);
158 
159   return m_scripted_thread_interface_sp;
160 }
161 
162 #endif
163