Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 1 Dec 2016 02:39:59 -0800
From:      Mark Millard <markmi@dsl-only.net>
To:        Ed Maste <emaste@freebsd.org>
Cc:        FreeBSD Toolchain <freebsd-toolchain@freebsd.org>, FreeBSD PowerPC ML <freebsd-ppc@freebsd.org>, Dimitry Andric <dim@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:  <8BA319C6-FAD1-445F-85C1-5086B5AA59A8@dsl-only.net>
In-Reply-To: <68972A8F-C8D4-4FF2-A933-ACCC79C15065@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>

next in thread | previous in thread | raw e-mail | index | archive | help
[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.]

First a correction to a systematic typing error:

-r309179 was correct but it is head, not stable/11 .

I repeat: My earlier comparison was between amd64
          9.3-RELEASE and amd64 12-CURRENT -r309179 .


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 )?

First _Unwind_RaiseException as an example from
inside libgc_s.so.1 for exception handling. . .

head -r309179 does *not* match stable/11 -r309125 or
release/9.3.0 .

stable/11 -r309125 is more like release/9.3.0 .

So head *has* changed the amd64 C++ exception handling
details as far as I can tell: WITH_LLVM_LIBUNWIND
changes things.

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.

stable/11 -r309125 _Unwind_RaiseException's code has:

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

[Because of code order differences the above shows somewhat
more than I did for 9.3 .]

stable/11 -r309125 _Unwind_RaiseException's dwarfdump shows:

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)

Note the r0 and r1 (and %rax and %rdx in the code)
so it is like release/9.3.0 in that respect.


(I've still not looked at 10.x and with 11 being as it
is I might not bother.)



What about programs that use libgcc_s.so.1 ? . . .

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:

0000000000400caf <main+0x1f> cmp    $0x1,%edx
0000000000400cb2 <main+0x22> jne    0000000000400cf3 <main+0x63>

(This has -O2 in use for both contexts.)

head -r309179 has that conditional code:

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>

The call to _Unwind_Resume@plt above is another difference:
stable/11 does not have that.


stable/11 -r309125 does not have either of those points:

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

The source for both is:

#include <stdlib.h>
#include <exception>

void g(void)
{
    throw std::exception();
}

void f(void)
{
    void *p =3D alloca(random() & 0xffu);
    g();
}

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;
}

I've looked at 9.3-RELEASE as well. . .

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?

9.3 has a _Unwind_Resume call based on the test.

head and 9.3 compare against 0x1.

The result is more similarity to head -r309179 than
to stable/11 -r309125 in the program code (i.e.,
outside libgcc_s.so.1).

[The libgcc_s.so.1 code is another matter.]

(-O2 does not remove as much unnecessary code
when gcc 4.2.1 is in use as well.)

9.3's code:

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>



So overall:

A) stable/11 is the odd ball for code using libgcc_s.so.1
   for exception handling

B) head is the odd ball for the exception handling code
   in libgcc_s.so.1

Either way the compatibility looks problematical for
spanning from 9.3 through head.


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.

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

On 2016-Nov-30, at 9:50 PM, Mark Millard <markmiat dsl-only.net> wrote:

[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.]

On 2016-Nov-30, at 6:03 PM, Mark Millard <markmi@dsl-only.net> wrote:

> 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

[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.]

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):

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

The 9.3 code has %rdx (r2) and %rax (r0) saved and
restored:

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) . . .

No other routine in 9.3's /lib/libgcc_s.so.1 pushes or pops
either of %rdx or %rax: only _Unwind_RaiseException.

The code structure allows executing exception landing-pad
code and such during the exception handling with the 2
registers used to provide context.

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:

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

No code in the stable/11 libgcc_s.so.1 has a "push %rdx",
but lots of code there has a "push %rax".

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.

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.)

I've not looked at amd64 10.x yet.

> 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.

=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?8BA319C6-FAD1-445F-85C1-5086B5AA59A8>