From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/5124 Path: news.gmane.org!not-for-mail From: Rich Felker Newsgroups: gmane.linux.lib.musl.general Subject: Re: Broken GCC versions: 4.8.2 and 4.9.0 Date: Thu, 15 May 2014 00:45:51 -0400 Message-ID: <20140515044551.GC507@brightrain.aerifal.cx> References: <20140511010503.GA6502@brightrain.aerifal.cx> <20140511181020.0a8b66f1@free-electrons.com> <20140511161943.GR26358@brightrain.aerifal.cx> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="pvezYHf7grwyp3Bc" X-Trace: ger.gmane.org 1400129209 22882 80.91.229.3 (15 May 2014 04:46:49 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Thu, 15 May 2014 04:46:49 +0000 (UTC) Cc: musl@lists.openwall.com To: Thomas Petazzoni Original-X-From: musl-return-5129-gllmg-musl=m.gmane.org@lists.openwall.com Thu May 15 06:46:42 2014 Return-path: Envelope-to: gllmg-musl@plane.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by plane.gmane.org with smtp (Exim 4.69) (envelope-from ) id 1WknZ4-0001GI-CV for gllmg-musl@plane.gmane.org; Thu, 15 May 2014 06:46:42 +0200 Original-Received: (qmail 7690 invoked by uid 550); 15 May 2014 04:46:40 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: Original-Received: (qmail 7682 invoked from network); 15 May 2014 04:46:40 -0000 Content-Disposition: inline In-Reply-To: <20140511161943.GR26358@brightrain.aerifal.cx> User-Agent: Mutt/1.5.21 (2010-09-15) Original-Sender: Rich Felker Xref: news.gmane.org gmane.linux.lib.musl.general:5124 Archived-At: --pvezYHf7grwyp3Bc Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Sun, May 11, 2014 at 12:19:43PM -0400, Rich Felker wrote: > On Sun, May 11, 2014 at 06:10:20PM +0200, Thomas Petazzoni wrote: > > Dear Rich Felker, > > > > On Sat, 10 May 2014 21:05:03 -0400, Rich Felker wrote: > > > > > It's come to my attention that GCC versions 4.8.2 and 4.9.0 are > > > performing invalid optimizations that result in a broken musl > > > libc.a/libc.so. It's not clear yet whether there's a good workaround, > > > or whether we should attempt to work around the problem, so for now, > > > please just be aware that these versions of GCC cannot be used to > > > compile musl. Using them to compile programs against musl should not > > > be a problem. I'll post more details later. The short version is that > > > it's making incorrect assumptions about the reachability of global > > > variables that have a local weak definition and an external strong > > > one. > > > > Hum, interesting. I've recently tested gcc 4.8.2 + musl on ARM, and gcc > > 4.9.0 + musl on i386, and I could boot a minimal musl+Busybox system > > under Qemu perfectly fine. Maybe the problem you refer to only affects > > certain parts of libc.a/libc.so? > > I've filed the bug report which you can see here: > > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=61144 > > Something like the following command should confirm whether your build > is affected: > > nm src/stdio/fflush.o | grep stdout > > For broken gcc versions, there is no output. For non-broken ones, you > should see something like: > > 00000000 V __stdout_used > > Note that fflush(0) is just one place where the behavior may be > affected by the invalid optimization. There are at least several > others, though at a glance the others are more likely to be affected > only with heavy inlining (but in principle, they "should" be affected > even without inlining as long as inter-procedural optimizations are > performed). Attached is a proposed patch to _detect_ this issue (not work around it) and reject the broken compiler. It does not hard-code an assumption that certain versions are broken, but tests the behavior with the seleted CFLAGS to see if the bug is present. I've considered multiple possible workarounds, but all of them have drawbacks: 1. Making the dummies non-static. This pollutes the symbol table and precludes -Wl,--gc-sections from being able to remove them when building libc.so unless visibility magic is also used. 2. Adding __attribute__((__used__)) to the static dummies. This works, and it's semantically correct that they should be considered "used" and not optimized out, but the problem actually isn't gcc optimizing them out; rather it's correctly keeping them around, but wrongly constant-folding them in expressions. So it's just "by chance" (a side effect of the bug) that adding this makes the problem go away. Also, adding it would require extra macro ugliness to account for the fact that we don't want to require the compiler to support __attribute__((__used__)). 3. Automatically adding -fno-toplevel-reorder to CFLAGS to suppress the optimizations when the bug is detected. This works now, but it's possible that it might not work for a future buggy gcc version. (It also produces a less-optimized libc.) Requiring the user to manually add this option if they want to try using a buggy compiler allows us to test and make sure the bug actually went away with the option added. Hopefully we can get the GCC folks to take this regression seriously and get it fixed before they release any more broken releases... Rich --pvezYHf7grwyp3Bc Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="detect_gcc_4.9.0_bug.diff" diff --git a/configure b/configure index 5d95672..26f60a7 100755 --- a/configure +++ b/configure @@ -125,6 +125,7 @@ debug=no warnings=no shared=yes static=yes +wrapper=auto for arg ; do case "$arg" in @@ -199,27 +200,35 @@ exit 1 fi # -# Only build musl-gcc wrapper if toolchain does not already target musl +# Need to know if the compiler is gcc to decide whether to build the +# musl-gcc wrapper, and for critical bug detection in some gcc versions. # -if test -z "$wrapper" ; then printf "checking whether compiler is gcc... " if fnmatch '*gcc\ version*' "$($CC -v 2>&1)" ; then -echo yes +cc_is_gcc=yes +else +cc_is_gcc=no +fi +echo "$cc_is_gcc" + +# +# Only build musl-gcc wrapper if toolchain does not already target musl +# +if test "$wrapper" = auto ; then printf "checking whether to build musl-gcc wrapper... " +if test "$cc_is_gcc" = yes ; then wrapper=yes while read line ; do case "$line" in */ld-musl-*) wrapper=no ;; esac done < "$tmpc" +echo 'extern int y __attribute__((__weak__, __alias__("x")));' >> "$tmpc" +echo 'extern int should_appear;' >> "$tmpc" +echo 'int foo() { return y ? should_appear : 0; }' >> "$tmpc" +case "$($CC $CFLAGS_C99FSE -I./arch/$ARCH -I./include \ + $CPPFLAGS $CFLAGS_AUTO $CFLAGS -S -o - "$tmpc" 2>/dev/null)" in +*should_appear*) +printf "no\n" +;; +*) +printf "yes\n" +fail "$0: error: broken compiler; try CFLAGS=-fno-toplevel-reorder" +;; +esac +fi + printf "creating config.mak... " cmdline=$(quote "$0") --pvezYHf7grwyp3Bc--