[pushed] gdb: Support printf 'z' size modifier

Sourceware to Gerrit sync (Code Review)
2019-11-12T23:53:26Z

The original change was created by Andrew Burgess.

Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/511
......................................................................

gdb: Support printf 'z' size modifier

The gdb format mechanism doesn't currently support the 'z' size
modifier, there are a few places in GDB where this is used. Instead
of removing these uses lets just add support to GDB for using 'z'.

I found this issue when trying to use some of the debug output.
Before this commit:

(gdb) set debug dwarf-line 9
(gdb) file test
Reading symbols from test...
Unrecognized format specifier 'z' in printf
(No debugging symbols found in test)
(gdb)

After this commit:

(gdb) set debug dwarf-line 9
(gdb) file test
Reading symbols from test...
Adding dir 1: /usr/include
Adding file 1: test.c
Adding file 2: stdc-predef.h
Processing actual line 3: file 1, address 0x4004a0, is_stmt 1, discrim 0
Processing actual line 4: file 1, address 0x4004a0, is_stmt 1, discrim 0
.... lots of debug output ...
Processing actual line 10: file 1, address 0x4003b7, is_stmt 0, discrim 0
(gdb)

I've added a self test to cover the integer format size modifiers,
including the 'z' modifier.

gdb/ChangeLog:

* gdbsupport/format.c (format_pieces::format_pieces): Support
printf 'z' size modifier.
* gdbsupport/format.h (enum argclass): Add size_t_arg.
* printcmd.c (ui_printf): Handle size_t_arg.
* ui-out.c (ui_out::vmessage): Likewise.
* unittests/format_pieces-selftests.c (test_format_int_sizes): New
function.
(run_tests): Call test_format_int_sizes.

gdb/gdbserver/ChangeLog:

* ax.c (ax_printf): Handle size_t_arg.

Change-Id: Ib6c44d88aa5bce265d757e4c0698881803dd186f
---
M gdb/ChangeLog
M gdb/gdbserver/ChangeLog
M gdb/gdbserver/ax.c
M gdb/gdbsupport/format.c
M gdb/gdbsupport/format.h
M gdb/printcmd.c
M gdb/ui-out.c
M gdb/unittests/format_pieces-selftests.c
8 files changed, 106 insertions(+), 2 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 44ace04..4f40ea8 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,14 @@
+2019-11-12 Andrew Burgess <andrew.burgess@embecosm.com>
+
+ * gdbsupport/format.c (format_pieces::format_pieces): Support
+ printf 'z' size modifier.
+ * gdbsupport/format.h (enum argclass): Add size_t_arg.
+ * printcmd.c (ui_printf): Handle size_t_arg.
+ * ui-out.c (ui_out::vmessage): Likewise.
+ * unittests/format_pieces-selftests.c (test_format_int_sizes): New
+ function.
+ (run_tests): Call test_format_int_sizes.
+
2019-11-12 Christian Biesinger <cbiesinger@google.com>

* ada-exp.y (write_ambiguous_var): Update.
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index 9d0afaa..e17a7ca 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,7 @@
+2019-11-12 Andrew Burgess <andrew.burgess@embecosm.com>
+
+ * ax.c (ax_printf): Handle size_t_arg.
+
2019-11-06 Christian Biesinger <cbiesinger@google.com>

* linux-tdep.c (linux_info_proc): Use strtok_r instead of strtok.
diff --git a/gdb/gdbserver/ax.c b/gdb/gdbserver/ax.c
index 2c096ef..21fde5e 100644
--- a/gdb/gdbserver/ax.c
+++ b/gdb/gdbserver/ax.c
@@ -904,6 +904,14 @@
break;
}

+ case size_t_arg:
+ {
+ size_t val = args[i];
+
+ printf (current_substring, val);
+ break;
+ }
+
case literal_piece:
/* Print a portion of the format string that has no
directives. Note that this will not include any
diff --git a/gdb/gdbsupport/format.c b/gdb/gdbsupport/format.c
index 1e80350..2e2d90a 100644
--- a/gdb/gdbsupport/format.c
+++ b/gdb/gdbsupport/format.c
@@ -123,6 +123,7 @@
int seen_space = 0, seen_plus = 0;
int seen_big_l = 0, seen_h = 0, seen_big_h = 0;
int seen_big_d = 0, seen_double_big_d = 0;
+ int seen_size_t = 0;
int bad = 0;
int n_int_args = 0;

@@ -234,6 +235,12 @@
else
seen_big_d = 1;
}
+ /* For size_t or ssize_t. */
+ else if (*f == 'z')
+ {
+ seen_size_t = 1;
+ f++;
+ }

