Bug 5967 - gcc bug when profiling nested functions on powerpc
Summary: gcc bug when profiling nested functions on powerpc
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 3.0.2
: P3 normal
Target Milestone: ---
Assignee: Alan Modra
Keywords: wrong-code
Depends on:
Reported: 2002-03-14 14:16 UTC by edmar
Modified: 2003-07-25 17:33 UTC (History)
1 user (show)

See Also:
Known to work:
Known to fail:
Last reconfirmed:

prog.c (359 bytes, application/octet-stream)
2003-05-21 15:17 UTC, edmar

Note You need to log in before you can comment on or make changes to this bug.
Description edmar 2002-03-14 14:16:01 UTC
gcc version:

When generating routine profiling header code, gcc conditionally inserts
move register (mr) instruction if the function being compiled
"needs_context".  The mr copies the register of the static chain pointer

to r30 before the call to _mcount, and copies it back after the _mcount
has returned.  However, r30 is not checked to see if it is being used by

the parent function.

How found:

Compiled glibc 2.1.3 using profiling options (with backport patch of
dl-machine.h from glibc 2.2.5).  When __printf_fp()  (a child function
printf() that is called when a floating point format is invoked) is
called, a segfault is seen.  This is because __printf_fp() calls a
function named hack_digit().

Example of brokenness:

1001014c <hack_digit.180>:
1001014c:       7c 08 02 a6     mflr    r0
10010150:       3d 80 10 05     lis     r12,4101
10010154:       90 01 00 04     stw     r0,4(r1)
10010158:       38 0c 20 78     addi    r0,r12,8312
1001015c:       7d 7e 5b 78     mr      r30,r11
10010160:       4b ff 9f 21     bl      1000a080 <_mcount>
10010164:       7f cb f3 78     mr      r11,r30
10010168:       94 21 ff e0     stwu    r1,-32(r1)
1001016c:       7c 08 02 a6     mflr    r0
10010170:       93 c1 00 18     stw     r30,24(r1)

Specific code from gcc:

from rs6000.c:

output_function_profiler (file, labelno)
  FILE *file;
  int labelno;


      if (current_function_needs_context)
        asm_fprintf (file, "\tmr %s,%s\n",
                     reg_names[30], reg_names[STATIC_CHAIN_REGNUM]);
      fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
      if (current_function_needs_context)
        asm_fprintf (file, "\tmr %s,%s\n",
                     reg_names[STATIC_CHAIN_REGNUM], reg_names[30]);

2.95.2 and 3.0.2

At least on 2.95.2, and 3.0.2.
Linux PowerPC

compile with gcc 2.95.2 or gcc-3.0.2 on a Linux PowerPC:
gcc -O2 -p -S prog.c
them look at prog.s and note that r30 is live across the
call to bar(), and bar clobbers r30 (profiling code).
Comment 1 Alan Modra 2002-07-17 19:16:29 UTC
Responsible-Changed-From-To: unassigned->amodra
Responsible-Changed-Why: Fixing it.
Comment 2 Alan Modra 2002-07-17 19:16:29 UTC
State-Changed-From-To: open->analyzed
State-Changed-Why: Patch submitted for PR 7114 will fix this one.
Comment 3 Alan Modra 2002-09-13 16:37:22 UTC
State-Changed-From-To: analyzed->closed
State-Changed-Why: Fixed on mainline and 3.2 branch