Bug 18749

Summary: GCC fails to mark stack-popping instruction in unwind-info
Product: gcc Reporter: davidm
Component: targetAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED DUPLICATE    
Severity: normal CC: gcc-bugs, johan.walles, ppluzhnikov, rth
Priority: P2 Keywords: EH, wrong-code
Version: 3.3.3   
Target Milestone: ---   
Host: x86_64-suse-linux Target: x86_64-suse-linux
Build: x86_64-suse-linux Known to work:
Known to fail: 3.3.3, 3.4.2, 4.0.0 Last reconfirmed: 2005-06-22 00:28:36
Bug Depends on:    
Bug Blocks: 29997    
Attachments: testcase

Description davidm 2004-12-01 02:48:34 UTC
The unwind info is wrong for any instruction-pointer (IP) in the epilog after
the point at which the stack-pointer has been popped.  For example:

0000000000400758 <func>:
  400758:       48 89 5c 24 d8          mov    %rbx,0xffffffffffffffd8(%rsp)
  40075d:       48 89 6c 24 e0          mov    %rbp,0xffffffffffffffe0(%rsp)
  400762:       4c 89 64 24 e8          mov    %r12,0xffffffffffffffe8(%rsp)
  400767:       4c 89 6c 24 f0          mov    %r13,0xfffffffffffffff0(%rsp)
  40076c:       4c 89 74 24 f8          mov    %r14,0xfffffffffffffff8(%rsp)
  400771:       48 81 ec 28 10 00 00    sub    $0x1028,%rsp
     :
  40081c:       48 81 c4 28 10 00 00    add    $0x1028,%rsp
  400823:       c3                      retq

The unwind-info for this function looks like this:

00000018 00000024 0000001c FDE cie=00000000 pc=00400758..00400824
  DW_CFA_advance_loc: 32 to 00400778
  DW_CFA_def_cfa_offset: 4144
  DW_CFA_offset: r14 at cfa-16
  DW_CFA_offset: r13 at cfa-24
  DW_CFA_offset: r12 at cfa-32
  DW_CFA_offset: r6 at cfa-40
  DW_CFA_offset: r3 at cfa-48

Note that there is no indication that the stack gets restored in the second-last
instruction, hence it is impossible to unwind when IP = 0x400823.
Comment 1 Steven Bosscher 2004-12-19 15:13:19 UTC
Without a test case, nobody can give this bug a proper look.  Can you  
provide an example of how this fails for you? 
 
