[PATCH] Fix prologue skipping on ppc32 for variadic functions
Kwok Cheung Yeung
kcy@codesourcery.com
Wed May 15 14:18:00 GMT 2013
GDB currently has a problem with setting breakpoints on or stepping into
variadic functions on 32-bit PowerPC architectures. e.g.
void f(int x, ...)
{
}
int main(void)
{
f (0, 1);
f (0, 1.0);
}
compiles (with gcc -g -O0) to:
10000478 <f>:
void f(int x, ...)
{
10000478: 94 21 ff 80 stwu r1,-128(r1)
1000047c: 93 e1 00 7c stw r31,124(r1)
10000480: 7c 3f 0b 78 mr r31,r1
10000484: 90 9f 00 0c stw r4,12(r31)
10000488: 90 bf 00 10 stw r5,16(r31)
1000048c: 90 df 00 14 stw r6,20(r31)
10000490: 90 ff 00 18 stw r7,24(r31)
10000494: 91 1f 00 1c stw r8,28(r31)
10000498: 91 3f 00 20 stw r9,32(r31)
1000049c: 91 5f 00 24 stw r10,36(r31)
100004a0: 40 86 00 24 bne cr1,100004c4 <f+0x4c>
100004a4: d8 3f 00 28 stfd f1,40(r31)
100004a8: d8 5f 00 30 stfd f2,48(r31)
100004ac: d8 7f 00 38 stfd f3,56(r31)
100004b0: d8 9f 00 40 stfd f4,64(r31)
100004b4: d8 bf 00 48 stfd f5,72(r31)
100004b8: d8 df 00 50 stfd f6,80(r31)
100004bc: d8 ff 00 58 stfd f7,88(r31)
100004c0: d9 1f 00 60 stfd f8,96(r31)
100004c4: 90 7f 00 68 stw r3,104(r31)
}
...
100004d8 <main>:
int main(void)
{
...
f (0, 1);
100004ec: 38 60 00 00 li r3,0
100004f0: 38 80 00 01 li r4,1
100004f4: 4c c6 31 82 crclr 4*cr1+eq
100004f8: 4b ff ff 81 bl 10000478 <f>
f (0, 1.0);
100004fc: 3d 20 10 00 lis r9,4096
10000500: c8 09 07 08 lfd f0,1800(r9)
10000504: 38 60 00 00 li r3,0
10000508: fc 20 00 90 fmr f1,f0
1000050c: 4c c6 32 42 crset 4*cr1+eq
10000510: 4b ff ff 69 bl 10000478 <f>
}
...
When this is loaded into GDB and a 'break f' issued, a breakpoint is placed at
0x100004a4. Consider the first call site at 0x10000f48 - at this point, cr1 will
be cleared, so when execution is resumed the branch at 0x100004a0 will be taken,
and the breakpoint will be skipped over. GDB has lost control over program
execution at this point, and unless another breakpoint is set elsewhere or f is
called without the branch taken (in this case, the second call), the program
will run to completion.
This branch in the prologue seems to be generated by GCC as an optimisation to
avoid saving the floating-point registers unless necessary (in the GCC source,
this is done by setup_incoming_varargs() in gcc/config/rs6000/rs6000.c). This is
controlled by the caller, which sets cr1 as required before branching to the
function.
When debug information is available, the breakpoint is placed at 0x100004a4 due
to rs6000_skip_prologue() using skip_prologue_using_sal(). The branch at
0x100004a0 marks the end of a basic block, and so line info has been placed
there. skip_prologue_using_sal() sees two line entries for the same line at the
beginning of the function, and so picks the address associated with the second,
which is just after the branch in the prologue.
This patch fixes this by checking instructions between the beginning of the
function and the address returned by skip_prologue_using_sal() for the 'bne cr1,
<target>' instruction. If it finds it, then after confirming that the
instructions between the instruction and the target are all floating-point save
instructions, the first line info item with an address greater-or-equal to the
target address will be used as the start of the function body.
When debug information is not available, the breakpoint is placed at 0x100004a0
due to skip_prologue() stopping at a branch instruction. While control over the
program is not lost in this case, the prologue still has not ended at this
point. This patch adds the 'bne cr1, <target>' instruction to the list of
recognised prologue instructions.
Kwok
gdb/ChangeLog:
* rs6000-tdep.c (skip_prologue): Add test for instruction used
to skip saving of the floating-point registers.
(GET_DEST_REG): New macro.
(BNE_CR1_MASK, BNE_CR1_INSTRUCTION, BNE_TARGET_MASK): New defines.
(SFP_MASK, SFP_R31_INSTRUCTION): New defines.
(skip_prologue_fp_reg_save): New.
(rs6000_skip_prologue): Use result of skip_prologue_fp_reg_save
when using SAL information to skip prologue.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ppc32_variadic.patch
Type: text/x-patch
Size: 4349 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/gdb-patches/attachments/20130515/2008c93b/attachment.bin>
More information about the Gdb-patches
mailing list