From owner-freebsd-ppc@freebsd.org Tue Oct 16 22:29:56 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 2D65210E3B47 for ; Tue, 16 Oct 2018 22:29:56 +0000 (UTC) (envelope-from marklmi@yahoo.com) Received: from sonic314-21.consmr.mail.ne1.yahoo.com (sonic314-21.consmr.mail.ne1.yahoo.com [66.163.189.147]) (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 A81F082EE5 for ; Tue, 16 Oct 2018 22:29:55 +0000 (UTC) (envelope-from marklmi@yahoo.com) X-YMail-OSG: H3tKvo8VM1lL61yMh6CAH_DAz0RjTyHGHoAL3Cl41607ETYPC6GQ4Ay.ZiIddB3 lwDmt6xgyj1vd27RIk_uht3rn2WaTSqkjfIlNGCS2h1fOkH16zcXkwkQE4Nab4QZU3yrfLhON7I9 fPRzZxgv_XdMMKaHoE7A1y9Gq3UmCuguJtgU0qkOeuGBjosvCbK.8_JlrkfPDogmAJmgKAWgguZp CTf_j3qBWQT77b3yTwWZH9KjTMvwNPFPA9hT5rW.ntq.mf8eKpvdVMefPATec02BFPCXGzFUvo.g 3QAOuuiMgsl5BhAhcgunQ50kG0mBLbFYbE62ts8P7ZLzT6193MBbsTFIeZcSVaprvDA9uWKMokQ4 SonwpY1ctf95rU7f7roYBa5MQ4VgT0SjJRWa1rlQtInql9SRVNbfCUSO11bqOZDSdVzwiuKQ9iD5 IyJ1QMNpfHVW.AqAAxq_YYEO4Ut3NYR2piJhtmsLXlvSbGX99Lf8jS5n6ztnwjNcCLsAgrfMKFAx Bh45DK4JA6Vj3a.VuvscMmUVG8x0Qafbz1MaHB_XkvBonwKefZ8FrB2gDvWaJ3z7i2Bc_WRE5sPA 2NJ_LICzvuWO1flzNOxVW9368VA4ldM90BdwjN_BwbBtxFfKQqxU3kLNFVzOx5BSfkEvrdVNmtf1 FWZuEgB2.u3Kd_t1NgWPYLEK6vXOweuKvWT65QJubcE3TKgiGmfdDsAWkiScalJZHu_KEhopJqUh bfN13MlcezuRAQAPtm4wcAOSZ1chlKeKyJ.iQ5jVIozGT8YVI6LfoSljXOpOxOhQIyUwzNh6oCkp BnbFqGyZjjij9SdI4ziNf.dSpFVI19xxF..WAKbDAnYzTLaix.zmctf_E04UOlIAcCktfhafISrF DXpcsQie2tVifS2dXLqWBtfUONWm7y.FC_IaYFQHCISddhjO5CZ8Kphp_L2uEIg.5obJlX5fw0kp Qca3bLjPnNU.Yw1qjrFvYAnprzJ_cZhBlXHEvuKC_9cFMx6zHf9rwnVFAumuU5pjec_oQw5HEBFJ z3HTRXahguBEb.kkXixI3DE4x_zrprV7EM_YG1hB475iqsKySkvKeIzXuXonh4VPFaNdGYaARzmZ o6SHQABNiz3SjrVga7Q-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic314.consmr.mail.ne1.yahoo.com with HTTP; Tue, 16 Oct 2018 22:29:48 +0000 Received: from c-76-115-7-162.hsd1.or.comcast.net (EHLO [192.168.1.25]) ([76.115.7.162]) by smtp412.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 513438678ecee606fe797d481f79ca2e; Tue, 16 Oct 2018 22:29:46 +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 11.5 \(3445.9.1\)) Subject: How to get devel/powerpc-gcc based WITH_LIBCPLUSPLUS= buildworld to have some throwing of C++ exceptions work (patch) Message-Id: <86E4687B-280A-4625-A56E-8D6FC4C4675B@yahoo.com> Date: Tue, 16 Oct 2018 15:29:45 -0700 Cc: Justin Hibbits To: FreeBSD PowerPC ML , FreeBSD Toolchain , FreeBSD X-Mailer: Apple Mail (2.3445.9.1) X-BeenThere: freebsd-ppc@freebsd.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: Porting FreeBSD to the PowerPC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 16 Oct 2018 22:29:56 -0000 I now have a patch that gets some basic C++ exception throwing going for WITH_LIBCPLUSPLUS=3D use when building via devel/powerpc64-gcc . But the overall mechanism seems to mess up the handling of powerpc64's "red zone" style of stack processing in various cases. I've had recent list submittals reporting that buildworld using WITH_LIBCPLUSPLUS=3D based on devel/powerpc64-gcc would get stuck looping in _Unwind_RaiseException. This prevented use of devel/gdb --which makes extensive use of throwing C++ exceptions in normal operation. Well, I now have a patch that avoids the problem in libcxxrt's throw_exception itself that made all throws get stuck --and so allows some C++ exceptions to be thrown. See below. (I'm not sure leading spaces will all be preserved.) Most of text is commentary, not code. # svnlite diff /usr/src/contrib/libcxxrt/ Index: /usr/src/contrib/libcxxrt/exception.cc =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /usr/src/contrib/libcxxrt/exception.cc (revision 339076) +++ /usr/src/contrib/libcxxrt/exception.cc (working copy) @@ -772,10 +772,71 @@ info->globals.uncaughtExceptions++; =20 _Unwind_Reason_Code err =3D = _Unwind_RaiseException(&ex->unwindHeader); +#if !defined(__powerpc64__) && !defined(__ppc64__) // The _Unwind_RaiseException() function should not return, it = should // unwind the stack past this function. If it does return, then = something // has gone wrong. report_failure(err, ex); +#else +// NOTE: Only tested for devel/powerpc64-gcc based buildworld +// because clang still silently ignores +// __builtin_eh_return(offset,handler) for powerpc64 +// (and powerpc), thus not generating correct output. +// +// NOTE: I've no clue if other archtiectures might have +// analogous issues to powerpc64. I'm not sure +// about powerpc because of it still being stuck +// at gcc 4.2.1 . (clang problems and no devel/powerpc-gcc .) +// +// The above/normal code produced the following sort of structure +// for throw_exception. r1 is the stack pointer, note its adjustments +// via stdu r1,-128(r1) and via addi r1,r1,128 . +// +// : mflr r0 +// : std r31,-8(r1) +// : mr r31,r3 +// : std r0,16(r1) +// : stdu r1,-128(r1) +// . . . +// : bl = <00000018.plt_call._Unwind_RaiseException@@GCC_3.0> +// : ld r2,40(r1) +// : addi r1,r1,128 +// : mr r4,r31 +// : ld r0,16(r1) +// : ld r31,-8(r1) +// : mtlr r0 +// : b +// +// The loop in __Unwind_RaiseException had its "fs" +// used with uw_frame_state_for and uw_update_context get +// stuck with the pc field having the address for +// throw_exception+152 (just after the stack adjustment +// addi r1,r1,128). Effectively, throw_exception unwinds +// its stack use before calling report_failure in a +// way that throw_exception is no longer on the stack. +// The exception unwinding logic did not handle this +// correctly and got stuck looping. +// +// The below avoids having any such stack adjustment here +// by avoiding the report_failure call and directly doing +// what case _URC_END_OF_STACK in report_failure does for +// its first couple of lines. (It is also the kind of +// thing that src/contrib/libstdc++/libsupc++/eh_throw.cc +// has in its __cxxabiv1::__cxa_throw after the +// _Unwind_RaiseException call.) +// +// Another option could be to turn report_failure into +// a macro so that no subroutine call could be involved. +// That should avoid the early stack pointer kadjsutment. +// +// Also: For the other archtiectures that I looked at, no +// such stack adjsutments were involved in the code +// generated (or the matching dwarfdump output). +// But I did not look at many. + + __cxa_begin_catch (&(ex->unwindHeader)); + std::terminate(); +#endif } =20 =20 However, code such as the following from devel/kyua leads to other examples of _Unwind_RaiseException looping without making progress. Note the stdu r1,-368(r1) and the addi r1,r1,368 stack pointer adjustments and their timing relative to stack usage (the "red zone" style used for FreeBSD's powerpc64 ABI): (gdb) x/64i 0x100a8528-88 0x100a84d0 : mflr = r0 0x100a84d4 : = std r30,-16(r1) 0x100a84d8 : = std r31,-8(r1) 0x100a84dc : = std r29,-24(r1) 0x100a84e0 : = mr r31,r4 0x100a84e4 : = std r0,16(r1) 0x100a84e8 : = stdu r1,-368(r1) 0x100a84ec : = mr r30,r3 0x100a84f0 : = bl 0x100abab0 0x100a84f4 : = nop 0x100a84f8 : = clrlwi r4,r31,16 0x100a84fc : = bl 0x10009fc0 <000000af.plt_call.mkdir@@FBSD_1.0> 0x100a8500 : = ld r2,40(r1) 0x100a8504 : = cmpwi cr7,r3,-1 0x100a8508 : = beq cr7,0x100a8528 0x100a850c : = addi r1,r1,368 0x100a8510 : = ld r0,16(r1) 0x100a8514 : = ld r29,-24(r1) 0x100a8518 : = ld r30,-16(r1) 0x100a851c : = ld r31,-8(r1) 0x100a8520 : = mtlr r0 0x100a8524 : = blr 0x100a8528 : = bl 0x10009d40 <000000af.plt_call.__error@@FBSD_1.0> . . . (more not shown here) . . . This goes along with (darfdump -v -v -F output): < 1323><0x100a84d0:0x100a8670> 0x100a84d0: =20 0x100a84e0: =20 0x100a84ec: =20 0x100a8510: =20 0x100a8524: =20 0x100a8528: =20 fde section offset 62424 0x0000f3d8 cie offset for fde: 61696 = 0x0000f100 0 DW_CFA_advance_loc 16 (4 * 4) 1 DW_CFA_register r65 =3D r0 4 DW_CFA_offset r30 -16 (2 * -8) 6 DW_CFA_offset r31 -8 (1 * -8) 8 DW_CFA_offset r29 -24 (3 * -8) 10 DW_CFA_advance_loc 12 (3 * 4) 11 DW_CFA_def_cfa_offset 368 14 DW_CFA_offset_extended_sf r65 16 (-2 * -8) 17 DW_CFA_advance_loc 36 (9 * 4) 18 DW_CFA_remember_state 19 DW_CFA_def_cfa_offset 0 21 DW_CFA_advance_loc 20 (5 * 4) 22 DW_CFA_restore_extended r65 24 DW_CFA_restore r31 25 DW_CFA_restore r30 26 DW_CFA_restore r29 27 DW_CFA_advance_loc 4 (1 * 4) 28 DW_CFA_restore_state 29 DW_CFA_nop 30 DW_CFA_nop The _Unwind_RaiseException's fs ends up reaching and the holding the following value in my attempted devel/kyua run for FreeBSD's test suite: (gdb) print fs $9 =3D {regs =3D {reg =3D {{loc =3D {reg =3D 0, offset =3D 0, exp =3D = 0x0}, how =3D REG_UNSAVED} , {loc =3D {reg =3D = 18446744073709551592, offset =3D -24,=20 exp =3D 0xffffffffffffffe8 }, how =3D REG_SAVED_OFFSET}, {loc =3D {reg =3D= 18446744073709551600, offset =3D -16,=20 exp =3D 0xfffffffffffffff0 }, how =3D REG_SAVED_OFFSET}, {loc =3D {reg =3D= 18446744073709551608, offset =3D -8,=20 exp =3D 0xfffffffffffffff8 }, how =3D REG_SAVED_OFFSET}, {loc =3D {reg =3D= 0, offset =3D 0, exp =3D 0x0},=20 how =3D REG_UNSAVED} , {loc =3D {reg =3D 16, = offset =3D 16, exp =3D 0x10 }, how =3D REG_SAVED_OFFSET}, {loc =3D {reg =3D 0, offset =3D 0,=20 exp =3D 0x0}, how =3D REG_UNSAVED} }, prev =3D= 0x0}, cfa_offset =3D 0, cfa_reg =3D 1, cfa_exp =3D 0x0, cfa_how =3D = CFA_REG_OFFSET,=20 pc =3D 0x100a8528 ,=20= personality =3D @0x810549c40: 0x81053c900 <__gxx_personality_v0(int, = _Unwind_Action, uint64_t, _Unwind_Exception*, _Unwind_Context*)>, = data_align =3D -8, code_align =3D 4, retaddr_column =3D 65,=20 fde_encoding =3D 27 '\033', lsda_encoding =3D 20 '\024', saw_z =3D 1 = '\001', signal_frame =3D 0 '\000', eh_ptr =3D 0x0} Note the invariant value it is looping with (fs.pc value): pc =3D 0x100a8528 But the routine is at 0x00000000100a85ec : (gdb) bt #0 _Unwind_RaiseException (exc=3D0x8109582e0) at = /usr/src/gnu/lib/libgcc/../../../contrib/gcc/unwind.inc:103 #1 0x000000081053d704 in throw_exception (ex=3D0x810958288) at = /usr/src/contrib/libcxxrt/exception.cc:774 #2 0x00000000100a85ec in utils::fs::mkdir (dir=3D..., = mode=3Dmode@entry=3D493) at utils/fs/operations.cpp:484 #3 0x00000000100a8694 in utils::fs::mkdir_p (dir=3D..., mode=3D) at utils/fs/operations.cpp:502 #4 0x000000001000cbf4 in (anonymous namespace)::safe_main = (mock_command=3D..., argv=3D0x3fffffffffffdb88, argc=3D4, = ui=3D0x3fffffffffffd960, this=3D, this=3D) = at cli/main.cpp:207 #5 cli::main (ui=3Dui@entry=3D0x3fffffffffffd960, argc=3Dargc@entry=3D4, = argv=3Dargv@entry=3D0x3fffffffffffdb88, mock_command=3D...) at = cli/main.cpp:280 #6 0x000000001000e9dc in cli::main (argc=3D, = argv=3D0x3fffffffffffdb88) at cli/main.cpp:353 #7 0x000000001000c570 in main (argc=3D, argv=3D) at main.cpp:49 where utils::fs::mkdir: 0x00000000100a85d0 <+256>: bne 0x100a85f0 = 0x00000000100a85d4 <+260>: addis r9,r2,-1 0x00000000100a85d8 <+264>: addis r10,r2,-1 0x00000000100a85dc <+268>: mr r3,r29 0x00000000100a85e0 <+272>: addi r5,r9,20864 0x00000000100a85e4 <+276>: addi r4,r10,-12216 0x00000000100a85e8 <+280>: bl 0x1000a140 = <000000af.plt_call.__cxa_throw@@CXXABI_1.3> =3D> 0x00000000100a85ec <+284>: ld r2,40(r1) 0x00000000100a85f0 <+288>: ld r3,320(r1) 0x00000000100a85f4 <+292>: bl 0x1000a8c0 = <000000af.plt_call._ZdlPv> 0x00000000100a85f8 <+296>: ld r2,40(r1) 0x00000000100a85fc <+300>: b 0x100a85d4 = This is for the devel/kyua code: void fs::mkdir(const fs::path& dir, const int mode) { if (::mkdir(dir.c_str(), static_cast< mode_t >(mode)) =3D=3D -1) { const int original_errno =3D errno; throw fs::system_error(F("Failed to create directory %s") % dir, original_errno); } } I've not figured out how to make general throwing of C++ exceptions avoid this _Unwind_RaiseException unbounded looping with a fixed fs.pc value. But at least now I can use devel/gdb for some of the investigation's activity. Other notes: WITH_LLVM_LIBUNWIND=3D does not even compile for targeting powerpc64 --so that is not currently a way around the problem. WITHOUT_LIB32=3D yse is because, for every post-gcc 4.2.1 that I've tried, the lib32 produced misuses R30 in crtbeginS code (vs. the ABI for FreeBSD) and 32-bit code just produces core files from a bad so-called address that is dereferenced via R30 content. =3D=3D=3D Mark Millard marklmi at yahoo.com ( dsl-only.net went away in early 2018-Mar)