]>
Commit | Line | Data |
---|---|---|
0f767f94 AB |
1 | /* Python interface to register, and register group information. |
2 | ||
3 | Copyright (C) 2020 Free Software Foundation, Inc. | |
4 | ||
5 | This file is part of GDB. | |
6 | ||
7 | This program is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 3 of the License, or | |
10 | (at your option) any later version. | |
11 | ||
12 | This program is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
19 | ||
20 | #include "defs.h" | |
21 | #include "gdbarch.h" | |
22 | #include "arch-utils.h" | |
23 | #include "disasm.h" | |
24 | #include "reggroups.h" | |
25 | #include "python-internal.h" | |
baf8791e | 26 | #include <unordered_map> |
0f767f94 | 27 | |
f7306dac AB |
28 | /* Token to access per-gdbarch data related to register descriptors. */ |
29 | static struct gdbarch_data *gdbpy_register_object_data = NULL; | |
30 | ||
0f767f94 AB |
31 | /* Structure for iterator over register descriptors. */ |
32 | typedef struct { | |
33 | PyObject_HEAD | |
34 | ||
35 | /* The register group that the user is iterating over. This will never | |
36 | be NULL. */ | |
37 | struct reggroup *reggroup; | |
38 | ||
39 | /* The next register number to lookup. Starts at 0 and counts up. */ | |
40 | int regnum; | |
41 | ||
42 | /* Pointer back to the architecture we're finding registers for. */ | |
43 | struct gdbarch *gdbarch; | |
44 | } register_descriptor_iterator_object; | |
45 | ||
46 | extern PyTypeObject register_descriptor_iterator_object_type | |
47 | CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("register_descriptor_iterator_object"); | |
48 | ||
49 | /* A register descriptor. */ | |
50 | typedef struct { | |
51 | PyObject_HEAD | |
52 | ||
53 | /* The register this is a descriptor for. */ | |
54 | int regnum; | |
55 | ||
56 | /* The architecture this is a register for. */ | |
57 | struct gdbarch *gdbarch; | |
58 | } register_descriptor_object; | |
59 | ||
60 | extern PyTypeObject register_descriptor_object_type | |
61 | CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("register_descriptor_object"); | |
62 | ||
64cb3757 AB |
63 | /* Structure for iterator over register groups. */ |
64 | typedef struct { | |
65 | PyObject_HEAD | |
66 | ||
67 | /* The last register group returned. Initially this will be NULL. */ | |
68 | struct reggroup *reggroup; | |
69 | ||
70 | /* Pointer back to the architecture we're finding registers for. */ | |
71 | struct gdbarch *gdbarch; | |
72 | } reggroup_iterator_object; | |
73 | ||
74 | extern PyTypeObject reggroup_iterator_object_type | |
75 | CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("reggroup_iterator_object"); | |
76 | ||
77 | /* A register group object. */ | |
78 | typedef struct { | |
79 | PyObject_HEAD | |
80 | ||
81 | /* The register group being described. */ | |
82 | struct reggroup *reggroup; | |
83 | } reggroup_object; | |
84 | ||
85 | extern PyTypeObject reggroup_object_type | |
86 | CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("reggroup_object"); | |
87 | ||
f7306dac AB |
88 | /* Associates a vector of gdb.RegisterDescriptor objects with GDBARCH as |
89 | gdbarch_data via the gdbarch post init registration mechanism | |
90 | (gdbarch_data_register_post_init). */ | |
91 | ||
92 | static void * | |
93 | gdbpy_register_object_data_init (struct gdbarch *gdbarch) | |
94 | { | |
a67a1c41 | 95 | return new std::vector<gdbpy_ref<>>; |
f7306dac AB |
96 | } |
97 | ||
baf8791e AB |
98 | /* Return a gdb.RegisterGroup object wrapping REGGROUP. The register |
99 | group objects are cached, and the same Python object will always be | |
100 | returned for the same REGGROUP pointer. */ | |
64cb3757 | 101 | |
baf8791e AB |
102 | static gdbpy_ref<> |
103 | gdbpy_get_reggroup (struct reggroup *reggroup) | |
64cb3757 | 104 | { |
baf8791e AB |
105 | /* Map from GDB's internal reggroup objects to the Python representation. |
106 | GDB's reggroups are global, and are never deleted, so using a map like | |
107 | this is safe. */ | |
108 | static std::unordered_map<struct reggroup *,gdbpy_ref<>> | |
109 | gdbpy_reggroup_object_map; | |
110 | ||
111 | /* If there is not already a suitable Python object in the map then | |
112 | create a new one, and add it to the map. */ | |
113 | if (gdbpy_reggroup_object_map[reggroup] == nullptr) | |
114 | { | |
115 | /* Create a new object and fill in its details. */ | |
116 | gdbpy_ref<reggroup_object> group | |
117 | (PyObject_New (reggroup_object, ®group_object_type)); | |
118 | if (group == NULL) | |
119 | return NULL; | |
120 | group->reggroup = reggroup; | |
121 | gdbpy_reggroup_object_map[reggroup] | |
122 | = gdbpy_ref<> ((PyObject *) group.release ()); | |
123 | } | |
124 | ||
125 | /* Fetch the Python object wrapping REGGROUP from the map, increasing | |
126 | the reference count is handled by the gdbpy_ref class. */ | |
127 | return gdbpy_reggroup_object_map[reggroup]; | |
64cb3757 AB |
128 | } |
129 | ||
130 | /* Convert a gdb.RegisterGroup to a string, it just returns the name of | |
131 | the register group. */ | |
132 | ||
133 | static PyObject * | |
134 | gdbpy_reggroup_to_string (PyObject *self) | |
135 | { | |
136 | reggroup_object *group = (reggroup_object *) self; | |
137 | struct reggroup *reggroup = group->reggroup; | |
138 | ||
139 | const char *name = reggroup_name (reggroup); | |
140 | return PyString_FromString (name); | |
141 | } | |
142 | ||
143 | /* Implement gdb.RegisterGroup.name (self) -> String. | |
144 | Return a string that is the name of this register group. */ | |
145 | ||
146 | static PyObject * | |
147 | gdbpy_reggroup_name (PyObject *self, void *closure) | |
148 | { | |
149 | return gdbpy_reggroup_to_string (self); | |
150 | } | |
151 | ||
f7306dac AB |
152 | /* Return a gdb.RegisterDescriptor object for REGNUM from GDBARCH. For |
153 | each REGNUM (in GDBARCH) only one descriptor is ever created, which is | |
154 | then cached on the GDBARCH. */ | |
155 | ||
156 | static gdbpy_ref<> | |
157 | gdbpy_get_register_descriptor (struct gdbarch *gdbarch, | |
0f767f94 AB |
158 | int regnum) |
159 | { | |
a67a1c41 AB |
160 | auto &vec |
161 | = *(std::vector<gdbpy_ref<>> *) gdbarch_data (gdbarch, | |
162 | gdbpy_register_object_data); | |
f7306dac AB |
163 | |
164 | /* Ensure that we have enough entries in the vector. */ | |
a67a1c41 AB |
165 | if (vec.size () <= regnum) |
166 | vec.resize ((regnum + 1), nullptr); | |
f7306dac AB |
167 | |
168 | /* If we don't already have a descriptor for REGNUM in GDBARCH then | |
169 | create one now. */ | |
a67a1c41 | 170 | if (vec[regnum] == nullptr) |
f7306dac AB |
171 | { |
172 | gdbpy_ref <register_descriptor_object> reg | |
173 | (PyObject_New (register_descriptor_object, | |
174 | ®ister_descriptor_object_type)); | |
175 | if (reg == NULL) | |
176 | return NULL; | |
177 | reg->regnum = regnum; | |
178 | reg->gdbarch = gdbarch; | |
a67a1c41 | 179 | vec[regnum] = gdbpy_ref<> ((PyObject *) reg.release ()); |
f7306dac AB |
180 | } |
181 | ||
182 | /* Grab the register descriptor from the vector, the reference count is | |
183 | automatically incremented thanks to gdbpy_ref. */ | |
a67a1c41 | 184 | return vec[regnum]; |
0f767f94 AB |
185 | } |
186 | ||
187 | /* Convert the register descriptor to a string. */ | |
188 | ||
189 | static PyObject * | |
190 | gdbpy_register_descriptor_to_string (PyObject *self) | |
191 | { | |
192 | register_descriptor_object *reg | |
193 | = (register_descriptor_object *) self; | |
194 | struct gdbarch *gdbarch = reg->gdbarch; | |
195 | int regnum = reg->regnum; | |
196 | ||
197 | const char *name = gdbarch_register_name (gdbarch, regnum); | |
198 | return PyString_FromString (name); | |
199 | } | |
200 | ||
201 | /* Implement gdb.RegisterDescriptor.name attribute get function. Return a | |
202 | string that is the name of this register. Due to checking when register | |
203 | descriptors are created the name will never by the empty string. */ | |
204 | ||
205 | static PyObject * | |
206 | gdbpy_register_descriptor_name (PyObject *self, void *closure) | |
207 | { | |
208 | return gdbpy_register_descriptor_to_string (self); | |
209 | } | |
210 | ||
64cb3757 AB |
211 | /* Return a reference to the gdb.RegisterGroupsIterator object. */ |
212 | ||
213 | static PyObject * | |
214 | gdbpy_reggroup_iter (PyObject *self) | |
215 | { | |
216 | Py_INCREF (self); | |
217 | return self; | |
218 | } | |
219 | ||
220 | /* Return the next gdb.RegisterGroup object from the iterator. */ | |
221 | ||
222 | static PyObject * | |
223 | gdbpy_reggroup_iter_next (PyObject *self) | |
224 | { | |
225 | reggroup_iterator_object *iter_obj | |
226 | = (reggroup_iterator_object *) self; | |
227 | struct gdbarch *gdbarch = iter_obj->gdbarch; | |
228 | ||
229 | struct reggroup *next_group = reggroup_next (gdbarch, iter_obj->reggroup); | |
230 | if (next_group == NULL) | |
231 | { | |
232 | PyErr_SetString (PyExc_StopIteration, _("No more groups")); | |
233 | return NULL; | |
234 | } | |
235 | ||
236 | iter_obj->reggroup = next_group; | |
baf8791e | 237 | return gdbpy_get_reggroup (iter_obj->reggroup).release (); |
64cb3757 AB |
238 | } |
239 | ||
240 | /* Return a new gdb.RegisterGroupsIterator over all the register groups in | |
241 | GDBARCH. */ | |
242 | ||
243 | PyObject * | |
244 | gdbpy_new_reggroup_iterator (struct gdbarch *gdbarch) | |
245 | { | |
246 | gdb_assert (gdbarch != nullptr); | |
247 | ||
248 | /* Create a new object and fill in its internal state. */ | |
249 | reggroup_iterator_object *iter | |
250 | = PyObject_New (reggroup_iterator_object, | |
251 | ®group_iterator_object_type); | |
252 | if (iter == NULL) | |
253 | return NULL; | |
254 | iter->reggroup = NULL; | |
255 | iter->gdbarch = gdbarch; | |
256 | return (PyObject *) iter; | |
257 | } | |
258 | ||
0f767f94 AB |
259 | /* Create and return a new gdb.RegisterDescriptorIterator object which |
260 | will iterate over all registers in GROUP_NAME for GDBARCH. If | |
261 | GROUP_NAME is either NULL or the empty string then the ALL_REGGROUP is | |
262 | used, otherwise lookup the register group matching GROUP_NAME and use | |
263 | that. | |
264 | ||
265 | This function can return NULL if GROUP_NAME isn't found. */ | |
266 | ||
267 | PyObject * | |
268 | gdbpy_new_register_descriptor_iterator (struct gdbarch *gdbarch, | |
269 | const char *group_name) | |
270 | { | |
271 | struct reggroup *grp = NULL; | |
272 | ||
273 | /* Lookup the requested register group, or find the default. */ | |
274 | if (group_name == NULL || *group_name == '\0') | |
275 | grp = all_reggroup; | |
276 | else | |
277 | { | |
278 | grp = reggroup_find (gdbarch, group_name); | |
279 | if (grp == NULL) | |
280 | { | |
281 | PyErr_SetString (PyExc_ValueError, | |
282 | _("Unknown register group name.")); | |
283 | return NULL; | |
284 | } | |
285 | } | |
286 | /* Create a new iterator object initialised for this architecture and | |
287 | fill in all of the details. */ | |
288 | register_descriptor_iterator_object *iter | |
289 | = PyObject_New (register_descriptor_iterator_object, | |
290 | ®ister_descriptor_iterator_object_type); | |
291 | if (iter == NULL) | |
292 | return NULL; | |
293 | iter->regnum = 0; | |
294 | iter->gdbarch = gdbarch; | |
295 | gdb_assert (grp != NULL); | |
296 | iter->reggroup = grp; | |
297 | ||
298 | return (PyObject *) iter; | |
299 | } | |
300 | ||
301 | /* Return a reference to the gdb.RegisterDescriptorIterator object. */ | |
302 | ||
303 | static PyObject * | |
304 | gdbpy_register_descriptor_iter (PyObject *self) | |
305 | { | |
306 | Py_INCREF (self); | |
307 | return self; | |
308 | } | |
309 | ||
310 | /* Return the next register name. */ | |
311 | ||
312 | static PyObject * | |
313 | gdbpy_register_descriptor_iter_next (PyObject *self) | |
314 | { | |
315 | register_descriptor_iterator_object *iter_obj | |
316 | = (register_descriptor_iterator_object *) self; | |
317 | struct gdbarch *gdbarch = iter_obj->gdbarch; | |
318 | ||
319 | do | |
320 | { | |
321 | if (iter_obj->regnum >= gdbarch_num_cooked_regs (gdbarch)) | |
322 | { | |
323 | PyErr_SetString (PyExc_StopIteration, _("No more registers")); | |
324 | return NULL; | |
325 | } | |
326 | ||
327 | const char *name = nullptr; | |
328 | int regnum = iter_obj->regnum; | |
329 | if (gdbarch_register_reggroup_p (gdbarch, regnum, | |
330 | iter_obj->reggroup)) | |
331 | name = gdbarch_register_name (gdbarch, regnum); | |
332 | iter_obj->regnum++; | |
333 | ||
334 | if (name != nullptr && *name != '\0') | |
f7306dac | 335 | return gdbpy_get_register_descriptor (gdbarch, regnum).release (); |
0f767f94 AB |
336 | } |
337 | while (true); | |
338 | } | |
339 | ||
340 | /* Initializes the new Python classes from this file in the gdb module. */ | |
341 | ||
342 | int | |
343 | gdbpy_initialize_registers () | |
344 | { | |
f7306dac AB |
345 | gdbpy_register_object_data |
346 | = gdbarch_data_register_post_init (gdbpy_register_object_data_init); | |
347 | ||
0f767f94 AB |
348 | register_descriptor_object_type.tp_new = PyType_GenericNew; |
349 | if (PyType_Ready (®ister_descriptor_object_type) < 0) | |
350 | return -1; | |
351 | if (gdb_pymodule_addobject | |
352 | (gdb_module, "RegisterDescriptor", | |
353 | (PyObject *) ®ister_descriptor_object_type) < 0) | |
354 | return -1; | |
355 | ||
64cb3757 AB |
356 | reggroup_iterator_object_type.tp_new = PyType_GenericNew; |
357 | if (PyType_Ready (®group_iterator_object_type) < 0) | |
358 | return -1; | |
359 | if (gdb_pymodule_addobject | |
360 | (gdb_module, "RegisterGroupsIterator", | |
361 | (PyObject *) ®group_iterator_object_type) < 0) | |
362 | return -1; | |
363 | ||
364 | reggroup_object_type.tp_new = PyType_GenericNew; | |
365 | if (PyType_Ready (®group_object_type) < 0) | |
366 | return -1; | |
367 | if (gdb_pymodule_addobject | |
368 | (gdb_module, "RegisterGroup", | |
369 | (PyObject *) ®group_object_type) < 0) | |
370 | return -1; | |
371 | ||
0f767f94 AB |
372 | register_descriptor_iterator_object_type.tp_new = PyType_GenericNew; |
373 | if (PyType_Ready (®ister_descriptor_iterator_object_type) < 0) | |
374 | return -1; | |
375 | return (gdb_pymodule_addobject | |
376 | (gdb_module, "RegisterDescriptorIterator", | |
377 | (PyObject *) ®ister_descriptor_iterator_object_type)); | |
378 | } | |
379 | ||
380 | PyTypeObject register_descriptor_iterator_object_type = { | |
381 | PyVarObject_HEAD_INIT (NULL, 0) | |
382 | "gdb.RegisterDescriptorIterator", /*tp_name*/ | |
383 | sizeof (register_descriptor_iterator_object), /*tp_basicsize*/ | |
384 | 0, /*tp_itemsize*/ | |
385 | 0, /*tp_dealloc*/ | |
386 | 0, /*tp_print*/ | |
387 | 0, /*tp_getattr*/ | |
388 | 0, /*tp_setattr*/ | |
389 | 0, /*tp_compare*/ | |
390 | 0, /*tp_repr*/ | |
391 | 0, /*tp_as_number*/ | |
392 | 0, /*tp_as_sequence*/ | |
393 | 0, /*tp_as_mapping*/ | |
394 | 0, /*tp_hash */ | |
395 | 0, /*tp_call*/ | |
396 | 0, /*tp_str*/ | |
397 | 0, /*tp_getattro*/ | |
398 | 0, /*tp_setattro*/ | |
399 | 0, /*tp_as_buffer*/ | |
400 | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/ | |
401 | "GDB architecture register descriptor iterator object", /*tp_doc */ | |
402 | 0, /*tp_traverse */ | |
403 | 0, /*tp_clear */ | |
404 | 0, /*tp_richcompare */ | |
405 | 0, /*tp_weaklistoffset */ | |
406 | gdbpy_register_descriptor_iter, /*tp_iter */ | |
407 | gdbpy_register_descriptor_iter_next, /*tp_iternext */ | |
408 | 0 /*tp_methods */ | |
409 | }; | |
410 | ||
411 | static gdb_PyGetSetDef gdbpy_register_descriptor_getset[] = { | |
412 | { "name", gdbpy_register_descriptor_name, NULL, | |
413 | "The name of this register.", NULL }, | |
414 | { NULL } /* Sentinel */ | |
415 | }; | |
416 | ||
417 | PyTypeObject register_descriptor_object_type = { | |
418 | PyVarObject_HEAD_INIT (NULL, 0) | |
419 | "gdb.RegisterDescriptor", /*tp_name*/ | |
420 | sizeof (register_descriptor_object), /*tp_basicsize*/ | |
421 | 0, /*tp_itemsize*/ | |
422 | 0, /*tp_dealloc*/ | |
423 | 0, /*tp_print*/ | |
424 | 0, /*tp_getattr*/ | |
425 | 0, /*tp_setattr*/ | |
426 | 0, /*tp_compare*/ | |
427 | 0, /*tp_repr*/ | |
428 | 0, /*tp_as_number*/ | |
429 | 0, /*tp_as_sequence*/ | |
430 | 0, /*tp_as_mapping*/ | |
431 | 0, /*tp_hash */ | |
432 | 0, /*tp_call*/ | |
433 | gdbpy_register_descriptor_to_string, /*tp_str*/ | |
434 | 0, /*tp_getattro*/ | |
435 | 0, /*tp_setattro*/ | |
436 | 0, /*tp_as_buffer*/ | |
437 | Py_TPFLAGS_DEFAULT, /*tp_flags*/ | |
438 | "GDB architecture register descriptor object", /*tp_doc */ | |
439 | 0, /*tp_traverse */ | |
440 | 0, /*tp_clear */ | |
441 | 0, /*tp_richcompare */ | |
442 | 0, /*tp_weaklistoffset */ | |
443 | 0, /*tp_iter */ | |
444 | 0, /*tp_iternext */ | |
445 | 0, /*tp_methods */ | |
446 | 0, /*tp_members */ | |
447 | gdbpy_register_descriptor_getset /*tp_getset */ | |
448 | }; | |
64cb3757 AB |
449 | |
450 | PyTypeObject reggroup_iterator_object_type = { | |
451 | PyVarObject_HEAD_INIT (NULL, 0) | |
452 | "gdb.RegisterGroupsIterator", /*tp_name*/ | |
453 | sizeof (reggroup_iterator_object), /*tp_basicsize*/ | |
454 | 0, /*tp_itemsize*/ | |
455 | 0, /*tp_dealloc*/ | |
456 | 0, /*tp_print*/ | |
457 | 0, /*tp_getattr*/ | |
458 | 0, /*tp_setattr*/ | |
459 | 0, /*tp_compare*/ | |
460 | 0, /*tp_repr*/ | |
461 | 0, /*tp_as_number*/ | |
462 | 0, /*tp_as_sequence*/ | |
463 | 0, /*tp_as_mapping*/ | |
464 | 0, /*tp_hash */ | |
465 | 0, /*tp_call*/ | |
466 | 0, /*tp_str*/ | |
467 | 0, /*tp_getattro*/ | |
468 | 0, /*tp_setattro*/ | |
469 | 0, /*tp_as_buffer*/ | |
470 | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/ | |
471 | "GDB register groups iterator object", /*tp_doc */ | |
472 | 0, /*tp_traverse */ | |
473 | 0, /*tp_clear */ | |
474 | 0, /*tp_richcompare */ | |
475 | 0, /*tp_weaklistoffset */ | |
476 | gdbpy_reggroup_iter, /*tp_iter */ | |
477 | gdbpy_reggroup_iter_next, /*tp_iternext */ | |
478 | 0 /*tp_methods */ | |
479 | }; | |
480 | ||
481 | static gdb_PyGetSetDef gdbpy_reggroup_getset[] = { | |
482 | { "name", gdbpy_reggroup_name, NULL, | |
483 | "The name of this register group.", NULL }, | |
484 | { NULL } /* Sentinel */ | |
485 | }; | |
486 | ||
487 | PyTypeObject reggroup_object_type = { | |
488 | PyVarObject_HEAD_INIT (NULL, 0) | |
489 | "gdb.RegisterGroup", /*tp_name*/ | |
490 | sizeof (reggroup_object), /*tp_basicsize*/ | |
491 | 0, /*tp_itemsize*/ | |
492 | 0, /*tp_dealloc*/ | |
493 | 0, /*tp_print*/ | |
494 | 0, /*tp_getattr*/ | |
495 | 0, /*tp_setattr*/ | |
496 | 0, /*tp_compare*/ | |
497 | 0, /*tp_repr*/ | |
498 | 0, /*tp_as_number*/ | |
499 | 0, /*tp_as_sequence*/ | |
500 | 0, /*tp_as_mapping*/ | |
501 | 0, /*tp_hash */ | |
502 | 0, /*tp_call*/ | |
503 | gdbpy_reggroup_to_string, /*tp_str*/ | |
504 | 0, /*tp_getattro*/ | |
505 | 0, /*tp_setattro*/ | |
506 | 0, /*tp_as_buffer*/ | |
507 | Py_TPFLAGS_DEFAULT, /*tp_flags*/ | |
508 | "GDB register group object", /*tp_doc */ | |
509 | 0, /*tp_traverse */ | |
510 | 0, /*tp_clear */ | |
511 | 0, /*tp_richcompare */ | |
512 | 0, /*tp_weaklistoffset */ | |
513 | 0, /*tp_iter */ | |
514 | 0, /*tp_iternext */ | |
515 | 0, /*tp_methods */ | |
516 | 0, /*tp_members */ | |
517 | gdbpy_reggroup_getset /*tp_getset */ | |
518 | }; |