aboutsummaryrefslogtreecommitdiff
path: root/gdb/value.c
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2011-02-14 11:30:37 +0000
committerPedro Alves <palves@redhat.com>2011-02-14 11:30:37 +0000
commit39d37385568d667a2f5fab7e10adda5813a54467 (patch)
tree4d9623ad33dc78fd0a5036ef9a97eaaa28bdc914 /gdb/value.c
parent06d72e16c409574a7facc283ef1fcd7c5fd5fa05 (diff)
downloadgdb-39d37385568d667a2f5fab7e10adda5813a54467.zip
gdb-39d37385568d667a2f5fab7e10adda5813a54467.tar.gz
gdb-39d37385568d667a2f5fab7e10adda5813a54467.tar.bz2
gdb/
* 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.
Diffstat (limited to 'gdb/value.c')
-rw-r--r--gdb/value.c72
1 files changed, 65 insertions, 7 deletions
diff --git a/gdb/value.c b/gdb/value.c
index a15315e..8061019 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -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));