Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Pedro Alves <pedro@codesourcery.com>
To: gdb-patches@sourceware.org
Subject: [unavailable values part 1, 04/17] map unavailable memory to unavailable value contents
Date: Mon, 07 Feb 2011 14:29:00 -0000	[thread overview]
Message-ID: <201102071429.40838.pedro@codesourcery.com> (raw)

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);
+
 \f
 
 #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)
 }
 \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: 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


             reply	other threads:[~2011-02-07 14:29 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-02-07 14:29 Pedro Alves [this message]
2011-02-14 12:00 ` Jan Kratochvil
2011-02-14 22:14   ` Pedro Alves
2011-02-14 22:30     ` Jan Kratochvil

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=201102071429.40838.pedro@codesourcery.com \
    --to=pedro@codesourcery.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox