Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 8 Oct 2017 16:06:15 -0700
From:      Mark Millard <markmi@dsl-only.net>
To:        Roman Divacky <rdivacky@vlakno.cz>, FreeBSD Toolchain <freebsd-toolchain@freebsd.org>, FreeBSD PowerPC ML <freebsd-ppc@freebsd.org>, freebsd-hackers <freebsd-hackers@freebsd.org>, Justin Hibbits <jrh29@alumni.cwru.edu>, Nathan Whitehorn <nwhitehorn@freebsd.org>, Warner Losh <imp@FreeBSD.org>
Subject:   Re: head -r324071 clang++ 5 for TARGET_ARCH=powerpc64 (e.g.): DW_CFA_offset_extended for r97-r108? Handled by FreeBSD's libgcc_s.so.1 ? (more. . .)
Message-ID:  <B0543889-A626-412D-9C4A-3889222DCA06@dsl-only.net>
In-Reply-To: <CF0CE1A7-7AC4-48C8-89EE-D8EABE408DBC@dsl-only.net>
References:  <6FEAEDA2-6036-4FC0-B794-15BC264BD31D@dsl-only.net> <1098914B-6BA2-419D-B8FB-01AB71C3DC29@dsl-only.net> <CF0CE1A7-7AC4-48C8-89EE-D8EABE408DBC@dsl-only.net>

next in thread | previous in thread | raw e-mail | index | archive | help
Another ABI variation/violation. I top post them
because it is largely separate from the AltiVec
Registers issue and is probably more important.

Summary:

Lack of r2-r6 save/restore (and so its
matching DW_CFA_<?> material) so lack
of places for the like of _Unwind_SetGR
to work with.

More detail:

Beyond the AltiVec Registers issue it turns out that
for:

_Unwind_RaiseException
_Unwind_ForcedUnwind
_Unwind_Resume
_Unwind_Resume_or_Rethrow

the code generation from clang 5 for them does
not save/restore the ABI's "scratch registers"
involved in the exception handling: r2-r6. But
they are in the code from powerpc64-gcc.

In FreeBSD's libgcc_s.so.1 and libcxxrt.so.1
terms:

This means that _Unwind_SetGR and _Unwind_GetGR
have no place to set or access the value of
the r2-r6 GR in question. It currently
crashes as the first attempt, which happens
to be for setting r3 (as a scratch value).

This in turn prevents __gxx_personality_v0
from working. That in turn prevents throwing
exceptions from working.

Without the code generation, it makes sense
to not have the DW_CFA_<?>'s as well. The
code generation (or lack of it) is a bigger
deal.

It appears that in this area clang 5 simply
does not currently match the ABI that
powerpc64-gcc is generating code for and
that FreeBSD's libgcc_s.so.1 and libcxxrt.so.1
are designed for. That is why throwing a C++
exception gets the failure at:

Loaded symbols for /libexec/ld-elf.so.1
#0  0x0000000050530c20 in _Unwind_SetGR (context=3D<value optimized =
out>, index=3D<value optimized out>, val=3D1342447712) at =
unwind-dw2-fde.h:162
162	{
(gdb) bt
#0  0x0000000050530c20 in _Unwind_SetGR (context=3D<value optimized =
out>, index=3D<value optimized out>, val=3D1342447712) at =
unwind-dw2-fde.h:162
#1  0x0000000050190194 in __gxx_personality_v0 (version=3D<value =
optimized out>, actions=3D<value optimized out>, exceptionClass=3D<value =
optimized out>, exceptionObject=3D0x50042060,=20
   context=3D0xffffffffffffcc70) at =
/usr/src/contrib/libcxxrt/exception.cc:1203
#2  0x0000000050531a60 in _Unwind_RaiseException_Phase2 (exc=3D0x50042060,=
 context=3D0xffffffffffffcc70) at unwind.inc:66
#3  0x0000000050531548 in _Unwind_RaiseException (exc=3D<value optimized =
out>) at unwind.inc:135
#4  0x000000005018f4f4 in __cxa_throw (thrown_exception=3D<value =
optimized out>, tinfo=3D<value optimized out>, dest=3D<value=20

Clang does save and restore other special
registers (special in DW_CFA_<?> terms):

In libgcc_s.so.1.full (via clang):

uw_update_context_1:           r70 (uw_update_context_1 was actually =
later in the file)
_Unwind_RaiseException:        =
r4[6-9],r5[0-9],r6[0-3],r70,r9[7-9],r10[0-8]
_Unwind_RaiseException_Phase2: r70
_Unwind_ForcedUnwind:          =
r4[6-9],r5[0-9],r6[0-3],r70,r9[7-9],r10[0-8]
_Unwind_Resume:                =
r4[6-9],r5[0-9],r6[0-3],r70,r9[7-9],r10[0-8]
_Unwind_Resume_or_Rethrow:     =
r4[6-9],r5[0-9],r6[0-3],r70,r9[7-9],r10[0-8]
_Unwind_Backtrace:             =
r4[6-9],r5[0-9],r6[0-3],r70,r9[7-9],r10[0-8]
__deregister_frame_info_bases: (nothing special matched)
_Unwind_Find_FDE:              (nothing special matched)