switch (*f)
{
@@ -251,7 +258,9 @@

case 'd':
case 'i':
- if (lcount == 0)
+ if (seen_size_t)
+ this_argclass = size_t_arg;
+ else if (lcount == 0)
this_argclass = int_arg;
else if (lcount == 1)
this_argclass = long_arg;
diff --git a/gdb/gdbsupport/format.h b/gdb/gdbsupport/format.h
index e2a47ba..07374db 100644
--- a/gdb/gdbsupport/format.h
+++ b/gdb/gdbsupport/format.h
@@ -38,7 +38,7 @@
enum argclass
{
literal_piece,
- int_arg, long_arg, long_long_arg, ptr_arg,
+ int_arg, long_arg, long_long_arg, size_t_arg, ptr_arg,
string_arg, wide_string_arg, wide_char_arg,
double_arg, long_double_arg,
dec32float_arg, dec64float_arg, dec128float_arg
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 27aaf7a..323a5d0 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -2663,6 +2663,16 @@
DIAGNOSTIC_POP
break;
}
+ case size_t_arg:
+ {
+ size_t val = value_as_long (val_args[i]);
+
+ DIAGNOSTIC_PUSH
+ DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL
+ fprintf_filtered (stream, current_substring, val);
+ DIAGNOSTIC_POP
+ break;
+ }
/* Handles floating-point values. */
case double_arg:
case long_double_arg:
diff --git a/gdb/ui-out.c b/gdb/ui-out.c
index 6b0b5ac..80845f4 100644
--- a/gdb/ui-out.c
+++ b/gdb/ui-out.c
@@ -688,6 +688,24 @@
}
}
break;
+ case size_t_arg:
+ {
+ size_t val = va_arg (args, size_t);
+ switch (piece.n_int_args)
+ {
+ case 0:
+ call_do_message (style, current_substring, val);
+ break;
+ case 1:
+ call_do_message (style, current_substring, intvals[0], val);
+ break;
+ case 2:
+ call_do_message (style, current_substring,
+ intvals[0], intvals[1], val);
+ break;
+ }
+ }
+ break;
case double_arg:
call_do_message (style, current_substring, va_arg (args, double));
break;
diff --git a/gdb/unittests/format_pieces-selftests.c b/gdb/unittests/format_pieces-selftests.c
index ed83d96..3971201 100644
--- a/gdb/unittests/format_pieces-selftests.c
+++ b/gdb/unittests/format_pieces-selftests.c
@@ -76,12 +76,56 @@
}, true);
}

+/* Test the different size modifiers that can be applied to an integer
+ argument. Test with different integer format specifiers too. */
+
+static void
+test_format_int_sizes ()
+{
+ check ("Hello\\t %hu%lu%llu%zu", /* ARI: %ll */
+ {
+ format_piece ("Hello\t ", literal_piece, 0),
+ format_piece ("%hu", int_arg, 0),
+ format_piece ("%lu", long_arg, 0),
+ format_piece ("%llu", long_long_arg, 0), /* ARI: %ll */
+ format_piece ("%zu", size_t_arg, 0)
+ });
+
+ check ("Hello\\t %hx%lx%llx%zx", /* ARI: %ll */
+ {
+ format_piece ("Hello\t ", literal_piece, 0),
+ format_piece ("%hx", int_arg, 0),
+ format_piece ("%lx", long_arg, 0),
+ format_piece ("%llx", long_long_arg, 0), /* ARI: %ll */
+ format_piece ("%zx", size_t_arg, 0)
+ });
+
+ check ("Hello\\t %ho%lo%llo%zo", /* ARI: %ll */
+ {
+ format_piece ("Hello\t ", literal_piece, 0),
+ format_piece ("%ho", int_arg, 0),
+ format_piece ("%lo", long_arg, 0),
+ format_piece ("%llo", long_long_arg, 0), /* ARI: %ll */
+ format_piece ("%zo", size_t_arg, 0)
+ });
+
+ check ("Hello\\t %hd%ld%lld%zd", /* ARI: %ll */
+ {
+ format_piece ("Hello\t ", literal_piece, 0),
+ format_piece ("%hd", int_arg, 0),
+ format_piece ("%ld", long_arg, 0),
+ format_piece ("%lld", long_long_arg, 0), /* ARI: %ll */
+ format_piece ("%zd", size_t_arg, 0)
+ });
+}
+
static void
run_tests ()
{
test_escape_sequences ();
test_format_specifier ();
test_gdb_formats ();
+ test_format_int_sizes ();
}

} /* namespace format_pieces */

--
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: Ib6c44d88aa5bce265d757e4c0698881803dd186f
Gerrit-Change-Number: 511
Gerrit-PatchSet: 3
Gerrit-Owner: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-Reviewer: Andrew Burgess <andrew.burgess@embecosm.com>
Gerrit-Reviewer: Kevin Buettner <kevinb@redhat.com>
Gerrit-CC: Joel Brobecker <brobecker@adacore.com>
Gerrit-CC: Pedro Alves <palves@redhat.com>
Gerrit-CC: Simon Marchi <simon.marchi@polymtl.ca>
Gerrit-CC: Tom Tromey <tromey@sourceware.org>
Gerrit-MessageType: newpatchset