Comment 2 davidm 2004-12-20 22:13:35 UTC
(In reply to comment #1)
> Without a test case, nobody can give this bug a proper look.  Can you  
> provide an example of how this fails for you?

Sorry, that was sloppy of me.  I'll attach a minimal test-case (bug.c).  With
that file:

$ gcc -v 2>&1|grep version
gcc version 3.4.2 20041017 (Red Hat 3.4.2-6.fc3)
$ gcc -c -O2 bug.c
$ objdump -d bug.o |tail -2
  76:   48 81 c4 28 10 00 00    add    $0x1028,%rsp
  7d:   c3                      retq   
$ readelf -wf bug.o 
The section .eh_frame contains:

00000000 00000014 00000000 CIE
  Version:               1
  Augmentation:          ""
  Code alignment factor: 1
  Data alignment factor: -8
  Return address column: 16

  DW_CFA_def_cfa: r7 ofs 8
  DW_CFA_offset: r16 at cfa-8
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop

00000018 00000024 0000001c FDE cie=00000000 pc=00000000..0000007e
  DW_CFA_advance_loc: 5 to 00000005
  DW_CFA_offset: r6 at cfa-32
  DW_CFA_advance_loc: 24 to 0000001d
  DW_CFA_def_cfa_offset: 4144
  DW_CFA_offset: r13 at cfa-16
  DW_CFA_offset: r3 at cfa-40
  DW_CFA_offset: r12 at cfa-24

While the code came out slightly differently, the same problem exists: the
DWARF2 frame info fails to describe the effect of popping the stack in the
second-last instruction.
Comment 3 davidm 2004-12-20 22:15:03 UTC
Created attachment 7786 [details]
testcase
Comment 4 Steven Bosscher 2004-12-21 00:21:10 UTC
"xgcc (GCC) 4.0.0 20041220 (experimental)" produces this: 
$ ./xgcc -c -B. -O2 bug.c 
$ objdump -d bug.o 
 
bug.o:     file format elf64-x86-64 
 
Disassembly of section .text: 
 
0000000000000000 <func>: 
   0:   48 89 5c 24 e0          mov    %rbx,0xffffffffffffffe0(%rsp) 
   5:   48 89 6c 24 e8          mov    %rbp,0xffffffffffffffe8(%rsp) 
   a:   89 fb                   mov    %edi,%ebx 
   c:   4c 89 64 24 f0          mov    %r12,0xfffffffffffffff0(%rsp) 
  11:   4c 89 6c 24 f8          mov    %r13,0xfffffffffffffff8(%rsp) 
  16:   48 81 ec 28 10 00 00    sub    $0x1028,%rsp 
  1d:   85 ff                   test   %edi,%edi 
  1f:   7f 36                   jg     57 <func+0x57> 
  21:   89 d8                   mov    %ebx,%eax 
  23:   48 8b ac 24 10 10 00    mov    0x1010(%rsp),%rbp 
  2a:   00 
  2b:   4c 8b a4 24 18 10 00    mov    0x1018(%rsp),%r12 
  32:   00 
  33:   c1 e8 1f                shr    $0x1f,%eax 
  36:   4c 8b ac 24 20 10 00    mov    0x1020(%rsp),%r13 
  3d:   00 
  3e:   01 d8                   add    %ebx,%eax 
  40:   48 8b 9c 24 08 10 00    mov    0x1008(%rsp),%rbx 
  47:   00 
  48:   d1 f8                   sar    %eax 
  4a:   48 98                   cltq 
  4c:   8b 04 84                mov    (%rsp,%rax,4),%eax 
  4f:   48 81 c4 28 10 00 00    add    $0x1028,%rsp 
  56:   c3                      retq 
  57:   44 8d 6b ff             lea    0xffffffffffffffff(%rbx),%r13d 
  5b:   45 31 e4                xor    %r12d,%r12d 
  5e:   48 89 e5                mov    %rsp,%rbp 
  61:   44 89 ef                mov    %r13d,%edi 
  64:   41 ff c4                inc    %r12d 
  67:   e8 00 00 00 00          callq  6c <func+0x6c> 
  6c:   89 45 00                mov    %eax,0x0(%rbp) 
  6f:   48 83 c5 04             add    $0x4,%rbp 
  73:   44 39 e3                cmp    %r12d,%ebx 
  76:   7f e9                   jg     61 <func+0x61> 
  78:   eb a7                   jmp    21 <func+0x21> 
 
 
$ readelf -wf bug.o 
The section .eh_frame contains: 
 
00000000 00000014 00000000 CIE 
  Version:               1 
  Augmentation:          "" 
  Code alignment factor: 1 
  Data alignment factor: -8 
  Return address column: 16 
 
  DW_CFA_def_cfa: r7 ofs 8 
  DW_CFA_offset: r16 at cfa-8 
  DW_CFA_nop 
  DW_CFA_nop 
  DW_CFA_nop 
  DW_CFA_nop 
  DW_CFA_nop 
  DW_CFA_nop 
 
00000018 00000024 0000001c FDE cie=00000000 pc=00000000..0000007a 
  DW_CFA_advance_loc: 10 to 0000000a 
  DW_CFA_offset: r6 at cfa-32 
  DW_CFA_offset: r3 at cfa-40 
  DW_CFA_advance_loc: 19 to 0000001d 
  DW_CFA_def_cfa_offset: 4144 
  DW_CFA_offset: r13 at cfa-16 
  DW_CFA_offset: r12 at cfa-24 
  DW_CFA_nop 
  DW_CFA_nop 
  DW_CFA_nop 
 
Comment 5 Paul Pluzhnikov 2009-03-27 01:51:18 UTC
dup of bug 12990 ?
Comment 6 Richard Henderson 2010-10-06 16:25:24 UTC
Dup

*** This bug has been marked as a duplicate of bug 12990 ***