This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA 2/5] Let print_decimal_chars handle signed values


This changes print_decimal_chars to handle signed values.

gdb/ChangeLog
2017-06-02  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.
---
 gdb/ChangeLog  |  8 ++++++++
 gdb/printcmd.c |  3 ++-
 gdb/valprint.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 gdb/valprint.h |  2 +-
 4 files changed, 66 insertions(+), 3 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index bc2ac04..a529694 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,6 +1,14 @@
 2017-06-02  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.
+
+2017-06-02  Tom Tromey  <tom@tromey.com>
+
+	PR exp/16225:
 	* valprint.h (print_binary_chars, print_hex_chars): Update.
 	* valprint.c (val_print_type_code_int): Update.
 	(print_binary_chars): Add "zero_pad" argument.
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 66395d5..84f41f5 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 aa34b68..fcd74f1 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->reserve (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.  */
 
diff --git a/gdb/valprint.h b/gdb/valprint.h
index 8bfad21..f71d4ab 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);
-- 
2.9.3


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]