This is the mail archive of the gdb-cvs@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]

[binutils-gdb] [Ada] split data unpacking code out of ada_value_primitive_packed_val.


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=f93fca700f0fd70532132ae535f48c1a936abb0a

commit f93fca700f0fd70532132ae535f48c1a936abb0a
Author: Joel Brobecker <brobecker@adacore.com>
Date:   Fri Oct 9 14:12:51 2015 -0700

    [Ada] split data unpacking code out of ada_value_primitive_packed_val.
    
    This patch is just preparation work which splits the function
    ada_value_primitive_packed_val into two function: one which unpacks
    the data, and the other which now uses it to implement
    ada_value_primitive_packed_val.
    
    This simplifies a bit ada_value_primitive_packed_val, but will also
    allow us to use the new function to unpack data without actually creating
    a struct value as a result.
    
    gdb/ChangeLog:
    
            * ada-lang.c (ada_unpack_from_contents): New function,
            extracted from ada_value_primitive_packed_val.
            (ada_value_primitive_packed_val): Replace extracted out code
            by call to ada_unpack_from_contents.

Diff:
---
 gdb/ChangeLog  |   7 ++
 gdb/ada-lang.c | 217 +++++++++++++++++++++++++++++++++------------------------
 2 files changed, 133 insertions(+), 91 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 968992e..a511592 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,12 @@
 2015-10-09  Joel Brobecker  <brobecker@adacore.com>
 
+	* ada-lang.c (ada_unpack_from_contents): New function,
+	extracted from ada_value_primitive_packed_val.
+	(ada_value_primitive_packed_val): Replace extracted out code
+	by call to ada_unpack_from_contents.
+
+2015-10-09  Joel Brobecker  <brobecker@adacore.com>
+
 	* ada-lang.c (ada_value_primitive_packed_val): Reorder local
 	variable declarations.
 
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 1dbbb07..6947d76 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -2382,24 +2382,23 @@ has_negatives (struct type *type)
     }
 }
 
+/* With SRC being a buffer containing BIT_SIZE bits of data at BIT_OFFSET,
+   unpack that data into UNPACKED. UNPACKED_LEN is the size in bytes of
+   the unpacked buffer.
 
-/* Create a new value of type TYPE from the contents of OBJ starting
-   at byte OFFSET, and bit offset BIT_OFFSET within that byte,
-   proceeding for BIT_SIZE bits.  If OBJ is an lval in memory, then
-   assigning through the result will set the field fetched from.
-   VALADDR is ignored unless OBJ is NULL, in which case,
-   VALADDR+OFFSET must address the start of storage containing the 
-   packed value.  The value returned  in this case is never an lval.
-   Assumes 0 <= BIT_OFFSET < HOST_CHAR_BIT.  */
+   IS_BIG_ENDIAN is nonzero if the data is stored in big endian mode,
+   zero otherwise.
 
