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
signature.asc
Description: OpenPGP digital signature