This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug debug/12990] New: DWARF frame information gives wrong CFA value in some cases


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.

-- 
           Summary: DWARF frame information gives wrong CFA value in some
                    cases
           Product: gcc
           Version: 3.3.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: debug
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: thh at cyberscience dot com
                CC: gcc-bugs at gcc dot gnu dot org
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12990


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]