[PATCH] Add gdb.integer_type Python function
Andrew Burgess
andrew.burgess@embecosm.com
Sat Oct 23 09:46:13 GMT 2021
* Tom Tromey via Gdb-patches <gdb-patches@sourceware.org> [2021-10-22 13:59:52 -0600]:
> 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;
Would it make sense to call arch_integer_type here to allow arbitrary
type to be created?
Thanks,
Andrew
> + }
> +
> + 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