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?
Mark Millard
markmi at dsl-only.net
Fri Dec 2 04:57:38 UTC 2016
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=c++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
===
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.]
>
> 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= )
> vs. head (by default WITH_LLVM_LIBUNWIND= ) --and both
> of those vs. release/9.3.0 (implicitly
> WITHOUT_LLVM_LIBUNWIND= )?
>
> 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
> [ 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
>
> [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 at 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 at plt>
> 0000000000400c9b <main+0xb> callq 000000000040093c <random at plt>
> 0000000000400ca0 <main+0x10> callq 000000000040093c <random at 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 at 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 at 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 at plt>
> 0000000000400ce5 <main+0x55> callq 000000000040096c <__cxa_end_catch at 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
> 0000000000400cf3 <main+0x63> callq 00000000004009ac <_Unwind_Resume at plt>
>
> The call to _Unwind_Resume at 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 at plt>
> 0000000000400beb <main+0xb> callq 00000000004008bc <random at plt>
> 0000000000400bf0 <main+0x10> callq 00000000004008bc <random at plt>
> 0000000000400bf5 <main+0x15> callq 0000000000400ba0 <_Z1gv>
> 0000000000400bfa <main+0x1a> mov %rax,%rdi
> 0000000000400bfd <main+0x1d> callq 00000000004008fc <__cxa_begin_catch at 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 at 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 at plt>
> 0000000000400c2e <main+0x4e> callq 00000000004008ec <__cxa_end_catch at 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
>
> The source for both is:
>
> #include <stdlib.h>
> #include <exception>
>
> void g(void)
> {
> throw std::exception();
> }
>
> void f(void)
> {
> void *p = alloca(random() & 0xffu);
> g();
> }
>
> int main(void)
> {
> void *p = alloca(random() & 0xffu);
> try {
> void *p2 = alloca(random() & 0xffu);
> f();
> }
> catch (std::exception& e) {
> static void * volatile eaddr = &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 at 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 at 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
> 0000000000400b1f <main+0x3f> xor %eax,%eax
> 0000000000400b21 <main+0x41> retq
> 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 at plt>
> 0000000000400b30 <main+0x50> callq 00000000004008fc <__cxa_begin_catch at 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 at plt>
> 0000000000400b46 <main+0x66> jmp 0000000000400b1a <main+0x3a>
> 0000000000400b48 <main+0x68> mov $0x600fa8,%edi
> 0000000000400b4d <main+0x6d> callq 000000000040087c <__cxa_guard_acquire at 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 at 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.
>
> ===
> 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 at dsl-only.net> wrote:
>
>> On 2016-Nov-29, at 2:56 PM, Ed Maste <emaste at freebsd.org> wrote:
>>
>>> On 29 November 2016 at 16:46, Mark Millard <markmi at dsl-only.net> wrote:
>>>>
>>>>
>>>> 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?
>>>>
>>>> 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)?
>>>
>>> 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.
>>
>> Good to know. Thanks.
>>
>> [As there are no clang-based powerpc64 linux builds to my knowledge
>> the following uses amd64/x86_64 examples instead for comparisons.]
>>
>> 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:
>>
>> _Unwind_RaiseException (9990 vs. c701)
>> _Unwind_ForcedUnwind (a330 vs. c857)
>> _Unwind_Resume (9fb0 vs. c927)
>> _Unwind_Resume_or_Rethrow (2da0 vs. c9e4)
>>
>> (The numbers are just for my reference in finding the dwarfdump
>> material.)
>>
>> By contrast FreeBSD has missing information from what I can tell.
>>
>> 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.
>>
>> Using _Unwind_RaiseException as an example of those 4 routines
>> that I'm worried about. . .
>>
>> [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.]
>>
>> FreeBSD _Unwind_RaiseException:
>>
>> 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
> 00000000000089b8 <_Unwind_RaiseException+0xe8> retq
> . . . (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.
>>
>> OpenMandriva Lx _Unwind_RaiseException:
>>
>> 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
>>
>> 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.
>>
>> 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.)
>>
>> 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.
>>
>> NOTE: Analogous incorrectness with observed scratch
>> register usage in builds based on clang 3.8.0 and
>> clang 3.9.0 for TARGET_ARCH=powerpc and
>> TARGET_ARCH=powerpc64 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.
>>
>>
>>> 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.
>>>
>>>> Your answer's detail might indicate that I've misdirected the llvm folks
>>>> in submittals like https://llvm.org/bugs/show_bug.cgi?id=26844 .
>>>>
>>>> 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.
>>>>
>>>> Should powerpc64 and powerpc clang 3.9.0 testing be using
>>>> WITH_LLVM_LIBUNWIND ? WITHOUT_LLVM_LIBUNWIND ? Both?
>>>
>>> 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.
>
> ===
> Mark Millard
> markmi at dsl-only.net
_______________________________________________
freebsd-ppc at freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-ppc
To unsubscribe, send any mail to "freebsd-ppc-unsubscribe at freebsd.org"
More information about the freebsd-ppc
mailing list