The following testcase gets wrong unwind info with
-m32 -Os -fpic -fno-asynchronous-unwind-tables
on the 4.3 branch (haven't tried 4.4 yet).  The problem is incorrect
DW_CFA_GNU_args_size (usually off by 16), which results in catch receiving
%esp 16 bytes above what should be received.  As this catch is called in the
loop 10 times, each iteration bumps %esp by 16 bytes and eventually trashes
saved variables on the stack (in http://bugzilla.redhat.com/447912
case already the 3rd iteration overwrites saved stderr pointer on the stack).

The interesting function is
_ZN17OleEmbeddedObject44TryToRetrieveCachedVisualRepresentation_ImplERKN3com3sun4star3uno9ReferenceINS2_2io7XStreamEEEh.
>From what I can see, DW_CFA_GNU_args_size matches the code from the beginning
until first call [EMAIL PROTECTED]  After the following addl $16, %esp
it is still right (after that insns args_size is set to 0):
.LCFI2090:
        call    [EMAIL PROTECTED]
        addl    $16, %esp
.LCFI2091:
        jmp     .L542
...
        .long   .LCFI2090-.LCFI2089
        .byte   0x2e    # DW_CFA_GNU_args_size
        .uleb128 0x10
        .byte   0x4     # DW_CFA_advance_loc4
        .long   .LCFI2091-.LCFI2090
        .byte   0x2e    # DW_CFA_GNU_args_size
        .uleb128 0x0

But the code jmp .L542 jumps to has args_size 16, not 0:
.LCFI2098:
        call    [EMAIL PROTECTED]
        addl    $16, %esp
.LCFI2099:
.LEHB94:
        call    [EMAIL PROTECTED]
.LEHE94:
.L542:
        # basic block 17
        cmpl    $0, -20(%ebp)
        je      .L547
        # basic block 18
        movl    [EMAIL PROTECTED](%ebx), %edx
        movl    $0, -144(%ebp)
        movl    %edx, -168(%ebp)
        movl    %edx, -172(%ebp)
        movl    %edx, -176(%ebp)
.L565:
        # basic block 19
        pushl   %eax
.LCFI2100:
...
        .long   .LCFI2098-.LCFI2097
        .byte   0x2e    # DW_CFA_GNU_args_size
        .uleb128 0x20
        .byte   0x4     # DW_CFA_advance_loc4
        .long   .LCFI2099-.LCFI2098
        .byte   0x2e    # DW_CFA_GNU_args_size
        .uleb128 0x10
        .byte   0x4     # DW_CFA_advance_loc4
        .long   .LCFI2100-.LCFI2099
        .byte   0x2e    # DW_CFA_GNU_args_size
        .uleb128 0x14
Without -fasynchronous-unwind-tables it honors second operands of CALL rtls and
those are correct for this codepath.


-- 
           Summary: [4.3 Regression] Wrong unwind info with -Os -
                    fasynchronous-unwind-tables
           Product: gcc
           Version: 4.3.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: jakub at gcc dot gnu dot org
GCC target triplet: i686-linux


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

Reply via email to