[llvm-bugs] [Bug 26844] New: clang 3.8.0/powerpc C++ exception .eh_frame ABI violation/incompleteness leads to SEGV

via llvm-bugs llvm-bugs at lists.llvm.org
Fri Mar 4 13:36:29 PST 2016


https://llvm.org/bugs/show_bug.cgi?id=26844

            Bug ID: 26844
           Summary: clang 3.8.0/powerpc C++ exception .eh_frame ABI
                    violation/incompleteness leads to SEGV
           Product: clang
           Version: 3.8
          Hardware: PC
                OS: FreeBSD
            Status: NEW
          Severity: normal
          Priority: P
         Component: C++
          Assignee: unassignedclangbugs at nondot.org
          Reporter: markmi at dsl-only.net
                CC: dgregor at apple.com, llvm-bugs at lists.llvm.org
    Classification: Unclassified

[This is for FreeBSD's projects/clang380-import-r296011 at the time of
submittal.]

In the normal C++ ABI exception handling uses 4 scratch registers: "These
scratch registers are reserved for passing arguments between the personality
routine and the landing pads". This is for "an unwind context representing a
handler frame, for which the personality routine will return
_URC_INSTALL_CONTEXT" (_Unwind_SetGR).

Prior to executing in the landing pad the context record is used to restore
various registers "to their state in the frame before the call that threw that
exception": callee-saved (not altered by the personality routine) and scratch.

For TARGET_ARCH=powerpc (or powerpc64) FreeBSD's system libgcc_s
_Unwind_RaiseException gets differing behavior for this between gcc/g++ and
clang/clang++ for the scratch registers (and more):

A) gcc/g++ uses the 4 registers r3, r4, r5, r6 as the scratch registers and
sets up to save/restore them, doing so being reported on by the .eh_frame
information for _Unwind_RaiseException. It also sets up to save/restore R14-r31
and floating point registers as r46-r63. It also sets up to save/restore "r70"
(holding the value from mfcr). (The powerpc ABI uses a bit in the cr for
floating point usage information in the call standard.)

B) clang/clang++ does not set up to save/restore any scratch registers or a
value from mfcr. It does set up to save/restore r14-r31 and floating point
registers as r46-r63.

The result is that if things get to the point of the following FreeBSD code as
part of handling the exception then the first _Unwind_SetGR gets a SEGV.
__builtin_eh_return_data_regno (0) returns 3 to identify r3 as the register
context.

678      /* For targets with pointers smaller than the word size, we must
extend the
679         pointer, and this extension is target dependent.  */
680      _Unwind_SetGR (context, __builtin_eh_return_data_regno (0),
681             __builtin_extend_pointer (ue_header));
682      _Unwind_SetGR (context, __builtin_eh_return_data_regno (1),
683             handler_switch_value);
684      _Unwind_SetIP (context, landing_pad);

As evidence of the difference for scratch register handling (and "r70"/cr
handling). . .

gcc/g++ dwarfdump -v -v -F output extraction for _Unwind_RaiseException:

fde section offset 1104 0x00000450 cie offset for fde: 1108 0x00000454
        0 DW_CFA_advance_loc 8  (8 * 1)
        1 DW_CFA_def_cfa_offset 3024
        4 DW_CFA_advance_loc1 156
        6 DW_CFA_offset r4 -232  (58 * -4)
        8 DW_CFA_offset r3 -236  (59 * -4)
       10 DW_CFA_offset r28 -160  (40 * -4)
       12 DW_CFA_offset r27 -164  (41 * -4)
       14 DW_CFA_offset r26 -168  (42 * -4)
       16 DW_CFA_offset r25 -172  (43 * -4)
       18 DW_CFA_offset r24 -176  (44 * -4)
       20 DW_CFA_offset r23 -180  (45 * -4)
       22 DW_CFA_offset r22 -184  (46 * -4)
       24 DW_CFA_offset r21 -188  (47 * -4)
       26 DW_CFA_offset r20 -192  (48 * -4)
       28 DW_CFA_offset r19 -196  (49 * -4)
       30 DW_CFA_offset r18 -200  (50 * -4)
       32 DW_CFA_offset r17 -204  (51 * -4)
       34 DW_CFA_offset r16 -208  (52 * -4)
       36 DW_CFA_offset r15 -212  (53 * -4)
       38 DW_CFA_offset r14 -216  (54 * -4)
       40 DW_CFA_offset r63 -8  (2 * -4)
       42 DW_CFA_offset r62 -16  (4 * -4)
       44 DW_CFA_offset r61 -24  (6 * -4)
       46 DW_CFA_offset r60 -32  (8 * -4)
       48 DW_CFA_offset r59 -40  (10 * -4)
       50 DW_CFA_offset r58 -48  (12 * -4)
       52 DW_CFA_offset r57 -56  (14 * -4)
       54 DW_CFA_offset r56 -64  (16 * -4)
       56 DW_CFA_offset r55 -72  (18 * -4)
       58 DW_CFA_offset r54 -80  (20 * -4)
       60 DW_CFA_offset r53 -88  (22 * -4)
       62 DW_CFA_offset r52 -96  (24 * -4)
       64 DW_CFA_offset r51 -104  (26 * -4)
       66 DW_CFA_offset r50 -112  (28 * -4)
       68 DW_CFA_offset r49 -120  (30 * -4)
       70 DW_CFA_offset r48 -128  (32 * -4)
       72 DW_CFA_offset r47 -136  (34 * -4)
       74 DW_CFA_offset r46 -144  (36 * -4)
       76 DW_CFA_register r70 = r12
       79 DW_CFA_offset_extended_sf r65 4  (-1 * -4)
       82 DW_CFA_advance_loc 32  (32 * 1)
       83 DW_CFA_offset r5 -228  (57 * -4)
       85 DW_CFA_offset r31 -148  (37 * -4)
       87 DW_CFA_offset r30 -152  (38 * -4)
       89 DW_CFA_offset r29 -156  (39 * -4)
       91 DW_CFA_offset_extended r70 -220  (55 * -4)
       94 DW_CFA_offset r6 -224  (56 * -4)
       96 DW_CFA_nop
       97 DW_CFA_nop
       98 DW_CFA_nop



