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