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

Reply via email to