clang/clang++ 3.8.0 dwarfdump -v -v -F output extraction for
_Unwind_RaiseException:

fde section offset 692 0x000002b4 cie offset for fde: 696 0x000002b8
        0 DW_CFA_advance_loc 20  (5 * 4)
        1 DW_CFA_def_cfa_offset 2992
        4 DW_CFA_offset r31 -148  (37 * -4)
        6 DW_CFA_offset r30 -152  (38 * -4)
        8 DW_CFA_offset_extended_sf r65 4  (-1 * -4)
       11 DW_CFA_advance_loc 4  (1 * 4)
       12 DW_CFA_def_cfa_register r31
       14 DW_CFA_offset r14 -216  (54 * -4)
       16 DW_CFA_offset r15 -212  (53 * -4)
       18 DW_CFA_offset r16 -208  (52 * -4)
       20 DW_CFA_offset r17 -204  (51 * -4)
       22 DW_CFA_offset r18 -200  (50 * -4)
       24 DW_CFA_offset r19 -196  (49 * -4)
       26 DW_CFA_offset r20 -192  (48 * -4)
       28 DW_CFA_offset r21 -188  (47 * -4)
       30 DW_CFA_offset r22 -184  (46 * -4)
       32 DW_CFA_offset r23 -180  (45 * -4)
       34 DW_CFA_offset r24 -176  (44 * -4)
       36 DW_CFA_offset r25 -172  (43 * -4)
       38 DW_CFA_offset r26 -168  (42 * -4)
       40 DW_CFA_offset r27 -164  (41 * -4)
       42 DW_CFA_offset r28 -160  (40 * -4)
       44 DW_CFA_offset r29 -156  (39 * -4)
       46 DW_CFA_offset r30 -152  (38 * -4)
       48 DW_CFA_offset r31 -148  (37 * -4)
       50 DW_CFA_offset r46 -144  (36 * -4)
       52 DW_CFA_offset r47 -136  (34 * -4)
       54 DW_CFA_offset r48 -128  (32 * -4)
       56 DW_CFA_offset r49 -120  (30 * -4)
       58 DW_CFA_offset r50 -112  (28 * -4)
       60 DW_CFA_offset r51 -104  (26 * -4)
       62 DW_CFA_offset r52 -96  (24 * -4)
       64 DW_CFA_offset r53 -88  (22 * -4)
       66 DW_CFA_offset r54 -80  (20 * -4)
       68 DW_CFA_offset r55 -72  (18 * -4)
       70 DW_CFA_offset r56 -64  (16 * -4)
       72 DW_CFA_offset r57 -56  (14 * -4)
       74 DW_CFA_offset r58 -48  (12 * -4)
       76 DW_CFA_offset r59 -40  (10 * -4)
       78 DW_CFA_offset r60 -32  (8 * -4)
       80 DW_CFA_offset r61 -24  (6 * -4)
       82 DW_CFA_offset r62 -16  (4 * -4)
       84 DW_CFA_offset r63 -8  (2 * -4)
       86 DW_CFA_nop

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20160304/31751d3d/attachment-0001.html>


More information about the llvm-bugs mailing list