-struct value *
-ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr,
-				long offset, int bit_offset, int bit_size,
-                                struct type *type)
-{
-  struct value *v;
+   IS_SIGNED_TYPE is nonzero if the data corresponds to a signed type.
 
-  gdb_byte *src;                /* First byte containing data to unpack */
+   IS_SCALAR is nonzero if the data corresponds to a signed type.  */
+
+static void
+ada_unpack_from_contents (const gdb_byte *src, int bit_offset, int bit_size,
+			  gdb_byte *unpacked, int unpacked_len,
+			  int is_big_endian, int is_signed_type,
+			  int is_scalar)
+{
   int src_len = (bit_size + bit_offset + HOST_CHAR_BIT - 1) / 8;
   int src_idx;                  /* Index into the source area */
   int src_bytes_left;           /* Number of source bytes left to process.  */
@@ -2407,7 +2406,6 @@ ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr,
   int unusedLS;                 /* Number of bits in next significant
                                    byte of source that are unused */
 
-  gdb_byte *unpacked;
   int unpacked_idx;             /* Index into the unpacked buffer */
   int unpacked_bytes_left;      /* Number of bytes left to set in unpacked.  */
 
@@ -2417,86 +2415,31 @@ ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr,
 
   /* Transmit bytes from least to most significant; delta is the direction
      the indices move.  */
-  int delta = gdbarch_bits_big_endian (get_type_arch (type)) ? -1 : 1;
-
-  type = ada_check_typedef (type);
-
-  if (obj == NULL)
-    {
-      v = allocate_value (type);
-      src = (gdb_byte *) valaddr + offset;
-    }
-  else if (VALUE_LVAL (obj) == lval_memory && value_lazy (obj))
-    {
-      v = value_at (type, value_address (obj) + offset);
-      type = value_type (v);
-      if (TYPE_LENGTH (type) * HOST_CHAR_BIT < bit_size)
-	{
-	  /* This can happen in the case of an array of dynamic objects,
-	     where the size of each element changes from element to element.
-	     In that case, we're initially given the array stride, but
-	     after resolving the element type, we find that its size is
-	     less than this stride.  In that case, adjust bit_size to
-	     match TYPE's length, and recompute LEN accordingly.  */
-	  bit_size = TYPE_LENGTH (type) * HOST_CHAR_BIT;
-	  src_len = TYPE_LENGTH (type) + (bit_offset + HOST_CHAR_BIT - 1) / 8;
-	}
-      src = alloca (src_len);
-      read_memory (value_address (v), src, src_len);
-    }
-  else
-    {
-      v = allocate_value (type);
-      src = (gdb_byte *) value_contents (obj) + offset;
-    }
-
-  if (obj != NULL)
-    {
-      long new_offset = offset;
-
-      set_value_component_location (v, obj);
-      set_value_bitpos (v, bit_offset + value_bitpos (obj));
-      set_value_bitsize (v, bit_size);
-      if (value_bitpos (v) >= HOST_CHAR_BIT)
-        {
-	  ++new_offset;
-          set_value_bitpos (v, value_bitpos (v) - HOST_CHAR_BIT);
-        }
-      set_value_offset (v, new_offset);
-
-      /* Also set the parent value.  This is needed when trying to
-	 assign a new value (in inferior memory).  */
-      set_value_parent (v, obj);
-    }
-  else
-    set_value_bitsize (v, bit_size);
-  unpacked = (gdb_byte *) value_contents (v);
+  int delta = is_big_endian ? -1 : 1;
 
   srcBitsLeft = bit_size;
   src_bytes_left = src_len;
-  unpacked_bytes_left = TYPE_LENGTH (type);
+  unpacked_bytes_left = unpacked_len;
   sign = 0;
-  if (bit_size == 0)
-    {
-      memset (unpacked, 0, TYPE_LENGTH (type));
-      return v;
-    }
-  else if (gdbarch_bits_big_endian (get_type_arch (type)))
+
+  if (is_big_endian)
     {
       src_idx = src_len - 1;
-      if (has_negatives (type)
-          && ((src[0] << bit_offset) & (1 << (HOST_CHAR_BIT - 1))))
+      if (is_signed_type
+	  && ((src[0] << bit_offset) & (1 << (HOST_CHAR_BIT - 1))))
         sign = ~0;
 
       unusedLS =
         (HOST_CHAR_BIT - (bit_size + bit_offset) % HOST_CHAR_BIT)
         % HOST_CHAR_BIT;
 
-      switch (TYPE_CODE (type))
-        {
-        case TYPE_CODE_ARRAY:
-        case TYPE_CODE_UNION:
-        case TYPE_CODE_STRUCT:
+      if (is_scalar)
+	{
+          accumSize = 0;
+          unpacked_idx = unpacked_len - 1;
+	}
+      else
+	{
           /* Non-scalar values must be aligned at a byte boundary...  */
           accumSize =
             (HOST_CHAR_BIT - bit_size % HOST_CHAR_BIT) % HOST_CHAR_BIT;
@@ -2504,12 +2447,7 @@ ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr,
              of the target.  */
           unpacked_idx = (bit_size + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT - 1;
           unpacked_bytes_left = unpacked_idx + 1;
-          break;
-        default:
-          accumSize = 0;
-          unpacked_idx = TYPE_LENGTH (type) - 1;
-          break;
-        }
+	}
     }
   else
     {
@@ -2519,7 +2457,7 @@ ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr,
       unusedLS = bit_offset;
       accumSize = 0;
 
-      if (has_negatives (type) && (src[src_len - 1] & (1 << sign_bit_offset)))
+      if (is_signed_type && (src[src_len - 1] & (1 << sign_bit_offset)))
         sign = ~0;
     }
 
@@ -2561,6 +2499,103 @@ ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr,
       unpacked_bytes_left -= 1;
       unpacked_idx += delta;
     }
+}
+
+/* Create a new value of type TYPE from the contents of OBJ starting
+   at byte OFFSET, and bit offset BIT_OFFSET within that byte,
+   proceeding for BIT_SIZE bits.  If OBJ is an lval in memory, then
+   assigning through the result will set the field fetched from.
+   VALADDR is ignored unless OBJ is NULL, in which case,
+   VALADDR+OFFSET must address the start of storage containing the 
+   packed value.  The value returned  in this case is never an lval.
+   Assumes 0 <= BIT_OFFSET < HOST_CHAR_BIT.  */
+
+struct value *
+ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr,
+				long offset, int bit_offset, int bit_size,
+                                struct type *type)
+{
+  struct value *v;
+  gdb_byte *src;                /* First byte containing data to unpack */
+  int src_len = (bit_size + bit_offset + HOST_CHAR_BIT - 1) / 8;
+  gdb_byte *unpacked;
+  int is_scalar;
+
+  type = ada_check_typedef (type);
+
+  if (obj == NULL)
+    {
+      v = allocate_value (type);
+      src = (gdb_byte *) valaddr + offset;
+    }
+  else if (VALUE_LVAL (obj) == lval_memory && value_lazy (obj))
+    {
+      v = value_at (type, value_address (obj) + offset);
+      type = value_type (v);
+      if (TYPE_LENGTH (type) * HOST_CHAR_BIT < bit_size)
+	{
+	  /* This can happen in the case of an array of dynamic objects,
+	     where the size of each element changes from element to element.
+	     In that case, we're initially given the array stride, but
+	     after resolving the element type, we find that its size is
+	     less than this stride.  In that case, adjust bit_size to
+	     match TYPE's length, and recompute LEN accordingly.  */
+	  bit_size = TYPE_LENGTH (type) * HOST_CHAR_BIT;
+	  src_len = TYPE_LENGTH (type) + (bit_offset + HOST_CHAR_BIT - 1) / 8;
+	}
+      src = alloca (src_len);
+      read_memory (value_address (v), src, src_len);
+    }
+  else
+    {
+      v = allocate_value (type);
+      src = (gdb_byte *) value_contents (obj) + offset;
+    }
+
+  if (obj != NULL)
+    {
+      long new_offset = offset;
+
+      set_value_component_location (v, obj);
+      set_value_bitpos (v, bit_offset + value_bitpos (obj));
+      set_value_bitsize (v, bit_size);
+      if (value_bitpos (v) >= HOST_CHAR_BIT)
+        {
+	  ++new_offset;
+          set_value_bitpos (v, value_bitpos (v) - HOST_CHAR_BIT);
+        }
+      set_value_offset (v, new_offset);
+
+      /* Also set the parent value.  This is needed when trying to
+	 assign a new value (in inferior memory).  */
+      set_value_parent (v, obj);
+    }
+  else
+    set_value_bitsize (v, bit_size);
+  unpacked = (gdb_byte *) value_contents (v);
+
+  if (bit_size == 0)
+    {
+      memset (unpacked, 0, TYPE_LENGTH (type));
+      return v;
+    }
+
+  switch (TYPE_CODE (type))
+    {
+    case TYPE_CODE_ARRAY:
+    case TYPE_CODE_UNION:
+    case TYPE_CODE_STRUCT:
+      is_scalar = 0;
+      break;
+    default:
+      is_scalar = 1;
+      break;
+    }
+
+  ada_unpack_from_contents (src, bit_offset, bit_size,
+			    unpacked, TYPE_LENGTH (type),
+			    gdbarch_bits_big_endian (get_type_arch (type)),
+			    has_negatives (type), is_scalar);
 
   if (is_dynamic_type (value_type (v)))
     v = value_from_contents_and_address (value_type (v), value_contents (v),


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