[PATCH] Add gdb.integer_type Python function
Tom Tromey
tromey@adacore.com
Fri Oct 22 19:59:52 GMT 2021
This adds a new Python function, gdb.integer_type, which can be used
to look up an integer type of a given size and signed-ness. This is
useful to avoid dependency on debuginfo when a particular integer type
would be useful.
---
gdb/NEWS | 3 ++
gdb/doc/python.texi | 15 +++++++++
gdb/python/py-type.c | 46 ++++++++++++++++++++++++++++
gdb/python/python-internal.h | 1 +
gdb/python/python.c | 6 ++++
gdb/testsuite/gdb.python/py-type.exp | 14 +++++++++
6 files changed, 85 insertions(+)
diff --git a/gdb/NEWS b/gdb/NEWS
index d001a03145d..ab095a2601c 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -49,6 +49,9 @@ maint show internal-warning backtrace
containing all of the possible Architecture.name() values. Each
entry is a string.
+ ** New function gdb.integer_type(), which returns an integer type
+ given a size and a signed-ness.
+
*** Changes in GDB 11
* The 'set disassembler-options' command now supports specifying options
diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
index 90214f24238..c6093c4d2ee 100644
--- a/gdb/doc/python.texi
+++ b/gdb/doc/python.texi
@@ -1125,6 +1125,21 @@ Ordinarily, this function will return an instance of @code{gdb.Type}.
If the named type cannot be found, it will throw an exception.
@end defun
+@findex gdb.integer_type
+@defun gdb.integer_type (size @r{[}, signed@r{]})
+This function looks up an integer type by its @var{size}, and
+optionally whether or not it is signed.
+
+@var{size} is the size, in bits, of the desired integer type. Only
+certain sizes are currently supported: 0, 8, 16, 24, 32, 64, and 128.
+
+If @var{signed} is not specified, it defaults to @code{True}. If
+@var{signed} is @code{False}, the returned type will be unsigned.
+
+If the indicated type cannot be found, this function will throw an
+exception.
+@end defun
+
If the type is a structure or class type, or an enum type, the fields
of that type can be accessed using the Python @dfn{dictionary syntax}.
For example, if @code{some_type} is a @code{gdb.Type} instance holding
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index f0f83579323..9908a017cb3 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -1433,6 +1433,52 @@ gdbpy_lookup_type (PyObject *self, PyObject *args, PyObject *kw)
return type_to_type_object (type);
}
+/* Implementation of gdb.integer_type. */
+PyObject *
+gdbpy_integer_type (PyObject *self, PyObject *args, PyObject *kw)
+{
+ static const char *keywords[] = { "size", "signed", NULL };
+ int size, is_signed = 1;
+
+ if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "i|p", keywords,
+ &size, &is_signed))
+ return nullptr;
+
+ const struct builtin_type *builtins = builtin_type (python_gdbarch);
+ struct type *type = nullptr;
+ switch (size)
+ {
+ case 0:
+ type = builtins->builtin_int0;
+ break;
+ case 8:
+ type = is_signed ? builtins->builtin_int8 : builtins->builtin_uint8;
+ break;
+ case 16:
+ type = is_signed ? builtins->builtin_int16 : builtins->builtin_uint16;
+ break;
+ case 24:
+ type = is_signed ? builtins->builtin_int24 : builtins->builtin_uint24;
+ break;
+ case 32:
+ type = is_signed ? builtins->builtin_int32 : builtins->builtin_uint32;
+ break;
+ case 64:
+ type = is_signed ? builtins->builtin_int64 : builtins->builtin_uint64;
+ break;
+ case 128:
+ type = is_signed ? builtins->builtin_int128 : builtins->builtin_uint128;
+ break;
+
+ default:
+ PyErr_SetString (PyExc_ValueError,
+ _("no integer type of that size is available"));
+ return nullptr;
+ }
+
+ return type_to_type_object (type);
+}
+
void _initialize_py_type ();
void
_initialize_py_type ()
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 24e28bc4767..1d0b90f8cda 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -429,6 +429,7 @@ PyObject *gdbpy_stop_recording (PyObject *self, PyObject *args);
PyObject *gdbpy_newest_frame (PyObject *self, PyObject *args);
PyObject *gdbpy_selected_frame (PyObject *self, PyObject *args);
PyObject *gdbpy_lookup_type (PyObject *self, PyObject *args, PyObject *kw);
+PyObject *gdbpy_integer_type (PyObject *self, PyObject *args, PyObject *kw);
int gdbpy_is_field (PyObject *obj);
PyObject *gdbpy_create_lazy_string_object (CORE_ADDR address, long length,
const char *encoding,
diff --git a/gdb/python/python.c b/gdb/python/python.c
index c81814c557b..6db9ba0bc3a 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -2236,6 +2236,12 @@ Stop current recording." },
METH_VARARGS | METH_KEYWORDS,
"lookup_type (name [, block]) -> type\n\
Return a Type corresponding to the given name." },
+ { "integer_type", (PyCFunction) gdbpy_integer_type,
+ METH_VARARGS | METH_KEYWORDS,
+ "integer_type (size [, signed]) -> type\n\
+Return an integer Type corresponding to the given bitsize and signed-ness.\n\
+If not specified, the type defaults to signed." },
+
{ "lookup_symbol", (PyCFunction) gdbpy_lookup_symbol,
METH_VARARGS | METH_KEYWORDS,
"lookup_symbol (name [, block] [, domain]) -> (symbol, is_field_of_this)\n\
diff --git a/gdb/testsuite/gdb.python/py-type.exp b/gdb/testsuite/gdb.python/py-type.exp
index 733b25d3210..96bbab55b02 100644
--- a/gdb/testsuite/gdb.python/py-type.exp
+++ b/gdb/testsuite/gdb.python/py-type.exp
@@ -297,6 +297,20 @@ if { [build_inferior "${binfile}" "c"] == 0 } {
test_fields "c"
test_enums
}
+
+ foreach size {0 1 2 3 4 8 16} {
+ foreach sign {"" ", True" ", False"} {
+ set fullsize [expr 8 * $size]
+ gdb_test_no_output "python t = gdb.integer_type($fullsize$sign)" \
+ "get integer type for $size$sign"
+ gdb_test "python print(t.sizeof)" "$size" \
+ "print size of integer type for $size$sign"
+ }
+ }
+
+ gdb_test "python gdb.integer_type(95)" \
+ ".*ValueError: no integer type of that size is available.*" \
+ "call integer_type with invalid size"
}
--
2.31.1
More information about the Gdb-patches
mailing list