A Bug in gcc or asm/string.h ?

From: Andreas Kies
Date: Sun Jun 26 2005 - 18:12:00 EST


Hello,

When running a kernel module compiled with gcc 3.3.5, I think I've found a bug
in either the compiler or the kernel definition of strcmp in
asm-i386/string.h . The exact compiler version is :

Reading specs from /usr/lib/gcc-lib/i586-suse-linux/3.3.5/specs
Configured with: ../configure --enable-threads=posix --prefix=/usr
--with-local-prefix=/usr/local --infodir=/usr/share/info
--mandir=/usr/share/man --enable-languages=c,c++,f77,objc,java,ada
--disable-checking --libdir=/usr/lib --enable-libgcj --with-slibdir=/lib
--with-system-zlib --enable-shared --enable-__cxa_atexit i586-suse-linux
Thread model: posix
gcc version 3.3.5 20050117 (prerelease) (SUSE Linux)

I was able to construct a small pure usermode program.
If you compile the included test program with optimization level 1 or less it
works, if compiled with level 2 it fails. Failing means the strcmp result
is != 0 because char ptr has valid contents at the time strcmp is expanded.
Other platforms besides i386 might be affected, too.
In the case of a failure you get "Unrecognized" as output on stdout.

So, here are my questions :
- Is this a bug in the compiler ?
In Documentation/Changes version 2.95.x is still recommended, I guess this is
outdated.
- Is it a bug in the definition of strcmp ? Maybe an addition volatile is
missing.

Thanks for reading.

Andreas.

Please CC me, as I'm not on the list.

------test program-----

/* taken from <asm-i386/string.h> */
static inline int strcmp(const char * cs,const char * ct)
{
int d0, d1;
register int __res;
__asm__ __volatile__(
"1:\tlodsb\n\t"
"scasb\n\t"
"jne 2f\n\t"
"testb %%al,%%al\n\t"
"jne 1b\n\t"
"xorl %%eax,%%eax\n\t"
"jmp 3f\n"
"2:\tsbbl %%eax,%%eax\n\t"
"orb $1,%%al\n"
"3:"
:"=a" (__res), "=&S" (d0), "=&D" (d1)
:"1" (cs),"2" (ct));
return __res;
}
/* end of code from <asm-i386/string.h> */

int oem;

int main(void)
{
char ptr[2];

ptr[0] = 'G';
ptr[1] = '\0';

if (strcmp(ptr, "G") == 0) {
oem = 0; /* this branch should always be executed*/
} else {
printf("Unrecognized\n");
oem = 1;
}
return oem;
}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/