This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: Checked in: [RFA] read_frame_register_value and big endian arches
- From: "Ulrich Weigand" <uweigand at de dot ibm dot com>
- To: brobecker at adacore dot com (Joel Brobecker)
- Cc: gdb-patches at sourceware dot org, tromey at redhat dot com
- Date: Fri, 18 Nov 2011 18:40:04 +0100 (CET)
- Subject: 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