lkml.org 
[lkml]   [1998]   [Jan]   [18]   [last100]   RSS Feed
Views: [more markup]  [less markup]  [headers]  [forward] 
 
Messages in this thread
/
DateSun, 18 Jan 1998 17:36:09 +0100 (MET)
From"Michael L. Galbraith" <>
SubjectRe: gcc-2.8.0 miscompiles kernel (Was: gcc-2.8 out...)
On Fri, 16 Jan 1998, Christopher Seawood wrote:

> On Fri, 16 Jan 1998, Jesse Thilo wrote:
> 
> > > They're not.
> > > gcc 2.8 is aimed at being 100% reliable,
> > 
> > For what it's worth, it doesn't seem to have quite reached that aim
> > yet.  When I compile kernel 2.0.33 with gcc 2.7.2.3, it works fine.
> > When I compile the same kernel (same configuration, after executing
> > "make mrproper") with gcc 2.8.0, my X servers and certain other
> > programs dump core.  I don't have detailed information yet, but it
> > appears that the programs are dumping core in routines that perform
> > I/O port access.
> 
> Last I heard, this was a known problem as some kernel code relied upon a
> gcc hack that got fixed. It is fixed in the lastest development kernels.
> Anyone know when/if these fixes will be backported to 2.0.x ?
> 
> Regards
> Christopher

Hello Christopher,

I compiled ./arch/i386/kernel/ioport.c (sys_iopl) with both 2.7.2.3
and 2.8.0 to find out just why this should be considered a kernel
code bug and not a compiler bug. Here's what I came up with.

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.

It looks like the compiler is now smart enough to take advantage of
the opportunity. If I'm wrong about this, I'll surely hear :)

	Cheers,

	-Mike
---------------------------------------------------------------------
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,long eflags,long esp,long ss)
{
 120:	55             	pushl  %ebp
 121:	89 e5          	movl   %esp,%ebp
	unsigned int level = ebx;
	if (level > 3)
 123:	83 7d 08 03    	cmpl   $0x3,0x8(%ebp)
 127:	76 07          	jbe    130 <sys_iopl+0x10>
		return -EINVAL;
 129:	b8 ea ff ff ff 	movl   $0xffffffea,%eax
 12e:	eb 1e          	jmp    14e <sys_iopl+0x2e>
 * normal permissions checks first, and check suser() last.
 */
extern inline int suser(void)
{
	if (current->euid == 0) {
 130:	a1 00 00 00 00 	movl   0x0,%eax
 135:	66 83 b8 1a 01 	cmpw   $0x0,0x11a(%eax)
 13a:	00 00 00 
 13d:	74 09          	je     148 <sys_iopl+0x28>
	if (!suser())
		return -EPERM;
 13f:	b8 ff ff ff ff 	movl   $0xffffffff,%eax
 144:	eb 08          	jmp    14e <sys_iopl+0x2e>
 146:	89 f6          	movl   %esi,%esi
 */
extern inline int suser(void)
{
	if (current->euid == 0) {
		current->flags |= PF_SUPERPRIV;
 148:	80 48 15 01    	orb    $0x1,0x15(%eax)
	*(&eflags) = (eflags & 0xffffcfff) | (level << 12);
	return 0; <=== insert missing assembler here :)
 14c:	31 c0          	xorl   %eax,%eax
}
 14e:	89 ec          	movl   %ebp,%esp
 150:	5d             	popl   %ebp
 151:	c3             	ret    

\
 
 \ /
  Last update: 2005-03-22 12:41    [W:1.227 / U:0.220 seconds]
©2003-2008 Jasper Spaans