From owner-freebsd-ppc@freebsd.org Fri Nov 9 05:01:11 2018 Return-Path: Delivered-To: freebsd-ppc@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5F8A11124E4F for ; Fri, 9 Nov 2018 05:01:11 +0000 (UTC) (envelope-from marklmi@yahoo.com) Received: from sonic306-20.consmr.mail.ne1.yahoo.com (sonic306-20.consmr.mail.ne1.yahoo.com [66.163.189.82]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 67B587E294 for ; Fri, 9 Nov 2018 05:01:10 +0000 (UTC) (envelope-from marklmi@yahoo.com) X-YMail-OSG: iJD6eZcVM1lJOg4OQ3GleRg2NocMF.k1GT.sMrz3ovKXs3UjcrMTWLpZW7M3cCc iwPfl__NVJ0csL_MvtO3NZ5BRZvEkLgPvYQtlxIDJ.sRa2xQ9ootcJ9k6s7GQIlANcQv3MDPcgam WGvpKuO0816k2UtJPIDJfiy98DjMD3CI6dfm0nYohGSKkFDlKyMaYwc3ho9D8cysNSXc7EPW5mXe wBm0Pdclx4PlRHQI1DZ55CDMYPWvAIPZrZUsFswibfV3zCqpYaiAkEAd1ZEa3MnttawC4D0aO2rk uP2cDQf49pcj3PgdUlXR0qPoGLL_bECzW.c26SkHKcpBJNiNKoIExLMBKu.241nJn43hJxbbzU6F 5wd57oxXpR5nxH6EmcgI3zIiaCMO7F0YumAlxYoigPh.5rN6Ftg4WzLXih.gNay31ZCqOkrPWEoH 9pCTdZQGrSlxPh6uuIlKLC_tXeeDVZTfCJwjZ.rNffq45qQDRaZE_9C25dek9AnzycOleZw4niCN gY9JR5N1Lw3Sw8PoAkQSORBv_925FB8w5fUdNOdJjCKM3SU5lY.nz9X0dW_jkI9b9ZwAl10Uc9Vw 7WAg5YAvn8GnxE3f_BQnfXXiA3KM5DSRXWa_v3kIdLeJ.ZhLE2OzgPE8aTD2VTeJW7Vk0lfBQxQO CTs24oqognIw35ev0v1GWNcy914ozMGM5sQKXl.q9ZWGbI_L1XSgsunirxYxJTGM9SAEUbuUqU_O _rQ_.G4zt0Q0Jmq.LA5Aqt6ILrMtFL1sZRyDpSK2y0MijipKxglKMTtjn_h1v6B0PQ9ChGWeB7g9 qw6WnsB_tXzveZA.uOisylJs732yn_Ea36NUDu_y5ZlFf3uzJouCkCqP37D7wfF6IxqttY6Gp25S nAuBYbT36e1kaCSogFm7XFk3gK5LUb53iHu96JjTGV0V6AvwrAC8.RX5yoj7uQaLo0s8Q89NOC4Q 99cCxbcusC2YI8djKAkOw.pxuQs4SNFZo5Y5qiJZunPxpBiarhO1PtO1pLwn.ajm0ApyfM4sa9hb YzkzdPfW57JKqd6bg0Z1gX.zgoTR_DUHOfxQMfsxfBleHWRZYJ8f9 Received: from sonic.gate.mail.ne1.yahoo.com by sonic306.consmr.mail.ne1.yahoo.com with HTTP; Fri, 9 Nov 2018 05:01:09 +0000 Received: from c-76-115-7-162.hsd1.or.comcast.net (EHLO [192.168.1.25]) ([76.115.7.162]) by smtp409.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID df49675ce8d2dffcdb3b606ae2bb193e; Fri, 09 Nov 2018 05:01:05 +0000 (UTC) From: Mark Millard Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable Mime-Version: 1.0 (Mac OS X Mail 12.1 \(3445.101.1\)) Subject: gnu/lib/libgcc 's unwind-dw2.c and company: DW_CFA_{remember,restore}_state handling is incomplete and gcc 4.2.1 output tends to avoid those (powerpc examples) Message-Id: Date: Thu, 8 Nov 2018 21:01:03 -0800 To: FreeBSD Toolchain , FreeBSD PowerPC ML X-Mailer: Apple Mail (2.3445.101.1) X-Rspamd-Queue-Id: 67B587E294 X-Spamd-Result: default: False [-1.34 / 200.00]; ARC_NA(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[]; R_DKIM_ALLOW(-0.20)[yahoo.com]; NEURAL_HAM_MEDIUM(-0.99)[-0.993,0]; FROM_HAS_DN(0.00)[]; R_SPF_ALLOW(-0.20)[+ptr:yahoo.com]; MV_CASE(0.50)[]; MIME_GOOD(-0.10)[text/plain]; FREEMAIL_FROM(0.00)[yahoo.com]; NEURAL_HAM_LONG(-0.99)[-0.991,0]; NEURAL_SPAM_SHORT(0.78)[0.777,0]; RCVD_COUNT_THREE(0.00)[3]; TO_MATCH_ENVRCPT_SOME(0.00)[]; TO_DN_ALL(0.00)[]; DKIM_TRACE(0.00)[yahoo.com:+]; MX_GOOD(-0.01)[cached: mta6.am0.yahoodns.net]; RCVD_IN_DNSWL_NONE(0.00)[82.189.163.66.list.dnswl.org : 127.0.5.0]; RCPT_COUNT_TWO(0.00)[2]; IP_SCORE(0.38)[ipnet: 66.163.184.0/21(1.09), asn: 36646(0.88), country: US(-0.09)]; DMARC_POLICY_ALLOW(-0.50)[yahoo.com,reject]; FROM_EQ_ENVFROM(0.00)[]; RCVD_TLS_LAST(0.00)[]; FREEMAIL_ENVFROM(0.00)[yahoo.com]; ASN(0.00)[asn:36646, ipnet:66.163.184.0/21, country:US]; MID_RHS_MATCH_FROM(0.00)[] X-Rspamd-Server: mx1.freebsd.org X-BeenThere: freebsd-ppc@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Porting FreeBSD to the PowerPC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 09 Nov 2018 05:01:11 -0000 Some context: /usr/src/gnu/lib/libgcc/Makefile has: .if ${TARGET_CPUARCH} =3D=3D "arm" LIB2ADDEH =3D unwind-arm.c libunwind-arm.S pr-support.c unwind-c.c .else LIB2ADDEH =3D unwind-dw2.c unwind-dw2-fde-glibc.c unwind-sjlj.c = gthr-gnat.c \ unwind-c.c .endif It appears that only powerpc families and sparc64 use unwind-dw2.c and company unless someone uses WITHOUT_LLVM_LIBUNWIND=3D deliberately for non-arm. This is about unwind-dw2.c and company and uses a powerpc context for illustration. The problem: gnu/lib/libgcc 's libgcc_s.so when based on unwind-dw2.c and company do not correctly/completely handle: DW_CFA_remember_state DW_CFA_restore_state as they are put to use by fairly modern c++ compilers, use that requires cfa-rule save/restore. Here I use g++8 for illustration, but g++6 is similar, for example. Yet gcc 4.2.1 tends to "work" because it has less complete stack (cfa) tracking in the exception handling output it produces, thus commonly avoiding use of DW_CFA_{remember,restore}_state . The evidence: I'm going to illustrate with 32-powerpc because I happen to have g++ 4.2.1 handy in that context, as well as g++8 . g++ 4.2.1 toolchain (and why it does not illustrate the problem): (The c++ source code is not directly significant here --but that it is the same for both g++*'s is important .) (gdb) disass g Dump of assembler code for function g(): (mixed with related dwarfdump lines and other notes) 0x018008e0: =20 0x018008e0 <+0>: mflr r0 0x018008e4 <+4>: stwu r1,-16(r1) 0x018008e8: =20 0x018008e8 <+8>: lis r9,385 0x018008ec <+12>: stw r0,20(r1) 0x018008f0: =20 0x018008f0 <+16>: lwz r0,3496(r9) 0x018008f4 <+20>: cmpwi cr7,r0,0 0x018008f8 <+24>: bne cr7,0x180090c (Note: the branch = target requires cfa=3D16(r1) ) 0x018008fc <+28>: lwz r0,20(r1) 0x01800900 <+32>: addi r1,r1,16 (Note: the cfa changed but nothing reports it here: still = treated as cfa=3D16(r1) ) (Later: Compare to what a more modern g++ compilers produce = after adjusting r1.) 0x01800904 <+36>: mtlr r0 0x01800908 <+40>: b 0x18008b8 (Compare here to what more modern g++ compilers produce.) 0x0180090c <+44>: li r3,4 0x01800910 <+48>: bl 0x1810e0c <__cxa_allocate_exception@plt> 0x01800914 <+52>: lis r9,385 0x01800918 <+56>: addi r9,r9,3712 0x0180091c <+60>: lis r4,385 0x01800920 <+64>: lis r5,385 0x01800924 <+68>: stw r9,0(r3) 0x01800928 <+72>: addi r4,r4,3724 0x0180092c <+76>: addi r5,r5,3652 0x01800930 <+80>: bl 0x1810e14 <__cxa_throw@plt> End of assembler dump. No use of DW_CFA_remember_state or DW_CFA_restore_state, despite the tail call optimization. This is why gcc 4.2.1 tests do not show the DW_CFA_{remember,restore}_state problem here. g++8 toolchain: (but a.out using /lib/libgcc_s.so.1 in order to test that library) (gdb) disass g Dump of assembler code for function g(): (mixed with related dwarfdump lines) (Note: f()'s code was inlined.) 0x01800978: =20 0x01800978 <+0>: lis r10,385 0x0180097c <+4>: stwu r1,-32(r1) 0x01800980: =20 0x01800980 <+8>: lwz r9,3176(r10) 0x01800984 <+12>: cmpwi cr7,r9,0 0x01800988 <+16>: bne cr7,0x18009ac (Note: branch = target requires cfa=3D32(r1) ) 0x0180098c <+20>: li r9,97 0x01800990 <+24>: stb r9,8(r1) 0x01800994 <+28>: lwz r9,3176(r10) 0x01800998 <+32>: addi r9,r9,1 0x0180099c <+36>: stw r9,3176(r10) 0x018009a0 <+40>: lbz r9,8(r1) 0x018009a4 <+44>: addi r1,r1,32 DW_CFA_remember_state is generate before the following change is = made. (unwind-dw2.c and company do not record the cfa=3D32(r1) = material but should) 0x018009a8: (gcc 4.2.1 did not generate = anything to cause this) 0x018009a8 <+48>: blr DW_CFA_restore_state is generated to cause the following change: 0x018009ac: (unwind-dw2.c and company did not record the cfa=3D32(r1) = material but should have) (unwind-dw2.c and company cause defaults here: cfa=3D0(r1), = which is wrong) 0x018009ac <+52>: mflr r0 0x018009b0: =20 (unwind-dw2.c and company caused defaults here: cfa=3D0(r1), = which is wrong) 0x018009b0 <+56>: li r3,4 0x018009b4 <+60>: stw r0,36(r1) 0x018009b8: =20 (unwind-dw2.c and company caused defaults here: cfa=3D0(r1), = which is wrong) 0x018009b8 <+64>: bl 0x1810cc4 <__cxa_allocate_exception@plt> 0x018009bc <+68>: lis r9,385 0x018009c0 <+72>: lis r5,385 0x018009c4 <+76>: addi r9,r9,2916 0x018009c8 <+80>: lis r4,385 0x018009cc <+84>: stw r9,0(r3) 0x018009d0 <+88>: addi r5,r5,3332 0x018009d4 <+92>: addi r4,r4,3380 0x018009d8 <+96>: bl 0x1810cec <__cxa_throw@plt> End of assembler dump. g++8 and the like track more of the cfa changes in the exception handling information and so use DW_CFA_{remember,restore}_state in more types of contexts. This leads to running into the incomplete implementation in unwind-dw2.c and company more as well. Based on the incorrect cfa=3D0(r1) _Unwind_RaiseException ends up looping, looking at the same frame each time, making no progress. powerpc64 notes: It turns out that devel/powerpc64-gcc used for buildworld generates code in /lib/libgcc_s.so's exception handling code that hits the problem, blocking all c++ exception handling via that library because of _Unwind_RaiseException never finishing. For testing I touched the library code to avoid ending up with the DW_CFA_{remember,restore}_state usage where it was a problem. This allowed for simple programs to be used for illustration of the problem in that context --and programs that do not show the problem as well (via lack of DW_CFA_{remember,restore}_state use). clang++ does generate DW_CFA_{remember,restore}_state in some contexts and these have the problem too. Any DW_CFA_restore_state where the result should not have cfa=3D0(r1) is broken for powerpc families. For reference: For the g++8 based a.out: # ldd a.out a.out: libstdc++.so.6 =3D> /usr/lib/libstdc++.so.6 (0x41860000) libm.so.5 =3D> /lib/libm.so.5 (0x41972000) libgcc_s.so.1 =3D> /lib/libgcc_s.so.1 (0x419ab000) libc.so.7 =3D> /lib/libc.so.7 (0x419cb000) (g++8's own libgcc_s.so does not have such problems.) # more exception_test1.cpp=20 #include // -O2 context used. volatile unsigned int v =3D 1; extern int f() { volatile unsigned char c =3D 'a'; v++; // despite volatile the access to v in g // was otherwise optimized out and the // std::exception was not followed by // code for f(). return c; } extern void g() { if (v) throw std::exception(); f(); // Modern g++'s: ends up inlined but the problem is = demonstrated. } int main(void) { try {g();} // Used a separate function to avoid any potential // special handling of code in main. catch (std::exception& e) {} return 0; } =3D=3D=3D Mark Millard marklmi at yahoo.com ( dsl-only.net went away in early 2018-Mar)