Red Hat Bugzilla – Bug 173460
all versions of gcc may miscompile kernel's sigaddset if signal is constant
Last modified: 2007-11-30 17:07:08 EST
gcc may miscompile code on i386 using kernel sigsetadd if signal argument is
constant. The probem is also reproducible in user space.
All versions of gcc and all versiong of kernels are affected. Attached please
find a program that can be compiled into module or executable. If compiled with
-O2 flags, the resulting code is wrong. Disassembly (or running in the
debugger) shows miscompilation. Disabling optimization or just using -O fixes
In short the following code is problematic:
b =a; /* this line causes incorrect code; any 64-bit assignment seems to
cause a problem! */
/* more sigaddset to c */
At some iteration of sigaddset to c, c may get the value of a!!!
Created attachment 121166 [details]
A sample of c code that gets miscompiled if -O2 flags is used.
That's just buggy testcase.
static __inline__ void __gen_sigaddset(sigset_t *set, int _sig)
__asm__("btsl %1,%0" : "=m"(*set) : "Ir"(_sig-1) : "cc");
You need either
__asm__("btsl %1,%0" : "+m"(*set) : "Ir"(_sig-1) : "cc");
__asm__("btsl %1,%0" : "=m"(*set) : "Ir"(_sig-1), "m"(*set) : "cc");
because the btsl instruction doesn't just set the memory to some value, but needs
to read its previous content as well. If you don't tell that fact to GCC,
GCC is of course free to optimize as if the asm was just setting the value
and not depended on the previous value.