+2020-07-28 Andrew Burgess <andrew.burgess@embecosm.com>
+
+ * python/py-registers.c: Add 'user-regs.h' include.
+ (register_descriptor_iter_find): New function.
+ (register_descriptor_iterator_object_methods): New static global
+ methods array.
+ (register_descriptor_iterator_object_type): Add pointer to methods
+ array.
+
2020-07-27 John Baldwin <jhb@FreeBSD.org>
* fbsd-nat.h: Include <osreldate.h>. Define USE_SIGTRAP_SIGINFO
The name of this register.
@end defvar
+It is also possible to lookup a register descriptor based on its name
+using the following @code{gdb.RegisterDescriptorIterator} function:
+
+@defun RegisterDescriptorIterator.find (@var{name})
+Takes @var{name} as an argument, which must be a string, and returns a
+@code{gdb.RegisterDescriptor} for the register with that name, or
+@code{None} if there is no register with that name.
+@end defun
+
Python code can also request from a @code{gdb.Architecture}
information about the set of register groups available on a given
architecture
#include "disasm.h"
#include "reggroups.h"
#include "python-internal.h"
+#include "user-regs.h"
#include <unordered_map>
/* Token to access per-gdbarch data related to register descriptors. */
while (true);
}
+/* Implement:
+
+ gdb.RegisterDescriptorIterator.find (self, name) -> gdb.RegisterDescriptor
+
+ Look up a descriptor for register with NAME. If no matching register is
+ found then return None. */
+
+static PyObject *
+register_descriptor_iter_find (PyObject *self, PyObject *args, PyObject *kw)
+{
+ static const char *keywords[] = { "name", NULL };
+ const char *register_name = NULL;
+
+ register_descriptor_iterator_object *iter_obj
+ = (register_descriptor_iterator_object *) self;
+ struct gdbarch *gdbarch = iter_obj->gdbarch;
+
+ if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s", keywords,
+ ®ister_name))
+ return NULL;
+
+ if (register_name != NULL && *register_name != '\0')
+ {
+ int regnum = user_reg_map_name_to_regnum (gdbarch, register_name,
+ strlen (register_name));
+ if (regnum >= 0)
+ return gdbpy_get_register_descriptor (gdbarch, regnum).release ();
+ }
+
+ Py_RETURN_NONE;
+}
+
/* Initializes the new Python classes from this file in the gdb module. */
int
(PyObject *) ®ister_descriptor_iterator_object_type));
}
+static PyMethodDef register_descriptor_iterator_object_methods [] = {
+ { "find", (PyCFunction) register_descriptor_iter_find,
+ METH_VARARGS | METH_KEYWORDS,
+ "registers (name) -> gdb.RegisterDescriptor.\n\
+Return a register descriptor for the register NAME, or None if no register\n\
+with that name exists in this iterator." },
+ {NULL} /* Sentinel */
+};
+
PyTypeObject register_descriptor_iterator_object_type = {
PyVarObject_HEAD_INIT (NULL, 0)
"gdb.RegisterDescriptorIterator", /*tp_name*/
0, /*tp_weaklistoffset */
gdbpy_register_descriptor_iter, /*tp_iter */
gdbpy_register_descriptor_iter_next, /*tp_iternext */
- 0 /*tp_methods */
+ register_descriptor_iterator_object_methods /*tp_methods */
};
static gdb_PyGetSetDef gdbpy_register_descriptor_getset[] = {
" raise gdb.GdbError (\"miss-matched objects\")" \
"\004" ] \
"check names and objects match" 1
+
+# Ensure that the '.find' method on the iterator returns the same
+# Python object as we got from the iterator's list of descriptors.
+gdb_py_test_silent_cmd \
+ [multi_line \
+ "python" \
+ "def check_regs (arch, regs):" \
+ " for r in (regs):" \
+ " if (arch.registers ().find (r.name) != r):" \
+ " raise gdb.GdbError (\"object miss-match\")" \
+ "end" ] \
+ "build check_obj function" 0
+gdb_py_test_silent_cmd \
+ "python check_regs (arch, arch.registers (\"general\"))" \
+ "ensure find gets expected descriptors" 1