Re: gcc-2.8.0 miscompiles kernel (Was: gcc-2.8 out...)

Florian Weimer (
19 Jan 1998 18:53:22 +0100

Hi! (Alan Cox) writes:

> > The output of objdump -d -S seems to indicate that the line..
> > *(&eflags) = (eflags & 0xffffcfff) | (level << 12);
> > .. was simply optimized away by 2.8.0.
> >
> > Since the manipulation in question is to a local variable, and there
> > are no references past this line, it's OK for gcc to throw it away as
> > it is not valid after the function returns.
> Interesting but ultimately the compiler does win the argument. Changing the
> kernel so it generates
> *((volatile u32 *)&eflags)
> should persuade gcc to behave. Right now the compiler knows the result of
> a local variable stack assigment is thrown and the kernel knows it isnt.

Unfortunately, gcc doesn't generate code for this line either. (Is
this a bug?) You have to specify the `volatile' keyword in the
parameter list:

asmlinkage int sys_iopl(long ebx,long ecx,long edx,
long esi, long edi, long ebp, long eax, long ds,
long es, long fs, long gs, long orig_eax,
long eip,long cs,volatile long eflags,long esp,long ss)
unsigned int level = ebx;

if (level > 3)
return -EINVAL;
if (!suser())
return -EPERM;
eflags = (eflags & 0xffffcfff) | (level << 12);
return 0;

The pointer magic is no longer needed. I guess it was included because
even 2.7.x optimized the assigment away without it.

(I'm writing this on a 2.0.33 kernel compiled with 2.8.0. The X server
is finally running, but I wonder whether there are other new bugs...)