[Prev][Next][Index][Thread]

Re: Possible bug in netboot



Thanks for the info.  Just a few more questions ;-)

What compiler and version are you using for this (and what OS and version),
and what -O flag?

Does this machine has an EISA bus?  What chipset and CPU does it have?
Does it have any EISA cards?

> Here is the information (Dump of trap_state)
> --------------------------------------------
> EAX = 0017fafe EBX = 00000000 ECX = 00000004 EDX = 00000005
> ESI = 0017fafe EDI = f000ef6f EBP = 0017fb18 ESP = 0017fac8
> EIP = 001247eb EFALGS = 206
> trapno 1 error 0 from kernel mode

This is the inlined code for strstr.
 
>   1247dd:	fc                   	cld    
>   1247de:	8b 3c 9f             	movl   (%edi,%ebx,4),%edi
>   1247e1:	f2 ae                	repnz scasb %es:(%edi),%al
>   1247e3:	f7 d1                	notl   %ecx
>   1247e5:	49                   	decl   %ecx
>   1247e6:	89 ca                	movl   %ecx,%edx
>   1247e8:	8b 3c 9f             	movl   (%edi,%ebx,4),%edi
>   1247eb:	89 f0                	movl   %esi,%eax
>   1247ed:	89 d1                	movl   %edx,%ecx
>   1247ef:	f3 a6                	repz cmpsb %ds:(%esi),%es:(%edi)
>   1247f1:	74 0a                	je     1247fd <EISA_signature+0x101>
>   1247f3:	96                   	xchgl  %eax,%esi
>   1247f4:	46                   	incl   %esi
>   1247f5:	80 78 ff 00          	cmpb   $0x0,0xffffffff(%eax)
>   1247f9:	75 ed                	jne    1247e8 <EISA_signature+0xec>
>   1247fb:	31 c0                	xorl   %eax,%eax

This is the part that worries me:
             	movl   (%edi,%ebx,4),%edi

The first one succeeds, but the second one fails.

The compiler I use translates both those references as:
		movl   0xffffffec(%ebp,%ebx,4),%edi

This is interesting, as scasb will increment edi (since cld
sets forward direction).  Not only that, but edi is destroyed
by loading it with a new value anyway.  It looks like your
compiler isn't counting on edi being used/modified by the
ASM statement.

The problem appears to be the the compiler generating
the wrong code, either due to a bug in the ASM statement
(see oskit/linux/src/include/asm-i386/string.h) or in the
compiler's interpretation of the ASM statement.

I have seen a lot of asm bugs with gcc in the past...
it appears to be the same problem, where gcc is using a
`trashed' register as in `in' register.  [Whether gcc is
allowed to do this may be a matter of interpretation]

Here is the original asm for reference:

extern inline char * strstr(const char * cs,const char * ct)
{
register char * __res;
__asm__ __volatile__(
        "cld\n\t" \
        "movl %4,%%edi\n\t"
        "repne\n\t"
        "scasb\n\t"
        "notl %%ecx\n\t"
        "decl %%ecx\n\t"        /* NOTE! This also sets Z if searchstring='' */
        "movl %%ecx,%%edx\n"
        "1:\tmovl %4,%%edi\n\t"
        "movl %%esi,%%eax\n\t"
        "movl %%edx,%%ecx\n\t"
        "repe\n\t"
        "cmpsb\n\t"
        "je 2f\n\t"             /* also works for empty string, see above */
        "xchgl %%eax,%%esi\n\t"
        "incl %%esi\n\t"
        "cmpb $0,-1(%%eax)\n\t"
        "jne 1b\n\t"
        "xorl %%eax,%%eax\n\t"
        "2:"
        :"=a" (__res):"0" (0),"c" (0xffffffff),"S" (cs),"g" (ct)
        :"cx","dx","di","si");
return __res;
}


This problem may only cause a trap when NULL pointers are trapped,
but the bug is certainly in this code, and not in the debug registers.
Not setting up the debug registers to catch bugs because there is a
bug is the wrong approach...

Kevin Van Maren
University of Utah