Mark pieces of values as unavailable if the corresponding memory
authorPedro Alves <palves@redhat.com>
Mon, 14 Feb 2011 11:21:25 +0000 (11:21 +0000)
committerPedro Alves <palves@redhat.com>
Mon, 14 Feb 2011 11:21:25 +0000 (11:21 +0000)
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.

gdb/ChangeLog
gdb/dwarf2loc.c
gdb/exec.c
gdb/exec.h
gdb/valops.c
gdb/value.h

index df7e871bd9fa0841f960536cd642c802159ed673..1fd5b020c03ff8ee842d798081a5aa0a45f1e6bb 100644 (file)
@@ -1,3 +1,16 @@
+2011-02-14  Pedro Alves  <pedro@codesourcery.com>
+
+       Mark pieces of values as unavailable if the corresponding memory
+       is unavailable.
+
+       * 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.
+
 2011-02-14  Pedro Alves  <pedro@codesourcery.com>
 
        * Makefile.in (SFILES): Add memrange.c.
index d9580c658889aa11143f60558565d8ee5df9e612..0f58954d76992778780c213e30be03b39c353ea2 100644 (file)
@@ -603,10 +603,10 @@ read_pieced_value (struct value *v)
          break;
 
        case DWARF_VALUE_MEMORY:
-         if (p->v.mem.in_stack_memory)
-           read_stack (p->v.mem.addr + source_offset, buffer, this_size);
-         else
-           read_memory (p->v.mem.addr + source_offset, buffer, this_size);
+         read_value_memory (v, offset,
+                            p->v.mem.in_stack_memory,
+                            p->v.mem.addr + source_offset,
+                            buffer, this_size);
          break;
 
        case DWARF_VALUE_STACK:
index 0eea1d70bd3955e7bd4cc24610003f8461741cab..1cca3b336d021ae3c4d4ac9fa96bd6f07f7b856f 100644 (file)
@@ -572,6 +572,43 @@ map_vmap (bfd *abfd, bfd *arch)
 }
 \f
 
+VEC(mem_range_s) *
+section_table_available_memory (VEC(mem_range_s) *memory,
+                               CORE_ADDR memaddr, LONGEST len,
+                               struct target_section *sections,
+                               struct target_section *sections_end)
+{
+  struct target_section *p;
+  ULONGEST memend = memaddr + len;
+
+  for (p = sections; p < sections_end; p++)
+    {
+      if ((bfd_get_section_flags (p->bfd, p->the_bfd_section)
+          & SEC_READONLY) == 0)
+       continue;
+
+      /* Copy the meta-data, adjusted.  */
+      if (mem_ranges_overlap (p->addr, p->endaddr - p->addr, memaddr, len))
+       {
+         ULONGEST lo1, hi1, lo2, hi2;
+         struct mem_range *r;
+
+         lo1 = memaddr;
+         hi1 = memaddr + len;
+
+         lo2 = p->addr;
+         hi2 = p->endaddr;
+
+         r = VEC_safe_push (mem_range_s, memory, NULL);
+
+         r->start = max (lo1, lo2);
+         r->length = min (hi1, hi2) - r->start;
+       }
+    }
+
+  return memory;
+}
+
 int
 section_table_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf,
                                   ULONGEST offset, LONGEST len,
index 8af2adf02796c1945c696aa8cbd6957351f0ba47..a8df60878b4410ed1f6e1de854fb96512730771e 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "target.h"
 #include "progspace.h"
+#include "memrange.h"
 
 struct target_section;
 struct target_ops;
@@ -44,6 +45,17 @@ extern int build_section_table (struct bfd *, struct target_section **,
 
 extern int resize_section_table (struct target_section_table *, int);
 
+/* Appends all read-only memory ranges found in the target section
+   table defined by SECTIONS and SECTIONS_END, starting at (and
+   intersected with) MEMADDR for LEN bytes.  Returns the augmented
+   VEC.  */
+
+extern VEC(mem_range_s) *
+  section_table_available_memory (VEC(mem_range_s) *ranges,
+                                 CORE_ADDR memaddr, LONGEST len,
+                                 struct target_section *sections,
+                                 struct target_section *sections_end);
+
 /* Read or write from mappable sections of BFD executable files.
 
    Request to transfer up to LEN 8-bit bytes of the target sections
index 24c22692ead2d47cd758be1619b36a208a51ade5..7fa87293fada501b67f7df8ee3ca56a82e2e4185 100644 (file)
@@ -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.  */
index d51567eeaa59c19eb334fc04e7ec6eabe2cc4c11..d2eb091ef5c364c05585bc22ecfd48310aa2ab38 100644 (file)
@@ -374,6 +374,17 @@ extern int value_bytes_available (const struct value *value,
 extern void mark_value_bytes_unavailable (struct value *value,
                                          int offset, int length);
 
+/* Read LENGTH bytes of memory starting at MEMADDR into BUFFER, which
+   is (or will be copied to) VAL's contents buffer offset by
+   EMBEDDED_OFFSET (that is, to &VAL->contents[EMBEDDED_OFFSET]).
+   Marks value contents ranges as unavailable if the corresponding
+   memory is likewise unavailable.  STACK indicates whether the memory
+   is known to be stack memory.  */
+
+extern void read_value_memory (struct value *val, int offset,
+                              int stack, CORE_ADDR memaddr,
+                              gdb_byte *buffer, size_t length);
+
 \f
 
 #include "symtab.h"