diff options
author | Tom Tromey <tom@tromey.com> | 2017-05-22 16:32:25 -0600 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2017-06-12 15:04:57 -0600 |
commit | 4ac0cb1cf04f105586746a6cce5b0f93d76f2b33 (patch) | |
tree | 3fb05b0178669f51b7f69bcfc45eddcf43e686ea /gdb/valprint.c | |
parent | 30a254669b16b86166fed1f9a4c4f9cc55a07fdc (diff) | |
download | gdb-4ac0cb1cf04f105586746a6cce5b0f93d76f2b33.zip gdb-4ac0cb1cf04f105586746a6cce5b0f93d76f2b33.tar.gz gdb-4ac0cb1cf04f105586746a6cce5b0f93d76f2b33.tar.bz2 |
Let print_decimal_chars handle signed values
This changes print_decimal_chars to handle signed values.
gdb/ChangeLog
2017-06-12 Tom Tromey <tom@tromey.com>
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.
Diffstat (limited to 'gdb/valprint.c')
-rw-r--r-- | gdb/valprint.c | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/gdb/valprint.c b/gdb/valprint.c index aa34b68..2420fb5 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<gdb_byte> *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<gdb_byte> 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. */ |