diff options
author | Pedro Alves <palves@redhat.com> | 2011-02-14 11:30:37 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2011-02-14 11:30:37 +0000 |
commit | 39d37385568d667a2f5fab7e10adda5813a54467 (patch) | |
tree | 4d9623ad33dc78fd0a5036ef9a97eaaa28bdc914 /gdb/value.c | |
parent | 06d72e16c409574a7facc283ef1fcd7c5fd5fa05 (diff) | |
download | gdb-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.c | 72 |
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)); |