1 //===-- DynamicRegisterInfo.cpp ----------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/lldb-python.h"
12 #include "DynamicRegisterInfo.h"
16 // Other libraries and framework includes
18 #include "lldb/Interpreter/Args.h"
20 #ifndef LLDB_DISABLE_PYTHON
21 #include "lldb/Interpreter/PythonDataObjects.h"
25 using namespace lldb_private;
27 DynamicRegisterInfo::DynamicRegisterInfo () :
32 m_reg_data_byte_size (0)
36 DynamicRegisterInfo::DynamicRegisterInfo (const lldb_private::PythonDictionary &dict) :
41 m_reg_data_byte_size (0)
43 SetRegisterInfo (dict);
46 DynamicRegisterInfo::~DynamicRegisterInfo ()
52 DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict)
54 #ifndef LLDB_DISABLE_PYTHON
55 PythonList sets (dict.GetItemForKey("sets"));
58 const uint32_t num_sets = sets.GetSize();
59 for (uint32_t i=0; i<num_sets; ++i)
61 PythonString py_set_name(sets.GetItemAtIndex(i));
64 set_name.SetCString(py_set_name.GetString());
67 RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL };
68 m_sets.push_back (new_set);
76 m_set_reg_nums.resize(m_sets.size());
78 PythonList regs (dict.GetItemForKey("registers"));
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)
94 PythonDictionary reg_info_dict(regs.GetItemAtIndex(i));
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));
101 reg_info.name = ConstString (reg_info_dict.GetItemForKeyAsString(name_pystr)).GetCString();
102 if (reg_info.name == NULL)
108 reg_info.alt_name = ConstString (reg_info_dict.GetItemForKeyAsString(altname_pystr)).GetCString();
110 reg_info.byte_offset = reg_info_dict.GetItemForKeyAsInteger(offset_pystr, UINT32_MAX);
112 if (reg_info.byte_offset == UINT32_MAX)
117 reg_info.byte_size = reg_info_dict.GetItemForKeyAsInteger(bitsize_pystr, 0) / 8;
119 if (reg_info.byte_size == 0)
125 const char *format_cstr = reg_info_dict.GetItemForKeyAsString(format_pystr);
128 if (Args::StringToFormat(format_cstr, reg_info.format, NULL).Fail())
135 reg_info.format = eFormatHex;
137 const char *encoding_cstr = reg_info_dict.GetItemForKeyAsString(encoding_pystr);
139 reg_info.encoding = Args::StringToEncoding (encoding_cstr, eEncodingUint);
141 reg_info.encoding = eEncodingUint;
143 const int64_t set = reg_info_dict.GetItemForKeyAsInteger(set_pystr, -1);
144 if (set >= m_sets.size())
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;
159 m_regs.push_back (reg_info);
160 m_set_reg_nums[set].push_back(i);
177 DynamicRegisterInfo::AddRegister (RegisterInfo ®_info,
178 ConstString ®_name,
179 ConstString ®_alt_name,
180 ConstString &set_name)
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;
198 DynamicRegisterInfo::Finalize ()
200 for (uint32_t set = 0; set < m_sets.size(); ++set)
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];
209 DynamicRegisterInfo::GetNumRegisters() const
211 return m_regs.size();
215 DynamicRegisterInfo::GetNumRegisterSets() const
217 return m_sets.size();
221 DynamicRegisterInfo::GetRegisterDataByteSize() const
223 return m_reg_data_byte_size;
227 DynamicRegisterInfo::GetRegisterInfoAtIndex (uint32_t i) const
229 if (i < m_regs.size())
235 DynamicRegisterInfo::GetRegisterSet (uint32_t i) const
237 if (i < m_sets.size())
243 DynamicRegisterInfo::GetRegisterSetIndexByName (ConstString &set_name, bool can_create)
245 name_collection::iterator pos, end = m_set_names.end();
246 for (pos = m_set_names.begin(); pos != end; ++pos)
248 if (*pos == set_name)
249 return std::distance (m_set_names.begin(), pos);
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;
260 DynamicRegisterInfo::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) const
262 reg_collection::const_iterator pos, end = m_regs.end();
263 for (pos = m_regs.begin(); pos != end; ++pos)
265 if (pos->kinds[kind] == num)
266 return std::distance (m_regs.begin(), pos);
269 return LLDB_INVALID_REGNUM;
273 DynamicRegisterInfo::Clear()
277 m_set_reg_nums.clear();