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]

Re: [RFA v2] valprint.c / *-valprint.c: Don't lose `embedded_offset'


On Monday 24 January 2011 13:22:42, Pedro Alves wrote:
> This is an updated version of the patch I posted here:
> <http://sourceware.org/ml/gdb-patches/2010-10/msg00108.html>
> 
> Compared to the previous patch, this fixes a bug in
> array repeat repetition handling, and adds a testcase
> to cover it.  My previous patch also had SCM related changes,
> but Tromey removed the SCM support from GDB meanwhile.
> 
> Joel, there are Ada changes in the patch, are those okay?
> 
> I have follow up patches that adjust other parts of GDB similarly,
> and patches that make it so that val_print always gets a non-NULL
> value to work with.
> 
> Here's the original description of the patch more or less unchanged:
> 
> 
> In a nutshell, the patch below makes sure in the value print routines
> throughout, the `embedded_offset' passed around makes sense when
> consulting the contents (or data about the contents) of the also passed
> along "struct value *original_value".  There are code paths where
> that connection is lost.
> 
> A bit of explaining on why this is necessary.  In the context of
> tracepoints, I'm adding support for partial/incomplete objects.  That is,
> say, when printing an array where only a few elements have been collected,
> print what you can, and print something like "<unavailable>"
> (like <optimized out>) for what has not been collected.  E.g., with:
> 
> struct foo {
>   int a, b;
>   int array[10000];
>   void *ptr;
> };
> 
> struct foo2 {
>   int d, ef;
>   struct foo foo;
> };
> 
> struct foo2 foo2;
> 
> and a tracepoint that just collects "foo2.foo.array[0]",
> when printing foo2 while inspecting the corresponding collected
> traceframe, currently we get:
> 
> (gdb) p foo2
> Cannot access memory at address 0x601080
> 
> This is GDB trying to read [&foo2, &foo2+sizeof foo2) for an lval_memory
> value representing "foo2" and the read failing because required
> memory is not "available" (it was not collected).
> 
> vs afterwards, after all the necessary changes, we'll get something like:
> 
> (gdb) p foo2
> $1 = {d = <unavailable>, ef = <unavailable>, foo = {a = <unavailable>, b =
> <unavailable>, array = {12345678,
>       <unavailable> <repeats 9999 times>}, ptr = <unavailable>}}
> 
> That is, we will still print what is available.
> 
> This requires marking chunks of a value's contents buffer as "unavailable"
>  at value read time, and, at value print time, check whether the value
> contents chunk being printed is "available".  The "unavailable"-ness of
> the contents needs to be part of the struct value itself, given that when
> printing a value from the value history, you still want to know what is
> or isn't available, without consulting the target (which may not
> exist anymore).
> 
> This value contents offset, is exactly `embedded_offset' in many
> of the *valprint.c routines.  E.g.:,
> 
> /* Print data of type TYPE located at VALADDR (within GDB), which came from
>    the inferior at address ADDRESS, onto stdio stream STREAM according to
>    OPTIONS.  The data at VALADDR is in target byte order.
> 
>    If the data are a string pointer, returns the number of string
> characters printed.  */
> 
> int
> c_val_print (struct type *type, const gdb_byte *valaddr, int
> embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse,
> const struct value *original_value,
>              const struct value_print_options *options)
> 
> The comment is actually not 100% correct or clear.  It's actually data of
> type TYPE located at VALADDR + EMBEDDED_OFFSET, which came from the
> inferior at address ADDRESS + EMBEDDED_OFFSET.  ORIGINAL_VALUE, if
> non-NULL, is what came from ADDRESS.  (the patch doesn't fix this; there
> are a bunch of copies of that comment around, and I want to fix them all
> in one go in a followup, or maybe in a next revision of this patch).
> 
> So, when printing, we want to check whether
> [original_value->contents + embedded_offset,
>  original_value->contents + embedded_offset + TYPE_LENGTH (type))
> has been optimized out; if it has, print "$n = <optimized out>" or throw an
> "value has been optimized out" error (preferably the former).  If not
> optimized out, check whether the same contents range value is actually
> "available".  If not, print "<unavailable>", otherwise, proceed printing
> as usual.
> 
> The root of the value print call tree is usually something
> like this:
> 
>   val_print (value_type (val),
>              value_contents_for_printing (val),
>              value_embedded_offset (val),
>              value_address (val), stream, 0,
>          val, &opts, current_language);
> 
> Then, in valprint.c/c-valprint.c/cp-valprint.c, subroutines where we pass
> down valaddr and the `original_value', adjust embedded_offset as required
> to move on to a sub-field, and pass down `valaddr' and `address' (see
> c_val_print description above) unmodified.  Thus, if original_value is
> non-NULL, then valaddr is always equal to original_value->contents (that
> is, value_contents_for_printing()).
> 
> This works nicelly, and allows making use of the running embedded_offset
> argument to query original_value whether the contents we're trying to print
> are actually valid/available.
> 
> But, not all are roses.  There are code paths where the original
> embedded_offset is lost, as e.g., when printing array elements.
> The fix looks then simple: just add an embedded_offset parameter to
> val_print_array_elements, and adjust the callers to not re-adjust
> `valaddr' and `address' themselves, but to instead pass down an adjusted
> embedded_offset (see the valprint.c and c-valprint.c hunks in the
> patch below).
> 
> Trouble is in languages other than C/C++ where the
> advance-embedded_offset-don't-touch-valaddr-or-address contract
> isn't compromised in many places.  The patch below fixes all those places
> as well.
> 
> Along the way, I made places that were passing value_contents() to
> val_print & co pass value_contents_for_printing(), value_embedded_offset()
> instead, as is meant to be, as value_contents_for_printing is not as strict
> about complaining about optimized out values (and in the
> future "unavailable" values), but instead defers that to the subroutines
> that actually do the printing, so we have a chance of printing as many
> scalar fields of an object as possible, even if other parts of the object
> have been optimized out or are "unavailable".
> 
> I have GNAT 4.4.5 to cover gdb.ada testing, gfortran 4.4.5 for gdb.fortran,
> gpc 20070904, based on gcc-4.1.3 for gdb.pascal, and gcj 4.4.5 for
> gdb.java.  I have no way of testing the D changes, though they are
> quite small.
> 
> I get no testsuite regressions with this patch applied on top of current
> mainline.

-- 
Pedro Alves

