This is the mail archive of the gdb-patches@sources.redhat.com 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]

Re: [PATCH]: Fixes for pseudo regs support


Stephane Carrez wrote:
> 
> Hi!
> 
> Andrew Cagney wrote:
> > Could I encourage you to persue this alternative.    It isn't that I
> > have something against extra multi-arch entries (ok I do but not in this
> > case :-) but rather that the problem you're describing (registers living
> > in memory space) is far more common than you might think.  Off hand, I
> > can think of at least three targets that have an identical problem.  In
> > those cases people ended up shoving hacks into either/and SIM and the
> > target stub :-(.
> 
> Ok.
> 
> After a close look of the problem, it's not that big or complex.
> 
> I assume that:
>   - Machine dependent parts need not be changed: they must know how
>     to handle pseudo registers (well, only the sh does that).
> 
>   - The remote, monitor, sim stubs need not be changed because they
>     only deal with real hard registers.  They are not aware at all
>     of the existence of pseudo registers.
> 
> Now, what remains is in fact the following places:
> 
>   - The stabs reader performs checks about the validity of the register
>     number.  A pseudo register can be referenced in stabs.
> 
>   - The frame_info structure must save the pseudo registers.
>     The pseudo register (which lies in memory) can be saved by GCC
>     at entry point of a function.

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.

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], ...)

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.

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.

PS2: I think the low level register functions should return a ``struct
value''.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]