aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2006-06-25 15:26:10 -0700
committerH. Peter Anvin <hpa@zytor.com>2006-06-25 15:26:10 -0700
commitfdd5576a86522e66464a909b175f86f96595307d (patch)
treed12e78a43416369eea8bc3ab322bf3c706b5517b
parenta83efd0838c3bb2a6f5c3b095a01b45014b8414e (diff)
downloadklibc-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.h38
-rw-r--r--usr/klibc/arch/i386/socketcall.S29
-rw-r--r--usr/klibc/socketcalls.pl10
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 {