xref: /llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp (revision a83b6cf2446ebba78ec38564b7021da08187ed4b)
1 //===-- OperatingSystemPython.cpp --------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 #ifndef LLDB_DISABLE_PYTHON
10 
11 #include "OperatingSystemPython.h"
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 #include "lldb/Core/ArchSpec.h"
16 #include "lldb/Core/DataBufferHeap.h"
17 #include "lldb/Core/Debugger.h"
18 #include "lldb/Core/Module.h"
19 #include "lldb/Core/PluginManager.h"
20 #include "lldb/Interpreter/PythonDataObjects.h"
21 #include "lldb/Core/RegisterValue.h"
22 #include "lldb/Core/ValueObjectVariable.h"
23 #include "lldb/Interpreter/CommandInterpreter.h"
24 #include "lldb/Interpreter/PythonDataObjects.h"
25 #include "lldb/Symbol/ClangNamespaceDecl.h"
26 #include "lldb/Symbol/ObjectFile.h"
27 #include "lldb/Symbol/VariableList.h"
28 #include "lldb/Target/Process.h"
29 #include "lldb/Target/StopInfo.h"
30 #include "lldb/Target/Target.h"
31 #include "lldb/Target/ThreadList.h"
32 #include "lldb/Target/Thread.h"
33 #include "Plugins/Process/Utility/DynamicRegisterInfo.h"
34 #include "Plugins/Process/Utility/RegisterContextMemory.h"
35 #include "Plugins/Process/Utility/ThreadMemory.h"
36 
37 using namespace lldb;
38 using namespace lldb_private;
39 
40 void
41 OperatingSystemPython::Initialize()
42 {
43     PluginManager::RegisterPlugin (GetPluginNameStatic(),
44                                    GetPluginDescriptionStatic(),
45                                    CreateInstance);
46 }
47 
48 void
49 OperatingSystemPython::Terminate()
50 {
51     PluginManager::UnregisterPlugin (CreateInstance);
52 }
53 
54 OperatingSystem *
55 OperatingSystemPython::CreateInstance (Process *process, bool force)
56 {
57     // Python OperatingSystem plug-ins must be requested by name, so force must be true
58     if (force)
59         return new OperatingSystemPython (process);
60     return NULL;
61 }
62 
63 
64 const char *
65 OperatingSystemPython::GetPluginNameStatic()
66 {
67     return "python";
68 }
69 
70 const char *
71 OperatingSystemPython::GetPluginDescriptionStatic()
72 {
73     return "Operating system plug-in that gathers OS information from a python class that implements the necessary OperatingSystem functionality.";
74 }
75 
76 
77 OperatingSystemPython::OperatingSystemPython (lldb_private::Process *process) :
78     OperatingSystem (process),
79     m_thread_list_valobj_sp (),
80     m_register_info_ap (),
81     m_interpreter(NULL),
82     m_python_object(NULL)
83 {
84     if (!process)
85         return;
86     lldb::TargetSP target_sp = process->CalculateTarget();
87     if (!target_sp)
88         return;
89     m_interpreter = target_sp->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
90     if (m_interpreter)
91     {
92         // TODO: hardcoded is not good
93         auto object_sp = m_interpreter->CreateOSPlugin("operating_system.PlugIn",process->CalculateProcess());
94         if (object_sp)
95         {
96             m_python_object = object_sp->GetObject();
97 
98             //GetDynamicRegisterInfo (); // COMMENT THIS LINE OUT PRIOR TO CHECKIN!!!
99         }
100     }
101 }
102 
103 OperatingSystemPython::~OperatingSystemPython ()
104 {
105 }
106 
107 DynamicRegisterInfo *
108 OperatingSystemPython::GetDynamicRegisterInfo ()
109 {
110     if (m_register_info_ap.get() == NULL)
111     {
112         if (!m_interpreter || !m_python_object)
113             return NULL;
114         auto object_sp = m_interpreter->OSPlugin_QueryForRegisterInfo(m_interpreter->MakeScriptObject(m_python_object));
115         if (!object_sp)
116             return NULL;
117         PythonDataObject dictionary_data_obj((PyObject*)object_sp->GetObject());
118         PythonDataDictionary dictionary = dictionary_data_obj.GetDictionaryObject();
119         if (!dictionary)
120             return NULL;
121 
122         m_register_info_ap.reset (new DynamicRegisterInfo (dictionary));
123         assert (m_register_info_ap->GetNumRegisters() > 0);
124         assert (m_register_info_ap->GetNumRegisterSets() > 0);
125     }
126     return m_register_info_ap.get();
127 }
128 
129 //------------------------------------------------------------------
130 // PluginInterface protocol
131 //------------------------------------------------------------------
132 const char *
133 OperatingSystemPython::GetPluginName()
134 {
135     return "OperatingSystemPython";
136 }
137 
138 const char *
139 OperatingSystemPython::GetShortPluginName()
140 {
141     return GetPluginNameStatic();
142 }
143 
144 uint32_t
145 OperatingSystemPython::GetPluginVersion()
146 {
147     return 1;
148 }
149 
150 bool
151 OperatingSystemPython::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
152 {
153 
154     if (!m_interpreter || !m_python_object)
155         return NULL;
156     auto object_sp = m_interpreter->OSPlugin_QueryForThreadsInfo(m_interpreter->MakeScriptObject(m_python_object));
157     if (!object_sp)
158         return NULL;
159     PythonDataObject pyobj((PyObject*)object_sp->GetObject());
160     PythonDataArray array = pyobj.GetArrayObject();
161     if(!array)
162         return NULL;
163 
164     // TODO: read from the dict
165 
166     // and parse the returned dictionary. We need to pass in the a Dictionary
167     // with the same kind of info we want back so we can reuse old threads, but
168     // only create new ones.
169 
170     // Make any constant strings once and cache the uniqued C string values
171     // so we don't have to rehash them each time through this function call
172 //    dict thread_info_dict = python.get_thread_info()
173 //    for thread_info in thread_info_dict:
174 //    {
175 //        ThreadSP thread_sp (old_thread_list.FindThreadByID (tid, false));
176 //        if (!thread_sp)
177 //            thread_sp.reset (new ThreadMemory (m_process->shared_from_this(), tid, valobj_sp));
178 //        new_thread_list.AddThread(thread_sp);
179 //    }
180     new_thread_list = old_thread_list;
181     return new_thread_list.GetSize(false) > 0;
182 }
183 
184 void
185 OperatingSystemPython::ThreadWasSelected (Thread *thread)
186 {
187 }
188 
189 RegisterContextSP
190 OperatingSystemPython::CreateRegisterContextForThread (Thread *thread)
191 {
192 
193     if (!m_interpreter || !m_python_object || !thread)
194         return NULL;
195     auto object_sp = m_interpreter->OSPlugin_QueryForThreadInfo(m_interpreter->MakeScriptObject(m_python_object),
196                                                                 thread->GetID());
197     if (!object_sp)
198         return NULL;
199     PythonDataObject pack_info_data_obj((PyObject*)object_sp->GetObject());
200     if(!pack_info_data_obj)
201         return NULL;
202 
203     RegisterContextSP reg_ctx_sp;
204 //    bytes b = get_register_context_data(thread)
205 //    if (b)
206 //    {
207 //        reg_ctx_sp.reset (new RegisterContextMemory (*thread, 0, *GetDynamicRegisterInfo (), base_addr));
208 //        // set bytes
209 //    }
210     return reg_ctx_sp;
211 }
212 
213 StopInfoSP
214 OperatingSystemPython::CreateThreadStopReason (lldb_private::Thread *thread)
215 {
216     // We should have gotten the thread stop info from the dictionary of data for
217     // the thread in the initial call to get_thread_info(), this should have been
218     // cached so we can return it here
219     StopInfoSP stop_info_sp; //(StopInfo::CreateStopReasonWithSignal (*thread, SIGSTOP));
220     return stop_info_sp;
221 }
222 
223 
224 #endif // #ifndef LLDB_DISABLE_PYTHON
225