Using the gcc 3.2.2 xscale-elf-gcc compiler had no problems with the test case. Using the gcc 3.3 xscale-elf-gcc compiler will produce the following messages: blkpg-test.c: In function `blk_ioctl': blkpg-test.c:13: error: asm-specifier for variable `myr1' conflicts with asm clobber list The basic problem is that the gcc code generator does NOT like the user forcing the use of registers r0 and r1 for the inline assembler. The workaround would appear to be to elide the asm("r1") and the two asm("r0") extensions and let gcc choose the register for the code... which really only works correctly if that is what the __put_user_1 function will accept. In the real world, this problem is found by building the file linux-2.4.19/drivers/block/blkpg.c which results in the error blkpg.c: In function `blk_ioctl': blkpg.c:285: warning: comparison between signed and unsigned blkpg.c:252: error: asm-specifier for variable `__r1' conflicts with asm clobber list Release: gcc 3.3 Target: xscale-elf Environment: Redhat 7.3 GNU/Linux: uname -a says: Linux mdb-lnx 2.4.20-13.7 #1 Mon May 12 13:13:52 EDT 2003 i686 unknown How-To-Repeat: cat <<EOF > blkpg-test.c /* * -------------- blkpg-test.c --------------- * xscale-elf-gcc -c blkpg-test.c */ int __put_user_1 (void *, unsigned int); int blk_ioctl (unsigned long long *arg) { const register unsigned long long myr1 asm("r1") = 0; const register unsigned long long *ptr asm("r0") = arg; register int res asm("r0"); __asm__ __volatile__ ("bl __put_user_1" : "=&r" (res) : "0" (ptr), "r" (myr1) : "r2", "lr"); return(res); } EOF xscale-elf-gcc -c blkpg-test.c
Confirmed with gcc 3.3 and mainline (20030608). I think this belongs in the inline-asm category though. Richard, would you mind commenting on whether the code in question is legal? Thanks, Dara
I get a similar error, error: asm-specifier for variable `_a1' conflicts with asm clobber list compiling glibc-2.3.2 with gcc-3.3 for arm-linux. In the real world, you should be able to reproduce this like so: wget http://www.kegel.com/crossgcc/crosstool-0.6.tar.gz tar -xzvf crosstool-0.6.tar.gz cd crosstool-0.6 eval `cat arm.dat` `cat gcc3.3-glibc2.3.2.dat` sh all.sh Here's the problem boiled down as small as I can easily get it (this is the output of $ cd build/arm-unknown-linux-gnu/gcc-3.3-glibc-2.3.2/glibc-2.3.2/signal $ arm-unknown-linux-gnu-gcc -E ../linuxthreads/sysdeps/pthread/sigaction.c cut down by hand and reformatted with indent): -- snip -- cat > bug.c <<_EOF_ extern int *__errno_location (void) __attribute__ ((__const__)); struct kernel_sigaction { //__sighandler_t k_sa_handler; unsigned long sa_flags; void (*sa_restorer) (void); //sigset_t sa_mask; }; int __libc_sigaction(sig, act, oact) int sig; const struct sigaction *act; struct sigaction *oact; { int result; struct kernel_sigaction kact, koact; result = ( { unsigned int _sys_result = ( { unsigned int _sys_result; { register int _a1 asm("a1"); register int _a4 asm("a4") = (int)(64 / 8); register int _a3 asm("a3") = (int)(oact ? (&koact) : ((void *)0)); register int _a2 asm("a2") = (int)(act ? (&kact) : ((void *)0)); _a1 = (int) (sig); asm volatile ("swi %1 @ syscall " "rt_sigaction": "=r" (_a1): "i"(((0x900000 + 174))), "r"(_a1), "r"(_a2), "r"(_a3), "r"(_a4):"a1", "memory"); _sys_result = _a1; } (int) _sys_result; }); if (__builtin_expect(((unsigned int) (_sys_result) >= 0xfffff001u), 0)) { ((*__errno_location()) = ((-(_sys_result)))); _sys_result = (unsigned int) -1;} (int) _sys_result;}); return result; } _EOF_ arm-unknown-linux-gnu-gcc bug.c -- snip --
As Richard noted (http://gcc.gnu.org/ml/gcc-bugs/2003-06/msg01134.html), the behavior of the compiler seems to be correct, and so the bug appears to be in the code here. I am marking this bug as invalid, but if for some reason this turns out to be incorrect, we can reopen this.
Ah, so I should open this as a glibc bug, then? OK, I'll try that.
Supposedly fixed in glibc cvs; see http://bugs.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=glibc&pr=5051