https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86213
Bug ID: 86213 Summary: -fsplit-stack runtime may clobber SSE input param reg Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: libgcc Assignee: unassigned at gcc dot gnu.org Reporter: thanm at google dot com Target Milestone: --- Created attachment 44295 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=44295&action=edit tar file with reproducer sources and makefile The runtime code in libgcc that supports the -fsplit-stack flag can in some cases clobber an SSE register that is being used for parameter passing. The scenario is as follows: - routine A calls routine B, passing a floating point argument (which does in xmm0) - the routine B (compiled with -fsplit-stack) invokes "__morestack", which in turn may wind up calling out to other system routines (mmap for example) - routine B then does something with its floating point argument (xmm0) The code as written in __morestack does not save incoming SSE registers, so if something gets calls that uses SSE, it can lose param values. At the moment the only way to trigger this problem is to insure that the very first call made to __morestack is from a routine with a live floating point input argument (since the SSE clobbering takes place during a call to "getenv", which typically only is invoked on the first pass through the code). So this qualifies as a pretty obscure bug. Reproducer case attached (written for linux/x86). Example of failing run: $ make clean ; make run rm -f *.o *.so main gcc -c -O -fPIC -o main.o main.c gcc -c -fsplit-stack -O -fPIC -o m1.o m1.c gcc -c -O -fPIC -o m2.o m2.c gcc -O -fuse-ld=gold -fPIC -shared m1.o m2.o -o m1.so gcc -O -fuse-ld=gold main.o -o main m1.so LD_LIBRARY_PATH=`pwd` ./main in main noframe(64.000000) = 0.000000 Last value should be 64.0, not 0.0. Example of passing run (here with -m32): $ make clean ; make run EXTRA=-m32 rm -f *.o *.so main gcc -c -O -m32 -fPIC -o main.o main.c gcc -c -fsplit-stack -O -m32 -fPIC -o m1.o m1.c gcc -c -O -m32 -fPIC -o m2.o m2.c gcc -O -m32 -fuse-ld=gold -fPIC -shared m1.o m2.o -o m1.so gcc -O -m32 -fuse-ld=gold main.o -o main m1.so LD_LIBRARY_PATH=`pwd` ./main in main noframe(64.000000) = 64.000000