Date: Tue, 19 Mar 2019 20:16:36 -0700 From: Mark Millard <marklmi@yahoo.com> To: FreeBSD PowerPC ML <freebsd-ppc@freebsd.org>, FreeBSD Toolchain <freebsd-toolchain@freebsd.org> Subject: powerpc64: clang/libunwind vs devel/powerpc64-gcc based code for C++ exception handling: incompatible [ignoring r2 handling issue] Message-ID: <1B1A8473-1A53-407B-B96D-D25D91EE9A6B@yahoo.com>
next in thread | raw e-mail | index | archive | help
[This note ignores libunwind's r2 (TOC) mishandling issue that has been noted elsewhere.] It appears to me that clang powerpc64 targeted code and devel/powerpc64-gcc generated code are incompatible for C++ exception handling. I show code examples later. clang does in-line setup of register save/restore in a.out but powerpc64-gcc leaves it to the unwind library. libunwind does not do that, expecting the compiler to have dealt with managing the save/restore activity. Thus when code produced by powerpc64-gcc is in use, the save/restore activity would not happen. [This also leads to matching differences in what dwarfdump -v -v -v -F shows in various relevant places, but I'll not show that in this message.] (Is there a detailed powerpc64 ABI definition that, if followed by both compilers, would make use of the two compilers compatible for C++ exceptions?) A question is: is it required to allow the likes of devel/powerpc64-xtoolchain-gcc based buildworld's that target powerpc64 if/when libunwind becomes official? [It appears to me that clang used under a historical libgcc_s.so that built with powerpc-gcc has redundant save/restore activity that, while non-optimal, would work. So: not as strong of a mis-match and I'll ignore that combination below.] Evidence for the problem being reported . . . For code like (causing lots of save/restore context for C++ exceptions to be involved): # more exception_test_regs.cpp=20 #include <exception> #include <stdlib.h> int main(void) { volatile int a[]=3D {0,1,2,3}; int incr=3D rand()%4; #define unit(v,init) \ int v=3D init; \ try { \ if (a[v] < 4) throw std::exception(); \ v=3D (v+incr) % 4; \ } \ catch (std::exception& e) {} unit(b,incr); unit(c,b); unit(d,c); unit(e,d); unit(f,e); unit(g,f); unit(h,g); unit(i,h); unit(j,i); unit(k,j); unit(l,k); unit(m,l); unit(n,m); unit(o,n); unit(p,o); unit(q,p); unit(r,q); unit(s,r); unit(t,s); unit(u,t); unit(v,u); unit(w,v); unit(x,w); unit(y,x); unit(z,y); a[(b+c+d+e+f+g+h+i+j+k+m+n+o+p+q+r+s+t+u+v+w+x+y+z)%4]=3D i; return 0; } clang produces code that is, in part, like: 000000001000110c <.main+0x370> add r3,r24,r29 0000000010001110 <.main+0x374> srawi r4,r3,2 0000000010001114 <.main+0x378> addze r4,r4 0000000010001118 <.main+0x37c> rlwinm r4,r4,2,0,29 000000001000111c <.main+0x380> subf r26,r4,r3 0000000010001120 <.main+0x384> extsw r25,r26 0000000010001124 <.main+0x388> rldicr r3,r25,2,61 0000000010001128 <.main+0x38c> lwzx r3,r30,r3 000000001000112c <.main+0x390> cmpwi r3,3 0000000010001130 <.main+0x394> ble- 00000000100018fc <.main+0xb60> 0000000010001134 <.main+0x398> add r3,r26,r29 . . . 00000000100018fc <.main+0xb60> li r3,8 0000000010001900 <.main+0xb64> stw r0,156(r31) 0000000010001904 <.main+0xb68> mr r14,r8 0000000010001908 <.main+0xb6c> mr r15,r7 000000001000190c <.main+0xb70> mr r16,r6 0000000010001910 <.main+0xb74> stw r12,152(r31) 0000000010001914 <.main+0xb78> mr r28,r5 0000000010001918 <.main+0xb7c> stw r11,148(r31) 000000001000191c <.main+0xb80> stw r10,144(r31) 0000000010001920 <.main+0xb84> stw r9,140(r31) 0000000010001924 <.main+0xb88> bl 0000000010000860 = <00000018.plt_call.__cxa_allocate_exception@@CXXABI_1.3> 0000000010001928 <.main+0xb8c> ld r2,40(r1) 000000001000192c <.main+0xb90> nop 0000000010001930 <.main+0xb94> ld r4,-32728(r2) 0000000010001934 <.main+0xb98> addi r4,r4,16 0000000010001938 <.main+0xb9c> std r4,0(r3) 000000001000193c <.main+0xba0> nop 0000000010001940 <.main+0xba4> nop 0000000010001944 <.main+0xba8> ld r4,-32720(r2) 0000000010001948 <.main+0xbac> ld r5,-32712(r2) 000000001000194c <.main+0xbb0> bl 00000000100008e0 = <00000018.plt_call.__cxa_throw@@CXXABI_1.3> 0000000010001950 <.main+0xbb4> ld r2,40(r1) 0000000010001954 <.main+0xbb8> b 0000000010001b20 <.main+0xd84> . . . 0000000010001b20 <.main+0xd84> cmplwi r4,1 0000000010001b24 <.main+0xd88> bne- 0000000010002104 <.main+0x1368> 0000000010001b28 <.main+0xd8c> bl 0000000010000880 = <00000018.plt_call.__cxa_begin_catch@@CXXABI_1.3> 0000000010001b2c <.main+0xd90> ld r2,40(r1) 0000000010001b30 <.main+0xd94> bl 00000000100008a0 = <00000018.plt_call.__cxa_end_catch@@CXXABI_1.3> 0000000010001b34 <.main+0xd98> ld r2,40(r1) 0000000010001b38 <.main+0xd9c> lwz r7,132(r31) 0000000010001b3c <.main+0xda0> mr r3,r14 0000000010001b40 <.main+0xda4> mr r5,r29 0000000010001b44 <.main+0xda8> mr r6,r25 0000000010001b48 <.main+0xdac> lwz r8,136(r31) 0000000010001b4c <.main+0xdb0> lwz r9,140(r31) 0000000010001b50 <.main+0xdb4> lwz r10,144(r31) 0000000010001b54 <.main+0xdb8> lwz r11,148(r31) 0000000010001b58 <.main+0xdbc> lwz r12,152(r31) 0000000010001b5c <.main+0xdc0> lwz r0,156(r31) 0000000010001b60 <.main+0xdc4> b 0000000010001210 <.main+0x474> Note the explicit stw's before the bl for 00000018.plt_call.__cxa_allocate_exception@@CXXABI_1.3 and the matching lwz's after the bl for 00000018.plt_call.__cxa_end_catch@@CXXABI_1.3, and also the save/restore use of some registers from R14-R31 that are part of the call standard. (I just picked one of the examples so show code for. The detailed save/restore code varies from one to the next.) powerpc64-gcc does not generate such code before 00000018.plt_call.__cxa_allocate_exception@@CXXABI_1.3 or after 00000018.plt_call.__cxa_end_catch@@CXXABI_1.3 . The code looks like (again just picking an example): 0000000010000ad4 <.main+0x1b4> add r9,r21,r30 0000000010000ad8 <.main+0x1b8> srawi r26,r9,2 0000000010000adc <.main+0x1bc> addze r26,r26 0000000010000ae0 <.main+0x1c0> rlwinm r26,r26,2,0,29 0000000010000ae4 <.main+0x1c4> subf r26,r26,r9 0000000010000ae8 <.main+0x1c8> extsw r26,r26 0000000010000aec <.main+0x1cc> rldicr r9,r26,2,61 0000000010000af0 <.main+0x1d0> lwzx r9,r29,r9 0000000010000af4 <.main+0x1d4> cmpwi cr7,r9,3 0000000010000af8 <.main+0x1d8> ble cr7,0000000010001428 = <.main+0xb08> . . . 0000000010001428 <.main+0xb08> li r3,8 000000001000142c <.main+0xb0c> bl 0000000010000860 = <0000004b.plt_call.__cxa_allocate_exception@@CXXABI_1.3> 0000000010001430 <.main+0xb10> ld r2,40(r1) 0000000010001434 <.main+0xb14> nop 0000000010001438 <.main+0xb18> ld r9,-32728(r2) 000000001000143c <.main+0xb1c> nop 0000000010001440 <.main+0xb20> ld r5,-32720(r2) 0000000010001444 <.main+0xb24> nop 0000000010001448 <.main+0xb28> std r9,0(r3) 000000001000144c <.main+0xb2c> ld r4,-32712(r2) 0000000010001450 <.main+0xb30> bl 0000000010000900 = <0000004b.plt_call.__cxa_throw@@CXXABI_1.3> 0000000010001454 <.main+0xb34> ld r2,40(r1) 0000000010001458 <.main+0xb38> cmpdi cr7,r4,1 000000001000145c <.main+0xb3c> bne cr7,0000000010000f5c = <.main+0x63c> 0000000010001460 <.main+0xb40> bl 00000000100008c0 = <0000004b.plt_call.__cxa_begin_catch@@CXXABI_1.3> 0000000010001464 <.main+0xb44> ld r2,40(r1) 0000000010001468 <.main+0xb48> mr r20,r26 000000001000146c <.main+0xb4c> bl 00000000100008e0 = <0000004b.plt_call.__cxa_end_catch@@CXXABI_1.3> 0000000010001470 <.main+0xb50> ld r2,40(r1) 0000000010001474 <.main+0xb54> b 0000000010000b14 <.main+0x1f4> (None of the allocate_exception..end_catch related code has code anything like doing what clang did for save/restore.) The result is that, used against libunwind built with either clang or powerpc-gcc, the relevant registers for a powerpc64-gcc based a.out are not saved/restored that need to be for correct operation. [libunwind does not use __builtin_eh_return to have (part of) what a historical libgcc_s.so had for for its save/restore.] [Note: In my context the "historical" libgcc_s.so has the interpretation of DW_CFA_remember_state and DW_CFA_restore_state shown in dwarfdmp -v -v -v -F output fixed for how to interpret it (instead of being incomplete).] =3D=3D=3D Mark Millard marklmi at yahoo.com ( dsl-only.net went away in early 2018-Mar)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1B1A8473-1A53-407B-B96D-D25D91EE9A6B>