gdb/
authorPedro Alves <palves@redhat.com>
Mon, 14 Feb 2011 11:25:59 +0000 (11:25 +0000)
committerPedro Alves <palves@redhat.com>
Mon, 14 Feb 2011 11:25:59 +0000 (11:25 +0000)
* value.h (unpack_bits_as_long): Delete declaration.
(unpack_value_bits_as_long): Declare.
(unpack_value_field_as_long): Declare.
(value_field_bitfield): Declare.
* value.c (unpack_bits_as_long): Rename to...
(unpack_value_bits_as_long_1): ... this.  Add embedded_offset and
value parameters.  Return the extracted result in a new output
parameter.  If the value contents are unavailable, return false,
otherwise return true.
(unpack_value_bits_as_long): New.
(unpack_field_as_long): Rename to...
(unpack_value_field_as_long_1): ... this.  Add embedded_offset and
Add embedded_offset and value parameters.  Return the extracted
result in a new output parameter. If the value contents are
unavailable, return false, otherwise return true.
(unpack_value_field_as_long): New.
(unpack_field_as_long_1): New.
(unpack_field_as_long): Reimplement as wrapper around
unpack_value_field_as_long_1.
(value_field_bitfield): New function.
* valops.c (value_fetch_lazy): When fetching a bitfield, use
unpack_value_bits_as_long.  Mark the value as unavailable, if it
is unavailable.
* jv-valprint.c (java_print_value_fields): Use
value_field_bitfield.
* p-valprint.c (pascal_object_print_value_fields): Use
value_field_bitfield.
* cp-valprint.c (cp_print_value_fields): Use value_field_bitfield.

gdb/ChangeLog
gdb/cp-valprint.c
gdb/jv-valprint.c
gdb/p-valprint.c
gdb/valops.c
gdb/value.c
gdb/value.h

index 106835a..e2ba5f5 100644 (file)
@@ -1,5 +1,36 @@
 2011-02-14  Pedro Alves  <pedro@codesourcery.com>
 
+       * value.h (unpack_bits_as_long): Delete declaration.
+       (unpack_value_bits_as_long): Declare.
+       (unpack_value_field_as_long): Declare.
+       (value_field_bitfield): Declare.
+       * value.c (unpack_bits_as_long): Rename to...
+       (unpack_value_bits_as_long_1): ... this.  Add embedded_offset and
+       value parameters.  Return the extracted result in a new output
+       parameter.  If the value contents are unavailable, return false,
+       otherwise return true.
+       (unpack_value_bits_as_long): New.
+       (unpack_field_as_long): Rename to...
+       (unpack_value_field_as_long_1): ... this.  Add embedded_offset and
+       Add embedded_offset and value parameters.  Return the extracted
+       result in a new output parameter. If the value contents are
+       unavailable, return false, otherwise return true.
+       (unpack_value_field_as_long): New.
+       (unpack_field_as_long_1): New.
+       (unpack_field_as_long): Reimplement as wrapper around
+       unpack_value_field_as_long_1.
+       (value_field_bitfield): New function.
+       * valops.c (value_fetch_lazy): When fetching a bitfield, use
+       unpack_value_bits_as_long.  Mark the value as unavailable, if it
+       is unavailable.
+       * jv-valprint.c (java_print_value_fields): Use
+       value_field_bitfield.
+       * p-valprint.c (pascal_object_print_value_fields): Use
+       value_field_bitfield.
+       * cp-valprint.c (cp_print_value_fields): Use value_field_bitfield.
+
+2011-02-14  Pedro Alves  <pedro@codesourcery.com>
+
        * value.c (get_internalvar_integer): Also return the int value of
        TYPE_CODE_INT INTERNALVAR_VALUE values.
        (set_internalvar): Don't special case TYPE_CODE_INT.
