Most recent kernel where this bug did not occur: n/a Distribution: n/a Hardware Environment: n/a Software Environment: gcc/g++ with -fpic or -fPIC commandline option Problem Description: gcc reserves %ebx when generating position-independent-code. The _syscallX() macros in include/asm-i386/unistd.h fail to preserve this register and are thus uncompilable in PIC mode. Steps to reproduce: Compile the following program with "gcc -fpic" #include <stdio.h> #include <asm/unistd.h> #include <errno.h> #include <unistd.h> #define __NR_my_write __NR_write static inline _syscall3(ssize_t, my_write, int, fd, const void *, buf, size_t, count); int main() { #ifdef __PIC__ const char s[] = "PIC is defined\n"; #else const char s[] = "PIC is undefined\n"; #endif my_write(1, s, sizeof(s)); return 0; } Bug fix: --- linux/include/asm-i386/unistd.h.orig 2006-03-05 11:07:54.000000000 -0800 +++ linux/include/asm-i386/unistd.h 2006-03-09 14:25:45.000000000 -0800 @@ -326,6 +326,7 @@ __syscall_return(type,__res); \ } +#ifndef __PIC__ #define _syscall1(type,name,type1,arg1) \ type name(type1 arg1) \ { \ @@ -393,6 +394,82 @@ __syscall_return(type,__res); \ } +#else /* __PIC__ */ + +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"ri" ((long)(arg1)) : "memory"); \ +__syscall_return(type,__res); \ +} + +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1,type2 arg2) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)) \ + : "memory"); \ +__syscall_return(type,__res); \ +} + +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1,type2 arg2,type3 arg3) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)), \ + "d" ((long)(arg3)) : "memory"); \ +__syscall_return(type,__res); \ +} + +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)), \ + "d" ((long)(arg3)),"S" ((long)(arg4)) : "memory"); \ +__syscall_return(type,__res); \ +} + +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; movl %1,%%eax ; " \ + "int $0x80 ; pop %%ebx" \ + : "=a" (__res) \ + : "i" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)), \ + "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)) \ + : "memory"); \ +__syscall_return(type,__res); \ +} + +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5,type6,arg6) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ +{ \ +long __res; \ + struct { long __a1; long __a6; } __s = { (long)arg1, (long)arg6 }; \ +__asm__ volatile ("push %%ebp ; push %%ebx ; movl 4(%2),%%ebp ; " \ + "movl 0(%2),%%ebx ; movl %1,%%eax ; int $0x80 ; " \ + "pop %%ebx ; pop %%ebp" \ + : "=a" (__res) \ + : "i" (__NR_##name),"0" ((long)(&__s)),"c" ((long)(arg2)), \ + "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)) \ + : "memory"); \ +__syscall_return(type,__res); \ +} +#endif /* __PIC__ */ + #ifdef __KERNEL__ #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR
Created attachment 7552 [details] This patch introduces alternative macros that will be used in PIC mode
Created attachment 7574 [details] Updated patch that was applied to -mm tree This patch was applied to the -mm tree by Andrew Morton and will hopefully make it into Linus' tree at some point.
The patch has been merged into Linus' tree: http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=aeefc956d5d8f8402216a5447bd72ade9eb37eff