This is the mail archive of the
gdb@sources.redhat.com
mailing list for the GDB project.
Re: Problem converting ia64 to use new frame model
I have things working reasonably well, but I have run into a problem when
returning from a function (e.g. restore.exp testcase). The bsp and
cfm values (used to compute where regs 32-127 are stored) do not get
restored to their previous values.
In the old code, the ia64_pop_frame_regular () code would reset the
bsp and cfm registers manually after calculating their previous values.
This was set up by using the set_gdbarch_deprecated_pop_frame method.
In the new code, nothing seems to reset these two registers on a return
call. They are normally set by the hardware when you call or return.
How do I set up the special rewrite of the registers when the
frame is popped?
-- Jeff J.
J. Johnston wrote:
Andrew Cagney wrote:
First take a look through: WIP: Register doco
http://sources.redhat.com/ml/gdb/2002-07/msg00202.html
It's now a bit dated but the basics still apply
I am having problems converting the ia64-tdep.c file to use the new
frame model.
The main problem stems from the fact that the next frame is asked
for the current
registers. When dealing with the innermost frame, the sentinel
frame doesn't know how
to get all of the ia64 registers.
In the current code, the bsp register is calculated based on the cfm
and the bsp
values returned from the system. For the innermost frame, the
sentinel frame just
goes to the sytem bsp value. The argument registers (32, 33, ...)
need to be fetched
from a memory location based on the calculated bsp value. These
registers are not accessible
via ptrace. When the sentinel frame is asked to fetch them, it ends
up just grabbing
them from the regcache which returns zero.
Are really two values? "bsp" which is the hardware register value
you see in the frame; and (for want of a better name) "vbsp",
computed from "bsp" and "cfm", which is a per-frame pointer into that
the saved register space.
Looking at the existing code, it appears to be:
- fetching `this frame's BSP
- compute the PREV BSP, but then store it in THIS->bsp
so I suspect that the problem is more of the existing frame code
being one frame out - it uses the PREV "bsp" when doing stuff for
THIS frame.
Can your register unwind code be modified to do things more along
those lines? Compute the previous frame's "bsp" but then save it in
this_cache?
As for how to "bsp". I see it is done two ways (one for the inner
most, and one for other frames) I have a feeling that the uwound
"cfm" value may need adjusting. Can it be adjusted so that, for all
frames, prev "bsp" can be computed using something like:
this_cache -> prev_bsp
= (frame_unwind_register (next, "bsp")
- frame_unwind_register (next, "cfm").size-of-frame)
instead of occasionally using size-of-locals (but note that I know
zilch about how ia64 frames are laid out).
Hmm, I think I missed half your problem:
The argument registers (32, 33, ...) need to be fetched
from a memory location based on the calculated bsp value. These
registers are not accessible
via ptrace.
So, once the "vbsp" is computed, gr32-gr127 registers, even for the
inner most frame, get fetched from memory using that "vbsp" value?
Looking at the ia64 code it, unlike the MIPS get_saved_register
method, it doesn't use the next frame, instead using this frame for
some of the register values.
Anyway, the MIPS solved a different problem using the following:
- all the general purpose registers are pseudos
(you'd probably just want the ones causing problems?)
- the pseudo register read/write methods map the pseudos onto raw
registers when at the regcache level
(you'd probably want to map them onto memory locations?)
- the frame unwind code (note the MIPS hasn't switched) does the same
thing for registers saved in a frame - it populates the pseudo
register range of saved addresses with the corresponding register
addresses
(very similar - set the saved_regs address for those registers)
- map the debug info register numbers onto the pseudos instead of the
raw registers
(straight forward)
I should note that currently I'm adding code (user-regs) that will let
a target (the MIPS at present) specify registers that are more like
what you have here, this is work-in-progress intended for only the
mainline though.
I have looked into pseudo registers, but this doesn't solve the
problem because there isn't
a way AFAICT to notify the frame code to convert a register number
into a pseudo register
number. The dwarf2_reg_to_regnum() interface, for example, isn't
used by the frame code when
performing an info registers call.
Things like `info registers' use register groups to decide which
registers should be displayed. The default register group
implementation relies on the presence/absence of register names :-/
Thanks, this was just what I was looking for. I now have info registers
working as it did before the new frame model.
You might want to customize the register groups (at least for general,
all and float) so that they better identify which registers should be
displayed.
Andrew