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