diff options
author | Eric Andersen <andersen@codepoet.org> | 2002-07-24 19:51:46 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2002-07-24 19:51:46 +0000 |
commit | 255cd531d67d4c5d110409e2a24e2aa5a6249a7a (patch) | |
tree | 9d1ef2999a4e4fc28644e01376684862e03b82dc | |
parent | bb364bda4be59f9141c1727524ffe459a742ddee (diff) |
Add support for people calling syscall()
-Erik
-rw-r--r-- | libc/sysdeps/linux/i386/Makefile | 6 | ||||
-rw-r--r-- | libc/sysdeps/linux/i386/__uClibc_syscall.S | 72 | ||||
-rw-r--r-- | libc/sysdeps/linux/i386/syscall.S | 76 |
3 files changed, 78 insertions, 76 deletions
diff --git a/libc/sysdeps/linux/i386/Makefile b/libc/sysdeps/linux/i386/Makefile index c15751ee1..28c64991e 100644 --- a/libc/sysdeps/linux/i386/Makefile +++ b/libc/sysdeps/linux/i386/Makefile @@ -36,10 +36,8 @@ CRT0_OBJ=$(patsubst %.S,%.o, $(CRT0)) endif -SSRC=__longjmp.S vfork.S clone.S setjmp.S bsd-setjmp.S bsd-_setjmp.S -ifeq ($(UNIFIED_SYSCALL),true) - SSRC += __uClibc_syscall.S -endif +SSRC=__longjmp.S vfork.S clone.S setjmp.S bsd-setjmp.S \ + bsd-_setjmp.S syscall.S SOBJS=$(patsubst %.S,%.o, $(SSRC)) CSRC=brk.c diff --git a/libc/sysdeps/linux/i386/__uClibc_syscall.S b/libc/sysdeps/linux/i386/__uClibc_syscall.S deleted file mode 100644 index b79d2666e..000000000 --- a/libc/sysdeps/linux/i386/__uClibc_syscall.S +++ /dev/null @@ -1,72 +0,0 @@ -/* - * June 27, 2001 Manuel Novoa III - * - * This is a heavily modified version of gcc's output for the syscall5 macro. - * The idea (originally from dietlibc) is that all syscall functions simply - * set the syscall number in %al (since <= 255) and then jump here. All the - * common work is done by __uClibc_syscall, saving a fair amount of generated - * code where a number of syscalls are used. The (potential) cost is some - * unnecessary pushes, pops, and movs but the execution time penalty should - * be relatively small compared to the cost of the syscall itself. - * - * WARNING: If the startup code for uClibc changes, I suppose it is possible - * that this code might try to access memory under the bottom of - * the stack. - * WARNING: This will need to be modified if the number of syscalls ever - * exceeds 255. So will the associated syscall macros. - */ - -.text - .align 4 -.globl __uClibc_syscall - .type __uClibc_syscall,@function -__uClibc_syscall: - pushl %edi - pushl %esi - pushl %ebx - and $0xff,%eax - movl 16(%esp),%ebx - movl 20(%esp),%ecx - movl 24(%esp),%edx - movl 28(%esp),%esi - movl 32(%esp),%edi -#APP - int $0x80 -#NO_APP - cmpl $-4095,%eax - jbe .Ldone - -#ifdef PIC - call Lhere -Lhere: - popl %ebx - addl $_GLOBAL_OFFSET_TABLE_+[.-Lhere],%ebx - negl %eax - movl %eax,%ecx -#ifdef _LIBC_REENTRANT - call __errno_location@PLT -#else - movl errno@GOT(%ebx),%eax -#endif /* _LIBC_REENTRANT */ - movl %ecx,(%eax) -#else - negl %eax -#ifdef _LIBC_REENTRANT - movl %eax,%ecx - call __errno_location - movl %ecx,(%eax) -#else - movl %eax,errno -#endif /* _LIBC_REENTRANT */ - -#endif /* PIC */ - - movl $-1,%eax - .p2align 4,,7 -.Ldone: - popl %ebx - popl %esi - popl %edi - ret -.Lsize: - .size __uClibc_syscall,.Lsize-__uClibc_syscall diff --git a/libc/sysdeps/linux/i386/syscall.S b/libc/sysdeps/linux/i386/syscall.S new file mode 100644 index 000000000..c67b39ece --- /dev/null +++ b/libc/sysdeps/linux/i386/syscall.S @@ -0,0 +1,76 @@ +/* + * June 27, 2001 Manuel Novoa III + * + * This is a heavily modified version of gcc's output for the _syscall5 macro. + * The idea (originally from dietlibc) is that all syscall functions simply set + * the syscall number as the first argument, then set the syscall arguments as + * the next up-to-five arguments, and then jump here. All the common work is + * done by syscall(), saving a fair amount of generated code when a number of + * syscalls are used. The (potential) cost is some unnecessary pushes, pops, + * and movs but the execution time penalty should be relatively small compared + * to the cost of the syscall itself. + * + * July 24, 2002 + * + * Modified by Erik Andersen to take all function parameters from off the stack + * like a proper function and eliminates the old 255 syscall number limit. So + * now we can just call this as a function as syscall() per the function + * prototype in unistd.h, so to call _exit(42) you can just call. + * syscall(__NR_exit, 42); + * and things will just work. + */ + +.text + .align 4 +.globl syscall + .type syscall,@function +syscall: + pushl %edi + pushl %esi + pushl %ebx + movl 36(%esp),%edi; /* Load the 5 syscall argument registers */ + movl 32(%esp),%esi; + movl 28(%esp),%edx; + movl 24(%esp),%ecx; + movl 20(%esp),%ebx; + movl 16(%esp),%eax /* Load syscall number into %eax. */ +#APP + int $0x80 +#NO_APP + cmpl $-4095,%eax + jbe .Ldone + +#ifdef PIC + call Lhere +Lhere: + popl %ebx + addl $_GLOBAL_OFFSET_TABLE_+[.-Lhere],%ebx + negl %eax + movl %eax,%ecx +#ifdef _LIBC_REENTRANT + call __errno_location@PLT +#else + movl errno@GOT(%ebx),%eax +#endif /* _LIBC_REENTRANT */ + movl %ecx,(%eax) +#else + negl %eax +#ifdef _LIBC_REENTRANT + movl %eax,%ecx + call __errno_location + movl %ecx,(%eax) +#else + movl %eax,errno +#endif /* _LIBC_REENTRANT */ + +#endif /* PIC */ + + movl $-1,%eax + .p2align 4,,7 +.Ldone: + popl %ebx + popl %esi + popl %edi + ret +.Lsize: + .size syscall,.Lsize-syscall |