[Bug 207359] projects/clang380-import for TARGET_ARCH=powerpc64 via powerpc64-gcc : c++ exceptions unbounded loop in _Unwind_RaiseException (9 line program)

bugzilla-noreply at freebsd.org bugzilla-noreply at freebsd.org
Fri Feb 26 11:08:16 UTC 2016


https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=207359

--- Comment #5 from Mark Millard <markmi at dsl-only.net> ---
(In reply to Mark Millard from comment #4)

A new, corrected, even lower level detail interpretation. . . which may put the
burden on the system's .eh_frame handling in libgcc_s.

I state the relationship from the point of view what the existing fde
operations would need to do to be correct. The alternate is that the missing
activity is missing operations instead of the activity being "inside"
DW_CFA_remember_state and DW_CFA_restore_state.

The problem is that the DW_CFA_remember_state and later DW_CFA_restore_state do
not in fact restore the cfa_offset (in this case 128 as it was at the time of
the DW_CFA_remember_state).

dwarfdump shows in its notation that the DW_CFA_restore_state should restore
the "off cfa=128(r1)" status. This makes sense for the code in question. But
DW_CFA_remember_state/DW_CFA_restore_state do not save and restore the
cfa_offset (12 here).

DW_CFA_remember_state only saves fs->regs.
DW_CFA_restore_state only restores fs->regs.

fs->cfa_offset is not part of regs but is used by uw_update_context_1 for:

  /* Compute this frame's CFA.  */
  switch (fs->cfa_how)
    {
    case CFA_REG_OFFSET:
      cfa = _Unwind_GetPtr (&orig_context, fs->cfa_reg);
      cfa += fs->cfa_offset;
      break;

In the example fs->cfa_offset ends up being 0 instead of 128 after the
DW_CFA_restore_state, causing the wrong frame's return address to be used.

For reference: The below is the dwarfdump -v -v -F for throw_exception (where
the "stuck" return address vale problem [0x000153a0] is observed):


<    0><0x00015310:0x000153dc><throw_exception><fde offset 0x000010d8 length:
0x00000034><eh aug data len 0x0>
        0x00015310: <off cfa=00(r1) > 
        0x00015318: <off cfa=00(r1) > <off r31=-8(cfa) > <off r65=r0 > 
        0x00015324: <off cfa=128(r1) > <off r31=-8(cfa) > <off r65=16(cfa) > 
        0x00015368: <off cfa=00(r1) > <off r31=-8(cfa) > <off r65=16(cfa) > 
        0x00015378: <off cfa=00(r1) > 
        0x00015380: <off cfa=128(r1) > <off r31=-8(cfa) > <off r65=16(cfa) > 
        0x000153a8: <off cfa=00(r1) > <off r31=-8(cfa) > <off r65=16(cfa) > 
        0x000153b8: <off cfa=00(r1) > 
        0x000153c0: <off cfa=128(r1) > <off r31=-8(cfa) > <off r65=16(cfa) > 
 fde section offset 4312 0x000010d8 cie offset for fde: 4316 0x000010dc
         0 DW_CFA_advance_loc 8  (2 * 4)
         1 DW_CFA_register r65 = r0
         4 DW_CFA_offset r31 -8  (1 * -8)
         6 DW_CFA_advance_loc 12  (3 * 4)
         7 DW_CFA_def_cfa_offset 128
        10 DW_CFA_offset_extended_sf r65 16  (-2 * -8)
        13 DW_CFA_advance_loc 68  (17 * 4)
        14 DW_CFA_remember_state
        15 DW_CFA_def_cfa_offset 0
        17 DW_CFA_advance_loc 16  (4 * 4)
        18 DW_CFA_restore_extended r65
        20 DW_CFA_restore r31
        21 DW_CFA_advance_loc 8  (2 * 4)
        22 DW_CFA_restore_state
        23 DW_CFA_advance_loc 40  (10 * 4)
        24 DW_CFA_remember_state
        25 DW_CFA_def_cfa_offset 0
        27 DW_CFA_advance_loc 16  (4 * 4)
        28 DW_CFA_restore_extended r65
        30 DW_CFA_restore r31
        31 DW_CFA_advance_loc 8  (2 * 4)
        32 DW_CFA_restore_state
        33 DW_CFA_nop
        34 DW_CFA_nop
        35 DW_CFA_nop
        36 DW_CFA_nop
        37 DW_CFA_nop
        38 DW_CFA_nop


Note that if fs->cfa_reg could be varying then DW_CFA_remember_state and
DW_CFA_restore_state would need to do appropriate save/restore activity for
that too.

-- 
You are receiving this mail because:
You are the assignee for the bug.


More information about the freebsd-bugs mailing list