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
ScriptedProcessPythonInterface(ScriptInterpreterPythonImpl & interpreter)28 ScriptedProcessPythonInterface::ScriptedProcessPythonInterface(
29 ScriptInterpreterPythonImpl &interpreter)
30 : ScriptedProcessInterface(), ScriptedPythonInterface(interpreter) {}
31
CreatePluginObject(llvm::StringRef class_name,ExecutionContext & exe_ctx,StructuredData::DictionarySP args_sp,StructuredData::Generic * script_obj)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
Launch()55 Status ScriptedProcessPythonInterface::Launch() {
56 return GetStatusFromMethod("launch");
57 }
58
Resume()59 Status ScriptedProcessPythonInterface::Resume() {
60 return GetStatusFromMethod("resume");
61 }
62
ShouldStop()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
Stop()73 Status ScriptedProcessPythonInterface::Stop() {
74 return GetStatusFromMethod("stop");
75 }
76
77 llvm::Optional<MemoryRegionInfo>
GetMemoryRegionContainingAddress(lldb::addr_t address,Status & error)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
GetThreadsInfo()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
GetThreadWithID(lldb::tid_t tid)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
GetRegistersForThread(lldb::tid_t tid)116 ScriptedProcessPythonInterface::GetRegistersForThread(lldb::tid_t tid) {
117 // TODO: Implement
118 return {};
119 }
120
ReadMemoryAtAddress(lldb::addr_t address,size_t size,Status & error)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
GetLoadedImages()127 StructuredData::ArraySP ScriptedProcessPythonInterface::GetLoadedImages() {
128 Status error;
129 StructuredData::ArraySP array =
130 Dispatch<StructuredData::ArraySP>("get_loaded_images", error);
131
132 if (!array || !array->IsValid() || error.Fail()) {
133 return ScriptedInterface::ErrorWithMessage<StructuredData::ArraySP>(
134 LLVM_PRETTY_FUNCTION,
135 llvm::Twine("Null or invalid object (" +
136 llvm::Twine(error.AsCString()) + llvm::Twine(")."))
137 .str(),
138 error);
139 }
140
141 return array;
142 }
143
GetProcessID()144 lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() {
145 Status error;
146 StructuredData::ObjectSP obj = Dispatch("get_process_id", error);
147
148 if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
149 return LLDB_INVALID_PROCESS_ID;
150
151 return obj->GetIntegerValue(LLDB_INVALID_PROCESS_ID);
152 }
153
IsAlive()154 bool ScriptedProcessPythonInterface::IsAlive() {
155 Status error;
156 StructuredData::ObjectSP obj = Dispatch("is_alive", error);
157
158 if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
159 return {};
160
161 return obj->GetBooleanValue();
162 }
163
164 llvm::Optional<std::string>
GetScriptedThreadPluginName()165 ScriptedProcessPythonInterface::GetScriptedThreadPluginName() {
166 Status error;
167 StructuredData::ObjectSP obj = Dispatch("get_scripted_thread_plugin", error);
168
169 if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
170 return {};
171
172 return obj->GetStringValue().str();
173 }
174
175 lldb::ScriptedThreadInterfaceSP
CreateScriptedThreadInterface()176 ScriptedProcessPythonInterface::CreateScriptedThreadInterface() {
177 return std::make_shared<ScriptedThreadPythonInterface>(m_interpreter);
178 }
179
180 #endif
181