aboutsummaryrefslogtreecommitdiff
path: root/gdb/typeprint.c
diff options
context:
space:
mode:
authorLancelot SIX <lsix@lancelotsix.com>2021-04-17 12:10:23 +0100
committerLancelot SIX <lsix@lancelotsix.com>2021-04-25 18:00:54 +0100
commitfbb46296d7e0d09e792a7c9d7841cb26753cb3ce (patch)
tree57a8906aac5ac27c70664f749980f2d3b6c6f517 /gdb/typeprint.c
parent18bbba46a974d8b667f9b60c5a7d41bb3cb07369 (diff)
downloadfsf-binutils-gdb-fbb46296d7e0d09e792a7c9d7841cb26753cb3ce.zip
fsf-binutils-gdb-fbb46296d7e0d09e792a7c9d7841cb26753cb3ce.tar.gz
fsf-binutils-gdb-fbb46296d7e0d09e792a7c9d7841cb26753cb3ce.tar.bz2
[PR gdb/22640] ptype: add option to use hexadecimal notation
This commit adds a flag to the ptype command in order to print the offsets and sizes of struct members using the hexadecimal notation. The 'x' flag ensures use of the hexadecimal notation while the 'd' flag ensures use of the decimal notation. The default is to use decimal notation. Before this patch, gdb only uses decimal notation, as pointed out in PR gdb/22640. Here is an example of this new behavior with hex output turned on: (gdb) ptype /ox struct type_print_options /* offset | size */ type = struct type_print_options { /* 0x0000: 0x0 | 0x0004 */ unsigned int raw : 1; /* 0x0000: 0x1 | 0x0004 */ unsigned int print_methods : 1; /* 0x0000: 0x2 | 0x0004 */ unsigned int print_typedefs : 1; /* 0x0000: 0x3 | 0x0004 */ unsigned int print_offsets : 1; /* 0x0000: 0x4 | 0x0004 */ unsigned int print_in_hex : 1; /* XXX 3-bit hole */ /* XXX 3-byte hole */ /* 0x0004 | 0x0004 */ int print_nested_type_limit; /* 0x0008 | 0x0008 */ typedef_hash_table *local_typedefs; /* 0x0010 | 0x0008 */ typedef_hash_table *global_typedefs; /* 0x0018 | 0x0008 */ ext_lang_type_printers *global_printers; /* total size (bytes): 32 */ } This patch also adds the 'set print type hex' and 'show print type hex' commands in order to set and inspect the default behavior regarding the use of decimal or hexadecimal notation when printing struct sizes and offsets. Tested using on x86_64. gdb/ChangeLog: PR gdb/22640 * typeprint.h (struct type_print_options): Add print_in_hex flag. (struct print_offset_data): Add print_in_hex flag, add a constructor accepting a type_print_options* argument. * typeprint.c (type_print_raw_options, default_ptype_flags): Set default value for print_in_hex. (print_offset_data::indentation): Allow more horizontal space. (print_offset_data::print_offset_data): Add ctor. (print_offset_data::maybe_print_hole, print_offset_data::update): Handle the print_in_hex flag. (whatis_exp): Handle 'x' and 'd' flags. (print_offsets_and_sizes_in_hex): Declare. (set_print_offsets_and_sizes_in_hex): Create. (show_print_offsets_and_sizes_in_hex): Create. (_initialize_typeprint): Update help message for the ptype command, register the 'set print type hex' and 'show print type hex' commands. * c-typeprint.c (c_print_type, c_type_print_base_struct_union) (c_type_print_base): Construct the print_offset_data object using the type_print_optons parameter. * rust-lang.c (rust_language::print_type): Construct the print_offset_data object using the type_print_optons parameter. * NEWS: Mention the new flags of the ptype command. gdb/doc/ChangeLog: PR gdb/22640 * gdb.texinfo (Symbols): Describe the 'x' and 'd' flags of the ptype command, describe 'set print type hex' and 'show print type hex' commands. Update 'ptype/o' examples. gdb/testsuite/ChangeLog: PR gdb/22640 * gdb.base/ptype-offsets.exp: Add tests to verify the behavior of 'ptype/ox' and 'ptype/od'. Check that 'set print type hex' changes the default behavior of 'ptype/o'. Update to take into account new horizontal layout. * gdb.rust/simple.exp: Update ptype test to check new horizontal layout. * gdb.rust/union.exp: Same.
Diffstat (limited to 'gdb/typeprint.c')
-rw-r--r--gdb/typeprint.c83
1 files changed, 72 insertions, 11 deletions
diff --git a/gdb/typeprint.c b/gdb/typeprint.c
index 1af1d17..eb47d91 100644
--- a/gdb/typeprint.c
+++ b/gdb/typeprint.c
@@ -44,6 +44,7 @@ const struct type_print_options type_print_raw_options =
1, /* print_methods */
1, /* print_typedefs */
0, /* print_offsets */
+ 0, /* print_in_hex */
0, /* print_nested_type_limit */
NULL, /* local_typedefs */
NULL, /* global_table */
@@ -58,6 +59,7 @@ static struct type_print_options default_ptype_flags =
1, /* print_methods */
1, /* print_typedefs */
0, /* print_offsets */
+ 0, /* print_in_hex */
0, /* print_nested_type_limit */
NULL, /* local_typedefs */
NULL, /* global_table */
@@ -68,8 +70,15 @@ static struct type_print_options default_ptype_flags =
/* See typeprint.h. */
-const int print_offset_data::indentation = 23;
+const int print_offset_data::indentation = 27;
+/* See typeprint.h. */
+
+print_offset_data::print_offset_data (const struct type_print_options *flags)
+{
+ if (flags != nullptr)
+ print_in_hex = flags->print_in_hex;
+}
/* See typeprint.h. */
@@ -95,11 +104,11 @@ print_offset_data::maybe_print_hole (struct ui_file *stream,
unsigned int hole_bit = hole % TARGET_CHAR_BIT;
if (hole_bit > 0)
- fprintf_filtered (stream, "/* XXX %2u-bit %s */\n", hole_bit,
+ fprintf_filtered (stream, "/* XXX %2u-bit %-7s */\n", hole_bit,
for_what);
if (hole_byte > 0)
- fprintf_filtered (stream, "/* XXX %2u-byte %s */\n", hole_byte,
+ fprintf_filtered (stream, "/* XXX %2u-byte %-7s */\n", hole_byte,
for_what);
}
}
@@ -121,8 +130,10 @@ print_offset_data::update (struct type *type, unsigned int field_idx,
{
/* Since union fields don't have the concept of offsets, we just
print their sizes. */
- fprintf_filtered (stream, "/* %4s */",
- pulongest (TYPE_LENGTH (ftype)));
+ fprintf_filtered (stream, "/* %6s */",
+ (print_in_hex ?
+ hex_string_custom (TYPE_LENGTH (ftype), 4) :
+ pulongest (TYPE_LENGTH (ftype))));
return;
}
@@ -140,20 +151,23 @@ print_offset_data::update (struct type *type, unsigned int field_idx,
unsigned real_bitpos = bitpos + offset_bitpos;
- fprintf_filtered (stream, "/* %4u:%2u", real_bitpos / TARGET_CHAR_BIT,
+ fprintf_filtered (stream,
+ (print_in_hex ? "/* 0x%04x: 0x%x" : "/* %6u:%2u "),
+ real_bitpos / TARGET_CHAR_BIT,
real_bitpos % TARGET_CHAR_BIT);
}
else
{
/* The position of the field, relative to the beginning of the
struct. */
- fprintf_filtered (stream, "/* %4u",
+ fprintf_filtered (stream, (print_in_hex ? "/* 0x%04x" : "/* %6u"),
(bitpos + offset_bitpos) / TARGET_CHAR_BIT);
- fprintf_filtered (stream, " ");
+ fprintf_filtered (stream, " ");
}
- fprintf_filtered (stream, " | %4u */", fieldsize_byte);
+ fprintf_filtered (stream, (print_in_hex ? " | 0x%04x */" : " | %6u */"),
+ fieldsize_byte);
end_bitpos = bitpos + fieldsize_bit;
}
@@ -468,6 +482,12 @@ whatis_exp (const char *exp, int show)
}
break;
}
+ case 'x':
+ flags.print_in_hex = 1;
+ break;
+ case 'd':
+ flags.print_in_hex = 0;
+ break;
default:
error (_("unrecognized flag '%c'"), *exp);
}
@@ -528,7 +548,7 @@ whatis_exp (const char *exp, int show)
if (flags.print_offsets
&& (type->code () == TYPE_CODE_STRUCT
|| type->code () == TYPE_CODE_UNION))
- fprintf_filtered (gdb_stdout, "/* offset | size */ ");
+ fprintf_filtered (gdb_stdout, "/* offset | size */ ");
printf_filtered ("type = ");
@@ -763,6 +783,35 @@ show_print_type_nested_types (struct ui_file *file, int from_tty,
}
}
+/* When printing structs, offsets and sizes of members can be displayed using
+ decimal notation or hexadecimal notation. By default, Decimal notation is
+ used. */
+
+static bool print_offsets_and_sizes_in_hex = false;
+
+/* Set the flags that instructs if sizes and offsets of struct members are
+ displayed in hexadecimal or decimal notation. */
+
+static void
+set_print_offsets_and_sizes_in_hex (const char *args,
+ int from_tty, struct cmd_list_element *c)
+{
+ default_ptype_flags.print_in_hex = print_offsets_and_sizes_in_hex;
+}
+
+/* Display whether struct members sizes and offsets are printed
+ using decimal or hexadecimal notation. */
+
+static void
+show_print_offsets_and_sizes_in_hex (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c,
+ const char *value)
+{
+ fprintf_filtered (file, _("\
+Display of struct members offsets and sizes in hexadecimal is %s\n"),
+ value);
+}
+
void _initialize_typeprint ();
void
_initialize_typeprint ()
@@ -784,7 +833,11 @@ Available FLAGS are:\n\
/M print methods defined in a class\n\
/t do not print typedefs defined in a class\n\
/T print typedefs defined in a class\n\
- /o print offsets and sizes of fields in a struct (like pahole)"));
+ /o print offsets and sizes of fields in a struct (like pahole)\n\
+ /x use hexadecimal notation when displaying sizes and offsets\n\
+ of struct members\n\
+ /d use decimal notation when displaying sizes and offsets\n\
+ of struct members "));
set_cmd_completer (c, expression_completer);
c = add_com ("whatis", class_vars, whatis_command,
@@ -825,6 +878,14 @@ Show the number of recursive nested type definitions to print."), NULL,
set_print_type_nested_types,
show_print_type_nested_types,
&setprinttypelist, &showprinttypelist);
+
+ add_setshow_boolean_cmd ("hex", no_class, &print_offsets_and_sizes_in_hex,
+ _("\
+Set printing of struct members sizes and offsets using hex notation."), _("\
+Show whether sizes and offsets of struct members are printed using hex \
+notation."), nullptr, set_print_offsets_and_sizes_in_hex,
+ show_print_offsets_and_sizes_in_hex,
+ &setprinttypelist, &showprinttypelist);
}
/* Print <not allocated> status to stream STREAM. */