* PowerPC prologue analysis
@ 2008-07-28 20:13 Aleksandar Ristovski
2008-07-28 20:29 ` Daniel Jacobowitz
0 siblings, 1 reply; 8+ messages in thread
From: Aleksandar Ristovski @ 2008-07-28 20:13 UTC (permalink / raw)
To: gdb
Hello,
In the code, in rs6000-tdep.c around line 3334, there is a comment stating:
/* if != -1, fdata.saved_gpr is the smallest number of saved_gpr.
All gpr's from saved_gpr to gpr31 are saved. */
I am, however, witnessing a function that appears to be saving r30, but not r31 (see the disassembly below). This, in turn, causes gdb to unwind r31 from a 'saved' area even though the area does not exist.
I am not very familiar with PowerPC ABI, but from what I gather reading the "function call" section, but can not see where is it stated that if r30 is saved, then r31 must be saved too? But again, I haven't studied the ABI very thoroughly and might be missing that line.
Just for the reference, here is the disassembly of the function:
(gdb) disassemble foo
Dump of assembler code for function foo
0xfe346aa0 <foo+0>: stwu r1,-16(r1)
0xfe346aa4 <foo+4>: mflr r0
0xfe346aa8 <foo+8>: bl 0xfe37ca18
0xfe346aac <foo+12>: mr r4,r3
0xfe346ab0 <foo+16>: stw r30,8(r1)
0xfe346ab4 <foo+20>: mflr r30
0xfe346ab8 <foo+24>: li r5,0
0xfe346abc <foo+28>: li r6,0
0xfe346ac0 <foo+32>: stw r0,20(r1)
0xfe346ac4 <foo+36>: lwz r3,-176(r30)
0xfe346ac8 <foo+40>: bl 0xfe37d738
0xfe346acc <foo+44>: lwz r0,20(r1)
0xfe346ad0 <foo+48>: lwz r30,8(r1)
0xfe346ad4 <foo+52>: addi r1,r1,16
0xfe346ad8 <foo+56>: mtlr r0
0xfe346adc <foo+60>: blr
End of assembler dump.
Thanks,
Aleksandar Ristovski
QNX Software Systems
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: PowerPC prologue analysis
2008-07-28 20:13 PowerPC prologue analysis Aleksandar Ristovski
@ 2008-07-28 20:29 ` Daniel Jacobowitz
2008-07-28 21:08 ` Aleksandar Ristovski
0 siblings, 1 reply; 8+ messages in thread
From: Daniel Jacobowitz @ 2008-07-28 20:29 UTC (permalink / raw)
To: Aleksandar Ristovski; +Cc: gdb
On Mon, Jul 28, 2008 at 04:09:54PM -0400, Aleksandar Ristovski wrote:
> Hello,
>
> In the code, in rs6000-tdep.c around line 3334, there is a comment stating:
>
> /* if != -1, fdata.saved_gpr is the smallest number of saved_gpr.
> All gpr's from saved_gpr to gpr31 are saved. */
>
> I am, however, witnessing a function that appears to be saving r30, but not r31 (see the disassembly below). This, in turn, causes gdb to unwind r31 from a 'saved' area even though the area does not exist.
>
> I am not very familiar with PowerPC ABI, but from what I gather reading
> the "function call" section, but can not see where is it stated that if
> r30 is saved, then r31 must be saved too? But again, I haven't studied the
> ABI very thoroughly and might be missing that line.
Might want to look at this patch:
http://sourceware.org/ml/gdb-patches/2007-12/msg00111.html
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: PowerPC prologue analysis
2008-07-28 20:29 ` Daniel Jacobowitz
@ 2008-07-28 21:08 ` Aleksandar Ristovski
2008-07-29 1:46 ` Daniel Jacobowitz
0 siblings, 1 reply; 8+ messages in thread
From: Aleksandar Ristovski @ 2008-07-28 21:08 UTC (permalink / raw)
To: gdb
Daniel Jacobowitz wrote:
> On Mon, Jul 28, 2008 at 04:09:54PM -0400, Aleksandar Ristovski wrote:
>> I am not very familiar with PowerPC ABI, but from what I gather reading
>> the "function call" section, but can not see where is it stated that if
>> r30 is saved, then r31 must be saved too? But again, I haven't studied the
>> ABI very thoroughly and might be missing that line.
>
> Might want to look at this patch:
>
> http://sourceware.org/ml/gdb-patches/2007-12/msg00111.html
>
Thanks for the link! I briefly looked at the patch and it seems to address some of the things I am talking about (r30-r31 issue) but the comment still reads:
+ All gpr's from saved_gpr to gpr31 are saved (except during the
+ prologue). */
Is that in the ABI? I would think that if it is, then the code I am looking at is not according to it (gcc issue or just me not understanding powerpc assembly?).
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: PowerPC prologue analysis
2008-07-28 21:08 ` Aleksandar Ristovski
@ 2008-07-29 1:46 ` Daniel Jacobowitz
2008-07-29 14:10 ` Aleksandar Ristovski
0 siblings, 1 reply; 8+ messages in thread
From: Daniel Jacobowitz @ 2008-07-29 1:46 UTC (permalink / raw)
To: Aleksandar Ristovski; +Cc: gdb
On Mon, Jul 28, 2008 at 04:29:18PM -0400, Aleksandar Ristovski wrote:
> Thanks for the link! I briefly looked at the patch and it seems to address some of the things I am talking about (r30-r31 issue) but the comment still reads:
>
> + All gpr's from saved_gpr to gpr31 are saved (except during the
> + prologue). */
>
> Is that in the ABI? I would think that if it is, then the code I am looking at is not according to it (gcc issue or just me not understanding powerpc assembly?).
Sorry, I don't know which.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: PowerPC prologue analysis
2008-07-29 1:46 ` Daniel Jacobowitz
@ 2008-07-29 14:10 ` Aleksandar Ristovski
2008-07-29 15:42 ` Aleksandar Ristovski
0 siblings, 1 reply; 8+ messages in thread
From: Aleksandar Ristovski @ 2008-07-29 14:10 UTC (permalink / raw)
To: gdb; +Cc: Daniel Jacobowitz
Daniel Jacobowitz wrote:
> On Mon, Jul 28, 2008 at 04:29:18PM -0400, Aleksandar Ristovski wrote:
>> Thanks for the link! I briefly looked at the patch and it seems to address some of the things I am talking about (r30-r31 issue) but the comment still reads:
>>
>> + All gpr's from saved_gpr to gpr31 are saved (except during the
>> + prologue). */
>>
>> Is that in the ABI? I would think that if it is, then the code I am looking at is not according to it (gcc issue or just me not understanding powerpc assembly?).
>
> Sorry, I don't know which.
>
There seems to be no such statement in the PowerPC ABI "all gpr's from saved_gpr to gpr31 are saved" - non-volatile registers do not need to be stored in this manner. For example, a function may save r29 but not r30 and r31. However PPC prologue analysis in gdb will assume there is r31 saved as well which will make unwind_register(r31) fail (fetch bogus value). (Note: I am using gcc 4.2.3).
Another assumption made in gdb code is that if multiple registers are saved by the prologue, they will be saved in the ascending index order - I am not sure this is a requirement stated in the ABI either. (Is it?) I believe there could be cases where registers are saved in different order, e.g. r30, r28, r29, etc... Hopefully this doesn't happen in practise.
I think your patch with gpr_mask covers the first case (not all registers saved) but the second issue (if real issue) is still not handled.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: PowerPC prologue analysis
2008-07-29 14:10 ` Aleksandar Ristovski
@ 2008-07-29 15:42 ` Aleksandar Ristovski
2008-07-29 15:47 ` Daniel Jacobowitz
0 siblings, 1 reply; 8+ messages in thread
From: Aleksandar Ristovski @ 2008-07-29 15:42 UTC (permalink / raw)
To: gdb
Aleksandar Ristovski wrote:
> Daniel Jacobowitz wrote:
>> On Mon, Jul 28, 2008 at 04:29:18PM -0400, Aleksandar Ristovski wrote:
>>> Thanks for the link! I briefly looked at the patch and it seems to
>>> address some of the things I am talking about (r30-r31 issue) but the
>>> comment still reads:
>>>
>>> + All gpr's from saved_gpr to gpr31 are saved (except during the
>>> + prologue). */
>>>
>>> Is that in the ABI? I would think that if it is, then the code I am
>>> looking at is not according to it (gcc issue or just me not
>>> understanding powerpc assembly?).
>>
>> Sorry, I don't know which.
>>
>
> There seems to be no such statement in the PowerPC ABI "all gpr's from
> saved_gpr to gpr31 are saved" - non-volatile registers do not need to be
> stored in this manner. For example, a function may save r29 but not r30
> and r31. However PPC prologue analysis in gdb will assume there is r31
> saved as well which will make unwind_register(r31) fail (fetch bogus
> value). (Note: I am using gcc 4.2.3).
>
> Another assumption made in gdb code is that if multiple registers are
> saved by the prologue, they will be saved in the ascending index order -
> I am not sure this is a requirement stated in the ABI either. (Is it?) I
> believe there could be cases where registers are saved in different
> order, e.g. r30, r28, r29, etc... Hopefully this doesn't happen in
> practise.
>
> I think your patch with gpr_mask covers the first case (not all
> registers saved) but the second issue (if real issue) is still not handled.
And for the reference: Daniel's patch ( http://sourceware.org/ml/gdb-patches/2007-12/msg00111.html ) does solve the problem with not all registers saved.
Why is the patch not in HEAD gdb?
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: PowerPC prologue analysis
2008-07-29 15:42 ` Aleksandar Ristovski
@ 2008-07-29 15:47 ` Daniel Jacobowitz
2008-07-29 16:52 ` Aleksandar Ristovski
0 siblings, 1 reply; 8+ messages in thread
From: Daniel Jacobowitz @ 2008-07-29 15:47 UTC (permalink / raw)
To: Aleksandar Ristovski; +Cc: gdb
On Tue, Jul 29, 2008 at 11:42:29AM -0400, Aleksandar Ristovski wrote:
> And for the reference: Daniel's patch (
> http://sourceware.org/ml/gdb-patches/2007-12/msg00111.html ) does
> solve the problem with not all registers saved.
>
> Why is the patch not in HEAD gdb?
There's a couple of questions in the posting and I never figured out
the answers to them. I'll be back to them at some point.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: PowerPC prologue analysis
2008-07-29 15:47 ` Daniel Jacobowitz
@ 2008-07-29 16:52 ` Aleksandar Ristovski
0 siblings, 0 replies; 8+ messages in thread
From: Aleksandar Ristovski @ 2008-07-29 16:52 UTC (permalink / raw)
To: gdb
[-- Attachment #1: Type: text/plain, Size: 737 bytes --]
Daniel Jacobowitz wrote:
> On Tue, Jul 29, 2008 at 11:42:29AM -0400, Aleksandar Ristovski wrote:
>> And for the reference: Daniel's patch (
>> http://sourceware.org/ml/gdb-patches/2007-12/msg00111.html ) does
>> solve the problem with not all registers saved.
>>
>> Why is the patch not in HEAD gdb?
>
> There's a couple of questions in the posting and I never figured out
> the answers to them. I'll be back to them at some point.
>
May I suggest that you break the patch in two patches: one dealing with not-all-registers-saved (i.e. gpr_mask) and the rest?
I extracted the gpr_mask part here with the testsuite changes and I believe this part of the patch is safe to apply.
Attached: Fragment extracted from Daniel's patch.
[-- Attachment #2: rs6000-tdep.c.Daniel-gpr_mask-part.diff --]
[-- Type: text/plain, Size: 2154 bytes --]
Index: gdb/rs6000-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/rs6000-tdep.c,v
retrieving revision 1.318
diff -u -p -r1.318 rs6000-tdep.c
--- gdb/rs6000-tdep.c 15 Jul 2008 18:32:06 -0000 1.318
+++ gdb/rs6000-tdep.c 29 Jul 2008 16:27:53 -0000
@@ -117,6 +117,7 @@ struct rs6000_framedata
by which we decrement sp to allocate
the frame */
int saved_gpr; /* smallest # of saved gpr */
+ unsigned int gpr_mask; /* Each bit is an individual saved GPR. */
int saved_fpr; /* smallest # of saved fpr */
int saved_vr; /* smallest # of saved vr */
int saved_ev; /* smallest # of saved ev */
@@ -1275,6 +1276,10 @@ skip_prologue (struct gdbarch *gdbarch,
{
reg = GET_SRC_REG (op);
+ if ((op & 0xfc1f0000) == 0xbc010000)
+ fdata->gpr_mask |= ~((1U << reg) - 1);
+ else
+ fdata->gpr_mask |= 1U << reg;
if (fdata->saved_gpr == -1 || fdata->saved_gpr > reg)
{
fdata->saved_gpr = reg;
@@ -1678,11 +1683,15 @@ skip_prologue (struct gdbarch *gdbarch,
else
{
+ unsigned int all_mask = ~((1U << fdata->saved_gpr) - 1);
+
/* Not a recognized prologue instruction.
Handle optimizer code motions into the prologue by continuing
the search if we have no valid frame yet or if the return
- address is not yet saved in the frame. */
- if (fdata->frameless == 0 && fdata->nosavedpc == 0)
+ address is not yet saved in the frame. Also skip instructions
+ if some of the GPRs expected to be saved are not yet saved. */
+ if (fdata->frameless == 0 && fdata->nosavedpc == 0
+ && (fdata->gpr_mask & all_mask) == all_mask)
break;
if (op == 0x4e800020 /* blr */
@@ -2573,7 +2582,8 @@ rs6000_frame_cache (struct frame_info *t
CORE_ADDR gpr_addr = cache->base + fdata.gpr_offset;
for (i = fdata.saved_gpr; i < ppc_num_gprs; i++)
{
- cache->saved_regs[tdep->ppc_gp0_regnum + i].addr = gpr_addr;
+ if (fdata.gpr_mask & (1U << i))
+ cache->saved_regs[tdep->ppc_gp0_regnum + i].addr = gpr_addr;
gpr_addr += wordsize;
}
}
[-- Attachment #3: gdb_arch_powerpc-prologue.exp.Daniel-gpr_mask-part.diff --]
[-- Type: text/plain, Size: 745 bytes --]
Index: gdb/testsuite/gdb.arch/powerpc-prologue.exp
===================================================================
--- gdb/testsuite/gdb.arch/powerpc-prologue.exp (revision 197)
+++ gdb/testsuite/gdb.arch/powerpc-prologue.exp (working copy)
@@ -64,7 +64,7 @@ gdb_test "backtrace 10" \
"backtrace in PIC"
gdb_test "info frame" \
- ".*Saved registers:.*r30 at.*r31 at.*pc at.*lr at.*" \
+ ".*Saved registers:.*r30 at.*pc at.*lr at.*" \
"saved registers in PIC"
# Testcase for scheduled prologue.
@@ -84,5 +84,5 @@ gdb_test "backtrace 10" \
"backtrace in optimized"
gdb_test "info frame" \
- ".*Saved registers:.*r30 at.*r31 at.*pc at.*lr at.*" \
+ ".*Saved registers:.*r30 at.*pc at.*lr at.*" \
"saved registers in optimized"
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2008-07-29 16:35 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-07-28 20:13 PowerPC prologue analysis Aleksandar Ristovski
2008-07-28 20:29 ` Daniel Jacobowitz
2008-07-28 21:08 ` Aleksandar Ristovski
2008-07-29 1:46 ` Daniel Jacobowitz
2008-07-29 14:10 ` Aleksandar Ristovski
2008-07-29 15:42 ` Aleksandar Ristovski
2008-07-29 15:47 ` Daniel Jacobowitz
2008-07-29 16:52 ` Aleksandar Ristovski
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox