This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: [RFC/mips] Problem with fetching/setting 32 bit registers
- From: Daniel Jacobowitz <drow at false dot org>
- To: Joel Brobecker <brobecker at adacore dot com>
- Cc: gdb-patches at sources dot redhat dot com
- Date: Wed, 23 Mar 2005 23:26:30 -0500
- Subject: Re: [RFC/mips] Problem with fetching/setting 32 bit registers
- References: <20050324041407.GG1324@adacore.com>
On Wed, Mar 23, 2005 at 08:14:07PM -0800, Joel Brobecker wrote:
> What I found was that the problem was related to the fact that
> the FSR register is 32 bits. So the cooked register type was set
> to a 32 bits type, while underneath, the value provided by the
> kernel is located in a 64 bits buffer. And looking close, I found
> that we're reading and writing th wrong end of the buffer :-(.
>
> Here is the relevant code using when reading a pseudo register
> whose size is smaller than the size of the cooked register:
>
> else if (register_size (gdbarch, rawnum) >
> register_size (gdbarch, cookednum))
> {
> if (gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p
> || TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
> regcache_raw_read_part (regcache, rawnum, 0, 4, buf);
> else
> regcache_raw_read_part (regcache, rawnum, 4, 4, buf);
>
> In our case (mips-irix), we have a big-endian byte order, and
> therefore read the register value from the last 4 bytes, while
> I found out that they are actually in the first 4.
This appears to be a bug in your native support, at least relative to
the rest of the MIPS port.
> - || TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
> + || TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE
> + || gdbarch_osabi (current_gdbarch) == GDB_OSABI_IRIX)
> And it works very well. In fact, not only does it fix the problem
> exposed here, but it does help a lot in the testsuite as well
> (with function calls, and signal testcases).
>
> But I am hesitating a bit. It looks a bit like a hack to be specifying
> specifically IRIX here. I am afraid that there might be another way of
> fixing this more cleanly. But I don't see anything. One idea I had was
> to add yet another flag in the tdep part to say force the side where
> to look. But that wouldn't very practical either. So I'm left with
> the change above.
??? What I'm not getting from your explanation is what besides the FSR
is affected. It looks to me like you want to take this (irix5-nat.c):
/* FIXME, this is wrong for the N32 ABI which has 64 bit FP regs. */
for (regi = 0; regi < 32; regi++)
regcache_raw_supply (current_regcache, FP0_REGNUM + regi,
(char *) &fpregsetp->fp_r.fp_regs[regi]);
regcache_raw_supply (current_regcache,
mips_regnum (current_gdbarch)->fp_control_status,
(char *) &fpregsetp->fp_csr);
... and fix it.
The real funny bit of the whole story appears to be (mips-tdep.c):
else if (regnum < NUM_REGS)
{
/* The raw or ISA registers. These are all sized according to
the ISA regsize. */
if (mips_isa_regsize (gdbarch) == 4)
return builtin_type_int32;
else
return builtin_type_int64;
}
I don't know why the raw view of this register is 64-bit. That's
probably affecting the mips-linux port too. However, changing that
messes with the remote protocol, so we're probably stuck.
--
Daniel Jacobowitz
CodeSourcery, LLC