Problem converting ia64 to use new frame model
J. Johnston
jjohnstn@redhat.com
Tue Jul 22 16:02:00 GMT 2003
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
>>
>>
>>
>
>
>
More information about the Gdb
mailing list