> -fstack-check and -fstack-clash both potentially create a loop for stack > probing. In that case they both need a scratch register to hold the > loop upper bound. > > The code to allocate a scratch register first starts with the > caller-saved registers as they're zero cost. Then it'll use any callee > saved register that is actually saved. If neither is available (say > because all the caller-saved regs are used for parameter passing and > there are no callee saved register used), then the allocation routine > will push %eax on the stack and the deallocation routine will pop it off > to restore its value. > > Of course there is a *stack allocation* between those two points. So > the pop ends up restoring garbage into the register.
There is a stack allocation only on Linux, there isn't any on Solaris, *BSD, Windows, LynxOS and other OSes where you can probe below the stack pointer. > Clearly this code had not be exercised. So I hacked up things so that > we always generated a probing loop and always assumed that we needed to > save/restore a scratch register and enabled stack clash protections by > default. Probably not on Linux indeed. But, since you modified the non-Linux path, you need to avoid repeating the same mistake and test on non-Linux native too. -- Eric Botcazou