[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