[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