This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: [PATCH]: Fixes for pseudo regs support
- To: Andrew Cagney <ac131313 at cygnus dot com>
- Subject: Re: [PATCH]: Fixes for pseudo regs support
- From: Stephane Carrez <Stephane dot Carrez at worldnet dot fr>
- Date: Tue, 21 Nov 2000 23:55:46 +0100
- CC: gdb-patches at sourceware dot cygnus dot com
- References: <39A5B4A7.8261D654@worldnet.fr> <3A06ACF1.AA32DF9C@cygnus.com>
Hi Andrew,
Andrew Cagney wrote:
>
> A pseudo register can't lie in memory as it is constructed from one or
> more real registers. The frame info code needs to be able to construct,
> on the fly, a pseudo register from a combination of both saved registers
> and real registers.
Ok. So, I'm back to my initial problem now.
I have registers that lie in memory. These registers are seen as
real registers and they are also saved within the frame.
>
> Lets consider a hypothetical architecture with N real registers
> (r[0]..r[N]) and M pseudo registers (p0..pN). Each pseudo register is
> contructed using something from all the real registers vis:
>
> p[i] == pseudo (i, r[0], r[1], ...)
>
It is not my case. The pseudos are not constructed from real registers.
> When the program stops, the inner most stack frame is being examined.
> Determining a pseudo value is easy as all the real real registers are
> available - their values can be obtained directly from the register
> buffer.
>
> When you start to move up and down between frames, however, things get
> messy. Lets look at a typical stack frame.
>
> main()
> calls outer()
>
> outer()
> prologue saves r[1]
> being used by main()
> on stack
>
> calls middle()
>
> middle()
> prologue saves r[2]
> being used by outer()
> on stack
>
> calls inner()
>
> inner()
> prologue saves r[1]
> being used by middle()
> on stack
>
> somewhere in inner's body.
>
> If the above program halted, inner() would be the currently selected
> frame and the register buffer would contain the current registers.
>
> When middle()'s frame is selected, all registers except r[1] are in the
> register buffer. r[1] is found in inner()'s stack frame.
>
> When outer()'s frame is selected, all registers except r[1] and r[2] are
> in the register buffer. r[1] is found in inner()s frame. r[2] is found
> in middle()'s frame.
Yes, I understood that. And this is what the fix solved too.
The soft registers that I have are in memory for frame 0, some are saved
within frame 1 and so on.
When the m68hc11 init_saved_regs is called for a given frame, it stores
in the frame->saved_regs table the soft registers that are saved on the
frame. The point is to have that table large enough to hold those
registers (which the fix did).
>
> Or to put it another way, something like:
>
> real_register (frame, regnr)
> for (f = next_inner (frame); f != NULL; f = next_inner (f))
> if (REGNR in f->saved_registers)
> return (saved value of REGNR in f->saved_registers)
> return value from register buffer
>
> (At this point, if you're looking at the code that handles info frame
> and looking puzzled, yes, that code is wrong. It searches in the wrong
> direction and has been ever since it was first written. The SPARC
> window code is ok - it should be possible to merge register windows into
> this model but I'm leaving that as an exercise for the reader :-)
>
> So? Well the fun beings when you go to compute a pseudo register given a
> frame. In our example, when outer()'s frame is selected. A pseudo for
> that frame should be computed using:
>
> p[i] for frame
> == pseudo (i,
> real_register (frame, 0),
> real_register (frame, 1), ...);
>
> which expanding ends up with:
>
> == pseudo (i,
> r[0],
> saved value of r[1] from inner() frame,
> saved value of r[2] from middle() frame,
> ....);
>
> Right now this just doesn't happen. Instead:
>
> pseudo (i, r[0], r[1], r[2], ...)
>
> is computed and then only if you're lucky.
>
> enjoy,
> Andrew
>
> PS1: I think everything to do with fetching a register should be
> parameterized with the frame it is being fetched from. GDB currently
> has one bunch of functions for accessing the registers in the register
> buffer and a second set of functions for accessing the registers given a
> frame. I can't see the difference.
Do you mean that the target_ops functions have to get the frame info pointer
and have to search within the frame?
From your description, I guess that only FETCH_PSEUDO_REGISTER needs
the frame. Is this right?
Well, this will not solve my initial problem anyway.
If a pseudo register *MUST* be constructed from real register, I need
some other mechanism. I think there are at least 3 categories of
registers:
- real registers, they are fetched by 'target_fetch_registers'.
- soft registers, they are fetched by something that does not exist
- pseudo registers, that are constructed from the above.
For 68HC11, I have the 3 categories (there is a register that is
a concatenation of two others, so this fits in the pseudo register class).
On top of these categories, Gdb searches for registers within the frame
or within these categories.
The fix I proposed, just assumed that soft registers are part of pseudo
registers...
Stephane
-----------------------------------------------------------------------
Home Office
E-mail: stcarrez@worldnet.fr Stephane.Carrez@sun.com
WWW: http://home.worldnet.fr/stcarrez http://www.sun.com
Mail: 17, rue Foucher Lepelletier 6, avenue Gustave Eiffel
92130 Issy Les Moulineaux 78182 Saint Quentin en Yvelines
France