1 //===-- ScriptedThreadPythonInterface.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/Core/PluginManager.h"
10 #include "lldb/Host/Config.h"
11 #include "lldb/Target/ExecutionContext.h"
12 #include "lldb/Utility/Log.h"
13 #include "lldb/lldb-enumerations.h"
14 
15 #if LLDB_ENABLE_PYTHON
16 
17 // clang-format off
18 // LLDB Python header must be included first
19 #include "../lldb-python.h"
20 //clang-format on
21 
22 #include "../SWIGPythonBridge.h"
23 #include "../ScriptInterpreterPythonImpl.h"
24 #include "OperatingSystemPythonInterface.h"
25 
26 using namespace lldb;
27 using namespace lldb_private;
28 using namespace lldb_private::python;
29 using Locker = ScriptInterpreterPythonImpl::Locker;
30 
31 OperatingSystemPythonInterface::OperatingSystemPythonInterface(
32     ScriptInterpreterPythonImpl &interpreter)
33     : OperatingSystemInterface(), ScriptedThreadPythonInterface(interpreter) {}
34 
35 llvm::Expected<StructuredData::GenericSP>
36 OperatingSystemPythonInterface::CreatePluginObject(
37     llvm::StringRef class_name, ExecutionContext &exe_ctx,
38     StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) {
39   return ScriptedPythonInterface::CreatePluginObject(class_name, nullptr,
40                                                      exe_ctx.GetProcessSP());
41 }
42 
43 StructuredData::DictionarySP
44 OperatingSystemPythonInterface::CreateThread(lldb::tid_t tid,
45                                              lldb::addr_t context) {
46   Status error;
47   StructuredData::DictionarySP dict = Dispatch<StructuredData::DictionarySP>(
48       "create_thread", error, tid, context);
49 
50   if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict,
51                                                     error))
52     return {};
53 
54   return dict;
55 }
56 
57 StructuredData::ArraySP OperatingSystemPythonInterface::GetThreadInfo() {
58   Status error;
59   StructuredData::ArraySP arr =
60       Dispatch<StructuredData::ArraySP>("get_thread_info", error);
61 
62   if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, arr,
63                                                     error))
64     return {};
65 
66   return arr;
67 }
68 
69 StructuredData::DictionarySP OperatingSystemPythonInterface::GetRegisterInfo() {
70   return ScriptedThreadPythonInterface::GetRegisterInfo();
71 }
72 
73 std::optional<std::string>
74 OperatingSystemPythonInterface::GetRegisterContextForTID(lldb::tid_t tid) {
75   Status error;
76   StructuredData::ObjectSP obj = Dispatch("get_register_data", error, tid);
77 
78   if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
79                                                     error))
80     return {};
81 
82   return obj->GetAsString()->GetValue().str();
83 }
84 
85 std::optional<bool> OperatingSystemPythonInterface::DoesPluginReportAllThreads() {
86   Status error;
87   StructuredData::ObjectSP obj = Dispatch("does_plugin_report_all_threads", error);
88   if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
89                                                     error))
90     return {};
91 
92   return obj->GetAsBoolean()->GetValue();
93 }
94 
95 void OperatingSystemPythonInterface::Initialize() {
96   const std::vector<llvm::StringRef> ci_usages = {
97       "settings set target.process.python-os-plugin-path <script-path>",
98       "settings set process.experimental.os-plugin-reports-all-threads [0/1]"};
99   const std::vector<llvm::StringRef> api_usages = {};
100   PluginManager::RegisterPlugin(
101       GetPluginNameStatic(), llvm::StringRef("Mock thread state"),
102       CreateInstance, eScriptLanguagePython, {ci_usages, api_usages});
103 }
104 
105 void OperatingSystemPythonInterface::Terminate() {
106   PluginManager::UnregisterPlugin(CreateInstance);
107 }
108 
109 #endif
110