[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