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: Checked in: [RFA] read_frame_register_value and big endian arches


Joel Brobecker wrote:

> > note that for big-endian architectures, value_offset is already
> > correct, so if you'd respect it, you wouldn't need any special-purpose
> > big-endian code.
> > 
> > Also, if you'd respect value_offset, the SPU special cases would work.
> 
> I will try to fix ASAP. I am sorry if that caused some fustration
> when trying to do your testing. I didn't want to do the work in
> the first place but I, too, got my testing broken by someone else's
> change!

No problem :-)

I've now implemented a fix for read_frame_register_value by simply
following the same logic as get_frame_register_bytes does.

This fixes the regressions on SPU for me.  Does this work for the
platforms where you were seeing issues as well?

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 16:49:05 -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)));
 
   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]