By contrast for powerpc64-gcc:

In libgcc_s.so.1.full (via powerpc64-gcc):

uw_update_context_1:           r70
_Unwind_RaiseException:        r[2-6],r4[6-9],r5[0-9],r6[0-3],r70
_Unwind_RaiseException_Phase2: (nothing special matched)
_Unwind_ForcedUnwind:          r[2-6],r4[6-9],r5[0-9],r6[0-3],r70
_Unwind_Resume:                r[2-6],r4[6-9],r5[0-9],r6[0-3],r70
_Unwind_Resume_or_Rethrow:     r[2-6],r4[6-9],r5[0-9],r6[0-3],r70
_Unwind_Backtrace:                    r4[6-9],r5[0-9],r6[0-3],r70
__deregister_frame_info_bases: r70
_Unwind_Find_FDE:              r70



On 2017-Oct-8, at 2:24 PM, Mark Millard <markmi at dsl-only.net> wrote:

> Quick top note: clang 5 does generate code sequences
> with AltiVec stvx and lvx instructions where r97-r108
> are listed but powerpc64-gcc is not doing so in those
> same sorts of places. This appears to be a ABI
> variation across toolchains to me, unless such is
> fully optional in the ABI somehow.
>=20
> On 2017-Oct-8, at 6:34 AM, Mark Millard <markmi at dsl-only.net> =
wrote:
>=20
>> [Looks like r97-r108 are for vr20-vr31 (AltiVec
>> Registers).]
>>=20
>> On 2017-Oct-8, at 4:34 AM, Mark Millard <markmi at dsl-only.net> =
wrote:
>>=20
>>> =46rom a dwarfdump's _Unwind_RaiseException information
>>> from a clang/clang++ 5 based compile:
>>>=20
>>>      91 DW_CFA_offset_extended r97 -496  (62 * -8)
>>>      94 DW_CFA_offset_extended r98 -480  (60 * -8)
>>>      97 DW_CFA_offset_extended r99 -464  (58 * -8)
>>>      100 DW_CFA_offset_extended r100 -448  (56 * -8)
>>>      103 DW_CFA_offset_extended r101 -432  (54 * -8)
>>>      106 DW_CFA_offset_extended r102 -416  (52 * -8)
>>>      109 DW_CFA_offset_extended r103 -400  (50 * -8)
>>>      112 DW_CFA_offset_extended r104 -384  (48 * -8)
>>>      115 DW_CFA_offset_extended r105 -368  (46 * -8)
>>>      118 DW_CFA_offset_extended r106 -352  (44 * -8)
>>>      121 DW_CFA_offset_extended r107 -336  (42 * -8)
>>>      124 DW_CFA_offset_extended r108 -320  (40 * -8)
>>>=20
>>> By contrast devel/powerpc64-gcc does not produce any
>>> of those. Is this lack of support of some part of an
>>> ABI? Is clang going outside the range of the intended
>>> ABI?
>>=20
>> ABI64BitOpenPOWERv1.1_16July2015_pub.pdf indicates
>> that r97-r108 are for vr20-vr31 (AltiVec Registers).
>> [Is AltiVec optional --possibly missing?]
>>=20
>> So the questions translate into questions about
>> AltiVec support/handling for C++ exceptions.
>>=20
>> [Note: R70 is supposed to be specific to CR2.]
>>=20
>>> Does FreeBSD's libgcc_s design and implementation handle
>>> these additional logical registers?
>> . . .
>>=20
>> So the libgcc_s question traces back to: does it
>> handle AltiVec Registers vr20-vr31 if they are
>> referenced (clang)? Is it well behaved if r97-r108
>> are not referenced (powerpc64-gcc)?
>>=20
>>> Supporting notes:
>>>=20
>>> r46-r63 are for floating point registers (that
>>> have been around for a long time: older
>>> powerpc family members).
>>=20
>> r46-r63 are for f14-f31.
>>=20
>>> r70 is for having/using the value from "mfcr".
>>=20
>> Apparently r70 is supposed to be specific to CR2.
>>=20
>>> r2(?)-r6 are scratch for C++ exception handling.
>>> (I originally identified r3-r6. r2 might have a
>>> somewhat distinct status?)
>>=20
>> In normal functions r2-r6 do not get
>> DW_CFA_offset_extended_sf or
>> DW_CFA_offset entries. They are special
>> to some internal exception handling
>> routines. (See later.)
>>=20
>>> r14-r31 are for the normal r14 through r31
>>> registers.
>>=20
>> r97-r108 are for AltiVec Registers vr20-vr31.
>>=20
>>> r65 is standard and heavily used on all(?)
>>> routines, not just some libgcc_s ones. (So
>>> r65 is not listed below.)
>>=20
>> r65 for lr.
>>=20
>>> In libgcc_s.so.1.full (via powerpc64-gcc):
>>>=20
>>> uw_update_context_1:           r70
>>> _Unwind_RaiseException:        r[2-6],r4[6-9],r5[0-9],r6[0-3],r70
>>> _Unwind_RaiseException_Phase2: (nothing special matched)
>>> _Unwind_ForcedUnwind:          r[2-6],r4[6-9],r5[0-9],r6[0-3],r70
>>> _Unwind_Resume:                r[2-6],r4[6-9],r5[0-9],r6[0-3],r70
>>> _Unwind_Resume_or_Rethrow:     r[2-6],r4[6-9],r5[0-9],r6[0-3],r70
>>> _Unwind_Backtrace:                    r4[6-9],r5[0-9],r6[0-3],r70
>>> __deregister_frame_info_bases: r70
>>> _Unwind_Find_FDE:              r70
>>=20
>> So no AltiVec Registers listed.
>>=20
>>> In libgcc_s.so.1.full (via clang):
>>>=20
>>> uw_update_context_1:           r70 (uw_update_context_1 was actually =
later in the file)
>>> _Unwind_RaiseException:        =
r4[6-9],r5[0-9],r6[0-3],r70,r9[7-9],r10[0-8]
>>> _Unwind_RaiseException_Phase2: r70
>>> _Unwind_ForcedUnwind:          =
r4[6-9],r5[0-9],r6[0-3],r70,r9[7-9],r10[0-8]
>>> _Unwind_Resume:                =
r4[6-9],r5[0-9],r6[0-3],r70,r9[7-9],r10[0-8]
>>> _Unwind_Resume_or_Rethrow:     =
r4[6-9],r5[0-9],r6[0-3],r70,r9[7-9],r10[0-8]
>>> _Unwind_Backtrace:             =
r4[6-9],r5[0-9],r6[0-3],r70,r9[7-9],r10[0-8]
>>> __deregister_frame_info_bases: (nothing special matched)
>>> _Unwind_Find_FDE:              (nothing special matched)
>>=20
>> So no internal, special-for-excpetion-routines
>> scratch register usage listed (r2-r6).
>>=20
>>> clang is missing all the r[2-6] references but
>>> the code generated does have the registers in
>>> use. Thrown C++ exceptions crash because of
>>> the lack of the r2-r6's, dying on a r3 attempt.
>>>=20
>> . . .
>>>=20
>>> I have no clue why _Unwind_RaiseException_Phase2
>>> has a r70 for clang but not for powerpc64-gcc.
>>> Or the other way around for __deregister_frame_info_bases
>>> and _Unwind_Find_FDE.
>>>=20
>>> Which file's implementations are used from
>>> what I can tell :
>>>=20
>>> uw_update_context_1:           /usr/src/contrib/gcc/unwind-dw2.c
>>> _Unwind_RaiseException:        /usr/src/contrib/gcc/unwind.inc
>>> _Unwind_RaiseException_Phase2: /usr/src/contrib/gcc/unwind.inc
>>> _Unwind_ForcedUnwind:          /usr/src/contrib/gcc/unwind.inc
>>> _Unwind_Resume:                /usr/src/contrib/gcc/unwind.inc
>>> _Unwind_Resume_or_Rethrow:     /usr/src/contrib/gcc/unwind.inc
>>> _Unwind_Backtrace:             /usr/src/contrib/gcc/unwind.inc
>>> __deregister_frame_info_bases: /usr/src/contrib/gcc/unwind-dw2-fde.c
>>> _Unwind_Find_FDE:              =
/usr/src/contrib/gcc/unwind-dw2-fde*.c (unsure)
>>>=20
>>> An implication is that GPL Version 2 source code
>>> is involved even when clang is the system compiler.
>>> Is that what FreeBSD intends for the powerpc
>>> families?
>>>=20
>>> /* Exception handling and frame unwind runtime interface routines. =
-*- C -*-
>>> Copyright (C) 2001, 2003 Free Software Foundation, Inc.
>>>=20
>>> This file is part of GCC.
>>>=20
>>> GCC is free software; you can redistribute it and/or modify it
>>> under the terms of the GNU General Public License as published by
>>> the Free Software Foundation; either version 2, or (at your option)
>>> any later version.
>>>=20
>>> In addition to the permissions in the GNU General Public License, =
the
>>> Free Software Foundation gives you unlimited permission to link the
>>> compiled version of this file into combinations with other programs,
>>> and to distribute those combinations without any restriction coming
>>> from the use of this file.  (The General Public License restrictions
>>> do apply in other respects; for example, they cover modification of
>>> the file, and distribution when not linked into a combined
>>> executable.)
>>>=20
>>> . . .
>>>=20
>>> Does libgcc_s.so.1 with its type of use form a "combined =
executable"?

=3D=3D=3D
Mark Millard
markmi at dsl-only.net





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?B0543889-A626-412D-9C4A-3889222DCA06>