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]

[commit] Re: Checked in: [RFA] read_frame_register_value and big endian arches


Joel Brobecker wrote:
> > This fixes the regressions on SPU for me.  Does this work for the
> > platforms where you were seeing issues as well?
> 
> Thanks for doing this, Ulrich. I tested the patch on x86_64-linux
> for kicks, but also on sparc-elf and avr, where the problems where
> detected, and no regression.

Thanks for the verification!

> Just one tiny detail:
> 
> > +  struct gdbarch *gdbarch = get_frame_arch (frame);
> >    int offset = 0;
> > +  int reg_offset = value_offset (value);
> >    int regnum = VALUE_REGNUM (value);
> >    const int len = TYPE_LENGTH (check_typedef (value_type (value)));
>      ^^^^^
> 
> I had to remove the const, since we are decrementing len each time
> we read contents from a register...

Oops.  I noticed this when building, and fixed it in my source
tree, but then forgot to regenerate the patch ...  Sorry.

I've now checked in the version below.

Bye,
Ulrich


ChangeLog:

	* findvar.c (read_frame_register_value): Respect value_offset
	of the register value.  Remove big-endian special case.

Index: gdb/findvar.c
===================================================================
RCS file: /cvs/src/src/gdb/findvar.c,v
retrieving revision 1.139
diff -u -p -r1.139 findvar.c
--- gdb/findvar.c	10 Nov 2011 17:14:40 -0000	1.139
+++ gdb/findvar.c	18 Nov 2011 20:01:55 -0000
@@ -631,31 +631,37 @@ default_value_from_register (struct type
 void
 read_frame_register_value (struct value *value, struct frame_info *frame)
 {
+  struct gdbarch *gdbarch = get_frame_arch (frame);
   int offset = 0;
+  int reg_offset = value_offset (value);
   int regnum = VALUE_REGNUM (value);
-  const int len = TYPE_LENGTH (check_typedef (value_type (value)));
+  int len = TYPE_LENGTH (check_typedef (value_type (value)));
 
   gdb_assert (VALUE_LVAL (value) == lval_register);
 
-  while (offset < len)
+  /* Skip registers wholly inside of REG_OFFSET.  */
+  while (reg_offset >= register_size (gdbarch, regnum))
+    {
+      reg_offset -= register_size (gdbarch, regnum);
+      regnum++;
+    }
+
+  /* Copy the data.  */
+  while (len > 0)
     {
       struct value *regval = get_frame_register_value (frame, regnum);
-      int reg_len = TYPE_LENGTH (value_type (regval));
-      int reg_offset = 0;
+      int reg_len = TYPE_LENGTH (value_type (regval)) - reg_offset;
 
       /* If the register length is larger than the number of bytes
          remaining to copy, then only copy the appropriate bytes.  */
-      if (offset + reg_len > len)
-	{
-	  reg_len = len - offset;
-	  if (gdbarch_byte_order (get_frame_arch (frame)) == BFD_ENDIAN_BIG)
-	    reg_offset = TYPE_LENGTH (value_type (regval)) - reg_len;
-	}
+      if (reg_len > len)
+	reg_len = len;
 
-      value_contents_copy (value, offset, regval,
-                           value_offset (regval) + reg_offset, reg_len);
+      value_contents_copy (value, offset, regval, reg_offset, reg_len);
 
       offset += reg_len;
+      len -= reg_len;
+      reg_offset = 0;
       regnum++;
     }
 }


-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


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