Control: retitle -1 (recompiled) runsv SIGILL on 32-bit PowerPC CPUs
Control: tags -1 + patch
# Justification: FTBFS or unusable runsv binary when recompiled
Control: severity -1 serious

On 11/24/2013 04:29 PM, Ryan Finnie wrote:
> So, it's actually a bit more complicated than I first reported.  As I
> mentioned, 2.1.1-6.2 will FTBFS on today's toolchain on a G4.  On a G5,
> it will build, but when I ran it on my production setup, it ran stage 2
> (a shell script whose last task is runsvdir to run gettys).  The gettys
> start, but then runit immediately goes on to stage 3, suggesting
> runsvdir crashed (though I have not debugged it to confirm).
> 
> I built a 2011-01-16 toolchain using snapshot.debian.net (the date the
> last Debian build was done) on my G5, and it does build and run
> correctly.  It also built on the G4, but I didn't test the resulting deb.
> 
> So yeah, it sounds like a code generation interaction issue with today's
> gcc and/or dietlibc, and is just manifesting itself in different ways on
> PowerPC.  I'll try to do some more debugging.

So, what's happening is the `diet` binary passthrough is adding
-mpowerpc-gpopt when given -Os.  -mpowerpc-gpopt appears to have
optimizations not supported on 32-bit PowerPC[0], namely FCFID.
(Reduced test output below.)  This is what was causing SIGILL when
compiling on a G4; it was generating code using FCFID in taia_approx,
which would fail the test suite if built on a G4.  If built on a G5, the
test suite would pass, but would the resulting binary would only work on
a 64-bit PowerPC CPU.

Attached is a patch to not let diet do -Os optimization passthrough on
PowerPC, and instead let GCC's own -Os handle it, which seems to work
fine.  This is ultimately a bug in diet since it produces unusable
binaries when compiled on a G4, but even if that were fixed, diet's docs
specify -Os optimization is specific to the /host/ CPU, not /target/, so
we still need to handle it specially here.

[0] http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24913


g4$ cat test.c
double
int_to_double (int *p)
{
  return (double)*p;
}

double
long_long_to_double (long long *p)
{
  return (double)*p;
}

g4$  diet -v -Os gcc -c test.c
gcc -include /usr/lib/diet/include/dietref.h -c test.c -isystem
/usr/lib/diet/include -D__dietlibc__ -Os -fomit-frame-pointer
-mpowerpc-gpopt -mpowerpc-gfxopt -fno-stack-protector
g4$ echo "disas long_long_to_double" | gdb test.o | grep fcfid
   0x00000028 <+4>:     fcfid   f1,f0

g4$ gcc -include /usr/lib/diet/include/dietref.h -c test.c -isystem
/usr/lib/diet/include -D__dietlibc__ -Os -fomit-frame-pointer
-fno-stack-protector
g4$ echo "disas long_long_to_double" | gdb test.o | grep fcfid

g4$ diet -v gcc -Os -c test.c
gcc -include /usr/lib/diet/include/dietref.h -Os -c test.c -isystem
/usr/lib/diet/include -D__dietlibc__ -fno-stack-protector
g4$ echo "disas long_long_to_double" | gdb test.o | grep fcfid

diff -u runit-2.1.1/debian/rules runit-2.1.1/debian/rules
--- runit-2.1.1/debian/rules
+++ runit-2.1.1/debian/rules
@@ -14,6 +14,16 @@
   CFLAGS =-O2 -Wall -g
 endif
 
+# Work around diet using -mpowerpc-gpopt when itself given -Os, as
+# -mpowerpc-gpopt generates instructions not available on 32-bit
+# PowerPC CPUs (Bug: #726008)
+ifneq (,$(findstring powerpc,$(DIET_ARCHS)))
+  ifneq (,$(findstring powerpc,$(ARCH)))
+    CC =diet -v gcc
+    CFLAGS =-Os
+  endif
+endif
+
 # readdir64, getdents64 seems to be broken in dietlibc on sparc
 ifeq (,$(findstring sparc,$(ARCH)))
   CFLAGS +=-D_FILE_OFFSET_BITS=64

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to