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