From: Tom Tromey Date: Mon, 22 May 2017 22:32:25 +0000 (-0600) Subject: Let print_decimal_chars handle signed values X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4ac0cb1cf04f105586746a6cce5b0f93d76f2b33;p=binutils-gdb.git Let print_decimal_chars handle signed values This changes print_decimal_chars to handle signed values. gdb/ChangeLog 2017-06-12 Tom Tromey PR exp/16225: * valprint.h (print_decimal_chars): Update. * valprint.c (maybe_negate_by_bytes): New function. (print_decimal_chars): Add "is_signed" argument. * printcmd.c (print_scalar_formatted): Update. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 16b5a3a8c39..07ba5f22f80 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2017-06-12 Tom Tromey + + PR exp/16225: + * valprint.h (print_decimal_chars): Update. + * valprint.c (maybe_negate_by_bytes): New function. + (print_decimal_chars): Add "is_signed" argument. + * printcmd.c (print_scalar_formatted): Update. + 2017-06-12 Tom Tromey PR exp/16225: diff --git a/gdb/printcmd.c b/gdb/printcmd.c index 66395d594e3..84f41f5b747 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -374,7 +374,8 @@ print_scalar_formatted (const gdb_byte *valaddr, struct type *type, return; case 'u': case 'd': - print_decimal_chars (stream, valaddr, len, byte_order); + print_decimal_chars (stream, valaddr, len, !TYPE_UNSIGNED (type), + byte_order); return; case 't': print_binary_chars (stream, valaddr, len, byte_order, size > 0); diff --git a/gdb/valprint.c b/gdb/valprint.c index aa34b68c833..2420fb5c96c 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -1763,12 +1763,58 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr, } +/* Possibly negate the integer represented by BYTES. It contains LEN + bytes in the specified byte order. If the integer is negative, + copy it into OUT_VEC, negate it, and return true. Otherwise, do + nothing and return false. */ + +static bool +maybe_negate_by_bytes (const gdb_byte *bytes, unsigned len, + enum bfd_endian byte_order, + std::vector *out_vec) +{ + gdb_byte sign_byte; + if (byte_order == BFD_ENDIAN_BIG) + sign_byte = bytes[0]; + else + sign_byte = bytes[len - 1]; + if ((sign_byte & 0x80) == 0) + return false; + + out_vec->resize (len); + + /* Compute -x == 1 + ~x. */ + if (byte_order == BFD_ENDIAN_LITTLE) + { + unsigned carry = 1; + for (unsigned i = 0; i < len; ++i) + { + unsigned tem = (0xff & ~bytes[i]) + carry; + (*out_vec)[i] = tem & 0xff; + carry = tem / 256; + } + } + else + { + unsigned carry = 1; + for (unsigned i = len; i > 0; --i) + { + unsigned tem = (0xff & ~bytes[i - 1]) + carry; + (*out_vec)[i - 1] = tem & 0xff; + carry = tem / 256; + } + } + + return true; +} + /* VALADDR points to an integer of LEN bytes. Print it in decimal on stream or format it in buf. */ void print_decimal_chars (struct ui_file *stream, const gdb_byte *valaddr, - unsigned len, enum bfd_endian byte_order) + unsigned len, bool is_signed, + enum bfd_endian byte_order) { #define TEN 10 #define CARRY_OUT( x ) ((x) / TEN) /* extend char to int */ @@ -1784,6 +1830,14 @@ print_decimal_chars (struct ui_file *stream, const gdb_byte *valaddr, int dummy; int flip; + std::vector negated_bytes; + if (is_signed + && maybe_negate_by_bytes (valaddr, len, byte_order, &negated_bytes)) + { + fputs_filtered ("-", stream); + valaddr = negated_bytes.data (); + } + /* Base-ten number is less than twice as many digits as the base 16 number, which is 2 digits per byte. */ diff --git a/gdb/valprint.h b/gdb/valprint.h index 8bfad21790e..f71d4ab9eab 100644 --- a/gdb/valprint.h +++ b/gdb/valprint.h @@ -138,7 +138,7 @@ extern void print_octal_chars (struct ui_file *, const gdb_byte *, unsigned int, enum bfd_endian); extern void print_decimal_chars (struct ui_file *, const gdb_byte *, - unsigned int, enum bfd_endian); + unsigned int, bool, enum bfd_endian); extern void print_hex_chars (struct ui_file *, const gdb_byte *, unsigned int, enum bfd_endian, bool);