2011-01-24  Pedro Alves  <pedro@codesourcery.com>

	Don't lose embedded_offset in printing routines throughout.

	gdb/
	* valprint.h (val_print_array_elements): Change prototype.
	* valprint.c (val_print_array_elements): Add `embedded_offset'
	parameter, and adjust to pass it down to val_print, while passing
	`valaddr' or `address' unmodified.  Take embedded_offset into
	account when checking repetitions.
	* c-valprint.c (c_val_print): Pass embedded_offset to
	val_print_array_elements instead of adjusting `valaddr' and
	`address'.
	* m2-valprint.c (m2_print_array_contents, m2_val_print): Pass
	embedded_offset to val_print_array_elements instead of adjusting
	`valaddr'.
	* p-lang.h (pascal_object_print_value_fields): Adjust prototype.
	* p-valprint.c (pascal_val_print): Pass embedded_offset to
	val_print_array_elements and pascal_object_print_value_fields
	instead of adjusting `valaddr'.
	(pascal_object_print_value_fields): Add `offset' parameter, and
	adjust to use it.
	(pascal_object_print_value): Add `offset' parameter, and adjust to
	use it.
	(pascal_object_print_static_field): Use
	value_contents_for_printing/value_embedded_offset, rather than
	value_contents.
	* ada-valprint.c (val_print_packed_array_elements): Add `offset'
	parameter, and adjust to use it.  Use
	value_contents_for_printing/value_embedded_offset, rather than
	value_contents.
	(ada_val_print): Rename `valaddr0' parameter to `valaddr'.
	(ada_val_print_array): Add `offset' parameter, and adjust to use
	it.
	(ada_val_print_1): Rename `valaddr0' parameter to `valaddr', and
	`embedded_offset' to `offset'.  Don't re-adjust `valaddr'.
	Instead work with offsets.  Use
	value_contents_for_printing/value_embedded_offset, rather than
	value_contents.  Change `defer_val_int' local type to CORE_ADDR,
	and use value_from_pointer to extract a target pointer, rather
	than value_from_longest.
	(print_variant_part): Add `offset' parameter.  Replace
	`outer_valaddr' parameter by a new `outer_offset' parameter.
	Don't re-adjust `valaddr'.  Instead pass down adjusted offsets.
	(ada_value_print): Use
	value_contents_for_printing/value_embedded_offset, rather than
	value_contents.
	(print_record): Add `offset' parameter, and adjust to pass it
	down.
	(print_field_values): Add `offset' parameter.  Replace
	`outer_valaddr' parameter by a new `outer_offset' parameter.
	Don't re-adjust `valaddr'.  Instead pass down adjusted offsets.
	Use value_contents_for_printing/value_embedded_offset, rather than
	value_contents.
	* d-valprint.c (dynamic_array_type): Use
	value_contents_for_printing/value_embedded_offset, rather than
	value_contents.
	* jv-valprint.c (java_print_value_fields): Add `offset' parameter.
	Don't re-adjust `valaddr'.  Instead pass down adjusted offsets.
	(java_print_value_fields): Take `offset' into account.  Don't
	re-adjust `valaddr'.  Instead pass down adjusted offsets.
	(java_val_print): Take `embedded_offset' into account.  Pass it to
	java_print_value_fields.
	* f-valprint.c (f77_print_array_1): Add `embedded_offset'
	parameter.  Don't re-adjust `valaddr' or `address'.  Instead pass
	down adjusted offsets.
	(f77_print_array): Add `embedded_offset' parameter.  Pass it down.
	(f_val_print): Take `embedded_offset' into account.

	gdb/testsuite/
	* gdb.base/printcmds.c (some_struct): New struct and instance.
	* gdb.base/printcmds.exp (test_print_repeats_embedded_array): New
	procedure.
	<global scope>: Call it.

---
 gdb/ada-valprint.c                   |  176 
++++++++++++++++++++---------------
 gdb/c-valprint.c                     |    7 -
 gdb/d-valprint.c                     |    8 -
 gdb/f-valprint.c                     |   75 ++++++++------
 gdb/jv-valprint.c                    |   42 ++++----
 gdb/m2-valprint.c                    |    4 
 gdb/p-lang.h                         |    1 
 gdb/p-valprint.c                     |   48 ++++++---
 gdb/testsuite/gdb.base/printcmds.c   |   22 ++++
 gdb/testsuite/gdb.base/printcmds.exp |   13 ++
 gdb/valprint.c                       |   17 ++-
 gdb/valprint.h                       |    2 
 12 files changed, 262 insertions(+), 153 deletions(-)

Index: src/gdb/valprint.h
===================================================================
--- src.orig/gdb/valprint.h	2011-01-24 12:54:32.000000000 +0000
+++ src/gdb/valprint.h	2011-01-24 12:54:35.236177001 +0000
@@ -113,7 +113,7 @@ extern void maybe_print_array_index (str
                                      struct ui_file *stream,
 				     const struct value_print_options *);
 
-extern void val_print_array_elements (struct type *, const gdb_byte *,
+extern void val_print_array_elements (struct type *, const gdb_byte *, int,
 				      CORE_ADDR, struct ui_file *, int,
 				      const struct value *,
 				      const struct value_print_options *,
Index: src/gdb/valprint.c
===================================================================
--- src.orig/gdb/valprint.c	2011-01-24 12:54:32.000000000 +0000
+++ src/gdb/valprint.c	2011-01-24 13:10:43.486176996 +0000
@@ -1108,7 +1108,8 @@ maybe_print_array_index (struct type *in
    perhaps we should try to use that notation when appropriate.  */
 
 void
-val_print_array_elements (struct type *type, const gdb_byte *valaddr,
+val_print_array_elements (struct type *type,
+			  const gdb_byte *valaddr, int embedded_offset,
 			  CORE_ADDR address, struct ui_file *stream,
 			  int recurse,
 			  const struct value *val,
@@ -1171,8 +1172,10 @@ val_print_array_elements (struct type *t
 
       rep1 = i + 1;
       reps = 1;
-      while ((rep1 < len) &&
-	     !memcmp (valaddr + i * eltlen, valaddr + rep1 * eltlen, eltlen))
+      while (rep1 < len
+	     && memcmp (valaddr + embedded_offset + i * eltlen,
+			valaddr + embedded_offset + rep1 * eltlen,
+			eltlen) == 0)
 	{
 	  ++reps;
 	  ++rep1;
@@ -1180,8 +1183,9 @@ val_print_array_elements (struct type *t
 
       if (reps > options->repeat_count_threshold)
 	{
-	  val_print (elttype, valaddr + i * eltlen, 0, address + i * eltlen,
-		     stream, recurse + 1, val, options, current_language);
+	  val_print (elttype, valaddr, embedded_offset + i * eltlen,
+		     address, stream, recurse + 1, val, options,
+		     current_language);
 	  annotate_elt_rep (reps);
 	  fprintf_filtered (stream, " <repeats %u times>", reps);
 	  annotate_elt_rep_end ();
@@ -1191,7 +1195,8 @@ val_print_array_elements (struct type *t
 	}
       else
 	{
-	  val_print (elttype, valaddr + i * eltlen, 0, address + i * eltlen,
+	  val_print (elttype, valaddr, embedded_offset + i * eltlen,
+		     address,
 		     stream, recurse + 1, val, options, current_language);
 	  annotate_elt ();
 	  things_printed++;
Index: src/gdb/c-valprint.c
===================================================================
--- src.orig/gdb/c-valprint.c	2011-01-24 12:54:32.000000000 +0000
+++ src/gdb/c-valprint.c	2011-01-24 12:54:35.246177002 +0000
@@ -233,10 +233,9 @@ c_val_print (struct type *type, const gd
 		{
 		  i = 0;
 		}
-	      val_print_array_elements (type, valaddr + embedded_offset,
-					address + embedded_offset,
-					stream, recurse,
-					original_value, options, i);
+	      val_print_array_elements (type, valaddr, embedded_offset,
+					address, stream,
+					recurse, original_value, options, i);
 	      fprintf_filtered (stream, "}");
 	    }
 	  break;
Index: src/gdb/m2-valprint.c
===================================================================
--- src.orig/gdb/m2-valprint.c	2011-01-24 12:54:32.000000000 +0000
+++ src/gdb/m2-valprint.c	2011-01-24 12:54:35.246177002 +0000
@@ -300,7 +300,7 @@ m2_print_array_contents (struct type *ty
       else
 	{
 	  fprintf_filtered (stream, "{");
-	  val_print_array_elements (type, valaddr + embedded_offset,
+	  val_print_array_elements (type, valaddr, embedded_offset,
 				    address, stream, recurse, val,
 				    options, 0);
 	  fprintf_filtered (stream, "}");
@@ -370,7 +370,7 @@ m2_val_print (struct type *type, const g
 	  else
 	    {
 	      fprintf_filtered (stream, "{");
-	      val_print_array_elements (type, valaddr + embedded_offset,
+	      val_print_array_elements (type, valaddr, embedded_offset,
 					address, stream,
 					recurse, original_value,
 					options, 0);
Index: src/gdb/p-valprint.c
===================================================================
--- src.orig/gdb/p-valprint.c	2011-01-24 12:54:32.000000000 +0000
+++ src/gdb/p-valprint.c	2011-01-24 12:54:35.246177002 +0000
@@ -125,7 +125,7 @@ pascal_val_print (struct type *type, con
 		{
 		  i = 0;
 		}
-	      val_print_array_elements (type, valaddr + embedded_offset,
+	      val_print_array_elements (type, valaddr, embedded_offset,
 					address, stream, recurse,
 					original_value, options, i);
 	      fprintf_filtered (stream, "}");
@@ -327,7 +327,7 @@ pascal_val_print (struct type *type, con
 			       len, NULL, 0, options);
 	    }
 	  else
-	    pascal_object_print_value_fields (type, valaddr + embedded_offset,
+	    pascal_object_print_value_fields (type, valaddr, embedded_offset,
 					      address, stream, recurse,
 					      original_value, options,
 					      NULL, 0);
@@ -629,6 +629,7 @@ static void pascal_object_print_static_f
 					      const struct value_print_options *);
 
 static void pascal_object_print_value (struct type *, const gdb_byte *,
+				       int,
 				       CORE_ADDR, struct ui_file *, int,
 				       const struct value *,
 				       const struct value_print_options *,
@@ -687,6 +688,7 @@ pascal_object_is_vtbl_member (struct typ
 
 void
 pascal_object_print_value_fields (struct type *type, const gdb_byte *valaddr,
+				  int offset,
 				  CORE_ADDR address, struct ui_file *stream,
 				  int recurse,
 				  const struct value *val,
@@ -706,8 +708,9 @@ pascal_object_print_value_fields (struct
   /* Print out baseclasses such that we don't print
      duplicates of virtual baseclasses.  */
   if (n_baseclasses > 0)
-    pascal_object_print_value (type, valaddr, address, stream,
-			       recurse + 1, val, options, dont_print_vb);
+    pascal_object_print_value (type, valaddr, offset, address,
+			       stream, recurse + 1, val,
+			       options, dont_print_vb);
 
   if (!len && n_baseclasses == 1)
     fprintf_filtered (stream, "<No data fields>");
@@ -814,7 +817,8 @@ pascal_object_print_value_fields (struct
 		  struct value_print_options opts = *options;
 
 		  v = value_from_longest (TYPE_FIELD_TYPE (type, i),
-				   unpack_field_as_long (type, valaddr, i));
+				   unpack_field_as_long (type,
+							 valaddr + offset, i));
 
 		  opts.deref_ref = 0;
 		  common_val_print (v, stream, recurse + 1, &opts,
@@ -833,8 +837,9 @@ pascal_object_print_value_fields (struct
 		     v4.17 specific.  */
 		  struct value *v;
 
-		  v = value_from_longest (TYPE_FIELD_TYPE (type, i),
-				   unpack_field_as_long (type, valaddr, i));
+		  v = value_from_longest
+		    (TYPE_FIELD_TYPE (type, i),
+		     unpack_field_as_long (type, valaddr + offset, i));
 
 		  if (v == NULL)
 		    fputs_filtered ("<optimized out>", stream);
@@ -852,9 +857,8 @@ pascal_object_print_value_fields (struct
 		     address + TYPE_FIELD_BITPOS (type, i) / 8, 0,
 		     stream, format, 0, recurse + 1, pretty); */
 		  val_print (TYPE_FIELD_TYPE (type, i),
-			     valaddr, TYPE_FIELD_BITPOS (type, i) / 8,
-			     address + TYPE_FIELD_BITPOS (type, i) / 8,
-			     stream, recurse + 1, val, &opts,
+			     valaddr, offset + TYPE_FIELD_BITPOS (type, i) / 8,
+			     address, stream, recurse + 1, val, &opts,
 			     current_language);
 		}
 	    }
@@ -883,6 +887,7 @@ pascal_object_print_value_fields (struct
 
 static void
 pascal_object_print_value (struct type *type, const gdb_byte *valaddr,
+			   int offset,
 			   CORE_ADDR address, struct ui_file *stream,
 			   int recurse,
 			   const struct value *val,
@@ -909,6 +914,7 @@ pascal_object_print_value (struct type *
       struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
       char *basename = type_name_no_tag (baseclass);
       const gdb_byte *base_valaddr;
+      int thisoffset;
 
       if (BASETYPE_VIA_VIRTUAL (type, i))
 	{
@@ -925,7 +931,9 @@ pascal_object_print_value (struct type *
 	  obstack_ptr_grow (&dont_print_vb_obstack, baseclass);
 	}
 
-      boffset = baseclass_offset (type, i, valaddr, address);
+      thisoffset = offset;
+
+      boffset = baseclass_offset (type, i, valaddr + offset, address + offset);
 
       if (options->pretty)
 	{
@@ -952,16 +960,19 @@ pascal_object_print_value (struct type *
 	  if (target_read_memory (address + boffset, buf,
 				  TYPE_LENGTH (baseclass)) != 0)
 	    boffset = -1;
+	  address = address + boffset;
+	  thisoffset = 0;
+	  boffset = 0;
 	}
       else
-	base_valaddr = valaddr + boffset;
+	base_valaddr = valaddr;
 
       if (boffset == -1)
 	fprintf_filtered (stream, "<invalid address>");
       else
 	pascal_object_print_value_fields (baseclass, base_valaddr,
-					  address + boffset, stream,
-					  recurse, val, options,
+					  thisoffset + boffset, address,
+					  stream, recurse, val, options,
 		     (struct type **) obstack_base (&dont_print_vb_obstack),
 					  0);
       fputs_filtered (", ", stream);
@@ -1025,9 +1036,12 @@ pascal_object_print_static_field (struct
 		    sizeof (CORE_ADDR));
 
       CHECK_TYPEDEF (type);
-      pascal_object_print_value_fields (type, value_contents (val), addr,
-					stream, recurse, NULL, options,
-					NULL, 1);
+      pascal_object_print_value_fields (type,
+					value_contents_for_printing (val),
+					value_embedded_offset (val),
+					addr,
+					stream, recurse,
+					val, options, NULL, 1);
       return;
     }
 
Index: src/gdb/ada-valprint.c
===================================================================
--- src.orig/gdb/ada-valprint.c	2011-01-24 12:54:32.000000000 +0000
+++ src/gdb/ada-valprint.c	2011-01-24 12:54:35.246177002 +0000
@@ -36,17 +36,18 @@
 #include "exceptions.h"
 #include "objfiles.h"
 
-static void print_record (struct type *, const gdb_byte *, struct ui_file *,
+static void print_record (struct type *, const gdb_byte *, int,
+			  struct ui_file *,
 			  int,
 			  const struct value *,
 			  const struct value_print_options *);
 
 static int print_field_values (struct type *, const gdb_byte *,
+			       int,
 			       struct ui_file *, int,
 			       const struct value *,
 			       const struct value_print_options *,
-			       int, struct type *,
-			       const gdb_byte *);
+			       int, struct type *, int);
 
 static void adjust_type_signedness (struct type *);
 
@@ -134,6 +135,7 @@ print_optional_low_bound (struct ui_file
 
 static void
 val_print_packed_array_elements (struct type *type, const gdb_byte *valaddr,
+				 int offset,
 				 int bitoffset, struct ui_file *stream,
 				 int recurse,
 				 const struct value *val,
@@ -185,7 +187,7 @@ val_print_packed_array_elements (struct
       maybe_print_array_index (index_type, i + low, stream, options);
 
       i0 = i;
-      v0 = ada_value_primitive_packed_val (NULL, valaddr,
+      v0 = ada_value_primitive_packed_val (NULL, valaddr + offset,
 					   (i0 * bitsize) / HOST_CHAR_BIT,
 					   (i0 * bitsize) % HOST_CHAR_BIT,
 					   bitsize, elttype);
@@ -194,7 +196,7 @@ val_print_packed_array_elements (struct
 	  i += 1;
 	  if (i >= len)
 	    break;
-	  v1 = ada_value_primitive_packed_val (NULL, valaddr,
+	  v1 = ada_value_primitive_packed_val (NULL, valaddr + offset,
 					       (i * bitsize) / HOST_CHAR_BIT,
 					       (i * bitsize) % HOST_CHAR_BIT,
 					       bitsize, elttype);
@@ -207,7 +209,8 @@ val_print_packed_array_elements (struct
 	  struct value_print_options opts = *options;
 
 	  opts.deref_ref = 0;
-	  val_print (elttype, value_contents (v0), 0, 0, stream,
+	  val_print (elttype, value_contents_for_printing (v0),
+		     value_embedded_offset (v0), 0, stream,
 		     recurse + 1, val, &opts, current_language);
 	  annotate_elt_rep (i - i0);
 	  fprintf_filtered (stream, _(" <repeats %u times>"), i - i0);
@@ -237,7 +240,8 @@ val_print_packed_array_elements (struct
 		  maybe_print_array_index (index_type, j + low,
 					   stream, options);
 		}
-	      val_print (elttype, value_contents (v0), 0, 0, stream,
+	      val_print (elttype, value_contents_for_printing (v0),
+			 value_embedded_offset (v0), 0, stream,
 			 recurse + 1, val, &opts, current_language);
 	      annotate_elt ();
 	    }
@@ -571,7 +575,7 @@ ada_printstr (struct ui_file *stream, st
    continuation lines; this amount is roughly twice the value of RECURSE.  */
 
 int
-ada_val_print (struct type *type, const gdb_byte *valaddr0,
+ada_val_print (struct type *type, const gdb_byte *valaddr,
 	       int embedded_offset, CORE_ADDR address,
 	       struct ui_file *stream, int recurse,
 	       const struct value *val,
@@ -580,9 +584,10 @@ ada_val_print (struct type *type, const
   volatile struct gdb_exception except;
   int result = 0;
 
+  /* XXX: this catches QUIT/ctrl-c as well.  Isn't that busted?  */
   TRY_CATCH (except, RETURN_MASK_ALL)
     {
-      result = ada_val_print_1 (type, valaddr0, embedded_offset, address,
+      result = ada_val_print_1 (type, valaddr, embedded_offset, address,
 				stream, recurse, val, options);
     }
 
@@ -599,7 +604,8 @@ ada_val_print (struct type *type, const
 
 static int
 ada_val_print_array (struct type *type, const gdb_byte *valaddr,
-		     CORE_ADDR address, struct ui_file *stream, int recurse,
+		     int offset, CORE_ADDR address,
+		     struct ui_file *stream, int recurse,
 		     const struct value *val,
 		     const struct value_print_options *options)
 {
@@ -636,12 +642,13 @@ ada_val_print_array (struct type *type,
           for (temp_len = 0;
                (temp_len < len
                 && temp_len < options->print_max
-                && char_at (valaddr, temp_len, eltlen, byte_order) != 0);
+                && char_at (valaddr + offset,
+			    temp_len, eltlen, byte_order) != 0);
                temp_len += 1);
           len = temp_len;
         }
 
-      printstr (stream, elttype, valaddr, len, 0, eltlen, options);
+      printstr (stream, elttype, valaddr + offset, len, 0, eltlen, options);
       result = len;
     }
   else
@@ -649,11 +656,11 @@ ada_val_print_array (struct type *type,
       fprintf_filtered (stream, "(");
       print_optional_low_bound (stream, type, options);
       if (TYPE_FIELD_BITSIZE (type, 0) > 0)
-        val_print_packed_array_elements (type, valaddr, 0, stream,
-                                         recurse, val, options);
+        val_print_packed_array_elements (type, valaddr, offset,
+					 0, stream, recurse, val, options);
       else
-        val_print_array_elements (type, valaddr, address, stream,
-                                  recurse, val, options, 0);
+        val_print_array_elements (type, valaddr, offset, address,
+				  stream, recurse, val, options, 0);
       fprintf_filtered (stream, ")");
     }
 
@@ -664,8 +671,8 @@ ada_val_print_array (struct type *type,
    does not catch evaluation errors (leaving that to ada_val_print).  */
 
 static int
-ada_val_print_1 (struct type *type, const gdb_byte *valaddr0,
-		 int embedded_offset, CORE_ADDR address,
+ada_val_print_1 (struct type *type, const gdb_byte *valaddr,
+		 int offset, CORE_ADDR address,
 		 struct ui_file *stream, int recurse,
 		 const struct value *original_value,
 		 const struct value_print_options *options)
@@ -674,7 +681,7 @@ ada_val_print_1 (struct type *type, cons
   int i;
   struct type *elttype;
   LONGEST val;
-  const gdb_byte *valaddr = valaddr0 + embedded_offset;
+  int offset_aligned;
 
   type = ada_check_typedef (type);
 
@@ -685,7 +692,7 @@ ada_val_print_1 (struct type *type, cons
       struct value *mark = value_mark ();
       struct value *val;
 
-      val = value_from_contents_and_address (type, valaddr, address);
+      val = value_from_contents_and_address (type, valaddr + offset, address);
       if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)  /* array access type.  */
 	val = ada_coerce_to_simple_array_ptr (val);
       else
@@ -697,32 +704,35 @@ ada_val_print_1 (struct type *type, cons
 	  retn = 0;
 	}
       else
-	retn = ada_val_print_1 (value_type (val), value_contents (val), 0,
+	retn = ada_val_print_1 (value_type (val),
+				value_contents_for_printing (val),
+				value_embedded_offset (val),
 				value_address (val), stream, recurse,
 				NULL, options);
       value_free_to_mark (mark);
       return retn;
     }
 
-  valaddr = ada_aligned_value_addr (type, valaddr);
-  embedded_offset -= valaddr - valaddr0 - embedded_offset;
-  type = printable_val_type (type, valaddr);
+  offset_aligned = offset + ada_aligned_value_addr (type, valaddr) - valaddr;
+  type = printable_val_type (type, valaddr + offset_aligned);
 
   switch (TYPE_CODE (type))
     {
     default:
-      return c_val_print (type, valaddr0, embedded_offset, address, stream,
+      return c_val_print (type, valaddr, offset, address, stream,
 			  recurse, original_value, options);
 
     case TYPE_CODE_PTR:
       {
-	int ret = c_val_print (type, valaddr0, embedded_offset, address, 
+	int ret = c_val_print (type, valaddr, offset, address,
 			       stream, recurse, original_value, options);
 
 	if (ada_is_tag_type (type))
 	  {
-	    struct value *val = 
-	      value_from_contents_and_address (type, valaddr, address);
+	    struct value *val =
+	      value_from_contents_and_address (type,
+					       valaddr + offset_aligned,
+					       address + offset_aligned);
 	    const char *name = ada_tag_name (val);
 
 	    if (name != NULL) 
@@ -736,7 +746,7 @@ ada_val_print_1 (struct type *type, cons
     case TYPE_CODE_RANGE:
       if (ada_is_fixed_point_type (type))
 	{
-	  LONGEST v = unpack_long (type, valaddr);
+	  LONGEST v = unpack_long (type, valaddr + offset_aligned);
 	  int len = TYPE_LENGTH (type);
 
 	  fprintf_filtered (stream, len < 4 ? "%.11g" : "%.17g",
@@ -753,16 +763,18 @@ ada_val_print_1 (struct type *type, cons
 	         its base type.  Perform a conversion, or we will get a
 	         nonsense value.  Actually, we could use the same
 	         code regardless of lengths; I'm just avoiding a cast.  */
-	      struct value *v = value_cast (target_type,
-					    value_from_contents_and_address
-					    (type, valaddr, 0));
-
-	      return ada_val_print_1 (target_type, value_contents (v), 0, 0,
-				      stream, recurse + 1, NULL, options);
+	      struct value *v1
+		= value_from_contents_and_address (type, valaddr + offset, 0);
+	      struct value *v = value_cast (target_type, v1);
+
+	      return ada_val_print_1 (target_type,
+				      value_contents_for_printing (v),
+				      value_embedded_offset (v), 0,
+ 				      stream, recurse + 1, NULL, options);
 	    }
 	  else
 	    return ada_val_print_1 (TYPE_TARGET_TYPE (type),
-				    valaddr0, embedded_offset,
+				    valaddr, offset,
 				    address, stream, recurse,
 				    original_value, options);
 	}
@@ -776,7 +788,8 @@ ada_val_print_1 (struct type *type, cons
 	      struct value_print_options opts = *options;
 
 	      opts.format = format;
-	      print_scalar_formatted (valaddr, type, &opts, 0, stream);
+	      print_scalar_formatted (valaddr + offset_aligned,
+				      type, &opts, 0, stream);
 	    }
           else if (ada_is_system_address_type (type))
             {
@@ -788,7 +801,8 @@ ada_val_print_1 (struct type *type, cons
 
 	      struct gdbarch *gdbarch = get_type_arch (type);
 	      struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
-	      CORE_ADDR addr = extract_typed_address (valaddr, ptr_type);
+	      CORE_ADDR addr = extract_typed_address (valaddr + offset_aligned,
+						      ptr_type);
 
               fprintf_filtered (stream, "(");
               type_print (type, "", stream, -1);
@@ -797,11 +811,14 @@ ada_val_print_1 (struct type *type, cons
             }
 	  else
 	    {
-	      val_print_type_code_int (type, valaddr, stream);
+	      val_print_type_code_int (type, valaddr + offset_aligned, stream);
 	      if (ada_is_character_type (type))
 		{
+		  LONGEST c;
+
 		  fputs_filtered (" ", stream);
-		  ada_printchar (unpack_long (type, valaddr), type, stream);
+		  c = unpack_long (type, valaddr + offset_aligned);
+		  ada_printchar (c, type, stream);
 		}
 	    }
 	  return 0;
@@ -810,11 +827,12 @@ ada_val_print_1 (struct type *type, cons
     case TYPE_CODE_ENUM:
       if (options->format)
 	{
-	  print_scalar_formatted (valaddr, type, options, 0, stream);
+	  print_scalar_formatted (valaddr + offset_aligned,
+				  type, options, 0, stream);
 	  break;
 	}
       len = TYPE_NFIELDS (type);
-      val = unpack_long (type, valaddr);
+      val = unpack_long (type, valaddr + offset_aligned);
       for (i = 0; i < len; i++)
 	{
 	  QUIT;
@@ -840,17 +858,18 @@ ada_val_print_1 (struct type *type, cons
 
     case TYPE_CODE_FLAGS:
       if (options->format)
-	print_scalar_formatted (valaddr, type, options, 0, stream);
+	print_scalar_formatted (valaddr + offset_aligned,
+				type, options, 0, stream);
       else
-	val_print_type_code_flags (type, valaddr, stream);
+	val_print_type_code_flags (type, valaddr + offset_aligned, stream);
       break;
 
     case TYPE_CODE_FLT:
       if (options->format)
-	return c_val_print (type, valaddr0, embedded_offset, address, stream,
+	return c_val_print (type, valaddr, offset, address, stream,
 			    recurse, original_value, options);
       else
-	ada_print_floating (valaddr0 + embedded_offset, type, stream);
+	ada_print_floating (valaddr + offset, type, stream);
       break;
 
     case TYPE_CODE_UNION:
@@ -862,14 +881,15 @@ ada_val_print_1 (struct type *type, cons
 	}
       else
 	{
-	  print_record (type, valaddr, stream, recurse, original_value,
-			options);
+	  print_record (type, valaddr, offset_aligned,
+			stream, recurse, original_value, options);
 	  return 0;
 	}
 
     case TYPE_CODE_ARRAY:
-      return ada_val_print_array (type, valaddr, address, stream,
-				  recurse, original_value, options);
+      return ada_val_print_array (type, valaddr, offset_aligned,
+				  address, stream, recurse, original_value,
+				  options);
 
     case TYPE_CODE_REF:
       /* For references, the debugger is expected to print the value as
@@ -881,17 +901,19 @@ ada_val_print_1 (struct type *type, cons
       
       if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF)
         {
-          LONGEST deref_val_int = (LONGEST) unpack_pointer (type, valaddr);
+          CORE_ADDR deref_val_int
+	    = unpack_pointer (type, valaddr + offset_aligned);
 
           if (deref_val_int != 0)
             {
               struct value *deref_val =
-                ada_value_ind (value_from_longest
+                ada_value_ind (value_from_pointer
                                (lookup_pointer_type (elttype),
                                 deref_val_int));
 
               val_print (value_type (deref_val),
-                         value_contents (deref_val), 0,
+                         value_contents_for_printing (deref_val),
+                         value_embedded_offset (deref_val),
                          value_address (deref_val), stream, recurse + 1,
 			 original_value, options, current_language);
             }
@@ -908,25 +930,28 @@ ada_val_print_1 (struct type *type, cons
 }
 
 static int
-print_variant_part (struct type *type, int field_num, const gdb_byte *valaddr,
+print_variant_part (struct type *type, int field_num,
+		    const gdb_byte *valaddr, int offset,
 		    struct ui_file *stream, int recurse,
 		    const struct value *val,
 		    const struct value_print_options *options,
 		    int comma_needed,
-		    struct type *outer_type, const gdb_byte *outer_valaddr)
+		    struct type *outer_type, int outer_offset)
 {
   struct type *var_type = TYPE_FIELD_TYPE (type, field_num);
-  int which = ada_which_variant_applies (var_type, outer_type, 
outer_valaddr);
+  int which = ada_which_variant_applies (var_type, outer_type,
+					 valaddr + outer_offset);
 
   if (which < 0)
     return 0;
   else
     return print_field_values
       (TYPE_FIELD_TYPE (var_type, which),
-       valaddr + TYPE_FIELD_BITPOS (type, field_num) / HOST_CHAR_BIT
+       valaddr,
+       offset + TYPE_FIELD_BITPOS (type, field_num) / HOST_CHAR_BIT
        + TYPE_FIELD_BITPOS (var_type, which) / HOST_CHAR_BIT,
        stream, recurse, val, options,
-       comma_needed, outer_type, outer_valaddr);
+       comma_needed, outer_type, outer_offset);
 }
 
 int
@@ -974,12 +999,14 @@ ada_value_print (struct value *val0, str
 
   opts = *options;
   opts.deref_ref = 1;
-  return (val_print (type, value_contents (val), 0, address,
+  return (val_print (type, value_contents_for_printing (val),
+		     value_embedded_offset (val), address,
 		     stream, 0, val, &opts, current_language));
 }
 
 static void
 print_record (struct type *type, const gdb_byte *valaddr,
+	      int offset,
 	      struct ui_file *stream, int recurse,
 	      const struct value *val,
 	      const struct value_print_options *options)
@@ -988,8 +1015,9 @@ print_record (struct type *type, const g
 
   fprintf_filtered (stream, "(");
 
-  if (print_field_values (type, valaddr, stream, recurse, val, options,
-			  0, type, valaddr) != 0 && options->pretty)
+  if (print_field_values (type, valaddr, offset,
+			  stream, recurse, val, options,
+			  0, type, offset) != 0 && options->pretty)
     {
       fprintf_filtered (stream, "\n");
       print_spaces_filtered (2 * recurse, stream);
@@ -1014,11 +1042,11 @@ print_record (struct type *type, const g
 
 static int
 print_field_values (struct type *type, const gdb_byte *valaddr,
-		    struct ui_file *stream, int recurse,
+		    int offset, struct ui_file *stream, int recurse,
 		    const struct value *val,
 		    const struct value_print_options *options,
 		    int comma_needed,
-		    struct type *outer_type, const gdb_byte *outer_valaddr)
+		    struct type *outer_type, int outer_offset)
 {
   int i, len;
 
@@ -1033,18 +1061,20 @@ print_field_values (struct type *type, c
 	{
 	  comma_needed =
 	    print_field_values (TYPE_FIELD_TYPE (type, i),
-				valaddr
-				+ TYPE_FIELD_BITPOS (type, i) / HOST_CHAR_BIT,
+				valaddr,
+				(offset
+				 + TYPE_FIELD_BITPOS (type, i) / HOST_CHAR_BIT),
 				stream, recurse, val, options,
-				comma_needed, type, valaddr);
+				comma_needed, type, offset);
 	  continue;
 	}
       else if (ada_is_variant_part (type, i))
 	{
 	  comma_needed =
 	    print_variant_part (type, i, valaddr,
-				stream, recurse, val, options, comma_needed,
-				outer_type, outer_valaddr);
+				offset, stream, recurse, val,
+				options, comma_needed,
+				outer_type, outer_offset);
 	  continue;
 	}
 
@@ -1109,7 +1139,9 @@ print_field_values (struct type *type, c
 						  TYPE_FIELD_TYPE (type, i));
 	      opts = *options;
 	      opts.deref_ref = 0;
-	      val_print (TYPE_FIELD_TYPE (type, i), value_contents (v), 0, 0,
+	      val_print (TYPE_FIELD_TYPE (type, i),
+			 value_contents_for_printing (v),
+			 value_embedded_offset (v), 0,
 			 stream, recurse + 1, v,
 			 &opts, current_language);
 	    }
@@ -1120,8 +1152,10 @@ print_field_values (struct type *type, c
 
 	  opts.deref_ref = 0;
 	  ada_val_print (TYPE_FIELD_TYPE (type, i),
-			 valaddr + TYPE_FIELD_BITPOS (type, i) / HOST_CHAR_BIT,
-			 0, 0, stream, recurse + 1, val, &opts);
+			 valaddr,
+			 (offset
+			  + TYPE_FIELD_BITPOS (type, i) / HOST_CHAR_BIT),
+			 0, stream, recurse + 1, val, &opts);
 	}
       annotate_field_end ();
     }
Index: src/gdb/p-lang.h
===================================================================
--- src.orig/gdb/p-lang.h	2011-01-24 12:54:32.000000000 +0000
+++ src/gdb/p-lang.h	2011-01-24 12:54:35.246177002 +0000
@@ -70,6 +70,7 @@ extern void
   pascal_type_print_varspec_prefix (struct type *, struct ui_file *, int, int);
 
 extern void pascal_object_print_value_fields (struct type *, const gdb_byte *,
+					      int,
 					      CORE_ADDR, struct ui_file *,
 					      int,
 					      const struct value *,
Index: src/gdb/d-valprint.c
===================================================================
--- src.orig/gdb/d-valprint.c	2011-01-24 12:54:32.000000000 +0000
+++ src/gdb/d-valprint.c	2011-01-24 12:54:35.246177002 +0000
@@ -45,7 +45,6 @@ dynamic_array_type (struct type *type, c
       struct type *elttype;
       struct type *true_type;
       struct type *ptr_type;
-      const gdb_byte *ptraddr;
       struct value *val;
       int length;
 
@@ -60,10 +59,11 @@ dynamic_array_type (struct type *type, c
 
       true_type = lookup_array_range_type (true_type, 0, length - 1);
       val = value_at (true_type, addr);
-      ptraddr = value_contents (val);
 
-      return d_val_print (true_type, ptraddr, 0, addr, stream, recurse + 1,
-			  NULL, options);
+      return d_val_print (true_type,
+			  value_contents_for_printing (val),
+			  value_embedded_offset (val), addr,
+			  stream, recurse + 1, val, options);
     }
   return -1;
 }
Index: src/gdb/jv-valprint.c
===================================================================
--- src.orig/gdb/jv-valprint.c	2011-01-24 12:54:32.000000000 +0000
+++ src/gdb/jv-valprint.c	2011-01-24 12:54:35.246177002 +0000
@@ -259,6 +259,7 @@ java_value_print (struct value *val, str
 
 static void
 java_print_value_fields (struct type *type, const gdb_byte *valaddr,
+			 int offset,
 			 CORE_ADDR address, struct ui_file *stream,
 			 int recurse,
 			 const struct value *val,
@@ -304,11 +305,11 @@ java_print_value_fields (struct type *ty
 
 	  base_valaddr = valaddr;
 
-	  java_print_value_fields (baseclass, base_valaddr, address + boffset,
+	  java_print_value_fields (baseclass, base_valaddr,
+				   offset + boffset, address,
 				   stream, recurse + 1, val, options);
 	  fputs_filtered (", ", stream);
 	}
-
     }
 
   if (!len && n_baseclasses == 1)
@@ -412,8 +413,9 @@ java_print_value_fields (struct type *ty
 		{
 		  struct value_print_options opts;
 
-		  v = value_from_longest (TYPE_FIELD_TYPE (type, i),
-				   unpack_field_as_long (type, valaddr, i));
+		  v = value_from_longest
+		    (TYPE_FIELD_TYPE (type, i),
+		     unpack_field_as_long (type, valaddr + offset, i));
 
 		  opts = *options;
 		  opts.deref_ref = 0;
@@ -454,9 +456,9 @@ java_print_value_fields (struct type *ty
 
 		  opts.deref_ref = 0;
 		  val_print (TYPE_FIELD_TYPE (type, i),
-			     valaddr + TYPE_FIELD_BITPOS (type, i) / 8, 0,
-			     address + TYPE_FIELD_BITPOS (type, i) / 8,
-			     stream, recurse + 1, val, &opts,
+			     valaddr,
+			     offset + TYPE_FIELD_BITPOS (type, i) / 8,
+			     address, stream, recurse + 1, val, &opts,
 			     current_language);
 		}
 	    }
@@ -497,7 +499,8 @@ java_val_print (struct type *type, const
     case TYPE_CODE_PTR:
       if (options->format && options->format != 's')
 	{
-	  print_scalar_formatted (valaddr, type, options, 0, stream);
+	  print_scalar_formatted (valaddr + embedded_offset,
+				  type, options, 0, stream);
 	  break;
 	}
 #if 0
@@ -507,14 +510,15 @@ java_val_print (struct type *type, const
 	  /* Print vtable entry - we only get here if we ARE using
 	     -fvtable_thunks.  (Otherwise, look under TYPE_CODE_STRUCT.)  */
 	  /* Extract an address, assume that it is unsigned.  */
-	  print_address_demangle (gdbarch,
-				  extract_unsigned_integer (valaddr,
-							    TYPE_LENGTH (type)),
-				  stream, demangle);
+	  print_address_demangle
+	    (gdbarch,
+	     extract_unsigned_integer (valaddr + embedded_offset,
+				       TYPE_LENGTH (type)),
+	     stream, demangle);
 	  break;
 	}
 #endif
-      addr = unpack_pointer (type, valaddr);
+      addr = unpack_pointer (type, valaddr + embedded_offset);
       if (addr == 0)
 	{
 	  fputs_filtered ("null", stream);
@@ -548,20 +552,22 @@ java_val_print (struct type *type, const
 
 	  opts.format = (options->format ? options->format
 			 : options->output_format);
-	  print_scalar_formatted (valaddr, type, &opts, 0, stream);
+	  print_scalar_formatted (valaddr + embedded_offset,
+				  type, &opts, 0, stream);
 	}
       else if (TYPE_CODE (type) == TYPE_CODE_CHAR
 	       || (TYPE_CODE (type) == TYPE_CODE_INT
 		   && TYPE_LENGTH (type) == 2
 		   && strcmp (TYPE_NAME (type), "char") == 0))
-	LA_PRINT_CHAR ((int) unpack_long (type, valaddr), type, stream);
+	LA_PRINT_CHAR ((int) unpack_long (type, valaddr + embedded_offset),
+		       type, stream);
       else
-	val_print_type_code_int (type, valaddr, stream);
+	val_print_type_code_int (type, valaddr + embedded_offset, stream);
       break;
 
     case TYPE_CODE_STRUCT:
-      java_print_value_fields (type, valaddr, address, stream, recurse,
-			       val, options);
+      java_print_value_fields (type, valaddr, embedded_offset,
+			       address, stream, recurse, val, options);
       break;
 
     default:
Index: src/gdb/f-valprint.c
===================================================================
--- src.orig/gdb/f-valprint.c	2011-01-24 12:54:32.000000000 +0000
+++ src/gdb/f-valprint.c	2011-01-24 12:54:35.246177002 +0000
@@ -163,7 +163,8 @@ f77_create_arrayprint_offset_tbl (struct
 
 static void
 f77_print_array_1 (int nss, int ndimensions, struct type *type,
-		   const gdb_byte *valaddr, CORE_ADDR address,
+		   const gdb_byte *valaddr,
+		   int embedded_offset, CORE_ADDR address,
 		   struct ui_file *stream, int recurse,
 		   const struct value *val,
 		   const struct value_print_options *options,
@@ -179,8 +180,9 @@ f77_print_array_1 (int nss, int ndimensi
 	{
 	  fprintf_filtered (stream, "( ");
 	  f77_print_array_1 (nss + 1, ndimensions, TYPE_TARGET_TYPE (type),
-			     valaddr + i * F77_DIM_OFFSET (nss),
-			     address + i * F77_DIM_OFFSET (nss),
+			     valaddr,
+			     embedded_offset + i * F77_DIM_OFFSET (nss),
+			     address,
 			     stream, recurse, val, options, elts);
 	  fprintf_filtered (stream, ") ");
 	}
@@ -193,10 +195,10 @@ f77_print_array_1 (int nss, int ndimensi
 	   i++, (*elts)++)
 	{
 	  val_print (TYPE_TARGET_TYPE (type),
-		     valaddr + i * F77_DIM_OFFSET (ndimensions),
-		     0,
-		     address + i * F77_DIM_OFFSET (ndimensions),
-		     stream, recurse, val, options, current_language);
+		     valaddr,
+		     embedded_offset + i * F77_DIM_OFFSET (ndimensions),
+		     address, stream, recurse,
+		     val, options, current_language);
 
 	  if (i != (F77_DIM_SIZE (nss) - 1))
 	    fprintf_filtered (stream, ", ");
@@ -213,6 +215,7 @@ f77_print_array_1 (int nss, int ndimensi
 
 static void
 f77_print_array (struct type *type, const gdb_byte *valaddr,
+		 int embedded_offset,
 		 CORE_ADDR address, struct ui_file *stream,
 		 int recurse,
 		 const struct value *val,
@@ -234,8 +237,8 @@ Type node corrupt! F77 arrays cannot hav
 
   f77_create_arrayprint_offset_tbl (type, stream);
 
-  f77_print_array_1 (1, ndimensions, type, valaddr, address, stream,
-		     recurse, val, options, &elts);
+  f77_print_array_1 (1, ndimensions, type, valaddr, embedded_offset,
+		     address, stream, recurse, val, options, &elts);
 }
 
 
@@ -266,25 +269,27 @@ f_val_print (struct type *type, const gd
     case TYPE_CODE_STRING:
       f77_get_dynamic_length_of_aggregate (type);
       LA_PRINT_STRING (stream, builtin_type (gdbarch)->builtin_char,
-		       valaddr, TYPE_LENGTH (type), NULL, 0, options);
+		       valaddr + embedded_offset,
+		       TYPE_LENGTH (type), NULL, 0, options);
       break;
 
     case TYPE_CODE_ARRAY:
       fprintf_filtered (stream, "(");
-      f77_print_array (type, valaddr, address, stream,
-		       recurse, original_value, options);
+      f77_print_array (type, valaddr, embedded_offset,
+		       address, stream, recurse, original_value, options);
       fprintf_filtered (stream, ")");
       break;
 
     case TYPE_CODE_PTR:
       if (options->format && options->format != 's')
 	{
-	  print_scalar_formatted (valaddr, type, options, 0, stream);
+	  print_scalar_formatted (valaddr + embedded_offset,
+				  type, options, 0, stream);
 	  break;
 	}
       else
 	{
-	  addr = unpack_pointer (type, valaddr);
+	  addr = unpack_pointer (type, valaddr + embedded_offset);
 	  elttype = check_typedef (TYPE_TARGET_TYPE (type));
 
 	  if (TYPE_CODE (elttype) == TYPE_CODE_FUNC)
@@ -347,7 +352,8 @@ f_val_print (struct type *type, const gd
     case TYPE_CODE_FUNC:
       if (options->format)
 	{
-	  print_scalar_formatted (valaddr, type, options, 0, stream);
+	  print_scalar_formatted (valaddr + embedded_offset,
+				  type, options, 0, stream);
 	  break;
 	}
       /* FIXME, we should consider, at least for ANSI C language, eliminating
@@ -366,36 +372,41 @@ f_val_print (struct type *type, const gd
 
 	  opts.format = (options->format ? options->format
 			 : options->output_format);
-	  print_scalar_formatted (valaddr, type, &opts, 0, stream);
+	  print_scalar_formatted (valaddr + embedded_offset,
+				  type, &opts, 0, stream);
 	}
       else
 	{
-	  val_print_type_code_int (type, valaddr, stream);
+	  val_print_type_code_int (type, valaddr + embedded_offset, stream);
 	  /* C and C++ has no single byte int type, char is used instead.
 	     Since we don't know whether the value is really intended to
 	     be used as an integer or a character, print the character
 	     equivalent as well.  */
 	  if (TYPE_LENGTH (type) == 1)
 	    {
+	      LONGEST c;
+
 	      fputs_filtered (" ", stream);
-	      LA_PRINT_CHAR ((unsigned char) unpack_long (type, valaddr),
-			     type, stream);
+	      c = unpack_long (type, valaddr + embedded_offset);
+	      LA_PRINT_CHAR ((unsigned char) c, type, stream);
 	    }
 	}
       break;
 
     case TYPE_CODE_FLAGS:
       if (options->format)
-	  print_scalar_formatted (valaddr, type, options, 0, stream);
+	print_scalar_formatted (valaddr + embedded_offset,
+				type, options, 0, stream);
       else
-	val_print_type_code_flags (type, valaddr, stream);
+	val_print_type_code_flags (type, valaddr + embedded_offset, stream);
       break;
 
     case TYPE_CODE_FLT:
       if (options->format)
-	print_scalar_formatted (valaddr, type, options, 0, stream);
+	print_scalar_formatted (valaddr + embedded_offset,
+				type, options, 0, stream);
       else
-	print_floating (valaddr, type, stream);
+	print_floating (valaddr + embedded_offset, type, stream);
       break;
 
     case TYPE_CODE_VOID:
@@ -418,11 +429,12 @@ f_val_print (struct type *type, const gd
 
 	  opts.format = (options->format ? options->format
 			 : options->output_format);
-	  print_scalar_formatted (valaddr, type, &opts, 0, stream);
+	  print_scalar_formatted (valaddr + embedded_offset,
+				  type, &opts, 0, stream);
 	}
       else
 	{
-	  val = extract_unsigned_integer (valaddr,
+	  val = extract_unsigned_integer (valaddr + embedded_offset,
 					  TYPE_LENGTH (type), byte_order);
 	  if (val == 0)
 	    fprintf_filtered (stream, ".FALSE.");
@@ -433,7 +445,8 @@ f_val_print (struct type *type, const gd
 	    {
 	      /* Bash the type code temporarily.  */
 	      TYPE_CODE (type) = TYPE_CODE_INT;
-	      val_print (type, valaddr, 0, address, stream, recurse,
+	      val_print (type, valaddr, embedded_offset,
+			 address, stream, recurse,
 			 original_value, options, current_language);
 	      /* Restore the type code so later uses work as intended.  */
 	      TYPE_CODE (type) = TYPE_CODE_BOOL;
@@ -444,9 +457,10 @@ f_val_print (struct type *type, const gd
     case TYPE_CODE_COMPLEX:
       type = TYPE_TARGET_TYPE (type);
       fputs_filtered ("(", stream);
-      print_floating (valaddr, type, stream);
+      print_floating (valaddr + embedded_offset, type, stream);
       fputs_filtered (",", stream);
-      print_floating (valaddr + TYPE_LENGTH (type), type, stream);
+      print_floating (valaddr + embedded_offset + TYPE_LENGTH (type),
+		      type, stream);
       fputs_filtered (")", stream);
       break;
 
@@ -466,8 +480,9 @@ f_val_print (struct type *type, const gd
         {
           int offset = TYPE_FIELD_BITPOS (type, index) / 8;
 
-          val_print (TYPE_FIELD_TYPE (type, index), valaddr + offset,
-		     embedded_offset, address, stream, recurse + 1,
+          val_print (TYPE_FIELD_TYPE (type, index), valaddr,
+		     embedded_offset + offset,
+		     address, stream, recurse + 1,
 		     original_value, options, current_language);
           if (index != TYPE_NFIELDS (type) - 1)
             fputs_filtered (", ", stream);
Index: src/gdb/testsuite/gdb.base/printcmds.c
===================================================================
--- src.orig/gdb/testsuite/gdb.base/printcmds.c	2011-01-24 
13:10:14.000000000 +0000
+++ src/gdb/testsuite/gdb.base/printcmds.c	2011-01-24 13:10:43.486176996 
+0000
@@ -96,6 +96,28 @@ enum some_volatile_enum { enumvolval1, e
    name.  See PR11827.  */
 volatile enum some_volatile_enum some_volatile_enum = enumvolval1;
 
+/* A structure with an embedded array at an offset > 0.  The array has
+   all elements with the same repeating value, which must not be the
+   same as the value of the preceding fields in the structure for the
+   test to be effective.  This tests whether GDB uses the correct
+   element content offsets (relative to the complete `some_struct'
+   value) when counting value repetitions.  */
+struct some_struct
+{
+  int a;
+  int b;
+  unsigned char array[20];
+} some_struct = {
+  0x12345678,
+  0x87654321,
+  {
+    0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+    0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+    0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+    0xaa, 0xaa, 0xaa, 0xaa, 0xaa
+  }
+};
+
 /* -- */
 
 int main ()
Index: src/gdb/testsuite/gdb.base/printcmds.exp
===================================================================
--- src.orig/gdb/testsuite/gdb.base/printcmds.exp	2011-01-24 
13:10:14.000000000 +0000
+++ src/gdb/testsuite/gdb.base/printcmds.exp	2011-01-24 13:10:43.486176996 
+0000
@@ -474,6 +474,18 @@ proc test_print_repeats_10 {} {
     }
 }
 
+# This tests whether GDB uses the correct element content offsets
+# (relative to the complete `some_struct' value) when counting value
+# repetitions.
+
+proc test_print_repeats_embedded_array {} {
+    global gdb_prompt
+
+    gdb_test_escape_braces "p/x some_struct" \
+	"= {a = 0x12345678, b = 0x87654321, array = {0xaa <repeats 20 times>}}" \
+	"correct element repeats in array embedded at offset > 0"
+}
+
 proc test_print_strings {} {
     global gdb_prompt
 
@@ -818,6 +830,7 @@ test_float_rejected
 test_character_literals_accepted
 test_print_all_chars
 test_print_repeats_10
+test_print_repeats_embedded_array
 test_print_strings
 test_print_int_arrays
 test_print_typedef_arrays


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]