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/lldb-enumerations.h"
12 
13 #if LLDB_ENABLE_PYTHON
14 
15 // LLDB Python header must be included first
16 #include "lldb-python.h"
17 
18 #include "SWIGPythonBridge.h"
19 #include "ScriptInterpreterPythonImpl.h"
20 #include "ScriptedProcessPythonInterface.h"
21 #include "ScriptedThreadPythonInterface.h"
22 
23 using namespace lldb;
24 using namespace lldb_private;
25 using namespace lldb_private::python;
26 using Locker = ScriptInterpreterPythonImpl::Locker;
27 
28 ScriptedProcessPythonInterface::ScriptedProcessPythonInterface(
29     ScriptInterpreterPythonImpl &interpreter)
30     : ScriptedProcessInterface(), ScriptedPythonInterface(interpreter) {}
31 
32 StructuredData::GenericSP ScriptedProcessPythonInterface::CreatePluginObject(
33     llvm::StringRef class_name, ExecutionContext &exe_ctx,
34     StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) {
35   if (class_name.empty())
36     return {};
37 
38   TargetSP target_sp = exe_ctx.GetTargetSP();
39   StructuredDataImpl args_impl(args_sp);
40   std::string error_string;
41 
42   Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
43                  Locker::FreeLock);
44 
45   PythonObject ret_val = LLDBSwigPythonCreateScriptedProcess(
46       class_name.str().c_str(), m_interpreter.GetDictionaryName(), target_sp,
47       args_impl, error_string);
48 
49   m_object_instance_sp =
50       StructuredData::GenericSP(new StructuredPythonObject(std::move(ret_val)));
51 
52   return m_object_instance_sp;
53 }
54 
55 Status ScriptedProcessPythonInterface::Launch() {
56   return GetStatusFromMethod("launch");
57 }
58 
59 Status ScriptedProcessPythonInterface::Resume() {
60   return GetStatusFromMethod("resume");
61 }
62 
63 bool ScriptedProcessPythonInterface::ShouldStop() {
64   Status error;
65   StructuredData::ObjectSP obj = Dispatch("is_alive", error);
66 
67   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
68     return {};
69 
70   return obj->GetBooleanValue();
71 }
72 
73 Status ScriptedProcessPythonInterface::Stop() {
74   return GetStatusFromMethod("stop");
75 }
76 
77 llvm::Optional<MemoryRegionInfo>
78 ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress(
79     lldb::addr_t address, Status &error) {
80   auto mem_region = Dispatch<llvm::Optional<MemoryRegionInfo>>(
81       "get_memory_region_containing_address", error, address);
82 
83   if (error.Fail()) {
84     return ErrorWithMessage<MemoryRegionInfo>(LLVM_PRETTY_FUNCTION,
85                                               error.AsCString(), error);
86   }
87 
88   return mem_region;
89 }
90 
91 StructuredData::DictionarySP ScriptedProcessPythonInterface::GetThreadsInfo() {
92   Status error;
93   StructuredData::DictionarySP dict =
94       Dispatch<StructuredData::DictionarySP>("get_threads_info", error);
95 
96   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error))
97     return {};
98 
99   return dict;
100 }
101 
102 StructuredData::DictionarySP
103 ScriptedProcessPythonInterface::GetThreadWithID(lldb::tid_t tid) {
104   Status error;
105   StructuredData::ObjectSP obj = Dispatch("get_thread_with_id", error, tid);
106 
107   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
108     return {};
109 
110   StructuredData::DictionarySP dict{obj->GetAsDictionary()};
111 
112   return dict;
113 }
114 
115 StructuredData::DictionarySP
116 ScriptedProcessPythonInterface::GetRegistersForThread(lldb::tid_t tid) {
117   // TODO: Implement
118   return {};
119 }
120 
121 lldb::DataExtractorSP ScriptedProcessPythonInterface::ReadMemoryAtAddress(
122     lldb::addr_t address, size_t size, Status &error) {
123   return Dispatch<lldb::DataExtractorSP>("read_memory_at_address", error,
124                                          address, size);
125 }
126 
127 StructuredData::DictionarySP ScriptedProcessPythonInterface::GetLoadedImages() {
128   // TODO: Implement
129   return {};
130 }
131 
132 lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() {
133   Status error;
134   StructuredData::ObjectSP obj = Dispatch("get_process_id", error);
135 
136   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
137     return LLDB_INVALID_PROCESS_ID;
138 
139   return obj->GetIntegerValue(LLDB_INVALID_PROCESS_ID);
140 }
141 
142 bool ScriptedProcessPythonInterface::IsAlive() {
143   Status error;
144   StructuredData::ObjectSP obj = Dispatch("is_alive", error);
145 
146   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
147     return {};
148 
149   return obj->GetBooleanValue();
150 }
151 
152 llvm::Optional<std::string>
153 ScriptedProcessPythonInterface::GetScriptedThreadPluginName() {
154   Status error;
155   StructuredData::ObjectSP obj = Dispatch("get_scripted_thread_plugin", error);
156 
157   if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
158     return {};
159 
160   return obj->GetStringValue().str();
161 }
162 
163 lldb::ScriptedThreadInterfaceSP
164 ScriptedProcessPythonInterface::CreateScriptedThreadInterface() {
165   return std::make_shared<ScriptedThreadPythonInterface>(m_interpreter);
166 }
167 
168 #endif
169