1//===-- DynamicRegisterInfo.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 10#include "lldb/lldb-python.h" 11 12#include "DynamicRegisterInfo.h" 13 14// C Includes 15// C++ Includes 16// Other libraries and framework includes 17// Project includes 18#include "lldb/Interpreter/Args.h" 19 20#ifndef LLDB_DISABLE_PYTHON 21#include "lldb/Interpreter/PythonDataObjects.h" 22#endif 23 24using namespace lldb; 25using namespace lldb_private; 26 27DynamicRegisterInfo::DynamicRegisterInfo () : 28 m_regs (), 29 m_sets (), 30 m_set_reg_nums (), 31 m_set_names (), 32 m_reg_data_byte_size (0) 33{ 34} 35 36DynamicRegisterInfo::DynamicRegisterInfo (const lldb_private::PythonDictionary &dict) : 37 m_regs (), 38 m_sets (), 39 m_set_reg_nums (), 40 m_set_names (), 41 m_reg_data_byte_size (0) 42{ 43 SetRegisterInfo (dict); 44} 45 46DynamicRegisterInfo::~DynamicRegisterInfo () 47{ 48} 49 50 51size_t 52DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict) 53{ 54#ifndef LLDB_DISABLE_PYTHON 55 PythonList sets (dict.GetItemForKey("sets")); 56 if (sets) 57 { 58 const uint32_t num_sets = sets.GetSize(); 59 for (uint32_t i=0; i<num_sets; ++i) 60 { 61 PythonString py_set_name(sets.GetItemAtIndex(i)); 62 ConstString set_name; 63 if (py_set_name) 64 set_name.SetCString(py_set_name.GetString()); 65 if (set_name) 66 { 67 RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL }; 68 m_sets.push_back (new_set); 69 } 70 else 71 { 72 Clear(); 73 return 0; 74 } 75 } 76 m_set_reg_nums.resize(m_sets.size()); 77 } 78 PythonList regs (dict.GetItemForKey("registers")); 79 if (regs) 80 { 81 const uint32_t num_regs = regs.GetSize(); 82 PythonString name_pystr("name"); 83 PythonString altname_pystr("alt-name"); 84 PythonString bitsize_pystr("bitsize"); 85 PythonString offset_pystr("offset"); 86 PythonString encoding_pystr("encoding"); 87 PythonString format_pystr("format"); 88 PythonString set_pystr("set"); 89 PythonString gcc_pystr("gcc"); 90 PythonString dwarf_pystr("dwarf"); 91 PythonString generic_pystr("generic"); 92 for (uint32_t i=0; i<num_regs; ++i) 93 { 94 PythonDictionary reg_info_dict(regs.GetItemAtIndex(i)); 95 if (reg_info_dict) 96 { 97 // { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 2, 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', }, 98 RegisterInfo reg_info; 99 bzero (®_info, sizeof(reg_info)); 100 101 reg_info.name = ConstString (reg_info_dict.GetItemForKeyAsString(name_pystr)).GetCString(); 102 if (reg_info.name == NULL) 103 { 104 Clear(); 105 return 0; 106 } 107 108 reg_info.alt_name = ConstString (reg_info_dict.GetItemForKeyAsString(altname_pystr)).GetCString(); 109 110 reg_info.byte_offset = reg_info_dict.GetItemForKeyAsInteger(offset_pystr, UINT32_MAX); 111 112 if (reg_info.byte_offset == UINT32_MAX) 113 { 114 Clear(); 115 return 0; 116 } 117 reg_info.byte_size = reg_info_dict.GetItemForKeyAsInteger(bitsize_pystr, 0) / 8; 118 119 if (reg_info.byte_size == 0) 120 { 121 Clear(); 122 return 0; 123 } 124 125 const char *format_cstr = reg_info_dict.GetItemForKeyAsString(format_pystr); 126 if (format_cstr) 127 { 128 if (Args::StringToFormat(format_cstr, reg_info.format, NULL).Fail()) 129 { 130 Clear(); 131 return 0; 132 } 133 } 134 else 135 reg_info.format = eFormatHex; 136 137 const char *encoding_cstr = reg_info_dict.GetItemForKeyAsString(encoding_pystr); 138 if (encoding_cstr) 139 reg_info.encoding = Args::StringToEncoding (encoding_cstr, eEncodingUint); 140 else 141 reg_info.encoding = eEncodingUint; 142 143 const int64_t set = reg_info_dict.GetItemForKeyAsInteger(set_pystr, -1); 144 if (set >= m_sets.size()) 145 { 146 Clear(); 147 return 0; 148 } 149 150 reg_info.kinds[lldb::eRegisterKindLLDB] = i; 151 reg_info.kinds[lldb::eRegisterKindGDB] = i; 152 reg_info.kinds[lldb::eRegisterKindGCC] = reg_info_dict.GetItemForKeyAsInteger(gcc_pystr, LLDB_INVALID_REGNUM); 153 reg_info.kinds[lldb::eRegisterKindDWARF] = reg_info_dict.GetItemForKeyAsInteger(dwarf_pystr, LLDB_INVALID_REGNUM); 154 reg_info.kinds[lldb::eRegisterKindGeneric] = Args::StringToGenericRegister (reg_info_dict.GetItemForKeyAsString(generic_pystr)); 155 const size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size; 156 if (m_reg_data_byte_size < end_reg_offset) 157 m_reg_data_byte_size = end_reg_offset; 158 159 m_regs.push_back (reg_info); 160 m_set_reg_nums[set].push_back(i); 161 162 } 163 else 164 { 165 Clear(); 166 return 0; 167 } 168 } 169 Finalize (); 170 } 171#endif 172 return 0; 173} 174 175 176void 177DynamicRegisterInfo::AddRegister (RegisterInfo ®_info, 178 ConstString ®_name, 179 ConstString ®_alt_name, 180 ConstString &set_name) 181{ 182 const uint32_t reg_num = m_regs.size(); 183 reg_info.name = reg_name.AsCString(); 184 assert (reg_info.name); 185 reg_info.alt_name = reg_alt_name.AsCString(NULL); 186 m_regs.push_back (reg_info); 187 uint32_t set = GetRegisterSetIndexByName (set_name, true); 188 assert (set < m_sets.size()); 189 assert (set < m_set_reg_nums.size()); 190 assert (set < m_set_names.size()); 191 m_set_reg_nums[set].push_back(reg_num); 192 size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size; 193 if (m_reg_data_byte_size < end_reg_offset) 194 m_reg_data_byte_size = end_reg_offset; 195} 196 197void 198DynamicRegisterInfo::Finalize () 199{ 200 for (uint32_t set = 0; set < m_sets.size(); ++set) 201 { 202 assert (m_sets.size() == m_set_reg_nums.size()); 203 m_sets[set].num_registers = m_set_reg_nums[set].size(); 204 m_sets[set].registers = &m_set_reg_nums[set][0]; 205 } 206} 207 208size_t 209DynamicRegisterInfo::GetNumRegisters() const 210{ 211 return m_regs.size(); 212} 213 214size_t 215DynamicRegisterInfo::GetNumRegisterSets() const 216{ 217 return m_sets.size(); 218} 219 220size_t 221DynamicRegisterInfo::GetRegisterDataByteSize() const 222{ 223 return m_reg_data_byte_size; 224} 225 226const RegisterInfo * 227DynamicRegisterInfo::GetRegisterInfoAtIndex (uint32_t i) const 228{ 229 if (i < m_regs.size()) 230 return &m_regs[i]; 231 return NULL; 232} 233 234const RegisterSet * 235DynamicRegisterInfo::GetRegisterSet (uint32_t i) const 236{ 237 if (i < m_sets.size()) 238 return &m_sets[i]; 239 return NULL; 240} 241 242uint32_t 243DynamicRegisterInfo::GetRegisterSetIndexByName (ConstString &set_name, bool can_create) 244{ 245 name_collection::iterator pos, end = m_set_names.end(); 246 for (pos = m_set_names.begin(); pos != end; ++pos) 247 { 248 if (*pos == set_name) 249 return std::distance (m_set_names.begin(), pos); 250 } 251 252 m_set_names.push_back(set_name); 253 m_set_reg_nums.resize(m_set_reg_nums.size()+1); 254 RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL }; 255 m_sets.push_back (new_set); 256 return m_sets.size() - 1; 257} 258 259uint32_t 260DynamicRegisterInfo::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) const 261{ 262 reg_collection::const_iterator pos, end = m_regs.end(); 263 for (pos = m_regs.begin(); pos != end; ++pos) 264 { 265 if (pos->kinds[kind] == num) 266 return std::distance (m_regs.begin(), pos); 267 } 268 269 return LLDB_INVALID_REGNUM; 270} 271 272void 273DynamicRegisterInfo::Clear() 274{ 275 m_regs.clear(); 276 m_sets.clear(); 277 m_set_reg_nums.clear(); 278 m_set_names.clear(); 279} 280