aboutsummaryrefslogtreecommitdiff
path: root/gdb/valprint.c
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2017-05-22 16:32:25 -0600
committerTom Tromey <tom@tromey.com>2017-06-12 15:04:57 -0600
commit4ac0cb1cf04f105586746a6cce5b0f93d76f2b33 (patch)
tree3fb05b0178669f51b7f69bcfc45eddcf43e686ea /gdb/valprint.c
parent30a254669b16b86166fed1f9a4c4f9cc55a07fdc (diff)
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.c56
1 files changed, 55 insertions, 1 deletions
diff --git a/gdb/valprint.c b/gdb/valprint.c
index aa34b68c83..2420fb5c96 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. */