xref: /llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp (revision 4300fab2d4ac7d04035779b509b8e38219386096)
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 "llvm/ADT/Triple.h"
16 
17 #include "lldb/Core/ArchSpec.h"
18 #include "lldb/Core/DataBufferHeap.h"
19 #include "lldb/Core/Debugger.h"
20 #include "lldb/Core/Module.h"
21 #include "lldb/Core/PluginManager.h"
22 #include "lldb/Core/RegisterValue.h"
23 #include "lldb/Core/ValueObjectVariable.h"
24 #include "lldb/Interpreter/CommandInterpreter.h"
25 #include "lldb/Interpreter/PythonDataObjects.h"
26 #include "lldb/Symbol/ClangNamespaceDecl.h"
27 #include "lldb/Symbol/ObjectFile.h"
28 #include "lldb/Symbol/VariableList.h"
29 #include "lldb/Target/Process.h"
30 #include "lldb/Target/StopInfo.h"
31 #include "lldb/Target/Target.h"
32 #include "lldb/Target/ThreadList.h"
33 #include "lldb/Target/Thread.h"
34 #include "Plugins/Process/Utility/DynamicRegisterInfo.h"
35 #include "Plugins/Process/Utility/RegisterContextMemory.h"
36 #include "Plugins/Process/Utility/ThreadMemory.h"
37 
38 using namespace lldb;
39 using namespace lldb_private;
40 
41 void
42 OperatingSystemPython::Initialize()
43 {
44     PluginManager::RegisterPlugin (GetPluginNameStatic(),
45                                    GetPluginDescriptionStatic(),
46                                    CreateInstance);
47 }
48 
49 void
50 OperatingSystemPython::Terminate()
51 {
52     PluginManager::UnregisterPlugin (CreateInstance);
53 }
54 
55 OperatingSystem *
56 OperatingSystemPython::CreateInstance (Process *process, bool force)
57 {
58     // Python OperatingSystem plug-ins must be requested by name, so force must be true
59     //if (force)
60         return new OperatingSystemPython (process);
61     return NULL;
62 }
63 
64 
65 const char *
66 OperatingSystemPython::GetPluginNameStatic()
67 {
68     return "python";
69 }
70 
71 const char *
72 OperatingSystemPython::GetPluginDescriptionStatic()
73 {
74     return "Operating system plug-in that gathers OS information from a python class that implements the necessary OperatingSystem functionality.";
75 }
76 
77 
78 OperatingSystemPython::OperatingSystemPython (lldb_private::Process *process) :
79     OperatingSystem (process),
80     m_thread_list_valobj_sp (),
81     m_register_info_ap (),
82     m_interpreter(NULL),
83     m_python_object(NULL)
84 {
85     if (!process)
86         return;
87     lldb::TargetSP target_sp = process->CalculateTarget();
88     if (!target_sp)
89         return;
90     m_interpreter = target_sp->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
91     if (m_interpreter)
92     {
93         // TODO: hardcoded is not good
94         auto object_sp = m_interpreter->CreateOSPlugin("operating_system.PlugIn",process->CalculateProcess());
95         if (object_sp)
96             m_python_object = object_sp->GetObject();
97     }
98 }
99 
100 OperatingSystemPython::~OperatingSystemPython ()
101 {
102 }
103 
104 DynamicRegisterInfo *
105 OperatingSystemPython::GetDynamicRegisterInfo ()
106 {
107     if (!m_interpreter || !m_python_object)
108         return NULL;
109     auto object_sp = m_interpreter->OSPlugin_QueryForRegisterInfo(m_interpreter->MakeScriptObject(m_python_object));
110     if (!object_sp)
111         return NULL;
112     PythonDataObject dictionary_data_obj((PyObject*)object_sp->GetObject());
113     PythonDataDictionary dictionary = dictionary_data_obj.GetDictionaryObject();
114     if(!dictionary)
115         return NULL;
116 
117     // TODO: iterate over the dictionary
118     if (m_register_info_ap.get() == NULL && m_thread_list_valobj_sp)
119     {
120 //        static ConstString g_gpr_member_name("gpr");
121 //        m_register_info_ap.reset (new DynamicRegisterInfo());
122 //        ConstString empty_name;
123 //        const bool can_create = true;
124 //        AddressType addr_type;
125 //        addr_t base_addr = LLDB_INVALID_ADDRESS;
126 //        ValueObjectSP gpr_valobj_sp (m_thread_list_valobj_sp->GetChildMemberWithName(GetThreadGPRMemberName (), can_create));
127 //
128 //        if (gpr_valobj_sp->IsPointerType ())
129 //            base_addr = gpr_valobj_sp->GetPointerValue (&addr_type);
130 //        else
131 //            base_addr = gpr_valobj_sp->GetAddressOf (true, &addr_type);
132 //
133 //        ValueObjectSP child_valobj_sp;
134 //        if (gpr_valobj_sp)
135 //        {
136 //            ABI *abi = m_process->GetABI().get();
137 //            assert (abi);
138 //            uint32_t num_children = gpr_valobj_sp->GetNumChildren();
139 //
140 //            ConstString gpr_name (gpr_valobj_sp->GetName());
141 //            uint32_t reg_num = 0;
142 //            for (uint32_t i=0; i<num_children; ++i)
143 //            {
144 //                child_valobj_sp = gpr_valobj_sp->GetChildAtIndex(i, can_create);
145 //
146 //                ConstString reg_name(child_valobj_sp->GetName());
147 //                if (reg_name)
148 //                {
149 //                    const char *reg_name_cstr = reg_name.GetCString();
150 //                    while (reg_name_cstr[0] == '_')
151 //                        ++reg_name_cstr;
152 //                    if (reg_name_cstr != reg_name.GetCString())
153 //                        reg_name.SetCString (reg_name_cstr);
154 //                }
155 //
156 //                RegisterInfo reg_info;
157 //                if (abi->GetRegisterInfoByName(reg_name, reg_info))
158 //                {
159 //                    // Adjust the byte size and the offset to match the layout of registers in our struct
160 //                    reg_info.byte_size = child_valobj_sp->GetByteSize();
161 //                    reg_info.byte_offset = child_valobj_sp->GetAddressOf(true, &addr_type) - base_addr;
162 //                    reg_info.kinds[eRegisterKindLLDB] = reg_num++;
163 //                    m_register_info_ap->AddRegister (reg_info, reg_name, empty_name, gpr_name);
164 //                }
165 //                else
166 //                {
167 //                    printf ("not able to find register info for %s\n", reg_name.GetCString()); // REMOVE THIS printf before checkin!!!
168 //                }
169 //            }
170 //
171 //            m_register_info_ap->Finalize();
172 //        }
173     }
174     assert (m_register_info_ap.get());
175     return m_register_info_ap.get();
176 }
177 
178 //------------------------------------------------------------------
179 // PluginInterface protocol
180 //------------------------------------------------------------------
181 const char *
182 OperatingSystemPython::GetPluginName()
183 {
184     return "OperatingSystemPython";
185 }
186 
187 const char *
188 OperatingSystemPython::GetShortPluginName()
189 {
190     return GetPluginNameStatic();
191 }
192 
193 uint32_t
194 OperatingSystemPython::GetPluginVersion()
195 {
196     return 1;
197 }
198 
199 bool
200 OperatingSystemPython::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
201 {
202 
203     if (!m_interpreter || !m_python_object)
204         return NULL;
205     auto object_sp = m_interpreter->OSPlugin_QueryForThreadsInfo(m_interpreter->MakeScriptObject(m_python_object));
206     if (!object_sp)
207         return NULL;
208     PythonDataObject dictionary_data_obj((PyObject*)object_sp->GetObject());
209     PythonDataDictionary dictionary = dictionary_data_obj.GetDictionaryObject();
210     if(!dictionary)
211         return NULL;
212 
213     // TODO: read from the dict
214 
215     // and parse the returned dictionary. We need to pass in the a Dictionary
216     // with the same kind of info we want back so we can reuse old threads, but
217     // only create new ones.
218 
219     // Make any constant strings once and cache the uniqued C string values
220     // so we don't have to rehash them each time through this function call
221 //    dict thread_info_dict = python.get_thread_info()
222 //    for thread_info in thread_info_dict:
223 //    {
224 //        ThreadSP thread_sp (old_thread_list.FindThreadByID (tid, false));
225 //        if (!thread_sp)
226 //            thread_sp.reset (new ThreadMemory (m_process->shared_from_this(), tid, valobj_sp));
227 //        new_thread_list.AddThread(thread_sp);
228 //    }
229     new_thread_list = old_thread_list;
230     return new_thread_list.GetSize(false) > 0;
231 }
232 
233 void
234 OperatingSystemPython::ThreadWasSelected (Thread *thread)
235 {
236 }
237 
238 RegisterContextSP
239 OperatingSystemPython::CreateRegisterContextForThread (Thread *thread)
240 {
241 
242     if (!m_interpreter || !m_python_object || !thread)
243         return NULL;
244     auto object_sp = m_interpreter->OSPlugin_QueryForThreadInfo(m_interpreter->MakeScriptObject(m_python_object),
245                                                                 thread->GetID());
246     if (!object_sp)
247         return NULL;
248     PythonDataObject pack_info_data_obj((PyObject*)object_sp->GetObject());
249     if(!pack_info_data_obj)
250         return NULL;
251 
252     RegisterContextSP reg_ctx_sp;
253 //    bytes b = get_register_context_data(thread)
254 //    if (b)
255 //    {
256 //        reg_ctx_sp.reset (new RegisterContextMemory (*thread, 0, *GetDynamicRegisterInfo (), base_addr));
257 //        // set bytes
258 //    }
259     return reg_ctx_sp;
260 }
261 
262 StopInfoSP
263 OperatingSystemPython::CreateThreadStopReason (lldb_private::Thread *thread)
264 {
265     // We should have gotten the thread stop info from the dictionary of data for
266     // the thread in the initial call to get_thread_info(), this should have been
267     // cached so we can return it here
268     StopInfoSP stop_info_sp; //(StopInfo::CreateStopReasonWithSignal (*thread, SIGSTOP));
269     return stop_info_sp;
270 }
271 
272 
273 #endif // #ifndef LLDB_DISABLE_PYTHON
274