public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
* Problem converting ia64 to use new frame model
@ 2003-07-07 22:13 J. Johnston
  2003-07-08 22:43 ` Andrew Cagney
  0 siblings, 1 reply; 7+ messages in thread
From: J. Johnston @ 2003-07-07 22:13 UTC (permalink / raw)
  To: gdb

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.

Some of this used to be handled by the deprecated_init_extra_frame_info routine
which would calculate the bsp.  The rest would get filled in by prologue examination.
In the new model, the prologue examination code doesn't get called by the sentinel
frame when it gets the "current" registers.

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.

Anybody have any other ideas?  Is a new exit routine required?

-- Jeff J.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Problem converting ia64 to use new frame model
  2003-07-07 22:13 Problem converting ia64 to use new frame model J. Johnston
@ 2003-07-08 22:43 ` Andrew Cagney
  2003-07-09 15:25   ` Andrew Cagney
  2003-07-09 15:41   ` J. Johnston
  0 siblings, 2 replies; 7+ messages in thread
From: Andrew Cagney @ 2003-07-08 22:43 UTC (permalink / raw)
  To: J. Johnston; +Cc: gdb

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

Andrew


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Problem converting ia64 to use new frame model
  2003-07-08 22:43 ` Andrew Cagney
@ 2003-07-09 15:25   ` Andrew Cagney
  2003-07-09 21:52     ` J. Johnston
  2003-07-09 15:41   ` J. Johnston
  1 sibling, 1 reply; 7+ messages in thread
From: Andrew Cagney @ 2003-07-09 15:25 UTC (permalink / raw)
  To: J. Johnston; +Cc: gdb

> 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 :-/

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


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Problem converting ia64 to use new frame model
  2003-07-08 22:43 ` Andrew Cagney
  2003-07-09 15:25   ` Andrew Cagney
@ 2003-07-09 15:41   ` J. Johnston
  1 sibling, 0 replies; 7+ messages in thread
From: J. Johnston @ 2003-07-09 15:41 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb

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.
> 

I had thought about that myself, but I can understand what the original writer
was thinking.  The bsp register value of the innermost frame has to be modified
to get the bsp address of where the innermost input argument registers are located.
To an end-user, it is more useful to know the bsp area for the current frame is
rather than being forced to do the calculation manually which involves bit shifting
and differs depending on whether you are an innermost frame or not.  So the bsp the user's
currently see is essentially a pseudo-register.

The bsp issue still doesn't help with regards to r32-r39.  These registers contain input
arguments to the function and are certainly useful to see.  I have made some
progress recently using pseudo-registers.  I have the innermost frame correctly printing
out the arguments and I can backtrace reasonably well   However, info registers on the innermost
frame still shows the argument registers as 0.  This is because I used a mapping of registers
to pseudo-registers and this mapping never gets done for the info registers case.  I am
currently using the set_gdbarch_dwarf2_reg_to_regnum interface.  Is there is a better way
to do this mapping?

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

I am sort of doing that now.  I just don't call it prev_bsp because it is actually used
to find the input registers for the current frame.  Another calculation is required to find
the bsp that holds the registers for the previous frame.

> Andrew
> 
> 
> 


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Problem converting ia64 to use new frame model
  2003-07-09 15:25   ` Andrew Cagney
@ 2003-07-09 21:52     ` J. Johnston
  2003-07-22 16:02       ` J. Johnston
  0 siblings, 1 reply; 7+ messages in thread
From: J. Johnston @ 2003-07-09 21:52 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb

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
> 
> 
> 


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Problem converting ia64 to use new frame model
  2003-07-09 21:52     ` J. Johnston
@ 2003-07-22 16:02       ` J. Johnston
  2003-07-22 17:57         ` Andrew Cagney
  0 siblings, 1 reply; 7+ messages in thread
From: J. Johnston @ 2003-07-22 16:02 UTC (permalink / raw)
  To: J. Johnston; +Cc: Andrew Cagney, gdb

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
>>
>>
>>
> 
> 
> 


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Problem converting ia64 to use new frame model
  2003-07-22 16:02       ` J. Johnston
@ 2003-07-22 17:57         ` Andrew Cagney
  0 siblings, 0 replies; 7+ messages in thread
From: Andrew Cagney @ 2003-07-22 17:57 UTC (permalink / raw)
  To: J. Johnston; +Cc: gdb

> 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.

Hmm, the new model is that the unwinder shall return register values 
exactly as if there were no more inner frame.
No additional adjustment necessary.

Perhaphs that model needs to be revisited, or adjusted slightly.

> 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? 

For the moment, add a comment to ia64 pop-frame explaining what happens. 
  Once the basic changes are in place, it will be easier to revisit this.

Andrew


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2003-07-22 17:57 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-07-07 22:13 Problem converting ia64 to use new frame model J. Johnston
2003-07-08 22:43 ` Andrew Cagney
2003-07-09 15:25   ` Andrew Cagney
2003-07-09 21:52     ` J. Johnston
2003-07-22 16:02       ` J. Johnston
2003-07-22 17:57         ` Andrew Cagney
2003-07-09 15:41   ` J. Johnston

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).