This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[unavailable values part 1, 04/17] map unavailable memory to unavailable value contents


In places where we read memory from the target to fill in
a value's contents, instead, use a new read_value_memory function,
that knows to mark the chunks of the value's contents that correspond
to unavailable memory, as unavailable.  The set of available
memory is that returned by the new traceframe_available_memory
function, unioned with the memory ranges defined by the
read-only (bfd) sections.

With this patch, not collected scalars and plain old data structures
that live in memory are already shown as unavailable.

E.g., with 

struct tuple
{
  int a;
  int b;
};

struct foo_s
{
  int a, b;
  int array[10000];
  struct tuple tarray[6];
  void *ptr;
  int ss:1;
};

struct foo2_s
{
  int d, ef;
  struct foo_s foo;
  int s:1;
  static struct foo_s sfoo;
  const char *string;
};

all memset to 0xaa, and a tracepoint with:

actions
	collect foo2.foo.array[0]
	collect foo2.foo.tarray[0].a
	collect foo2.foo.tarray[1].a
	collect foo2.foo.tarray[4].b
	collect foo2.foo.tarray[5].b
	end
tstart

One gets:

(gdb) p /x foo2
$2 = {d = <unavailable>, ef = <unavailable>, foo = {a = <unavailable>, b = <unavailable>, array = {0xaaaaaaaa, 
      <unavailable> <repeats 9999 times>}, tarray = {{a = 0xaaaaaaaa, b = <unavailable>}, {a = 0xaaaaaaaa, 
        b = <unavailable>}, {a = <unavailable>, b = <unavailable>}, {a = <unavailable>, b = <unavailable>}, {
        a = <unavailable>, b = 0xaaaaaaaa}, {a = <unavailable>, b = 0xaaaaaaaa}}, ptr = <unavailable>, ss = 0x0}, 
  s = 0x0, static sfoo = {a = <unavailable>, b = <unavailable>, array = {<unavailable> <repeats 10000 times>}, 
    tarray = {{a = <unavailable>, b = <unavailable>}, {a = <unavailable>, b = <unavailable>}, {a = <unavailable>, 
        b = <unavailable>}, {a = <unavailable>, b = <unavailable>}, {a = <unavailable>, b = <unavailable>}, {
        a = <unavailable>, b = <unavailable>}}, ptr = <unavailable>, ss = 0x0}, string = <unavailable>}

The sharp eye will notice there's a couple of 0x0's above.  Those are
bitfields, which require further fixing.

Tests for all this functionality will be added later in
the series (patch 12), after this and a bunch of other cases
have been fixed to handle unavailable-ness.

-- 
Pedro Alves

2011-02-07  Pedro Alves  <pedro@codesourcery.com>

	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.

---
 gdb/dwarf2loc.c |    8 ++--
 gdb/exec.c      |   37 ++++++++++++++++++++++
 gdb/exec.h      |   12 +++++++
 gdb/valops.c    |   93 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
 gdb/value.h     |   11 ++++++
 5 files changed, 150 insertions(+), 11 deletions(-)

Index: src/gdb/valops.c
===================================================================
--- src.orig/gdb/valops.c	2011-02-02 18:58:36.337899006 +0000
+++ src/gdb/valops.c	2011-02-07 11:15:02.926705996 +0000
@@ -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: src/gdb/value.h
===================================================================
--- src.orig/gdb/value.h	2011-02-07 11:12:35.406706000 +0000
+++ src/gdb/value.h	2011-02-07 11:15:02.926705996 +0000
@@ -374,6 +374,17 @@ extern int value_bytes_available (const
 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);
+
 
 
 #include "symtab.h"
Index: src/gdb/dwarf2loc.c
===================================================================
--- src.orig/gdb/dwarf2loc.c	2011-02-02 18:58:36.337899006 +0000
+++ src/gdb/dwarf2loc.c	2011-02-07 11:15:02.946706002 +0000
@@ -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: src/gdb/exec.c
===================================================================
--- src.orig/gdb/exec.c	2011-02-02 18:58:36.337899006 +0000
+++ src/gdb/exec.c	2011-02-07 11:15:03.046706003 +0000
@@ -572,6 +572,43 @@ map_vmap (bfd *abfd, bfd *arch)
 }
 
 
+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: src/gdb/exec.h
===================================================================
--- src.orig/gdb/exec.h	2011-02-02 18:58:36.337899006 +0000
+++ src/gdb/exec.h	2011-02-07 11:15:03.046706003 +0000
@@ -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 b
 
 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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]