]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/python/py-registers.c
gdb/python: Add gdb.Architecture.registers method
[thirdparty/binutils-gdb.git] / gdb / python / py-registers.c
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"
26
27 /* Structure for iterator over register descriptors. */
28 typedef struct {
29 PyObject_HEAD
30
31 /* The register group that the user is iterating over. This will never
32 be NULL. */
33 struct reggroup *reggroup;
34
35 /* The next register number to lookup. Starts at 0 and counts up. */
36 int regnum;
37
38 /* Pointer back to the architecture we're finding registers for. */
39 struct gdbarch *gdbarch;
40 } register_descriptor_iterator_object;
41
42 extern PyTypeObject register_descriptor_iterator_object_type
43 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("register_descriptor_iterator_object");
44
45 /* A register descriptor. */
46 typedef struct {
47 PyObject_HEAD
48
49 /* The register this is a descriptor for. */
50 int regnum;
51
52 /* The architecture this is a register for. */
53 struct gdbarch *gdbarch;
54 } register_descriptor_object;
55
56 extern PyTypeObject register_descriptor_object_type
57 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("register_descriptor_object");
58
59 /* Create an return a new gdb.RegisterDescriptor object. */
60 static PyObject *
61 gdbpy_new_register_descriptor (struct gdbarch *gdbarch,
62 int regnum)
63 {
64 /* Create a new object and fill in its details. */
65 register_descriptor_object *reg
66 = PyObject_New (register_descriptor_object,
67 &register_descriptor_object_type);
68 if (reg == NULL)
69 return NULL;
70 reg->regnum = regnum;
71 reg->gdbarch = gdbarch;
72 return (PyObject *) reg;
73 }
74
75 /* Convert the register descriptor to a string. */
76
77 static PyObject *
78 gdbpy_register_descriptor_to_string (PyObject *self)
79 {
80 register_descriptor_object *reg
81 = (register_descriptor_object *) self;
82 struct gdbarch *gdbarch = reg->gdbarch;
83 int regnum = reg->regnum;
84
85 const char *name = gdbarch_register_name (gdbarch, regnum);
86 return PyString_FromString (name);
87 }
88
89 /* Implement gdb.RegisterDescriptor.name attribute get function. Return a
90 string that is the name of this register. Due to checking when register
91 descriptors are created the name will never by the empty string. */
92
93 static PyObject *
94 gdbpy_register_descriptor_name (PyObject *self, void *closure)
95 {
96 return gdbpy_register_descriptor_to_string (self);
97 }
98
99 /* Create and return a new gdb.RegisterDescriptorIterator object which
100 will iterate over all registers in GROUP_NAME for GDBARCH. If
101 GROUP_NAME is either NULL or the empty string then the ALL_REGGROUP is
102 used, otherwise lookup the register group matching GROUP_NAME and use
103 that.
104
105 This function can return NULL if GROUP_NAME isn't found. */
106
107 PyObject *
108 gdbpy_new_register_descriptor_iterator (struct gdbarch *gdbarch,
109 const char *group_name)
110 {
111 struct reggroup *grp = NULL;
112
113 /* Lookup the requested register group, or find the default. */
114 if (group_name == NULL || *group_name == '\0')
115 grp = all_reggroup;
116 else
117 {
118 grp = reggroup_find (gdbarch, group_name);
119 if (grp == NULL)
120 {
121 PyErr_SetString (PyExc_ValueError,
122 _("Unknown register group name."));
123 return NULL;
124 }
125 }
126 /* Create a new iterator object initialised for this architecture and
127 fill in all of the details. */
128 register_descriptor_iterator_object *iter
129 = PyObject_New (register_descriptor_iterator_object,
130 &register_descriptor_iterator_object_type);
131 if (iter == NULL)
132 return NULL;
133 iter->regnum = 0;
134 iter->gdbarch = gdbarch;
135 gdb_assert (grp != NULL);
136 iter->reggroup = grp;
137
138 return (PyObject *) iter;
139 }
140
141 /* Return a reference to the gdb.RegisterDescriptorIterator object. */
142
143 static PyObject *
144 gdbpy_register_descriptor_iter (PyObject *self)
145 {
146 Py_INCREF (self);
147 return self;
148 }
149
150 /* Return the next register name. */
151
152 static PyObject *
153 gdbpy_register_descriptor_iter_next (PyObject *self)
154 {
155 register_descriptor_iterator_object *iter_obj
156 = (register_descriptor_iterator_object *) self;
157 struct gdbarch *gdbarch = iter_obj->gdbarch;
158
159 do
160 {
161 if (iter_obj->regnum >= gdbarch_num_cooked_regs (gdbarch))
162 {
163 PyErr_SetString (PyExc_StopIteration, _("No more registers"));
164 return NULL;
165 }
166
167 const char *name = nullptr;
168 int regnum = iter_obj->regnum;
169 if (gdbarch_register_reggroup_p (gdbarch, regnum,
170 iter_obj->reggroup))
171 name = gdbarch_register_name (gdbarch, regnum);
172 iter_obj->regnum++;
173
174 if (name != nullptr && *name != '\0')
175 return gdbpy_new_register_descriptor (gdbarch, regnum);
176 }
177 while (true);
178 }
179
180 /* Initializes the new Python classes from this file in the gdb module. */
181
182 int
183 gdbpy_initialize_registers ()
184 {
185 register_descriptor_object_type.tp_new = PyType_GenericNew;
186 if (PyType_Ready (&register_descriptor_object_type) < 0)
187 return -1;
188 if (gdb_pymodule_addobject
189 (gdb_module, "RegisterDescriptor",
190 (PyObject *) &register_descriptor_object_type) < 0)
191 return -1;
192
193 register_descriptor_iterator_object_type.tp_new = PyType_GenericNew;
194 if (PyType_Ready (&register_descriptor_iterator_object_type) < 0)
195 return -1;
196 return (gdb_pymodule_addobject
197 (gdb_module, "RegisterDescriptorIterator",
198 (PyObject *) &register_descriptor_iterator_object_type));
199 }
200
201 PyTypeObject register_descriptor_iterator_object_type = {
202 PyVarObject_HEAD_INIT (NULL, 0)
203 "gdb.RegisterDescriptorIterator", /*tp_name*/
204 sizeof (register_descriptor_iterator_object), /*tp_basicsize*/
205 0, /*tp_itemsize*/
206 0, /*tp_dealloc*/
207 0, /*tp_print*/
208 0, /*tp_getattr*/
209 0, /*tp_setattr*/
210 0, /*tp_compare*/
211 0, /*tp_repr*/
212 0, /*tp_as_number*/
213 0, /*tp_as_sequence*/
214 0, /*tp_as_mapping*/
215 0, /*tp_hash */
216 0, /*tp_call*/
217 0, /*tp_str*/
218 0, /*tp_getattro*/
219 0, /*tp_setattro*/
220 0, /*tp_as_buffer*/
221 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/
222 "GDB architecture register descriptor iterator object", /*tp_doc */
223 0, /*tp_traverse */
224 0, /*tp_clear */
225 0, /*tp_richcompare */
226 0, /*tp_weaklistoffset */
227 gdbpy_register_descriptor_iter, /*tp_iter */
228 gdbpy_register_descriptor_iter_next, /*tp_iternext */
229 0 /*tp_methods */
230 };
231
232 static gdb_PyGetSetDef gdbpy_register_descriptor_getset[] = {
233 { "name", gdbpy_register_descriptor_name, NULL,
234 "The name of this register.", NULL },
235 { NULL } /* Sentinel */
236 };
237
238 PyTypeObject register_descriptor_object_type = {
239 PyVarObject_HEAD_INIT (NULL, 0)
240 "gdb.RegisterDescriptor", /*tp_name*/
241 sizeof (register_descriptor_object), /*tp_basicsize*/
242 0, /*tp_itemsize*/
243 0, /*tp_dealloc*/
244 0, /*tp_print*/
245 0, /*tp_getattr*/
246 0, /*tp_setattr*/
247 0, /*tp_compare*/
248 0, /*tp_repr*/
249 0, /*tp_as_number*/
250 0, /*tp_as_sequence*/
251 0, /*tp_as_mapping*/
252 0, /*tp_hash */
253 0, /*tp_call*/
254 gdbpy_register_descriptor_to_string, /*tp_str*/
255 0, /*tp_getattro*/
256 0, /*tp_setattro*/
257 0, /*tp_as_buffer*/
258 Py_TPFLAGS_DEFAULT, /*tp_flags*/
259 "GDB architecture register descriptor object", /*tp_doc */
260 0, /*tp_traverse */
261 0, /*tp_clear */
262 0, /*tp_richcompare */
263 0, /*tp_weaklistoffset */
264 0, /*tp_iter */
265 0, /*tp_iternext */
266 0, /*tp_methods */
267 0, /*tp_members */
268 gdbpy_register_descriptor_getset /*tp_getset */
269 };