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 threads_array (pyobj.GetArrayObject()); 161 if (threads_array) 162 { 163 // const uint32_t num_old_threads = old_thread_list.GetSize(false); 164 // for (uint32_t i=0; i<num_old_threads; ++i) 165 // { 166 // ThreadSP old_thread_sp(old_thread_list.GetThreadAtIndex(i, false)); 167 // if (old_thread_sp->GetID() < 0x10000) 168 // new_thread_list.AddThread (old_thread_sp); 169 // } 170 171 PythonDataString tid_pystr("tid"); 172 PythonDataString name_pystr("name"); 173 PythonDataString queue_pystr("queue"); 174 PythonDataString state_pystr("state"); 175 PythonDataString stop_reason_pystr("stop_reason"); 176 177 const uint32_t num_threads = threads_array.GetSize(); 178 for (uint32_t i=0; i<num_threads; ++i) 179 { 180 PythonDataDictionary thread_dict(threads_array.GetItemAtIndex(i).GetDictionaryObject()); 181 if (thread_dict) 182 { 183 const tid_t tid = thread_dict.GetItemForKeyAsInteger(tid_pystr, LLDB_INVALID_THREAD_ID); 184 const char *name = thread_dict.GetItemForKeyAsString (name_pystr); 185 const char *queue = thread_dict.GetItemForKeyAsString (queue_pystr); 186 //const char *state = thread_dict.GetItemForKeyAsString (state_pystr); 187 //const char *stop_reason = thread_dict.GetItemForKeyAsString (stop_reason_pystr); 188 189 ThreadSP thread_sp (old_thread_list.FindThreadByID (tid, false)); 190 if (!thread_sp) 191 thread_sp.reset (new ThreadMemory (m_process->shared_from_this(), 192 tid, 193 name, 194 queue)); 195 new_thread_list.AddThread(thread_sp); 196 197 } 198 } 199 } 200 else 201 { 202 new_thread_list = old_thread_list; 203 } 204 return new_thread_list.GetSize(false) > 0; 205 } 206 207 void 208 OperatingSystemPython::ThreadWasSelected (Thread *thread) 209 { 210 } 211 212 RegisterContextSP 213 OperatingSystemPython::CreateRegisterContextForThread (Thread *thread) 214 { 215 RegisterContextSP reg_ctx_sp; 216 if (!m_interpreter || !m_python_object || !thread) 217 return NULL; 218 auto object_sp = m_interpreter->OSPlugin_QueryForRegisterContextData (m_interpreter->MakeScriptObject(m_python_object), 219 thread->GetID()); 220 221 if (!object_sp) 222 return NULL; 223 224 PythonDataString reg_context_data((PyObject*)object_sp->GetObject()); 225 if (reg_context_data) 226 { 227 DataBufferSP data_sp (new DataBufferHeap (reg_context_data.GetString(), 228 reg_context_data.GetSize())); 229 if (data_sp->GetByteSize()) 230 { 231 RegisterContextMemory *reg_ctx_memory = new RegisterContextMemory (*thread, 0, *GetDynamicRegisterInfo (), LLDB_INVALID_ADDRESS); 232 if (reg_ctx_memory) 233 { 234 reg_ctx_sp.reset(reg_ctx_memory); 235 reg_ctx_memory->SetAllRegisterData (data_sp); 236 } 237 } 238 } 239 return reg_ctx_sp; 240 } 241 242 StopInfoSP 243 OperatingSystemPython::CreateThreadStopReason (lldb_private::Thread *thread) 244 { 245 // We should have gotten the thread stop info from the dictionary of data for 246 // the thread in the initial call to get_thread_info(), this should have been 247 // cached so we can return it here 248 StopInfoSP stop_info_sp; //(StopInfo::CreateStopReasonWithSignal (*thread, SIGSTOP)); 249 return stop_info_sp; 250 } 251 252 253 #endif // #ifndef LLDB_DISABLE_PYTHON 254