]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
Copy head (r256279) to stable/10 as part of the 10.0-RELEASE cycle.
[FreeBSD/stable/10.git] / contrib / llvm / tools / lldb / source / Plugins / Process / Utility / DynamicRegisterInfo.cpp
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
24 using namespace lldb;
25 using namespace lldb_private;
26
27 DynamicRegisterInfo::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
36 DynamicRegisterInfo::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
46 DynamicRegisterInfo::~DynamicRegisterInfo ()
47 {
48 }
49
50
51 size_t
52 DynamicRegisterInfo::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 (&reg_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
176 void
177 DynamicRegisterInfo::AddRegister (RegisterInfo &reg_info,
178                                   ConstString &reg_name, 
179                                   ConstString &reg_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
197 void
198 DynamicRegisterInfo::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
208 size_t
209 DynamicRegisterInfo::GetNumRegisters() const
210 {
211     return m_regs.size();
212 }
213
214 size_t
215 DynamicRegisterInfo::GetNumRegisterSets() const
216 {
217     return m_sets.size();
218 }
219
220 size_t
221 DynamicRegisterInfo::GetRegisterDataByteSize() const
222 {
223     return m_reg_data_byte_size;
224 }
225
226 const RegisterInfo *
227 DynamicRegisterInfo::GetRegisterInfoAtIndex (uint32_t i) const
228 {
229     if (i < m_regs.size())
230         return &m_regs[i];
231     return NULL;
232 }
233
234 const RegisterSet *
235 DynamicRegisterInfo::GetRegisterSet (uint32_t i) const
236 {
237     if (i < m_sets.size())
238         return &m_sets[i];
239     return NULL;
240 }
241
242 uint32_t
243 DynamicRegisterInfo::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
259 uint32_t
260 DynamicRegisterInfo::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
272 void
273 DynamicRegisterInfo::Clear()
274 {
275     m_regs.clear();
276     m_sets.clear();
277     m_set_reg_nums.clear();
278     m_set_names.clear();
279 }