mailing list of musl libc
 help / color / mirror / code / Atom feed
From: Rich Felker <dalias@libc.org>
To: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: musl@lists.openwall.com
Subject: Re: Broken GCC versions: 4.8.2 and 4.9.0
Date: Thu, 15 May 2014 00:45:51 -0400	[thread overview]
Message-ID: <20140515044551.GC507@brightrain.aerifal.cx> (raw)
In-Reply-To: <20140511161943.GR26358@brightrain.aerifal.cx>

[-- Attachment #1: Type: text/plain, Size: 3545 bytes --]

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

[-- Attachment #2: detect_gcc_4.9.0_bug.diff --]
[-- Type: text/plain, Size: 1914 bytes --]

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 <<EOF
 $($CC -dumpspecs)
 EOF
-echo $wrapper
 else
-echo no
+wrapper=no
 fi
+echo "$wrapper"
 fi
 
-
-
 #
 # Find the target architecture
 #
@@ -484,6 +493,27 @@ printf "no\n"
 fail "$0: error: unsupported long double type"
 fi
 
+#
+# Check for known bug in GCC 4.9.0 that results in a broken libc.
+#
+if test "$cc_is_gcc" = yes ; then
+printf "checking for gcc constant folding bug with weak aliases... "
+echo 'static int x = 0;' > "$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")

  parent reply	other threads:[~2014-05-15  4:45 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-05-11  1:05 Rich Felker
2014-05-11 16:10 ` Thomas Petazzoni
2014-05-11 16:19   ` Rich Felker
2014-05-11 18:46     ` James Cloos
2014-05-11 19:03       ` Rich Felker
2014-05-11 20:08         ` James Cloos
2014-05-11 21:20           ` Rich Felker
2014-05-12  1:23             ` Stephen Thomas
2014-05-12  9:28             ` Natanael Copa
2014-05-12 14:30               ` Anthony G. Basile
2014-05-14  7:49                 ` Natanael Copa
2014-05-12 12:13           ` Rich Felker
2014-05-12 13:49             ` Thorsten Glaser
2014-05-12 13:56             ` James Cloos
2014-05-11 20:20     ` Matias A. Fonzo
2014-05-15  4:45     ` Rich Felker [this message]
2014-05-19  0:47       ` Rich Felker
2014-05-19 11:47         ` Szabolcs Nagy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140515044551.GC507@brightrain.aerifal.cx \
    --to=dalias@libc.org \
    --cc=musl@lists.openwall.com \
    --cc=thomas.petazzoni@free-electrons.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).