aboutsummaryrefslogtreecommitdiff
path: root/gdb/valops.c
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2011-02-14 11:21:25 +0000
committerPedro Alves <palves@redhat.com>2011-02-14 11:21:25 +0000
commite6ca34fcfbd6f341cb70c680d45f229cb5801eeb (patch)
tree93e23d44a35a3d9a0107b9cb0732e44608858668 /gdb/valops.c
parent2a7498d819aef97a9abf94dc20899affe68080fe (diff)
downloadgdb-e6ca34fcfbd6f341cb70c680d45f229cb5801eeb.zip
gdb-e6ca34fcfbd6f341cb70c680d45f229cb5801eeb.tar.gz
gdb-e6ca34fcfbd6f341cb70c680d45f229cb5801eeb.tar.bz2
Mark pieces of values as unavailable if the corresponding memory
is unavailable. gdb/ * valops.c: Include tracepoint.h. (value_fetch_lazy): Use read_value_memory. (read_value_memory): New. * value.h (read_value_memory): Declare. * dwarf2loc.c (read_pieced_value): Use read_value_memory. * exec.c (section_table_available_memory): New function. * exec.h (section_table_available_memory): Declare.
Diffstat (limited to 'gdb/valops.c')
-rw-r--r--gdb/valops.c93
1 files changed, 86 insertions, 7 deletions
diff --git a/gdb/valops.c b/gdb/valops.c
index 24c2269..7fa8729 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -38,7 +38,7 @@
#include "cp-support.h"
#include "dfp.h"
#include "user-regs.h"
-
+#include "tracepoint.h"
#include <errno.h>
#include "gdb_string.h"
#include "gdb_assert.h"
@@ -1009,12 +1009,8 @@ value_fetch_lazy (struct value *val)
int length = TYPE_LENGTH (check_typedef (value_enclosing_type (val)));
if (length)
- {
- if (value_stack (val))
- read_stack (addr, value_contents_all_raw (val), length);
- else
- read_memory (addr, value_contents_all_raw (val), length);
- }
+ read_value_memory (val, 0, value_stack (val),
+ addr, value_contents_all_raw (val), length);
}
else if (VALUE_LVAL (val) == lval_register)
{
@@ -1113,6 +1109,89 @@ value_fetch_lazy (struct value *val)
return 0;
}
+void
+read_value_memory (struct value *val, int embedded_offset,
+ int stack, CORE_ADDR memaddr,
+ gdb_byte *buffer, size_t length)
+{
+ if (length)
+ {
+ VEC(mem_range_s) *available_memory;
+
+ if (get_traceframe_number () < 0
+ || !traceframe_available_memory (&available_memory, memaddr, length))
+ {
+ if (stack)
+ read_stack (memaddr, buffer, length);
+ else
+ read_memory (memaddr, buffer, length);
+ }
+ else
+ {
+ struct target_section_table *table;
+ struct cleanup *old_chain;
+ CORE_ADDR unavail;
+ mem_range_s *r;
+ int i;
+
+ /* Fallback to reading from read-only sections. */
+ table = target_get_section_table (&exec_ops);
+ available_memory =
+ section_table_available_memory (available_memory,
+ memaddr, length,
+ table->sections,
+ table->sections_end);
+
+ old_chain = make_cleanup (VEC_cleanup(mem_range_s),
+ &available_memory);
+
+ normalize_mem_ranges (available_memory);
+
+ /* Mark which bytes are unavailable, and read those which
+ are available. */
+
+ unavail = memaddr;
+
+ for (i = 0;
+ VEC_iterate (mem_range_s, available_memory, i, r);
+ i++)
+ {
+ if (mem_ranges_overlap (r->start, r->length,
+ memaddr, length))
+ {
+ CORE_ADDR lo1, hi1, lo2, hi2;
+ CORE_ADDR start, end;
+
+ /* Get the intersection window. */
+ lo1 = memaddr;
+ hi1 = memaddr + length;
+ lo2 = r->start;
+ hi2 = r->start + r->length;
+ start = max (lo1, lo2);
+ end = min (hi1, hi2);
+
+ gdb_assert (end - memaddr <= length);
+
+ if (start > unavail)
+ mark_value_bytes_unavailable (val,
+ (embedded_offset
+ + unavail - memaddr),
+ start - unavail);
+ unavail = end;
+
+ read_memory (start, buffer + start - memaddr, end - start);
+ }
+ }
+
+ if (unavail != memaddr + length)
+ mark_value_bytes_unavailable (val,
+ embedded_offset + unavail - memaddr,
+ (memaddr + length) - unavail);
+
+ do_cleanups (old_chain);
+ }
+ }
+}
/* Store the contents of FROMVAL into the location of TOVAL.
Return a new value with the location of TOVAL and contents of FROMVAL. */