[arm] Add support for FPU registers in prologue unwinder
[binutils-gdb.git] / gdb / python / py-arch.c
1 /* Python interface to architecture
2
3 Copyright (C) 2013-2022 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 "python-internal.h"
25
26 struct arch_object {
27 PyObject_HEAD
28 struct gdbarch *gdbarch;
29 };
30
31 static struct gdbarch_data *arch_object_data = NULL;
32
33 /* Require a valid Architecture. */
34 #define ARCHPY_REQUIRE_VALID(arch_obj, arch) \
35 do { \
36 arch = arch_object_to_gdbarch (arch_obj); \
37 if (arch == NULL) \
38 { \
39 PyErr_SetString (PyExc_RuntimeError, \
40 _("Architecture is invalid.")); \
41 return NULL; \
42 } \
43 } while (0)
44
45 extern PyTypeObject arch_object_type
46 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("arch_object");
47
48 /* Associates an arch_object with GDBARCH as gdbarch_data via the gdbarch
49 post init registration mechanism (gdbarch_data_register_post_init). */
50
51 static void *
52 arch_object_data_init (struct gdbarch *gdbarch)
53 {
54 arch_object *arch_obj = PyObject_New (arch_object, &arch_object_type);
55
56 if (arch_obj == NULL)
57 return NULL;
58
59 arch_obj->gdbarch = gdbarch;
60
61 return (void *) arch_obj;
62 }
63
64 /* Returns the struct gdbarch value corresponding to the given Python
65 architecture object OBJ, which must be a gdb.Architecture object. */
66
67 struct gdbarch *
68 arch_object_to_gdbarch (PyObject *obj)
69 {
70 gdb_assert (gdbpy_is_architecture (obj));
71
72 arch_object *py_arch = (arch_object *) obj;
73 return py_arch->gdbarch;
74 }
75
76 /* See python-internal.h. */
77
78 bool
79 gdbpy_is_architecture (PyObject *obj)
80 {
81 return PyObject_TypeCheck (obj, &arch_object_type);
82 }
83
84 /* Returns the Python architecture object corresponding to GDBARCH.
85 Returns a new reference to the arch_object associated as data with
86 GDBARCH. */
87
88 PyObject *
89 gdbarch_to_arch_object (struct gdbarch *gdbarch)
90 {
91 PyObject *new_ref = (PyObject *) gdbarch_data (gdbarch, arch_object_data);
92
93 /* new_ref could be NULL if registration of arch_object with GDBARCH failed
94 in arch_object_data_init. */
95 Py_XINCREF (new_ref);
96
97 return new_ref;
98 }
99
100 /* Implementation of gdb.Architecture.name (self) -> String.
101 Returns the name of the architecture as a string value. */
102
103 static PyObject *
104 archpy_name (PyObject *self, PyObject *args)
105 {
106 struct gdbarch *gdbarch = NULL;
107 const char *name;
108
109 ARCHPY_REQUIRE_VALID (self, gdbarch);
110
111 name = (gdbarch_bfd_arch_info (gdbarch))->printable_name;
112 return PyUnicode_FromString (name);
113 }
114
115 /* Implementation of
116 gdb.Architecture.disassemble (self, start_pc [, end_pc [,count]]) -> List.
117 Returns a list of instructions in a memory address range. Each instruction
118 in the list is a Python dict object.
119 */
120
121 static PyObject *
122 archpy_disassemble (PyObject *self, PyObject *args, PyObject *kw)
123 {
124 static const char *keywords[] = { "start_pc", "end_pc", "count", NULL };
125 CORE_ADDR start, end = 0;
126 CORE_ADDR pc;
127 gdb_py_ulongest start_temp;
128 long count = 0, i;
129 PyObject *end_obj = NULL, *count_obj = NULL;
130 struct gdbarch *gdbarch = NULL;
131
132 ARCHPY_REQUIRE_VALID (self, gdbarch);
133
134 if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, GDB_PY_LLU_ARG "|OO",
135 keywords, &start_temp, &end_obj,
136 &count_obj))
137 return NULL;
138
139 start = start_temp;
140 if (end_obj)
141 {
142 /* Make a long logic check first. In Python 3.x, internally,
143 all integers are represented as longs. In Python 2.x, there
144 is still a differentiation internally between a PyInt and a
145 PyLong. Explicitly do this long check conversion first. In
146 GDB, for Python 3.x, we #ifdef PyInt = PyLong. This check has
147 to be done first to ensure we do not lose information in the
148 conversion process. */
149 if (PyLong_Check (end_obj))
150 end = PyLong_AsUnsignedLongLong (end_obj);
151 else
152 {
153 PyErr_SetString (PyExc_TypeError,
154 _("Argument 'end_pc' should be a (long) integer."));
155
156 return NULL;
157 }
158
159 if (end < start)
160 {
161 PyErr_SetString (PyExc_ValueError,
162 _("Argument 'end_pc' should be greater than or "
163 "equal to the argument 'start_pc'."));
164
165 return NULL;
166 }
167 }
168 if (count_obj)
169 {
170 count = PyLong_AsLong (count_obj);
171 if (PyErr_Occurred () || count < 0)
172 {
173 PyErr_SetString (PyExc_TypeError,
174 _("Argument 'count' should be an non-negative "
175 "integer."));
176
177 return NULL;
178 }
179 }
180
181 gdbpy_ref<> result_list (PyList_New (0));
182 if (result_list == NULL)
183 return NULL;
184
185 for (pc = start, i = 0;
186 /* All args are specified. */
187 (end_obj && count_obj && pc <= end && i < count)
188 /* end_pc is specified, but no count. */
189 || (end_obj && count_obj == NULL && pc <= end)
190 /* end_pc is not specified, but a count is. */
191 || (end_obj == NULL && count_obj && i < count)
192 /* Both end_pc and count are not specified. */
193 || (end_obj == NULL && count_obj == NULL && pc == start);)
194 {
195 int insn_len = 0;
196 gdbpy_ref<> insn_dict (PyDict_New ());
197
198 if (insn_dict == NULL)
199 return NULL;
200 if (PyList_Append (result_list.get (), insn_dict.get ()))
201 return NULL; /* PyList_Append Sets the exception. */
202
203 string_file stb;
204
205 try
206 {
207 insn_len = gdb_print_insn (gdbarch, pc, &stb, NULL);
208 }
209 catch (const gdb_exception &except)
210 {
211 gdbpy_convert_exception (except);
212 return NULL;
213 }
214
215 gdbpy_ref<> pc_obj = gdb_py_object_from_ulongest (pc);
216 if (pc_obj == nullptr)
217 return nullptr;
218
219 gdbpy_ref<> asm_obj
220 (PyUnicode_FromString (!stb.empty () ? stb.c_str () : "<unknown>"));
221 if (asm_obj == nullptr)
222 return nullptr;
223
224 gdbpy_ref<> len_obj = gdb_py_object_from_longest (insn_len);
225 if (len_obj == nullptr)
226 return nullptr;
227
228 if (PyDict_SetItemString (insn_dict.get (), "addr", pc_obj.get ())
229 || PyDict_SetItemString (insn_dict.get (), "asm", asm_obj.get ())
230 || PyDict_SetItemString (insn_dict.get (), "length", len_obj.get ()))
231 return NULL;
232
233 pc += insn_len;
234 i++;
235 }
236
237 return result_list.release ();
238 }
239
240 /* Implementation of gdb.Architecture.registers (self, reggroup) -> Iterator.
241 Returns an iterator over register descriptors for registers in GROUP
242 within the architecture SELF. */
243
244 static PyObject *
245 archpy_registers (PyObject *self, PyObject *args, PyObject *kw)
246 {
247 static const char *keywords[] = { "reggroup", NULL };
248 struct gdbarch *gdbarch = NULL;
249 const char *group_name = NULL;
250
251 /* Parse method arguments. */
252 if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "|s", keywords,
253 &group_name))
254 return NULL;
255
256 /* Extract the gdbarch from the self object. */
257 ARCHPY_REQUIRE_VALID (self, gdbarch);
258
259 return gdbpy_new_register_descriptor_iterator (gdbarch, group_name);
260 }
261
262 /* Implementation of gdb.Architecture.register_groups (self) -> Iterator.
263 Returns an iterator that will give up all valid register groups in the
264 architecture SELF. */
265
266 static PyObject *
267 archpy_register_groups (PyObject *self, PyObject *args)
268 {
269 struct gdbarch *gdbarch = NULL;
270
271 /* Extract the gdbarch from the self object. */
272 ARCHPY_REQUIRE_VALID (self, gdbarch);
273 return gdbpy_new_reggroup_iterator (gdbarch);
274 }
275
276 /* Implementation of gdb.integer_type. */
277 static PyObject *
278 archpy_integer_type (PyObject *self, PyObject *args, PyObject *kw)
279 {
280 static const char *keywords[] = { "size", "signed", NULL };
281 int size;
282 PyObject *is_signed_obj = nullptr;
283
284 if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "i|O", keywords,
285 &size, &is_signed_obj))
286 return nullptr;
287
288 /* Assume signed by default. */
289 bool is_signed = (is_signed_obj == nullptr
290 || PyObject_IsTrue (is_signed_obj));
291
292 struct gdbarch *gdbarch;
293 ARCHPY_REQUIRE_VALID (self, gdbarch);
294
295 const struct builtin_type *builtins = builtin_type (gdbarch);
296 struct type *type = nullptr;
297 switch (size)
298 {
299 case 0:
300 type = builtins->builtin_int0;
301 break;
302 case 8:
303 type = is_signed ? builtins->builtin_int8 : builtins->builtin_uint8;
304 break;
305 case 16:
306 type = is_signed ? builtins->builtin_int16 : builtins->builtin_uint16;
307 break;
308 case 24:
309 type = is_signed ? builtins->builtin_int24 : builtins->builtin_uint24;
310 break;
311 case 32:
312 type = is_signed ? builtins->builtin_int32 : builtins->builtin_uint32;
313 break;
314 case 64:
315 type = is_signed ? builtins->builtin_int64 : builtins->builtin_uint64;
316 break;
317 case 128:
318 type = is_signed ? builtins->builtin_int128 : builtins->builtin_uint128;
319 break;
320
321 default:
322 PyErr_SetString (PyExc_ValueError,
323 _("no integer type of that size is available"));
324 return nullptr;
325 }
326
327 return type_to_type_object (type);
328 }
329
330 /* Implementation of gdb.architecture_names(). Return a list of all the
331 BFD architecture names that GDB understands. */
332
333 PyObject *
334 gdbpy_all_architecture_names (PyObject *self, PyObject *args)
335 {
336 gdbpy_ref<> list (PyList_New (0));
337 if (list == nullptr)
338 return nullptr;
339
340 std::vector<const char *> name_list = gdbarch_printable_names ();
341 for (const char *name : name_list)
342 {
343 gdbpy_ref <> py_name (PyUnicode_FromString (name));
344 if (py_name == nullptr)
345 return nullptr;
346 if (PyList_Append (list.get (), py_name.get ()) < 0)
347 return nullptr;
348 }
349
350 return list.release ();
351 }
352
353 void _initialize_py_arch ();
354 void
355 _initialize_py_arch ()
356 {
357 arch_object_data = gdbarch_data_register_post_init (arch_object_data_init);
358 }
359
360 /* Initializes the Architecture class in the gdb module. */
361
362 int
363 gdbpy_initialize_arch (void)
364 {
365 arch_object_type.tp_new = PyType_GenericNew;
366 if (PyType_Ready (&arch_object_type) < 0)
367 return -1;
368
369 return gdb_pymodule_addobject (gdb_module, "Architecture",
370 (PyObject *) &arch_object_type);
371 }
372
373 static PyMethodDef arch_object_methods [] = {
374 { "name", archpy_name, METH_NOARGS,
375 "name () -> String.\n\
376 Return the name of the architecture as a string value." },
377 { "disassemble", (PyCFunction) archpy_disassemble,
378 METH_VARARGS | METH_KEYWORDS,
379 "disassemble (start_pc [, end_pc [, count]]) -> List.\n\
380 Return a list of at most COUNT disassembled instructions from START_PC to\n\
381 END_PC." },
382 { "integer_type", (PyCFunction) archpy_integer_type,
383 METH_VARARGS | METH_KEYWORDS,
384 "integer_type (size [, signed]) -> type\n\
385 Return an integer Type corresponding to the given bitsize and signed-ness.\n\
386 If not specified, the type defaults to signed." },
387 { "registers", (PyCFunction) archpy_registers,
388 METH_VARARGS | METH_KEYWORDS,
389 "registers ([ group-name ]) -> Iterator.\n\
390 Return an iterator of register descriptors for the registers in register\n\
391 group GROUP-NAME." },
392 { "register_groups", archpy_register_groups,
393 METH_NOARGS,
394 "register_groups () -> Iterator.\n\
395 Return an iterator over all of the register groups in this architecture." },
396 {NULL} /* Sentinel */
397 };
398
399 PyTypeObject arch_object_type = {
400 PyVarObject_HEAD_INIT (NULL, 0)
401 "gdb.Architecture", /* tp_name */
402 sizeof (arch_object), /* tp_basicsize */
403 0, /* tp_itemsize */
404 0, /* tp_dealloc */
405 0, /* tp_print */
406 0, /* tp_getattr */
407 0, /* tp_setattr */
408 0, /* tp_compare */
409 0, /* tp_repr */
410 0, /* tp_as_number */
411 0, /* tp_as_sequence */
412 0, /* tp_as_mapping */
413 0, /* tp_hash */
414 0, /* tp_call */
415 0, /* tp_str */
416 0, /* tp_getattro */
417 0, /* tp_setattro */
418 0, /* tp_as_buffer */
419 Py_TPFLAGS_DEFAULT, /* tp_flags */
420 "GDB architecture object", /* tp_doc */
421 0, /* tp_traverse */
422 0, /* tp_clear */
423 0, /* tp_richcompare */
424 0, /* tp_weaklistoffset */
425 0, /* tp_iter */
426 0, /* tp_iternext */
427 arch_object_methods, /* tp_methods */
428 0, /* tp_members */
429 0, /* tp_getset */
430 0, /* tp_base */
431 0, /* tp_dict */
432 0, /* tp_descr_get */
433 0, /* tp_descr_set */
434 0, /* tp_dictoffset */
435 0, /* tp_init */
436 0, /* tp_alloc */
437 };