Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 1 Dec 2016 20:57:34 -0800
From:      Mark Millard <markmi@dsl-only.net>
To:        Ed Maste <emaste@freebsd.org>
Cc:        FreeBSD Toolchain <freebsd-toolchain@freebsd.org>, Dimitry Andric <dim@freebsd.org>, FreeBSD PowerPC ML <freebsd-ppc@freebsd.org>
Subject:   Re: WITH_LLVM_LIBUNWIND vs. WITHOUT_LLVM_LIBUNWIND, clang vs. gcc (such as devel/powerpc64-xtoolchain-gcc ): What is intended to be required for C++ exceptions to work?
Message-ID:  <BB2D1D3F-8B3F-4F2F-A431-A65E86C30516@dsl-only.net>
In-Reply-To: <8BA319C6-FAD1-445F-85C1-5086B5AA59A8@dsl-only.net>
References:  <750FCE4D-F25B-46E1-9383-B8A94AAA8792@dsl-only.net> <CAPyFy2ArXUYsyTC9LY_CqbU3FLVV0TeV%2BSandqd-SpPGMBL6Cg@mail.gmail.com> <81CBAB7A-B855-4673-B2E2-7862F441FDDA@dsl-only.net> <68972A8F-C8D4-4FF2-A933-ACCC79C15065@dsl-only.net> <8BA319C6-FAD1-445F-85C1-5086B5AA59A8@dsl-only.net>