index fff41d8..1a171ea 100644 (file)
@@ -323,9 +323,8 @@ cp_print_value_fields (struct type *type, struct type *real_type,
                  struct value_print_options opts = *options;
 
                  opts.deref_ref = 0;
-                 v = value_from_longest
-                   (TYPE_FIELD_TYPE (type, i), 
-                    unpack_field_as_long (type, valaddr + offset, i));
+
+                 v = value_field_bitfield (type, i, valaddr, offset, val);
 
                  common_val_print (v, stream, recurse + 1, &opts,
                                    current_language);
index bed9b2f..f49b172 100644 (file)
@@ -416,9 +416,7 @@ java_print_value_fields (struct type *type, const gdb_byte *valaddr,
                {
                  struct value_print_options opts;
 
-                 v = value_from_longest
-                   (TYPE_FIELD_TYPE (type, i),
-                    unpack_field_as_long (type, valaddr + offset, i));
+                 v = value_field_bitfield (type, i, valaddr, offset, val);
 
                  opts = *options;
                  opts.deref_ref = 0;
index 8e79070..7031a77 100644 (file)
@@ -810,9 +810,7 @@ pascal_object_print_value_fields (struct type *type, const gdb_byte *valaddr,
                {
                  struct value_print_options opts = *options;
 
-                 v = value_from_longest (TYPE_FIELD_TYPE (type, i),
-                                  unpack_field_as_long (type,
-                                                        valaddr + offset, i));
+                 v = value_field_bitfield (type, i, valaddr, offset, val);
 
                  opts.deref_ref = 0;
                  common_val_print (v, stream, recurse + 1, &opts,
@@ -831,9 +829,7 @@ pascal_object_print_value_fields (struct type *type, const gdb_byte *valaddr,
                     v4.17 specific.  */
                  struct value *v;
 
-                 v = value_from_longest
-                   (TYPE_FIELD_TYPE (type, i),
-                    unpack_field_as_long (type, valaddr + offset, i));
+                 v = value_field_bitfield (type, i, valaddr, offset, val);
 
                  if (v == NULL)
                    val_print_optimized_out (stream);
index 7fa8729..802242c 100644 (file)
@@ -989,11 +989,7 @@ value_fetch_lazy (struct value *val)
       enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
       struct value *parent = value_parent (val);
       LONGEST offset = value_offset (val);
-      LONGEST num = unpack_bits_as_long (value_type (val),
-                                        (value_contents_for_printing (parent)
-                                         + offset),
-                                        value_bitpos (val),
-                                        value_bitsize (val));
+      LONGEST num;
       int length = TYPE_LENGTH (type);
 
       if (!value_bits_valid (val,
@@ -1001,7 +997,17 @@ value_fetch_lazy (struct value *val)
                             value_bitsize (val)))
        error (_("value has been optimized out"));
 
-      store_signed_integer (value_contents_raw (val), length, byte_order, num);
+      if (!unpack_value_bits_as_long (value_type (val),
+                                     value_contents_for_printing (parent),
+                                     offset,
+                                     value_bitpos (val),
+                                     value_bitsize (val), parent, &num))
+       mark_value_bytes_unavailable (val,
+                                     value_embedded_offset (val),
+                                     length);
+      else
+       store_signed_integer (value_contents_raw (val), length,
+                             byte_order, num);
     }
   else if (VALUE_LVAL (val) == lval_memory)
     {
index ee53914..a15315e 100644 (file)
@@ -2532,30 +2532,24 @@ value_fn_field (struct value **arg1p, struct fn_field *f,
 }
 
 \f
-/* Unpack a bitfield of the specified FIELD_TYPE, from the anonymous
-   object at VALADDR.  The bitfield starts at BITPOS bits and contains
-   BITSIZE bits.
 
-   Extracting bits depends on endianness of the machine.  Compute the
-   number of least significant bits to discard.  For big endian machines,
-   we compute the total number of bits in the anonymous object, subtract
-   off the bit count from the MSB of the object to the MSB of the
-   bitfield, then the size of the bitfield, which leaves the LSB discard
-   count.  For little endian machines, the discard count is simply the
-   number of bits from the LSB of the anonymous object to the LSB of the
-   bitfield.
+/* Helper function for both unpack_value_bits_as_long and
+   unpack_bits_as_long.  See those functions for more details on the
+   interface; the only difference is that this function accepts either
+   a NULL or a non-NULL ORIGINAL_VALUE.  */
 
-   If the field is signed, we also do sign extension.  */
-
-LONGEST
-unpack_bits_as_long (struct type *field_type, const gdb_byte *valaddr,
-                    int bitpos, int bitsize)
+static int
+unpack_value_bits_as_long_1 (struct type *field_type, const gdb_byte *valaddr,
+                            int embedded_offset, int bitpos, int bitsize,
+                            const struct value *original_value,
+                            LONGEST *result)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (field_type));
   ULONGEST val;
   ULONGEST valmask;
   int lsbcount;
   int bytes_read;
+  int read_offset;
 
   /* Read the minimum number of bytes required; there may not be
      enough bytes to read an entire ULONGEST.  */
@@ -2565,7 +2559,14 @@ unpack_bits_as_long (struct type *field_type, const gdb_byte *valaddr,
   else
     bytes_read = TYPE_LENGTH (field_type);
 
-  val = extract_unsigned_integer (valaddr + bitpos / 8,
+  read_offset = bitpos / 8;
+
+  if (original_value != NULL
+      && !value_bytes_available (original_value, embedded_offset + read_offset,
+                                bytes_read))
+    return 0;
+
+  val = extract_unsigned_integer (valaddr + embedded_offset + read_offset,
                                  bytes_read, byte_order);
 
   /* Extract bits.  See comment above.  */
@@ -2591,20 +2592,118 @@ unpack_bits_as_long (struct type *field_type, const gdb_byte *valaddr,
            }
        }
     }
-  return (val);
+
+  *result = val;
+  return 1;
 }
 
-/* Unpack a field FIELDNO of the specified TYPE, from the anonymous object at
-   VALADDR.  See unpack_bits_as_long for more details.  */
+/* Unpack a bitfield of the specified FIELD_TYPE, from the object at
+   VALADDR + EMBEDDED_OFFSET, and store the result in *RESULT.
+   VALADDR points to the contents of ORIGINAL_VALUE, which must not be
+   NULL.  The bitfield starts at BITPOS bits and contains BITSIZE
+   bits.
 
-LONGEST
-unpack_field_as_long (struct type *type, const gdb_byte *valaddr, int fieldno)
+   Returns false if the value contents are unavailable, otherwise
+   returns true, indicating a valid value has been stored in *RESULT.
+
+   Extracting bits depends on endianness of the machine.  Compute the
+   number of least significant bits to discard.  For big endian machines,
+   we compute the total number of bits in the anonymous object, subtract
+   off the bit count from the MSB of the object to the MSB of the
+   bitfield, then the size of the bitfield, which leaves the LSB discard
+   count.  For little endian machines, the discard count is simply the
+   number of bits from the LSB of the anonymous object to the LSB of the
+   bitfield.
+
+   If the field is signed, we also do sign extension.  */
+
+int
+unpack_value_bits_as_long (struct type *field_type, const gdb_byte *valaddr,
+                          int embedded_offset, int bitpos, int bitsize,
+                          const struct value *original_value,
+                          LONGEST *result)
+{
+  gdb_assert (original_value != NULL);
+
+  return unpack_value_bits_as_long_1 (field_type, valaddr, embedded_offset,
+                                     bitpos, bitsize, original_value, result);
+
+}
+
+/* Unpack a field FIELDNO of the specified TYPE, from the object at
+   VALADDR + EMBEDDED_OFFSET.  VALADDR points to the contents of
+   ORIGINAL_VALUE.  See unpack_value_bits_as_long for more
+   details.  */
+
+static int
+unpack_value_field_as_long_1 (struct type *type, const gdb_byte *valaddr,
+                             int embedded_offset, int fieldno,
+                             const struct value *val, LONGEST *result)
 {
   int bitpos = TYPE_FIELD_BITPOS (type, fieldno);
   int bitsize = TYPE_FIELD_BITSIZE (type, fieldno);
   struct type *field_type = TYPE_FIELD_TYPE (type, fieldno);
 
-  return unpack_bits_as_long (field_type, valaddr, bitpos, bitsize);
+  return unpack_value_bits_as_long_1 (field_type, valaddr, embedded_offset,
+                                     bitpos, bitsize, val,
+                                     result);
+}
+
+/* Unpack a field FIELDNO of the specified TYPE, from the object at
+   VALADDR + EMBEDDED_OFFSET.  VALADDR points to the contents of
+   ORIGINAL_VALUE, which must not be NULL.  See
+   unpack_value_bits_as_long for more details.  */
+
+int
+unpack_value_field_as_long (struct type *type, const gdb_byte *valaddr,
+                           int embedded_offset, int fieldno,
+                           const struct value *val, LONGEST *result)
+{
+  gdb_assert (val != NULL);
+
+  return unpack_value_field_as_long_1 (type, valaddr, embedded_offset,
+                                      fieldno, val, result);
+}
+
+/* Unpack a field FIELDNO of the specified TYPE, from the anonymous
+   object at VALADDR.  See unpack_value_bits_as_long for more details.
+   This function differs from unpack_value_field_as_long in that it
+   operates without a struct value object.  */
+
+LONGEST
+unpack_field_as_long (struct type *type, const gdb_byte *valaddr, int fieldno)
+{
+  LONGEST result;
+
+  unpack_value_field_as_long_1 (type, valaddr, 0, fieldno, NULL, &result);
+  return result;
+}
+
+/* Return a new value with type TYPE, which is FIELDNO field of the
+   object at VALADDR + EMBEDDEDOFFSET.  VALADDR points to the contents
+   of VAL.  If the VAL's contents required to extract the bitfield
+   from are unavailable, the new value is correspondingly marked as
+   unavailable.  */
+
+struct value *
+value_field_bitfield (struct type *type, int fieldno,
+                     const gdb_byte *valaddr,
+                     int embedded_offset, const struct value *val)
+{
+  LONGEST l;
+
+  if (!unpack_value_field_as_long (type, valaddr, embedded_offset, fieldno,
+                                  val, &l))
+    {
+      struct type *field_type = TYPE_FIELD_TYPE (type, fieldno);
+      struct value *retval = allocate_value (field_type);
+      mark_value_bytes_unavailable (retval, 0, TYPE_LENGTH (field_type));
+      return retval;
+    }
+  else
+    {
+      return value_from_longest (TYPE_FIELD_TYPE (type, fieldno), l);
+    }
 }
 
 /* Modify the value of a bitfield.  ADDR points to a block of memory in
index 0feb92f..5bd48e0 100644 (file)
@@ -430,11 +430,25 @@ extern LONGEST unpack_long (struct type *type, const gdb_byte *valaddr);
 extern DOUBLEST unpack_double (struct type *type, const gdb_byte *valaddr,
                               int *invp);
 extern CORE_ADDR unpack_pointer (struct type *type, const gdb_byte *valaddr);
-LONGEST unpack_bits_as_long (struct type *field_type, const gdb_byte *valaddr,
-                            int bitpos, int bitsize);
+
+extern int unpack_value_bits_as_long (struct type *field_type,
+                                     const gdb_byte *valaddr,
+                                     int embedded_offset, int bitpos,
+                                     int bitsize,
+                                     const struct value *original_value,
+                                     LONGEST *result);
+
 extern LONGEST unpack_field_as_long (struct type *type,
                                     const gdb_byte *valaddr,
                                     int fieldno);
+extern int unpack_value_field_as_long (struct type *type, const gdb_byte *valaddr,
+                               int embedded_offset, int fieldno,
+                               const struct value *val, LONGEST *result);
+
+extern struct value *value_field_bitfield (struct type *type, int fieldno,
+                                          const gdb_byte *valaddr,
+                                          int embedded_offset,
+                                          const struct value *val);
 
 extern void pack_long (gdb_byte *buf, struct type *type, LONGEST num);