gdb/
authorPedro Alves <palves@redhat.com>
Mon, 14 Feb 2011 11:30:37 +0000 (11:30 +0000)
committerPedro Alves <palves@redhat.com>
Mon, 14 Feb 2011 11:30:37 +0000 (11:30 +0000)
* value.h (value_contents_copy, value_contents_copy_raw): Declare.
* value.c (value_contents_copy_raw, value_contents_copy): New
functions.
(value_primitive_field): Use value_contents_copy_raw instead of
memcpy.
* valops.c (value_fetch_lazy): Use value_contents_copy instead of
memcpy.
(value_array, value_slice): Ditto.
* valarith.c (value_subscripted_rvalue): Use
value_contents_copy_raw instead of memcpy.

gdb/testsuite/
* gdb.trace/unavailable.exp (gdb_collect_globals_test): Add new
tests for building arrays from unavailable values, subscripting
non-memory rvalue unvailable arrays, and accessing fields or
baseclasses of non-lazy unavailable values,
* gdb.trace/unavailable.cc (small_struct, small_struct_b): New
struct types.
(g_smallstruct, g_smallstruct_b): New globals.

gdb/ChangeLog
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.trace/unavailable.cc
gdb/testsuite/gdb.trace/unavailable.exp
gdb/valarith.c
gdb/valops.c
gdb/value.c
gdb/value.h

index b77cdf22b040a5e05c6cd1a7846d3c2b4a7290f3..6cbfdf835552cc05163bfad500177b0b38fc576a 100644 (file)
@@ -1,3 +1,16 @@
+2011-02-14  Pedro Alves  <pedro@codesourcery.com>
+
+       * value.h (value_contents_copy, value_contents_copy_raw): Declare.
+       * value.c (value_contents_copy_raw, value_contents_copy): New
+       functions.
+       (value_primitive_field): Use value_contents_copy_raw instead of
+       memcpy.
+       * valops.c (value_fetch_lazy): Use value_contents_copy instead of
+       memcpy.
+       (value_array, value_slice): Ditto.
+       * valarith.c (value_subscripted_rvalue): Use
+       value_contents_copy_raw instead of memcpy.
+
 2011-02-14  Pedro Alves  <pedro@codesourcery.com>
 
        <unavailable> references.
index d5ea01a27d8d825f4a63091cc5133a44a2bfcfe8..95ad1951c096f7548bf7483eae6201122fb506b5 100644 (file)
@@ -1,3 +1,13 @@
+2011-02-14  Pedro Alves  <pedro@codesourcery.com>
+
+       * gdb.trace/unavailable.exp (gdb_collect_globals_test): Add new
+       tests for building arrays from unavailable values, subscripting
+       non-memory rvalue unvailable arrays, and accessing fields or
+       baseclasses of non-lazy unavailable values,
+       * gdb.trace/unavailable.cc (small_struct, small_struct_b): New
+       struct types.
+       (g_smallstruct, g_smallstruct_b): New globals.
+
 2011-02-14  Pedro Alves  <pedro@codesourcery.com>
 
        * gdb.trace/unavailable.cc, gdb.trace/unavailable.exp: New files.
index 23c709b030cb5a724778b06140d6596a42859091..d25837df217e0b7fdc50d10b72d74406a6af48a7 100644 (file)
@@ -30,6 +30,15 @@ typedef struct TEST_STRUCT {
   double memberd;
 } test_struct;
 
+struct small_struct
+{
+  int member;
+};
+
+struct small_struct_b : public small_struct
+{
+};
+
 typedef int test_array [4];
 
 /* Global variables to be collected.  */
@@ -41,6 +50,8 @@ double       globald;
 test_struct  globalstruct;
 test_struct *globalp;
 int          globalarr[16];
+small_struct g_smallstruct;
+small_struct_b g_smallstruct_b;
 
 /* Strings.  */
 
