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