public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Add gdb.integer_type Python function
@ 2021-10-22 19:59 Tom Tromey
  2021-10-23  6:26 ` Eli Zaretskii
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Tom Tromey @ 2021-10-22 19:59 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

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


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Add gdb.integer_type Python function
  2021-10-22 19:59 [PATCH] Add gdb.integer_type Python function Tom Tromey
@ 2021-10-23  6:26 ` Eli Zaretskii
  2021-10-25 16:08   ` Tom Tromey
  2021-10-23  9:46 ` Andrew Burgess
  2021-10-23 12:36 ` Simon Marchi
  2 siblings, 1 reply; 7+ messages in thread
From: Eli Zaretskii @ 2021-10-23  6:26 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

> Date: Fri, 22 Oct 2021 13:59:52 -0600
> From: Tom Tromey via Gdb-patches <gdb-patches@sourceware.org>
> Cc: Tom Tromey <tromey@adacore.com>
> 
> 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(+)

The documentation parts are OK, thanks.

> +@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.

Would it make more sense to have SIZE specified in bytes instead?

Btw, is the set of types somehow restricted by what Python supports,
or by what GDB supports?

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Add gdb.integer_type Python function
  2021-10-22 19:59 [PATCH] Add gdb.integer_type Python function Tom Tromey
  2021-10-23  6:26 ` Eli Zaretskii
@ 2021-10-23  9:46 ` Andrew Burgess
  2021-10-25 16:07   ` Tom Tromey
  2021-10-23 12:36 ` Simon Marchi
  2 siblings, 1 reply; 7+ messages in thread
From: Andrew Burgess @ 2021-10-23  9:46 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

* 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
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Add gdb.integer_type Python function
  2021-10-22 19:59 [PATCH] Add gdb.integer_type Python function Tom Tromey
  2021-10-23  6:26 ` Eli Zaretskii
  2021-10-23  9:46 ` Andrew Burgess
@ 2021-10-23 12:36 ` Simon Marchi
  2021-10-25 16:10   ` Tom Tromey
  2 siblings, 1 reply; 7+ messages in thread
From: Simon Marchi @ 2021-10-23 12:36 UTC (permalink / raw)
  To: Tom Tromey, gdb-patches

On 2021-10-22 15:59, Tom Tromey via Gdb-patches wrote:
> 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.

IIUC, by "avoid dependency on debuginfo", you mean where you would use
gdb.lookup_type instead?

So, gdb.integer_type depends on the current inferior, because it uses
its gdbarch.  Since I'd like to see Python methods depend less on "the
current thing", what about making a method on gdb.Architecture instead?


> ---
>  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.

IWBN to document which kind of exception.

Simon

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Add gdb.integer_type Python function
  2021-10-23  9:46 ` Andrew Burgess
@ 2021-10-25 16:07   ` Tom Tromey
  0 siblings, 0 replies; 7+ messages in thread
From: Tom Tromey @ 2021-10-25 16:07 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: Tom Tromey, gdb-patches

>>>>> "Andrew" == Andrew Burgess <andrew.burgess@embecosm.com> writes:

Andrew> Would it make sense to call arch_integer_type here to allow arbitrary
Andrew> type to be created?

We could do that, but I didn't need it, and doing so would introduce a
kind of memory leak.

Tom

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Add gdb.integer_type Python function
  2021-10-23  6:26 ` Eli Zaretskii
@ 2021-10-25 16:08   ` Tom Tromey
  0 siblings, 0 replies; 7+ messages in thread
From: Tom Tromey @ 2021-10-25 16:08 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Tom Tromey, gdb-patches

>> +@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.

Eli> Would it make more sense to have SIZE specified in bytes instead?

It doesn't matter for my purposes, but using the bit size leaves more
flexibility if we want to extend the supported range.

Eli> Btw, is the set of types somehow restricted by what Python supports,
Eli> or by what GDB supports?

GDB.

Tom

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Add gdb.integer_type Python function
  2021-10-23 12:36 ` Simon Marchi
@ 2021-10-25 16:10   ` Tom Tromey
  0 siblings, 0 replies; 7+ messages in thread
From: Tom Tromey @ 2021-10-25 16:10 UTC (permalink / raw)
  To: Simon Marchi; +Cc: Tom Tromey, gdb-patches

>> 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.

Simon> IIUC, by "avoid dependency on debuginfo", you mean where you would use
Simon> gdb.lookup_type instead?

Yeah.  In our situation, we'd like a pretty-printer to be able to use a
uint32_t.  However, this type doesn't appear in the inferior's debuginfo.

Simon> So, gdb.integer_type depends on the current inferior, because it uses
Simon> its gdbarch.  Since I'd like to see Python methods depend less on "the
Simon> current thing", what about making a method on gdb.Architecture instead?

I had thought the results were arch-independent, but of course they
aren't due to endianness.  I'll make this change for v2.

Tom

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2021-10-25 16:10 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-22 19:59 [PATCH] Add gdb.integer_type Python function Tom Tromey
2021-10-23  6:26 ` Eli Zaretskii
2021-10-25 16:08   ` Tom Tromey
2021-10-23  9:46 ` Andrew Burgess
2021-10-25 16:07   ` Tom Tromey
2021-10-23 12:36 ` Simon Marchi
2021-10-25 16:10   ` Tom Tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).