Bug 12990 - CFA not tracked in epilogues
Summary: CFA not tracked in epilogues
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: debug (show other bugs)
Version: 3.3.2
: P2 enhancement
Target Milestone: 4.5.0
Assignee: Not yet assigned to anyone
URL:
Keywords:
: 18749 (view as bug list)
Depends on:
Blocks:
 
Reported: 2003-11-10 09:12 UTC by Tom Hughes
Modified: 2019-09-09 04:16 UTC (History)
7 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2005-12-28 06:13:01


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tom Hughes 2003-11-10 09:12:41 UTC
On x86 architecture when -fomit-frame-pointer is used, the CFA address given by
the DWARF frame information is wrong for some instructions when a return is
placed in the middle of the code generated for a function. As an example,
consider this small .i file:

# 1 "cfatest.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "cfatest.c"
void foo(int a)
{
   int x[12];
 
   if ( a < 0 )
   {
      x[0] = 1;
      x[1] = 2;
 
      return;
   }
   else
   {
      x[0] = 2;
      x[1] = 3;
 
      return;
   }
}

This was compiled with the following command line:

  gcc -O3 -c -gdwarf-2 -fomit-frame-pointer cfatest.c

The compiled code looks like this:

00000000 <foo>:
   0:   83 ec 3c                sub    $0x3c,%esp
   3:   8b 44 24 40             mov    0x40(%esp,1),%eax
   7:   85 c0                   test   %eax,%eax
   9:   78 15                   js     20 <foo+0x20>
   b:   c7 04 24 02 00 00 00    movl   $0x2,(%esp,1)
  12:   ba 03 00 00 00          mov    $0x3,%edx
  17:   89 54 24 04             mov    %edx,0x4(%esp,1)
  1b:   83 c4 3c                add    $0x3c,%esp
  1e:   c3                      ret
  1f:   90                      nop
  20:   c7 04 24 01 00 00 00    movl   $0x1,(%esp,1)
  27:   b8 02 00 00 00          mov    $0x2,%eax
  2c:   89 44 24 04             mov    %eax,0x4(%esp,1)
  30:   eb e9                   jmp    1b <foo+0x1b>

and the DWARF FDE record for the function looks like this:

fde:
<  0><0:0x32><><fde offset 0x14 length: 0x10><eh offset none>
    00000000:   cfa=04(r4/a0) r8/t0=-4(cfa)
    00000003:   cfa=64(r4/a0) r8/t0=-4(cfa)
        fde sec. offset 20 0x14 cie offset for fde: 0 0x0
         0 DW_CFA_advance_loc 3  (3 * 1)
         1 DW_CFA_def_cfa_offset 64
         3 DW_CFA_nop
 
As you can see, the CFA offset from %esp is increased to 64 at address 0x3 to
account for the sub instruction that makes space for the local variables. There
is however no equivalent modification made at address 0x1e when %esp is moved
back before the return. As a result the CFA generated from the FDE will be wrong
for the ret instruction.

In some ways this is actually an improvement from 3.2.2 where the CFA would get
adjusted when %esp was incrmented before the return but wouldn't then get
restored to the previous value after the return, as that meant that the whole of
the rest of the routine had the wrong CFA value. It is still a bug however that
the CFA is not correctly described for some addresses.
Comment 1 Drea Pinski 2003-11-10 16:35:50 UTC
This is really a dup of bug 10005 which takes about tracking variables and that patch fixes this 
problem.

*** This bug has been marked as a duplicate of 10005 ***
Comment 2 Daniel Jacobowitz 2003-11-10 16:39:44 UTC
Actually, the CFA is handled differently than var-tracking; it is tracked
via RTX_FRAME_RELATED_P, if I'm remembering right.
Comment 3 Richard Henderson 2003-11-11 01:39:27 UTC
We don't emit CFA information for epilogues at all.
This would be an enhancement to begin doing so.
Comment 4 Richard Henderson 2010-10-06 16:25:24 UTC
*** Bug 18749 has been marked as a duplicate of this bug. ***
Comment 5 Richard Henderson 2010-10-06 16:30:13 UTC
This was fixed for gcc 4.5.