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 // TODO: python: call "dict get_thread_info()" on the 203 // python object that represents our instance of the OperatingSystem plug-in 204 // and parse the returned dictionary. We need to pass in the a Dictionary 205 // with the same kind of info we want back so we can reuse old threads, but 206 // only create new ones. 207 208 // Make any constant strings once and cache the uniqued C string values 209 // so we don't have to rehash them each time through this function call 210 // dict thread_info_dict = python.get_thread_info() 211 // for thread_info in thread_info_dict: 212 // { 213 // ThreadSP thread_sp (old_thread_list.FindThreadByID (tid, false)); 214 // if (!thread_sp) 215 // thread_sp.reset (new ThreadMemory (m_process->shared_from_this(), tid, valobj_sp)); 216 // new_thread_list.AddThread(thread_sp); 217 // } 218 new_thread_list = old_thread_list; 219 return new_thread_list.GetSize(false) > 0; 220 } 221 222 void 223 OperatingSystemPython::ThreadWasSelected (Thread *thread) 224 { 225 } 226 227 RegisterContextSP 228 OperatingSystemPython::CreateRegisterContextForThread (Thread *thread) 229 { 230 // TODO: python: call "bytes get_register_context_data(SBThread thread)" 231 // and populate resulting data into thread 232 RegisterContextSP reg_ctx_sp; 233 // bytes b = get_register_context_data(thread) 234 // if (b) 235 // { 236 // reg_ctx_sp.reset (new RegisterContextMemory (*thread, 0, *GetDynamicRegisterInfo (), base_addr)); 237 // // set bytes 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