next in thread | previous in thread | raw e-mail | index | archive | help
Quick summaries from looking around at official amd64 builds
(via downloaded .iso's installed in VirtualBox under Mac OS X):

_Unwind_RaiseException content (amd64 context only):

                    RaiseExc. RaiseExc.  RaiseException
                    dwarfdump save/rest. has "mov %rcx,%rsp"
                    r0?,r1?   rdx? rax?  return path?
                    --------- ---------- ------------------
release/9.3.0:      r0,r1     rdx,rax    mov %rcx,%rsp path
release/10.3.0:     r0,r1     rdx,rax    mov %rcx,%rsp path
stable/10 -r309258: r0,r1     rdx,rax    mov %rcx,%rsp path
release/11.0.1:     r0,r1     rdx,rax    mov %rcx,%rsp path
stable/11 -r309280: r0,r1     rdx,rax    mov %rcx,%rsp path
head (12) -r309302: <Niether> <Niether>  <No>

My simple example program's content compiled under the
host compiler:
("clang++ -g -std=3Dc++11 -pedantic -O2" when possible.)

                    program uses    pre _cxa_begin_catch compare and =
jump
                    _Unwind_Resume? logic?
                    --------------- =
-------------------------------------------
release/9.3.0:      _Unwind_Resume  sub $0x1,%rdx; je to =
_cxa_begin_catch call
release/10.3.0:     _Unwind_Resume  cmp $0x1,%edx; jne skips =
_cxa_begin_catch
stable/10 -r309258: _Unwind_Resume  cmp $0x1,%edx; jne skips =
_cxa_begin_catch
release/11.0.1:     <No>            <No test or jump>
stable/11 -r309280: <No>            <No test or jump>
head (12) -r309302: _Unwind_Resume  cmp $0x1,%edx; jne skips =
_cxa_begin_catch


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

On 2016-Dec-1, at 2:39 AM, Mark Millard <markmi at dsl-only.net> wrote:

> [A top-post noting that it is head -r309179 that is different
> from 9.3-RELELASE for _Unwind_raiseException --and from
> stable/11 -r309125-- after noting my repeated "stable/11"
> references that should have said "head". Also for code
> that uses libgcc_s.so.1 for C++ exception handling the
> odd one is instead stable/11 that is not like the other
> two.]
>=20
> First a correction to a systematic typing error:
>=20
> -r309179 was correct but it is head, not stable/11 .
>=20
> I repeat: My earlier comparison was between amd64
>          9.3-RELEASE and amd64 12-CURRENT -r309179 .
>=20
>=20
> What of stable/11 (by default WITHOUT_LLVM_LIBUNWIND=3D )
> vs. head (by default WITH_LLVM_LIBUNWIND=3D ) --and both
> of those vs. release/9.3.0 (implicitly
> WITHOUT_LLVM_LIBUNWIND=3D )?
>=20
> First _Unwind_RaiseException as an example from
> inside libgc_s.so.1 for exception handling. . .
>=20
> head -r309179 does *not* match stable/11 -r309125 or
> release/9.3.0 .
>=20
> stable/11 -r309125 is more like release/9.3.0 .
>=20
> So head *has* changed the amd64 C++ exception handling
> details as far as I can tell: WITH_LLVM_LIBUNWIND
> changes things.
>=20
> A quick report below for stable/11 -r309125 shows
> it has both styles of returns, like release/9.3.0
> does. It has r0 and r1 saved and restored too.
>=20
> stable/11 -r309125 _Unwind_RaiseException's code has:
>=20
> 0000000000002cb0 <_Unwind_RaiseException> push   %rbp
> 0000000000002cb1 <_Unwind_RaiseException+0x1> mov    %rsp,%rbp
> 0000000000002cb4 <_Unwind_RaiseException+0x4> push   %r15
> 0000000000002cb6 <_Unwind_RaiseException+0x6> push   %r14
> 0000000000002cb8 <_Unwind_RaiseException+0x8> push   %r13
> 0000000000002cba <_Unwind_RaiseException+0xa> push   %r12
> 0000000000002cbc <_Unwind_RaiseException+0xc> push   %rbx
> 0000000000002cbd <_Unwind_RaiseException+0xd> push   %rdx
> 0000000000002cbe <_Unwind_RaiseException+0xe> push   %rax
> 0000000000002cbf <_Unwind_RaiseException+0xf> sub    $0x368,%rsp
> . . .
> [ the below is mostly like the 2nd 9.3 return path ]
> 0000000000002e2b <_Unwind_RaiseException+0x17b> lea    =
0x8(%rbp,%rax,1),%rcx
> 0000000000002e30 <_Unwind_RaiseException+0x180> add    $0x368,%rsp
> 0000000000002e37 <_Unwind_RaiseException+0x187> pop    %rax
> 0000000000002e38 <_Unwind_RaiseException+0x188> pop    %rdx
> 0000000000002e39 <_Unwind_RaiseException+0x189> pop    %rbx
> 0000000000002e3a <_Unwind_RaiseException+0x18a> pop    %r12
> 0000000000002e3c <_Unwind_RaiseException+0x18c> pop    %r13
> 0000000000002e3e <_Unwind_RaiseException+0x18e> pop    %r14
> 0000000000002e40 <_Unwind_RaiseException+0x190> pop    %r15
> 0000000000002e42 <_Unwind_RaiseException+0x192> pop    %rbp
> 0000000000002e43 <_Unwind_RaiseException+0x193> mov    %rcx,%rsp
> 0000000000002e46 <_Unwind_RaiseException+0x196> retq  =20
> [ the above really does update %rsp twice during the return
>  sequence; the first of those updates is ineffective overall
>  and is from not having set optimization explicitly ]
> [ the below is much like the first 9.3 return path ]
> 0000000000002e4a <_Unwind_RaiseException+0x19a> add    $0x368,%rsp
> 0000000000002e51 <_Unwind_RaiseException+0x1a1> pop    %rax
> 0000000000002e52 <_Unwind_RaiseException+0x1a2> pop    %rdx
> 0000000000002e53 <_Unwind_RaiseException+0x1a3> pop    %rbx
> 0000000000002e54 <_Unwind_RaiseException+0x1a4> pop    %r12
> 0000000000002e56 <_Unwind_RaiseException+0x1a6> pop    %r13
> 0000000000002e58 <_Unwind_RaiseException+0x1a8> pop    %r14
> 0000000000002e5a <_Unwind_RaiseException+0x1aa> pop    %r15
> 0000000000002e5c <_Unwind_RaiseException+0x1ac> pop    %rbp
> 0000000000002e5d <_Unwind_RaiseException+0x1ad> retq  =20
>=20
> [Because of code order differences the above shows somewhat
> more than I did for 9.3 .]
>=20
> stable/11 -r309125 _Unwind_RaiseException's dwarfdump shows:
>=20
> fde section offset 720 0x000002d0 cie offset for fde: 724 0x000002d4
>         0 DW_CFA_advance_loc 1  (1 * 1)
>         1 DW_CFA_def_cfa_offset 16
>         3 DW_CFA_offset r6 -16  (2 * -8)
>         5 DW_CFA_advance_loc 3  (3 * 1)
>         6 DW_CFA_def_cfa_register r6
>         8 DW_CFA_advance_loc 18  (18 * 1)
>         9 DW_CFA_offset r0 -72  (9 * -8)
>        11 DW_CFA_offset r1 -64  (8 * -8)
>        13 DW_CFA_offset r3 -56  (7 * -8)
>        15 DW_CFA_offset r12 -48  (6 * -8)
>        17 DW_CFA_offset r13 -40  (5 * -8)
>        19 DW_CFA_offset r14 -32  (4 * -8)
>        21 DW_CFA_offset r15 -24  (3 * -8)
>=20
> Note the r0 and r1 (and %rax and %rdx in the code)
> so it is like release/9.3.0 in that respect.
>=20
>=20
> (I've still not looked at 10.x and with 11 being as it
> is I might not bother.)
>=20
>=20
>=20
> What about programs that use libgcc_s.so.1 ? . . .
>=20
> Looking at an example program shows a code interface
> difference visible in that code. Look just before the
> __cxa_begin_catch@plt call in head vs. stable/11:
> head -r309179 has conditional code that stable/11
> -r309125 does not:
>=20
> 0000000000400caf <main+0x1f> cmp    $0x1,%edx
> 0000000000400cb2 <main+0x22> jne    0000000000400cf3 <main+0x63>
>=20
> (This has -O2 in use for both contexts.)
>=20
> head -r309179 has that conditional code:
>=20
> 0000000000400c90 <main> push   %rbp
> 0000000000400c91 <main+0x1> mov    %rsp,%rbp
> 0000000000400c94 <main+0x4> push   %rbx
> 0000000000400c95 <main+0x5> push   %rax
> 0000000000400c96 <main+0x6> callq  000000000040093c <random@plt>
> 0000000000400c9b <main+0xb> callq  000000000040093c <random@plt>
> 0000000000400ca0 <main+0x10> callq  000000000040093c <random@plt>
> 0000000000400ca5 <main+0x15> callq  0000000000400c50 <_Z1gv>
> 0000000000400caa <main+0x1a> jmp    0000000000400cac <main+0x1c>
> 0000000000400cac <main+0x1c> mov    %rax,%rdi
> 0000000000400caf <main+0x1f> cmp    $0x1,%edx
> 0000000000400cb2 <main+0x22> jne    0000000000400cf3 <main+0x63>
> 0000000000400cb4 <main+0x24> callq  000000000040097c =
<__cxa_begin_catch@plt>
> 0000000000400cb9 <main+0x29> mov    %rax,%rbx
> 0000000000400cbc <main+0x2c> mov    0x20062e(%rip),%al        # =
00000000006012f0 <_ZGVZ4mainE5eaddr>
> 0000000000400cc2 <main+0x32> test   %al,%al
> 0000000000400cc4 <main+0x34> jne    0000000000400ce5 <main+0x55>
> 0000000000400cc6 <main+0x36> mov    $0x6012f0,%edi
> 0000000000400ccb <main+0x3b> callq  00000000004008fc =
<__cxa_guard_acquire@plt>
> 0000000000400cd0 <main+0x40> test   %eax,%eax
> 0000000000400cd2 <main+0x42> je     0000000000400ce5 <main+0x55>
> 0000000000400cd4 <main+0x44> mov    %rbx,0x20060d(%rip)        # =
00000000006012e8 <_ZZ4mainE5eaddr>
> 0000000000400cdb <main+0x4b> mov    $0x6012f0,%edi
> 0000000000400ce0 <main+0x50> callq  000000000040092c =
<__cxa_guard_release@plt>
> 0000000000400ce5 <main+0x55> callq  000000000040096c =
<__cxa_end_catch@plt>
> 0000000000400cea <main+0x5a> xor    %eax,%eax
> 0000000000400cec <main+0x5c> add    $0x8,%rsp
> 0000000000400cf0 <main+0x60> pop    %rbx
> 0000000000400cf1 <main+0x61> pop    %rbp
> 0000000000400cf2 <main+0x62> retq  =20
> 0000000000400cf3 <main+0x63> callq  00000000004009ac =
<_Unwind_Resume@plt>
>=20
> The call to _Unwind_Resume@plt above is another difference:
> stable/11 does not have that.
>=20
>=20
> stable/11 -r309125 does not have either of those points:
>=20
> 0000000000400be1 <main+0x1> mov    %rsp,%rbp
> 0000000000400be4 <main+0x4> push   %rbx
> 0000000000400be5 <main+0x5> push   %rax
> 0000000000400be6 <main+0x6> callq  00000000004008bc <random@plt>
> 0000000000400beb <main+0xb> callq  00000000004008bc <random@plt>
> 0000000000400bf0 <main+0x10> callq  00000000004008bc <random@plt>
> 0000000000400bf5 <main+0x15> callq  0000000000400ba0 <_Z1gv>
> 0000000000400bfa <main+0x1a> mov    %rax,%rdi
> 0000000000400bfd <main+0x1d> callq  00000000004008fc =
<__cxa_begin_catch@plt>
> 0000000000400c02 <main+0x22> mov    %rax,%rbx
> 0000000000400c05 <main+0x25> mov    0x2006c5(%rip),%al        # =
00000000006012d0 <_ZGVZ4mainE5eaddr>
> 0000000000400c0b <main+0x2b> test   %al,%al
> 0000000000400c0d <main+0x2d> jne    0000000000400c2e <main+0x4e>
> 0000000000400c0f <main+0x2f> mov    $0x6012d0,%edi
> 0000000000400c14 <main+0x34> callq  000000000040087c =
<__cxa_guard_acquire@plt>
> 0000000000400c19 <main+0x39> test   %eax,%eax
> 0000000000400c1b <main+0x3b> je     0000000000400c2e <main+0x4e>
> 0000000000400c1d <main+0x3d> mov    %rbx,0x2006a4(%rip)        # =
00000000006012c8 <_ZZ4mainE5eaddr>
> 0000000000400c24 <main+0x44> mov    $0x6012d0,%edi
> 0000000000400c29 <main+0x49> callq  00000000004008ac =
<__cxa_guard_release@plt>
> 0000000000400c2e <main+0x4e> callq  00000000004008ec =
<__cxa_end_catch@plt>
> 0000000000400c33 <main+0x53> xor    %eax,%eax
> 0000000000400c35 <main+0x55> add    $0x8,%rsp
> 0000000000400c39 <main+0x59> pop    %rbx
> 0000000000400c3a <main+0x5a> pop    %rbp
> 0000000000400c3b <main+0x5b> retq  =20
>=20
> The source for both is:
>=20
> #include <stdlib.h>
> #include <exception>
>=20
> void g(void)
> {
>    throw std::exception();
> }
>=20
> void f(void)
> {
>    void *p =3D alloca(random() & 0xffu);
>    g();
> }
>=20
> int main(void)
> {
>    void *p =3D alloca(random() & 0xffu);
>    try {
>        void *p2 =3D alloca(random() & 0xffu);
>        f();
>    }
>    catch (std::exception& e) {
>        static void * volatile eaddr =3D &e;
>    }
>    return 0;
> }
>=20
> I've looked at 9.3-RELEASE as well. . .
>=20
> 9.3 does not compare against %edx but against %rdx.
> That is a 32-bit vs. 64-bit difference that would
> require a large value in %rdx to matter. I've not
> analyzed the libgcc_s.so.1 code for the "high bits"
> issue: are they always zero in each context that
> does a comparison?
>=20
> 9.3 has a _Unwind_Resume call based on the test.
>=20
> head and 9.3 compare against 0x1.
>=20
> The result is more similarity to head -r309179 than
> to stable/11 -r309125 in the program code (i.e.,
> outside libgcc_s.so.1).
>=20
> [The libgcc_s.so.1 code is another matter.]
>=20
> (-O2 does not remove as much unnecessary code
> when gcc 4.2.1 is in use as well.)
>=20
> 9.3's code:
>=20
> 0000000000400ae0 <main> push   %rbp
> 0000000000400ae1 <main+0x1> mov    %rsp,%rbp
> 0000000000400ae4 <main+0x4> push   %rbx
> 0000000000400ae5 <main+0x5> sub    $0x8,%rsp
> 0000000000400ae9 <main+0x9> callq  00000000004008bc <random@plt>
> 0000000000400aee <main+0xe> and    $0xff,%eax
> 0000000000400af3 <main+0x13> add    $0x1e,%rax
> 0000000000400af7 <main+0x17> and    $0x1f0,%eax
> 0000000000400afc <main+0x1c> sub    %rax,%rsp
> 0000000000400aff <main+0x1f> callq  00000000004008bc <random@plt>
> 0000000000400b04 <main+0x24> and    $0xff,%eax
> 0000000000400b09 <main+0x29> add    $0x1e,%rax
> 0000000000400b0d <main+0x2d> and    $0x1f0,%eax
> 0000000000400b12 <main+0x32> sub    %rax,%rsp
> 0000000000400b15 <main+0x35> callq  0000000000400ab0 <_Z1fv>
> 0000000000400b1a <main+0x3a> mov    -0x8(%rbp),%rbx
> 0000000000400b1e <main+0x3e> leaveq=20
> 0000000000400b1f <main+0x3f> xor    %eax,%eax
> 0000000000400b21 <main+0x41> retq  =20
> 0000000000400b22 <main+0x42> sub    $0x1,%rdx
> 0000000000400b26 <main+0x46> mov    %rax,%rdi
> 0000000000400b29 <main+0x49> je     0000000000400b30 <main+0x50>
> 0000000000400b2b <main+0x4b> callq  000000000040092c =
<_Unwind_Resume@plt>
> 0000000000400b30 <main+0x50> callq  00000000004008fc =
<__cxa_begin_catch@plt>
> 0000000000400b35 <main+0x55> cmpb   $0x0,0x20046c(%rip)        # =
0000000000600fa8 <_ZGVZ4mainE5eaddr>
> 0000000000400b3c <main+0x5c> mov    %rax,%rbx
> 0000000000400b3f <main+0x5f> je     0000000000400b48 <main+0x68>
> 0000000000400b41 <main+0x61> callq  00000000004008ec =
<__cxa_end_catch@plt>
> 0000000000400b46 <main+0x66> jmp    0000000000400b1a <main+0x3a>
> 0000000000400b48 <main+0x68> mov    $0x600fa8,%edi
> 0000000000400b4d <main+0x6d> callq  000000000040087c =
<__cxa_guard_acquire@plt>
> 0000000000400b52 <main+0x72> test   %eax,%eax
> 0000000000400b54 <main+0x74> je     0000000000400b41 <main+0x61>
> 0000000000400b56 <main+0x76> mov    $0x600fa8,%edi
> 0000000000400b5b <main+0x7b> mov    %rbx,0x20044e(%rip)        # =
0000000000600fb0 <_ZZ4mainE5eaddr>
> 0000000000400b62 <main+0x82> callq  00000000004008ac =
<__cxa_guard_release@plt>
> 0000000000400b67 <main+0x87> jmp    0000000000400b41 <main+0x61>
>=20
>=20
>=20
> So overall:
>=20
> A) stable/11 is the odd ball for code using libgcc_s.so.1
>   for exception handling
>=20
> B) head is the odd ball for the exception handling code
>   in libgcc_s.so.1
>=20
> Either way the compatibility looks problematical for
> spanning from 9.3 through head.
>=20
>=20
> Have you tried old 9.3, 10.x, or 11.x amd64 code that
> depends on C++ exceptions heavily on the more modern
> versions in each case? For example devel/kyua makes
> heavy use of C++ exceptions as I remember. (But I do
> not know how other aspects of compatibility would go
> for using old ones on newer systems.) I do not know
> how much kyua covers the variety of possible
> dependencies on the libgcc_s.so.1 C++ exception
> handling interface that a program could validly
> have.
>=20
> =3D=3D=3D
> Mark Millard
> markmi at dsl-only.net
>=20
> On 2016-Nov-30, at 9:50 PM, Mark Millard <markmiat dsl-only.net> =
wrote:
>=20
> [I add the dwarfdump -v -v -F /lib/libgcc_s.so.1 from 9.3-RELEASE
> -r268512 that does not agree with stable/11 -r309179's clang 3.9.0
> content: it is like OpenMandriva Lx for the scratch register
> handling. I looked back this far because it was gcc 4.2.1 based
> for official amd64 releases.]
>=20
> On 2016-Nov-30, at 6:03 PM, Mark Millard <markmi@dsl-only.net> wrote:
>=20
>> On 2016-Nov-29, at 2:56 PM, Ed Maste <emaste at freebsd.org> wrote:
>>=20
>>> On 29 November 2016 at 16:46, Mark Millard <markmi at dsl-only.net> =
wrote:
>>>>=20
>>>>=20
>>>> Summary: Does using clang 3.9.0 as the system compiler imply one =
should or
>>>> must (eventually?) use WITH_LLVM_LIBUNWIND to have C++ exceptions =
work?
>>>>=20
>>>> Do WITH_LLVM_LIBUNWIND and WITHOUT_LLVM_LIBUNWIND have the same =
criteria
>>>> for what dwarfdump should show for the exception information (if =
the
>>>> information to be shown is to be correct/sufficient for libunwind)?
>>>=20
>>> It does not. It should be possible to build a functional system both
>>> WITH_ and WITHOUT_LLVM_LIBUNWIND. The compiler is unaware of the
>>> _LLVM_LIBUNWIND setting. Both unwind libraries use the same unwind
>>> data.
>>=20
>> Good to know. Thanks.
>>=20
>> [As there are no clang-based powerpc64 linux builds to my knowledge
>> the following uses amd64/x86_64 examples instead for comparisons.]
>>=20
>> What I see from "dwarfdump -v -v -F .../libgcc_s.so.1" for FreeBSD
>> head -r309179 vs. what I see for the clang 3.8.0 based OpenMandriva
>> Lx V3.0 leaves me a little worried: OpenMandriva Lx V3.0 is more
>> like what I would expect for:
>>=20
>> _Unwind_RaiseException    (9990 vs. c701)
>> _Unwind_ForcedUnwind      (a330 vs. c857)
>> _Unwind_Resume            (9fb0 vs. c927)
>> _Unwind_Resume_or_Rethrow (2da0 vs. c9e4)
>>=20
>> (The numbers are just for my reference in finding the dwarfdump
>> material.)
>>=20
>> By contrast FreeBSD has missing information from what I can tell.
>>=20
>> For these 4 routines only: OpenMandriva Lx has scratch registers
>> listed (r0 and r1 from the set of normally volatile registers
>> normally not listed). No other routines in libgcc_s.so.1 have
>> this. FreeBSD has no such extra registers listed anywhere,
>> including not on the 4 where I'd expect them.
>>=20
>> Using _Unwind_RaiseException as an example of those 4 routines
>> that I'm worried about. . .
>>=20
>> [Notes: r7 is %rsp, r6 is %rbp, r3 is %rbx, r2 is %rcx, r1 is %rdx,
>> and r0 is %rax in amd64/x86_64 land. Only OpenMandriva Lx had
>> examples of the last two. I use the dwarfdump naming below.]
>>=20
>> FreeBSD _Unwind_RaiseException:
>>=20
>> fde section offset 5328 0x000014d0 cie offset for fde: 5332 =
0x000014d4
>>       0 DW_CFA_advance_loc 1  (1 * 1)
>>       1 DW_CFA_def_cfa_offset 16
>>       3 DW_CFA_offset r6 -16  (2 * -8)
>>       5 DW_CFA_advance_loc 3  (3 * 1)
>>       6 DW_CFA_def_cfa_register r6
>>       8 DW_CFA_advance_loc 16  (16 * 1)
>>       9 DW_CFA_offset r3 -56  (7 * -8)
>>      11 DW_CFA_offset r12 -48  (6 * -8)
>>      13 DW_CFA_offset r13 -40  (5 * -8)
>>      15 DW_CFA_offset r14 -32  (4 * -8)
>>      17 DW_CFA_offset r15 -24  (3 * -8)
>>      19 DW_CFA_nop
>>      20 DW_CFA_nop
>>      21 DW_CFA_nop
>>      22 DW_CFA_nop
>=20
> [It may be that some sort of update after 9.x makes what
> I report below expected. If so I've not identified it yet.
> At this point that is my guess: a different amd64 ABI now
> than in 9.3 for C++ exception handling, at least for some
> details.]
>=20
> The amd64 9.3-RELEASE -r268512 dwarfdump output for its
> _Unwind_RaiseException in its /lib/libgcc_s.so.1 does
> not match the above from stable/11 -r309179 for the
> scratch register handling. Note the r0 and r1 items
> (20 and 22):
>=20
> fde section offset 2672 0x00000a70 cie offset for fde: 2676 0x00000a74
>        0 DW_CFA_advance_loc 1  (1 * 1)
>        1 DW_CFA_def_cfa_offset 16
>        3 DW_CFA_offset r6 -16  (2 * -8)
>        5 DW_CFA_advance_loc 3  (3 * 1)
>        6 DW_CFA_def_cfa_register r6
>        8 DW_CFA_advance_loc 13  (13 * 1)
>        9 DW_CFA_offset r3 -56  (7 * -8)
>       11 DW_CFA_offset r12 -48  (6 * -8)
>       13 DW_CFA_offset r13 -40  (5 * -8)
>       15 DW_CFA_offset r14 -32  (4 * -8)
>       17 DW_CFA_offset r15 -24  (3 * -8)
>       19 DW_CFA_advance_loc 9  (9 * 1)
>       20 DW_CFA_offset r0 -72  (9 * -8)
>       22 DW_CFA_offset r1 -64  (8 * -8)
>       24 DW_CFA_nop
>       25 DW_CFA_nop
>       26 DW_CFA_nop
>       27 DW_CFA_nop
>       28 DW_CFA_nop
>       29 DW_CFA_nop
>       30 DW_CFA_nop
>=20
> The 9.3 code has %rdx (r2) and %rax (r0) saved and
> restored:
>=20
> 00000000000088d0 <_Unwind_RaiseException> push   %rbp
> 00000000000088d1 <_Unwind_RaiseException+0x1> mov    %rsp,%rbp
> 00000000000088d4 <_Unwind_RaiseException+0x4> push   %r15
> 00000000000088d6 <_Unwind_RaiseException+0x6> lea    0x10(%rbp),%rsi
> 00000000000088da <_Unwind_RaiseException+0xa> push   %r14
> 00000000000088dc <_Unwind_RaiseException+0xc> push   %r13
> 00000000000088de <_Unwind_RaiseException+0xe> push   %r12
> 00000000000088e0 <_Unwind_RaiseException+0x10> push   %rbx
> 00000000000088e1 <_Unwind_RaiseException+0x11> lea    =
-0x3a0(%rbp),%rbx
> 00000000000088e8 <_Unwind_RaiseException+0x18> push   %rdx
> 00000000000088e9 <_Unwind_RaiseException+0x19> push   %rax
> . . . (the code here freely assigns to and uses %rdx and %rax) . . .
> . . . (also there are multiple return paths with differing properties) =
. . .
> 00000000000089a3 <_Unwind_RaiseException+0xd3> mov    -0x28(%rbp),%rbx
> 00000000000089a7 <_Unwind_RaiseException+0xd7> mov    -0x20(%rbp),%r12
> 00000000000089ab <_Unwind_RaiseException+0xdb> mov    -0x18(%rbp),%r13
> 00000000000089af <_Unwind_RaiseException+0xdf> mov    -0x10(%rbp),%r14
> 00000000000089b3 <_Unwind_RaiseException+0xe3> mov    -0x8(%rbp),%r15
> 00000000000089b7 <_Unwind_RaiseException+0xe7> leaveq=20
> 00000000000089b8 <_Unwind_RaiseException+0xe8> retq  =20
> . . . (Note the lack of restoring %rax above and the
>      normal %rbp/%rsp restore: leaveq) . . .
> . . . (before the below involves _Unwind_Backtrace
>      that the above did not) . . .
> 0000000000008a33 <_Unwind_RaiseException+0x163> lea    =
0x8(%rbp,%rcx,1),%rcx
> 0000000000008a38 <_Unwind_RaiseException+0x168> mov    =
-0x38(%rbp),%rax
> 0000000000008a3c <_Unwind_RaiseException+0x16c> mov    =
-0x30(%rbp),%rdx
> 0000000000008a40 <_Unwind_RaiseException+0x170> mov    =
-0x28(%rbp),%rbx
> 0000000000008a44 <_Unwind_RaiseException+0x174> mov    =
-0x20(%rbp),%r12
> 0000000000008a48 <_Unwind_RaiseException+0x178> mov    =
-0x18(%rbp),%r13
> 0000000000008a4c <_Unwind_RaiseException+0x17c> mov    =
-0x10(%rbp),%r14
> 0000000000008a50 <_Unwind_RaiseException+0x180> mov    -0x8(%rbp),%r15
> 0000000000008a54 <_Unwind_RaiseException+0x184> mov    0x0(%rbp),%rbp
> 0000000000008a58 <_Unwind_RaiseException+0x188> mov    %rcx,%rsp
> 0000000000008a5b <_Unwind_RaiseException+0x18b> retq
> . . . (Note the abnormal %rbp/%rsp restore above) . . .
>=20
> No other routine in 9.3's /lib/libgcc_s.so.1 pushes or pops
> either of %rdx or %rax: only _Unwind_RaiseException.
>=20
> The code structure allows executing exception landing-pad
> code and such during the exception handling with the 2
> registers used to provide context.
>=20
> The stable/11 -r309179 code for _Unwind_RaiseException
> does not have those scratch registers saved and restored
> and has some other basic differences for related aspects:
>=20
> 0000000000009990 <_Unwind_RaiseException> push   %rbp
> 0000000000009991 <_Unwind_RaiseException+0x1> mov    %rsp,%rbp
> 0000000000009994 <_Unwind_RaiseException+0x4> push   %r15
> 0000000000009996 <_Unwind_RaiseException+0x6> push   %r14
> 0000000000009998 <_Unwind_RaiseException+0x8> push   %r13
> 000000000000999a <_Unwind_RaiseException+0xa> push   %r12
> 000000000000999c <_Unwind_RaiseException+0xc> push   %rbx
> 000000000000999d <_Unwind_RaiseException+0xd> sub    $0x418,%rsp
> . . . (the code here freely assigns to and uses %rdx and %rax) . . .
> 0000000000009c61 <_Unwind_RaiseException+0x2d1> add    $0x418,%rsp
> 0000000000009c68 <_Unwind_RaiseException+0x2d8> pop    %rbx
> 0000000000009c69 <_Unwind_RaiseException+0x2d9> pop    %r12
> 0000000000009c6b <_Unwind_RaiseException+0x2db> pop    %r13
> 0000000000009c6d <_Unwind_RaiseException+0x2dd> pop    %r14
> 0000000000009c6f <_Unwind_RaiseException+0x2df> pop    %r15
> 0000000000009c71 <_Unwind_RaiseException+0x2e1> pop    %rbp
> 0000000000009c72 <_Unwind_RaiseException+0x2e2> retq
>=20
> No code in the stable/11 libgcc_s.so.1 has a "push %rdx",
> but lots of code there has a "push %rax".
>=20
> The only means by which _Unwind_RaiseException's %rsp is
> restored/"popped" is also very different for stable/11's
> code compared to the 2nd of the 9.3 code paths for
> returning: stable/11 seems to not have any match analogous
> to that path.
>=20
> The differences seem too large to be the same ABI when things
> seem to be working. (Although I've not tried 9.3 application
> code that uses C++ exceptions under stable/11 : old stuff
> could fail if well tested for all I know.)
>=20
> I've not looked at amd64 10.x yet.
>=20
>> All the registers referenced are very common: lots of routines
>> having nothing to do with the Exception handling also list them.
>>=20
>> OpenMandriva Lx _Unwind_RaiseException:
>>=20
>> fde section offset 4280 0x000010b8 cie offset for fde: 4284 =
0x000010bc
>>       0 DW_CFA_advance_loc 1  (1 * 1)
>>       1 DW_CFA_def_cfa_offset 16
>>       3 DW_CFA_offset r6 -16  (2 * -8)
>>       5 DW_CFA_advance_loc 3  (3 * 1)
>>       6 DW_CFA_def_cfa_register r6
>>       8 DW_CFA_advance_loc 8  (8 * 1)
>>       9 DW_CFA_offset r15 -24  (3 * -8)
>>      11 DW_CFA_offset r14 -32  (4 * -8)
>>      13 DW_CFA_offset r13 -40  (5 * -8)
>>      15 DW_CFA_offset r12 -48  (6 * -8)
>>      17 DW_CFA_advance_loc 20  (20 * 1)
>>      18 DW_CFA_offset r3 -56  (7 * -8)
>>      20 DW_CFA_offset r1 -64  (8 * -8)
>>      22 DW_CFA_offset r0 -72  (9 * -8)
>>      24 DW_CFA_advance_loc2 284
>>      27 DW_CFA_remember_state
>>      28 DW_CFA_restore r6
>>      29 DW_CFA_def_cfa r2 8
>>      32 DW_CFA_advance_loc 4  (4 * 1)
>>      33 DW_CFA_restore_state
>>      34 DW_CFA_advance_loc 21  (21 * 1)
>>      35 DW_CFA_def_cfa r7 8
>>      38 DW_CFA_nop
>>=20
>> Note the lines for r1 and r0 that FreeBSD has no
>> equivalent of: These are the Exception ABI's
>> scratch registers usage that only apply to exception
>> handling code that uses certain built-ins that
>> imply the context. In normal routines r1 and r0 are
>> volatile and so are not listed on OpenMandriva Lx.
>>=20
>> But FreeBSD never lists any scratch registers for the
>> exception handing ABI, unlike the Itanium's standard
>> that specified there are 4 --2 with predefined
>> purposes. (Itanimum used GP15-GP18 for the exception
>> handling scratch registers or something like that if
>> I remember right.)
>>=20
>> So the amd64 FreeBSD information from clang 3.9.0 looks
>> wrong to me unless the Itanium's standard is not the
>> basis for what FreeBSD is doing here.
>>=20
>> NOTE: Analogous incorrectness with observed scratch
>> register usage in builds based on clang 3.8.0 and
>> clang 3.9.0 for TARGET_ARCH=3Dpowerpc and
>> TARGET_ARCH=3Dpowerpc64 are part of what I've reported
>> as wrong to llvm for what blocks clang for them. In
>> this context actual crashes from asserts or SIGSEGV
>> during _Unwind_GetGR or _Unwind_SetGR for a scratch
>> register's index is what started my investigation of
>> the dwarfdump reports in the first place. I found
>> the register information missing in the dwarfdump
>> output and comments in the code about being such a
>> missing status for any GR leading to what I had
>> observed for references to that GR --and that is
>> my interpretation of the code so commented as well.
>>=20
>>=20
>>> Eventually new features may show up in Clang and LLVM's libunwind =
(and
>>> new versions of GNU's unwinder) that won't work with the old =
unwinder.
>>>=20
>>>> Your answer's detail might indicate that I've misdirected the llvm =
folks
>>>> in submittals like  https://llvm.org/bugs/show_bug.cgi?id=3D26844 .
>>>>=20
>>>> There is also the question of if/when llvm's libunwind is ready to =
be used
>>>> for powerpc64 or powerpc (or . . .) if there are architecture =
specifics
>>>> involved. That answer might determine when C++ exceptions work (and =
so
>>>> when devel/kyua might have a chance to work) and is sort of =
separate from
>>>> the main question here but is still of interest overall.
>>>>=20
>>>> Should powerpc64 and powerpc clang 3.9.0 testing be using
>>>> WITH_LLVM_LIBUNWIND ? WITHOUT_LLVM_LIBUNWIND ? Both?
>>>=20
>>> For testing I think WITH_LLVM_LIBUNWIND is the interesting case. My
>>> eventual goal is to have a functioning Clang, LLD, LLDB, libunwind,
>>> and ELF Tool Chain on all of our supported architectures.
>=20
> =3D=3D=3D
> Mark Millard
> markmi at dsl-only.net



_______________________________________________
freebsd-ppc@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-ppc
To unsubscribe, send any mail to "freebsd-ppc-unsubscribe@freebsd.org"




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?BB2D1D3F-8B3F-4F2F-A431-A65E86C30516>