Add gdb.Architecture.integer_type Python function

This adds a new Python function, gdb.Architecture.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.

v2 moves this to be a method on gdb.Architecture and addresses other
review comments.
This commit is contained in:
Tom Tromey 2021-10-22 10:49:19 -06:00
parent 7a72f09da5
commit d3771fe234
4 changed files with 89 additions and 0 deletions

View file

@ -49,6 +49,9 @@ maint show internal-warning backtrace
containing all of the possible Architecture.name() values. Each containing all of the possible Architecture.name() values. Each
entry is a string. entry is a string.
** New function gdb.Architecture.integer_type(), which returns an
integer type given a size and a signed-ness.
* New features in the GDB remote stub, GDBserver * New features in the GDB remote stub, GDBserver
** GDBserver is now supported on OpenRISC GNU/Linux. ** GDBserver is now supported on OpenRISC GNU/Linux.

View file

@ -1125,6 +1125,9 @@ Ordinarily, this function will return an instance of @code{gdb.Type}.
If the named type cannot be found, it will throw an exception. If the named type cannot be found, it will throw an exception.
@end defun @end defun
Integer types can be found without looking them up by name.
@xref{Architectures In Python}, for the @code{integer_type} method.
If the type is a structure or class type, or an enum type, the fields 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}. 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 For example, if @code{some_type} is a @code{gdb.Type} instance holding
@ -5883,6 +5886,21 @@ instruction in bytes.
@end table @end table
@end defun @end defun
@findex Architecture.integer_type
@defun Architecture.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 a
@code{ValueError} exception.
@end defun
@anchor{gdbpy_architecture_registers} @anchor{gdbpy_architecture_registers}
@defun Architecture.registers (@r{[} @var{reggroup} @r{]}) @defun Architecture.registers (@r{[} @var{reggroup} @r{]})
Return a @code{gdb.RegisterDescriptorIterator} (@pxref{Registers In Return a @code{gdb.RegisterDescriptorIterator} (@pxref{Registers In

View file

@ -271,6 +271,55 @@ archpy_register_groups (PyObject *self, PyObject *args)
return gdbpy_new_reggroup_iterator (gdbarch); return gdbpy_new_reggroup_iterator (gdbarch);
} }
/* Implementation of gdb.integer_type. */
static PyObject *
archpy_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;
struct gdbarch *gdbarch;
ARCHPY_REQUIRE_VALID (self, gdbarch);
const struct builtin_type *builtins = builtin_type (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);
}
/* Implementation of gdb.architecture_names(). Return a list of all the /* Implementation of gdb.architecture_names(). Return a list of all the
BFD architecture names that GDB understands. */ BFD architecture names that GDB understands. */
@ -323,6 +372,11 @@ Return the name of the architecture as a string value." },
"disassemble (start_pc [, end_pc [, count]]) -> List.\n\ "disassemble (start_pc [, end_pc [, count]]) -> List.\n\
Return a list of at most COUNT disassembled instructions from START_PC to\n\ Return a list of at most COUNT disassembled instructions from START_PC to\n\
END_PC." }, END_PC." },
{ "integer_type", (PyCFunction) archpy_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." },
{ "registers", (PyCFunction) archpy_registers, { "registers", (PyCFunction) archpy_registers,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"registers ([ group-name ]) -> Iterator.\n\ "registers ([ group-name ]) -> Iterator.\n\

View file

@ -63,6 +63,20 @@ if { ![is_address_zero_readable] } {
"test bad memory access" "test bad memory access"
} }
foreach size {0 1 2 3 4 8 16} {
foreach sign {"" ", True" ", False"} {
set fullsize [expr 8 * $size]
gdb_test_no_output "python t = arch.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 arch.integer_type(95)" \
".*ValueError: no integer type of that size is available.*" \
"call integer_type with invalid size"
# Test for gdb.architecture_names(). First we're going to grab the # Test for gdb.architecture_names(). First we're going to grab the
# complete list of architecture names using the 'complete' command. # complete list of architecture names using the 'complete' command.
set arch_names [] set arch_names []