diff options
author | H. Peter Anvin <hpa@zytor.com> | 2006-06-25 15:26:10 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2006-06-25 15:26:10 -0700 |
commit | fdd5576a86522e66464a909b175f86f96595307d (patch) | |
tree | d12e78a43416369eea8bc3ab322bf3c706b5517b | |
parent | a83efd0838c3bb2a6f5c3b095a01b45014b8414e (diff) | |
download | klibc-fdd5576a86522e66464a909b175f86f96595307d.tar.gz |
[klibc] i386: use the standard calling convention for socketcallsklibc-1.4.6
Instead of relying on all users to have a separate calling convention
for socketcalls, use the same calling convention for everything. This
means doing a minor amount of parameter marshalling, but no big deal.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r-- | usr/include/sys/socket.h | 38 | ||||
-rw-r--r-- | usr/klibc/arch/i386/socketcall.S | 29 | ||||
-rw-r--r-- | usr/klibc/socketcalls.pl | 10 |
3 files changed, 42 insertions, 35 deletions
diff --git a/usr/include/sys/socket.h b/usr/include/sys/socket.h index 9e19f503b965b..2de1d6acc1acc 100644 --- a/usr/include/sys/socket.h +++ b/usr/include/sys/socket.h @@ -19,34 +19,26 @@ # define SOCK_PACKET 10 #endif -#ifdef __i386__ -# define __socketcall __extern __cdecl -#else -# define __socketcall __extern -#endif - typedef int socklen_t; -__socketcall int socket(int, int, int); -__socketcall int bind(int, struct sockaddr *, int); -__socketcall int connect(int, struct sockaddr *, socklen_t); -__socketcall int listen(int, int); -__socketcall int accept(int, struct sockaddr *, socklen_t *); -__socketcall int getsockname(int, struct sockaddr *, socklen_t *); -__socketcall int getpeername(int, struct sockaddr *, socklen_t *); -__socketcall int socketpair(int, int, int, int *); +__extern int socket(int, int, int); +__extern int bind(int, struct sockaddr *, int); +__extern int connect(int, struct sockaddr *, socklen_t); +__extern int listen(int, int); +__extern int accept(int, struct sockaddr *, socklen_t *); +__extern int getsockname(int, struct sockaddr *, socklen_t *); +__extern int getpeername(int, struct sockaddr *, socklen_t *); +__extern int socketpair(int, int, int, int *); __extern int send(int, const void *, size_t, unsigned int); -__socketcall int sendto(int, const void *, size_t, int, const struct sockaddr *, +__extern int sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t); __extern int recv(int, void *, size_t, unsigned int); -__socketcall int recvfrom(int, void *, size_t, unsigned int, struct sockaddr *, +__extern int recvfrom(int, void *, size_t, unsigned int, struct sockaddr *, socklen_t *); -__socketcall int shutdown(int, int); -__socketcall int setsockopt(int, int, int, const void *, socklen_t); -__socketcall int getsockopt(int, int, int, void *, socklen_t *); -__socketcall int sendmsg(int, const struct msghdr *, unsigned int); -__socketcall int recvmsg(int, struct msghdr *, unsigned int); - -#undef __socketcall +__extern int shutdown(int, int); +__extern int setsockopt(int, int, int, const void *, socklen_t); +__extern int getsockopt(int, int, int, void *, socklen_t *); +__extern int sendmsg(int, const struct msghdr *, unsigned int); +__extern int recvmsg(int, struct msghdr *, unsigned int); #endif /* _SYS_SOCKET_H */ diff --git a/usr/klibc/arch/i386/socketcall.S b/usr/klibc/arch/i386/socketcall.S index a2762dce14f14..816db34718576 100644 --- a/usr/klibc/arch/i386/socketcall.S +++ b/usr/klibc/arch/i386/socketcall.S @@ -1,11 +1,12 @@ # # socketcall.S # -# On i386, the main (only?) user of socketcall(2), the memory array -# socketcall(2) needs is conveniently already assembled for us on -# the stack. Capitalize on that to make a common socketcall stub. +# Socketcalls use the following convention: +# %eax = __NR_socketcall +# %ebx = socketcall number +# %ecx = pointer to arguments (up to 6) # - + #include <asm/unistd.h> #ifdef __i386__ @@ -16,13 +17,27 @@ .type __socketcall_common, @function __socketcall_common: - pushl %ebx + xchgl %ebx,(%esp) # The stub passes the socketcall # on stack + +#ifdef _REGPARM + pushl 16(%esp) # Arg 6 + pushl 16(%esp) # Arg 5 + pushl 16(%esp) # Arg 4 + pushl %ecx + pushl %edx + pushl %eax + movl %esp,%ecx +#else + leal 8(%esp),%ecx # Arguments already contiguous on-stack +#endif - movzbl %al,%ebx # The socketcall number is passed in in %al - leal 8(%esp),%ecx # Argument pointer movl $__NR_socketcall,%eax int $0x80 +#ifdef _REGPARM + addl $6*4, %esp +#endif + cmpl $-4095,%eax # Error return? popl %ebx diff --git a/usr/klibc/socketcalls.pl b/usr/klibc/socketcalls.pl index a901a0294638c..e6f75ab79878d 100644 --- a/usr/klibc/socketcalls.pl +++ b/usr/klibc/socketcalls.pl @@ -49,12 +49,12 @@ while ( defined($line = <FILE>) ) { print OUT "#include <sys/socketcalls.h>\n"; print OUT "\n"; print OUT "\t.text\n"; - print OUT "\t.align 4\n"; - print OUT "\t.globl ${name}\n"; - print OUT "\t.type ${name},\@function\n"; + print OUT "\t.align 4\n"; + print OUT "\t.globl ${name}\n"; + print OUT "\t.type ${name},\@function\n"; print OUT "${name}:\n"; - print OUT "\tmovb \$SYS_\U${name}\E,%al\n"; - print OUT "\tjmp __socketcall_common\n"; + print OUT "\tpushl \$SYS_\U${name}\n"; + print OUT "\tjmp __socketcall_common\n"; print OUT "\t.size ${name},.-${name}\n"; close(OUT); } else { |