index f77d96e0c7c3341d77c5c6b3c59d50347d0ce1c5..00fb332e43b432e43415ed40d428306381ff8047 100644 (file)
@@ -214,6 +214,31 @@ proc gdb_collect_globals_test { } {
 
     gdb_test "p \$__" " = <unavailable>" "last examined value was <unavailable>"
 
+    # This tests that building the array does not require accessing
+    # g_int's contents.
+    gdb_test "print { 1, g_int, 3 }" \
+       " = \\{1, <unavailable>, 3\\}" \
+       "build array from unavailable value"
+
+    # Note, depends on previous test.
+    gdb_test "print \$\[1\]" \
+       " = <unavailable>" \
+       "subscript a non-memory rvalue array, accessing an unvailable element"
+
+    # Access a field of a non-lazy value, making sure the
+    # unavailable-ness is propagated.  History values are easy
+    # non-lazy values, so use those.  The first test just sets up for
+    # the second.
+    gdb_test "print g_smallstruct" " = \\{member = <unavailable>\\}"
+    gdb_test "print \$.member" " = <unavailable>"
+
+    # Cast to baseclass, checking the unavailable-ness is propagated.
+    gdb_test "print (small_struct) g_smallstruct_b" " = \\{member = <unavailable>\\}"
+
+    # Same cast, but starting from a non-lazy, value.
+    gdb_test "print g_smallstruct_b" " = \\{<small_struct> = \\{member = <unavailable>\\}, <No data fields>\\}"
+    gdb_test "print (small_struct) \$" " = \\{member = <unavailable>\\}"
+
     gdb_test "tfind none" \
        "#0  end .*" \
        "cease trace debugging"
index 265532cd4f611fb00c32ac5a3ad34b82fc470a6e..787fc69390c7753dd7503203ee1b2232cc31c5d9 100644 (file)
@@ -210,8 +210,9 @@ value_subscripted_rvalue (struct value *array, LONGEST index, int lowerbound)
   else
     {
       v = allocate_value (elt_type);
-      memcpy (value_contents_writeable (v),
-             value_contents (array) + elt_offs, elt_size);
+      value_contents_copy (v, value_embedded_offset (v),
+                          array, value_embedded_offset (array) + elt_offs,
+                          elt_size);
     }
 
   set_value_component_location (v, array);
index ab31976041c6e54660cfb290da1c0197e39c266f..1c37fae46a9588e186487750a8c3a683075ad7d8 100644 (file)
@@ -1044,12 +1044,16 @@ value_fetch_lazy (struct value *val)
       if (value_lazy (new_val))
        value_fetch_lazy (new_val);
 
-      /* If the register was not saved, mark it unavailable.  */
+      /* If the register was not saved, mark it optimized out.  */
       if (value_optimized_out (new_val))
        set_value_optimized_out (val, 1);
       else
-       memcpy (value_contents_raw (val), value_contents (new_val),
-               TYPE_LENGTH (type));
+       {
+         set_value_lazy (val, 0);
+         value_contents_copy (val, value_embedded_offset (val),
+                              new_val, value_embedded_offset (new_val),
+                              TYPE_LENGTH (type));
+       }
 
       if (frame_debug)
        {
@@ -1765,9 +1769,8 @@ value_ind (struct value *arg1)
   return 0;                    /* For lint -- never reached.  */
 }
 \f
-/* Create a value for an array by allocating space in GDB, copying
-   copying the data into that space, and then setting up an array
-   value.
+/* Create a value for an array by allocating space in GDB, copying the
+   data into that space, and then setting up an array value.
 
    The array bounds are set from LOWBOUND and HIGHBOUND, and the array
    is populated from the values passed in ELEMVEC.
@@ -1809,11 +1812,8 @@ value_array (int lowbound, int highbound, struct value **elemvec)
     {
       val = allocate_value (arraytype);
       for (idx = 0; idx < nelem; idx++)
-       {
-         memcpy (value_contents_all_raw (val) + (idx * typelength),
-                 value_contents_all (elemvec[idx]),
-                 typelength);
-       }
+       value_contents_copy (val, idx * typelength, elemvec[idx], 0,
+                            typelength);
       return val;
     }
 
@@ -1822,9 +1822,7 @@ value_array (int lowbound, int highbound, struct value **elemvec)
 
   val = allocate_value (arraytype);
   for (idx = 0; idx < nelem; idx++)
-    memcpy (value_contents_writeable (val) + (idx * typelength),
-           value_contents_all (elemvec[idx]),
-           typelength);
+    value_contents_copy (val, idx * typelength, elemvec[idx], 0, typelength);
   return val;
 }
 
@@ -3711,9 +3709,8 @@ value_slice (struct value *array, int lowbound, int length)
       else
        {
          slice = allocate_value (slice_type);
-         memcpy (value_contents_writeable (slice),
-                 value_contents (array) + offset,
-                 TYPE_LENGTH (slice_type));
+         value_contents_copy (slice, 0, array, offset,
+                              TYPE_LENGTH (slice_type));
        }
 
       set_value_component_location (slice, array);
index a15315ed4b51b00ed22287a96975c0c4e57113b1..806101910d288c37fc94c36d9edb2b5bb86b1b3c 100644 (file)
@@ -840,6 +840,64 @@ value_contents_all (struct value *value)
   return result;
 }
 
+/* Copy LENGTH bytes of SRC value's contents starting at SRC_OFFSET,
+   into DST value's contents, starting at DST_OFFSET.  If unavailable
+   contents are being copied from SRC, the corresponding DST contents
+   are marked unavailable accordingly.  Neither DST nor SRC may be
+   lazy values.  */
+
+void
+value_contents_copy_raw (struct value *dst, int dst_offset,
+                        struct value *src, int src_offset, int length)
+{
+  range_s *r;
+  int i;
+
+  /* A lazy DST would make that this copy operation useless, since as
+     soon as DST's contents were un-lazied (by a later value_contents
+     call, say), the contents would be overwritten.  A lazy SRC would
+     mean we'd be copying garbage.  */
+  gdb_assert (!dst->lazy && !src->lazy);
+
+  /* Copy the data.  */
+  memcpy (value_contents_all_raw (dst) + dst_offset,
+         value_contents_all_raw (src) + src_offset,
+         length);
+
+  /* Copy the meta-data, adjusted.  */
+  for (i = 0; VEC_iterate (range_s, src->unavailable, i, r); i++)
+    {
+      ULONGEST h, l;
+
+      l = max (r->offset, src_offset);
+      h = min (r->offset + r->length, src_offset + length);
+
+      if (l < h)
+       mark_value_bytes_unavailable (dst,
+                                     dst_offset + (l - src_offset),
+                                     h - l);
+    }
+}
+
+/* Copy LENGTH bytes of SRC value's contents starting at SRC_OFFSET
+   byte, into DST value's contents, starting at DST_OFFSET.  If
+   unavailable contents are being copied from SRC, the corresponding
+   DST contents are marked unavailable accordingly.  DST must not be
+   lazy.  If SRC is lazy, it will be fetched now.  If SRC is not valid
+   (is optimized out), an error is thrown.  */
+
+void
+value_contents_copy (struct value *dst, int dst_offset,
+                    struct value *src, int src_offset, int length)
+{
+  require_not_optimized_out (src);
+
+  if (src->lazy)
+    value_fetch_lazy (src);
+
+  value_contents_copy_raw (dst, dst_offset, src, src_offset, length);
+}
+
 int
 value_lazy (struct value *value)
 {
@@ -2413,8 +2471,8 @@ value_primitive_field (struct value *arg1, int offset,
   else if (fieldno < TYPE_N_BASECLASSES (arg_type))
     {
       /* This field is actually a base subobject, so preserve the
-         entire object's contents for later references to virtual
-         bases, etc.  */
+        entire object's contents for later references to virtual
+        bases, etc.  */
 
       /* Lazy register values with offsets are not supported.  */
       if (VALUE_LVAL (arg1) == lval_register && value_lazy (arg1))
@@ -2425,8 +2483,8 @@ value_primitive_field (struct value *arg1, int offset,
       else
        {
          v = allocate_value (value_enclosing_type (arg1));
-         memcpy (value_contents_all_raw (v), value_contents_all_raw (arg1),
-                 TYPE_LENGTH (value_enclosing_type (arg1)));
+         value_contents_copy_raw (v, 0, arg1, 0,
+                                  TYPE_LENGTH (value_enclosing_type (arg1)));
        }
       v->type = type;
       v->offset = value_offset (arg1);
@@ -2447,9 +2505,9 @@ value_primitive_field (struct value *arg1, int offset,
       else
        {
          v = allocate_value (type);
-         memcpy (value_contents_raw (v),
-                 value_contents_raw (arg1) + offset,
-                 TYPE_LENGTH (type));
+         value_contents_copy_raw (v, value_embedded_offset (v),
+                                  arg1, value_embedded_offset (arg1) + offset,
+                                  TYPE_LENGTH (type));
        }
       v->offset = (value_offset (arg1) + offset
                   + value_embedded_offset (arg1));
index 5bd48e01e02f49a647296e237baeaaad4250f72c..4dec28e0f2fed64c483678930dd6f99a8b427d29 100644 (file)
@@ -492,6 +492,12 @@ extern struct value *read_var_value (struct symbol *var,
 extern struct value *allocate_value (struct type *type);
 extern struct value *allocate_value_lazy (struct type *type);
 extern void allocate_value_contents (struct value *value);
+extern void value_contents_copy (struct value *dst, int dst_offset,
+                                struct value *src, int src_offset,
+                                int length);
+extern void value_contents_copy_raw (struct value *dst, int dst_offset,
+                                    struct value *src, int src_offset,
+                                    int length);
 
 extern struct value *allocate_repeat_value (struct type *type, int count);