From owner-freebsd-toolchain@freebsd.org Fri May 26 11:00:36 2017 Return-Path: Delivered-To: freebsd-toolchain@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id B01FCD7B66A for ; Fri, 26 May 2017 11:00:36 +0000 (UTC) (envelope-from markmi@dsl-only.net) Received: from asp.reflexion.net (outbound-mail-210-63.reflexion.net [208.70.210.63]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 75E271062 for ; Fri, 26 May 2017 11:00:35 +0000 (UTC) (envelope-from markmi@dsl-only.net) Received: (qmail 12637 invoked from network); 26 May 2017 11:00:34 -0000 Received: from unknown (HELO mail-cs-01.app.dca.reflexion.local) (10.81.19.1) by 0 (rfx-qmail) with SMTP; 26 May 2017 11:00:34 -0000 Received: by mail-cs-01.app.dca.reflexion.local (Reflexion email security v8.40.0) with SMTP; Fri, 26 May 2017 07:00:34 -0400 (EDT) Received: (qmail 1700 invoked from network); 26 May 2017 11:00:34 -0000 Received: from unknown (HELO iron2.pdx.net) (69.64.224.71) by 0 (rfx-qmail) with (AES256-SHA encrypted) SMTP; 26 May 2017 11:00:34 -0000 Received: from [192.168.1.114] (c-76-115-7-162.hsd1.or.comcast.net [76.115.7.162]) by iron2.pdx.net (Postfix) with ESMTPSA id 58486EC805D; Fri, 26 May 2017 04:00:33 -0700 (PDT) Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 10.3 \(3273\)) Subject: Re: PowerPC64 C++ exceptions with clang/llvm From: Mark Millard In-Reply-To: <74D091B2-71CD-42DE-8C1E-8E0BDED1EAFD@dsl-only.net> Date: Fri, 26 May 2017 04:00:32 -0700 Content-Transfer-Encoding: quoted-printable Message-Id: References: <20170524113441.GA58092@vlakno.cz> <74D091B2-71CD-42DE-8C1E-8E0BDED1EAFD@dsl-only.net> To: FreeBSD Toolchain , FreeBSD PowerPC ML X-Mailer: Apple Mail (2.3273) X-BeenThere: freebsd-toolchain@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Maintenance of FreeBSD's integrated toolchain List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 26 May 2017 11:00:36 -0000 [Turns out Roman's working case was based on gcc 4.2.1 based system libraries, not ones built by clang.] On 2017-May-24, at 9:03 PM, Mark Millard wrote: > [So far I've been unable to replicate dwarfump reporting > anything near "0x94 00 00 00 01 00 01 02 ed 14 1b". The > compiled code still gets SIGSEGV: it is only the low > level detail that I'm noting as different. Roman has > more information from me than I show here.] >=20 > On 2017-May-24, at 4:34 AM, Roman Divacky = wrote: >=20 >> Hi, >>=20 >> Currently C++ exceptions don't work on PowerPC64 when compiled with = clang. I >> looked at why and discovered the following. >>=20 >> With the default gcc unwinder and libstdc++ this simple test program: >>=20 >> #include >>=20 >> int main() >> { >> try { >> std::cout << "Before\n"; >> throw std::exception(); >> std::cout << "After\n"; >> } catch (...) { >> std::cout << "Exception\n"; >> } >> } >>=20 >> segfaults right after printing "Before\n". This is because the = .eh_frame is corrupted and >> the personality relocation is wrong: >>=20 >> < 1> version 1 >> cie section offset 56 0x00000038 >> augmentation zPLR >> code_alignment_factor 4 >> data_alignment_factor -8 >> return_address_register 65 >> eh aug data len 0xb bytes 0x94 00 00 00 01 00 01 02 ed 14 1b=20 >=20 > So far I'm unable to replicate producing anything like > the "large one" as I'll call it. >=20 > I get things like: >=20 > # clang++ -std=3Dc++11 exception_test_dots.cpp > # dwarfdump -v -v -F a.out | more >=20 > .eh_frame > . . . > cie: > < 0> version 1 > . . . > eh aug data len 0xb bytes 0x94 00 00 00 00 00 01 03 45 14 1b=20 > . . . >=20 > (No cia<1> at all.) >=20 > and like: >=20 > # clang++ -B /usr/local/bin/ -std=3Dc++11 exception_test_dots.cpp > # dwarfdump -v -v -F a.out | more >=20 > .eh_frame > . . . > cie: > < 0> version 1 > . . . > < 1> version 1 > . . . > eh aug data len 0xb bytes 0x94 00 00 00 00 00 01 f1 1d 14 1b=20 > . . . >=20 > My context is head -r317820 on a system built with > the system clang without building gcc 4.2.1 materials. >=20 > # uname -paKU > FreeBSD FBSDG5L 12.0-CURRENT FreeBSD 12.0-CURRENT r317820M powerpc = powerpc64 1200030 1200030 >=20 > # ld --version > GNU ld 2.17.50 [FreeBSD] 2007-07-03 > Copyright 2007 Free Software Foundation, Inc. > This program is free software; you may redistribute it under the terms = of > the GNU General Public License. This program has absolutely no = warranty. >=20 > # /usr/local/bin/ld --version > GNU ld (GNU Binutils) 2.27 > Copyright (C) 2016 Free Software Foundation, Inc. > This program is free software; you may redistribute it under the terms = of > the GNU General Public License version 3 or (at your option) a later = version. > This program has absolutely no warranty. >=20 > (I have avoided 2.28 so far because of the > "return code" consequences on the likes of > aarch64.) >=20 > I've tried variations like omitting -std=3Dc++11. > So far I've not found a way to get near: >=20 > "0x94 00 00 00 01 00 01 02 ed 14 1b" >=20 > but all the experiments get SIGSEGV when > I run the produced program. >=20 > (I do not have a gcc 4.2.1 build around and so > do not have libstdc++ on powerpc64.) It is still true that I've not replicated the "large one" problems (as I called it). But my environment is not a mix of gcc 4.2.1 and clang based: just clang based, including libc++ and the like. So things are very different from Roman's context. >> bytes of initial instructions 3 >> cie length 28 >> initial instructions >> 0 DW_CFA_def_cfa r1 0 >>=20 >> the personality relocation is "00 00 00 01 00 01 02 ed" encoded as pc = relative. The program segfaults >> because this address is wrong. The 33rd bit is incorrect, the real = address should be "00 00 00 00 00 01 02 ed". >> The same problem applies for LDSA encoding. Both personality and LDSA = relocations are produced by CFI instructions >> in the assembler source code. >>=20 >> I verified this theory by hacking the gcc unwinder and libsupc++ &=3D = the address with 0xffffffff; and that made >> the application work. (the full patch can be found at = http://www.vlakno.cz/~rdivacky/ppc64.exceptions.hack.patch). Roman did not test a libstdc++ built with clang here. He was using a library to support handling thrown C++ exceptions that was built by gcc 4.2.1 . Instead the only clang code tested was in his a.out (or whatever he named the program generated). My past testing indicates that whatever library is supposed to support thrown C++ exceptions is broken when built by clang. (I've a couple of llvm submittals about messed up dwarf information and the like.) In essence the consequences of the builtin's that are involved in creating the supporting code in the library is wrong/incomplete in clang's code and/or dwarf generation as I understand. For example: __builtin_unwind_init() __builtin_eh_return_data_regno (0) __builtin_eh_return __builtin_dwarf_cfa() were involved back when I did the clang 3.8 investigation (that mostly seems to still apply in the C++ exception handling area). I'm not surprised that clang generated code can use the library code that gcc 4.2.1 generated, at least for the small examples involved (and probably far more). >> I checked why this relocation is wrong and it turns out it's our old = in-tree ld that (wrongly) produces this. >> Our old gcc does not use CFI to produce these and hardcodes the CIE = manually and produces correct address. And for >> some reason ld is fine with that. >>=20 >> When I compile and assemble the above source code using clang++ and = only use newer ld linker from ports the resulting >> binary is correct and works as expected. >>=20 >> So this is a bug in our in-tree ld linker. I don't know why ld has = this bug but given Mark Millard's report of ld >> being broken for other stuff (kernel iirc) I am not going to bother = trying to fix it. I suspect it might be related >> to comdats but I didn't really investigate. As my libc++ and the like was built with clang for my tests, the system ld does not work for buildworld for such a context, nor does lld. So I used devel/powerpc64-binutils for buildworld and buildkernel. Given that clang built it all instead of gcc 4.2.1, what the system ld does for the little test program in my context would be expected to be likely to not match Roman's results. But my context gives more information about the status of things for attempting to avoid gcc 4.2.1, since that is what I was doing (gcc 4.2.1 and related material not built or present) . >> I didn't try the situation with the LLVM unwinder and libcxxrt, but I = hope it might be the same. Last I tried the llvm unwinder could not be be built by clang. I submitted llvm bugzilla material for it at the time. lld did not work last I tried either. (In fact Roman supplied one patch that let me get far enough to report some on what else is a problem for lld.) =3D=3D=3D Mark Millard markmi at dsl-only.net