From: Andrew Cagney <ac131313@cygnus.com>
To: David Taylor <taylor@cygnus.com>, gdb-patches@sources.redhat.com
Subject: Re: [RFA] regcache.c (register_fetched) + related changes
Date: Tue, 13 Mar 2001 08:52:00 -0000 [thread overview]
Message-ID: <3AAE44A1.F975DA2A@cygnus.com> (raw)
In-Reply-To: <3A9FF8B5.E88307BD@cygnus.com>
To follow this up, David went through the problem in detail by phone. I
belive the below describes the underlying problem.
Consider an architecture with three registers:
$s0 $s1
$d0
where $d0 is made up of both $s0 and $s1. Using the current code, the
developer would lay this out as:
REGNUM name size offset
0 s0 1 0
1 s1 1 1
then the pseudo as either
2 d0 2 0
or
2 d0 2 2
The choice is pretty arbitrary. Under my proposed changes to make
everything bound to a frame, the user would instead lay it out as:
RAWNUM rawname size
0 rs0 1
1 rs1 1
and then the frame/cooked registers would be arranged as:
REGNUM name size
0 s0 1
1 s1 1
2 d0 2
and d0 would be implemented as:
read/write rs0
read/write rs1
Anyway....
The user enters:
(gdb) set $d0 = value
GDB creates an expression tree that contains an LVAL with (at a guess)
the following:
register number
register size
register address (in regcache or in memory)
this infomation is then used (valops.c) to write the register value
using write_register_bytes().
[Side note one: Previous discussion has agreed that
write_register_bytes() is bad. The above should be changed so that it
stores the location of the register in some less implementation specific
way. Fixing this little nastyness is part of binding everything to a
frame.]
write_register_bytes() iterates through all the registers (real and
pseudo) looking to see where those bytes need to go. In michaels case,
that code would generate one or more calls (depending on how the
registers are layed out). One of the calls would be:
write_register_gen (d1regnum, buffer);
Write register gen, then writes bytes into the pseudo register, set
register_valid[] for the pseudo register and finally calls:
store_register (d1regnum);
The immediate problem is that the pseudo registers register_valid[] bit
has been set. That is a pseudo register has been marked as valid in the
register cache.
This becomes a problem when a user goes to again display that or one of
the other registers affected by that pseudo. For instance consider:
(gdb) set $d0 = 22
(gdb) set $s1 = 1
(gdb) set $s0 = 0
(gdb) print $d0
If you follow the register read side through, you'll find that $d0 can
potentially become inconsistent with s0/s1 because $d0 is considered to
already be valid.
The obvious fix is to modify store_register() so that it clears
register_valid[] and thus ensures that D1 is never valid in the cache.
(an invalid register is always fetched/computed).
Discussion with David suggests a better fix - one that is more in line
with with the direction that the register interface is going - catch
writes to pseudos before they hit the cache so that the inferior-arch
can redirect them as needed.
The first bit of the change is to modify write_register_gen() to ask the
architecture to perform the write vis:
write_register_gen (regnum, buf)
gdbarch_write_register_gen (regnum, buf)
In Davids case, write register gen would look like:
if (regnum < NUM_REGS)
regcache_write (regnum, buff)
else if (regnum == d0regnum)
regcache_write (s0regnum, buff)
regcache_write (s1regnum, buff)
regcache_write() would only allow writes to 0 .. NUM_REG. Legacy code
would use a compatiblity function that would also allow writes to
NUM_REG .. NUM_REG+PSEUDO_NUM_REG. Sane code would just set
gdbarch_write_register_gen() to regcache_write
Of course, life isn't that simple. One additional change is to
write_register() which should be calling write_register_bytes(). This
also avoids the write_register_bytes() problem and completly avoids
read_register_bytes() :-(
However, on the bright side. This does mean that Davids immediate
problem is addressed _and_ the need to blat register_valid[] is
avoided. As an additional bonus, this pushes the code in the general
direction of separate cooked and raw registers. In the future, the
above gdbarch_write_register_gen would become part of a write
frame-register function.
Andrew
next prev parent reply other threads:[~2001-03-13 8:52 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2001-03-01 16:59 David Taylor
2001-03-02 9:06 ` Andrew Cagney
2001-03-02 11:49 ` Andrew Cagney
2001-03-13 8:52 ` Andrew Cagney [this message]
-- strict thread matches above, loose matches on Subject: below --
2001-03-01 10:34 David Taylor
2001-03-01 14:07 ` Andrew Cagney
2001-02-28 13:14 David Taylor
2001-02-28 15:17 ` Andrew Cagney
2001-02-28 16:01 ` Andrew Cagney
2001-02-28 18:27 ` Andrew Cagney
2001-02-27 15:27 David Taylor
2001-02-27 14:25 David Taylor
2001-02-27 14:48 ` Michael Snyder
2001-02-27 15:21 ` Andrew Cagney
2001-02-27 17:40 ` Andrew Cagney
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3AAE44A1.F975DA2A@cygnus.com \
--to=ac131313@cygnus.com \
--cc=gdb-patches@sources.redhat.com \
--cc=taylor@cygnus.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox