gcc bug when profiling nested functions on powerpc

Edmar Wienskoski edmar@motorola.com
Thu Mar 14 08:02:00 GMT 2002


A colegue here at Motorola asked me to report this problem to the list.
Is that a known bug ?

Thanks

Edmar

-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

gcc version:

2.95.2, but apparently also present in 3.0.2.


Target Platform:

Linux


Bug description:

When generating routine profiling header code, gcc conditionally inserts
a
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
of
printf() that is called when a floating point format is invoked) is
called, a segfault is seen.  This is because __printf_fp() calls a
nested
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:

void
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]);
        ...




More information about the Gcc mailing list