summaryrefslogtreecommitdiff
path: root/libc/sysdeps
diff options
context:
space:
mode:
authorJoel Stanley <joel@jms.id.au>2017-12-06 12:26:21 +1030
committerWaldemar Brodkorb <wbx@openadk.org>2017-12-10 19:36:45 +0100
commitf764bcffed69d8c62625dc4b6c1a6af21bd6dbc2 (patch)
tree31bf056e4035b87d8f4317b82a651214f5bb92a9 /libc/sysdeps
parent7c36bcae09d66bbaa35cbb02253ae0556f42677e (diff)
or1k: syscall: Pass arguments on the stack
Busybox internally calls syscall(2). - in unistd.h defined something like int syscall(nr, ....) - in syscall.c (common) implemented as int syscall(nr, arg1, arg3, arg3, arg4, arg5, arg6) This will not work, busybox thinks syscall should have varargs calling conventions. But it doesnt in the uclibc implementation so no args go through. Most architectures this will work. But on openrisc varargs are all sent on the stack. Regular args are passed in registers. Commit message and idea from Stafford Horne <shorne@gmail.com>. Signed-off-by: Joel Stanley <joel@jms.id.au>
Diffstat (limited to 'libc/sysdeps')
-rw-r--r--libc/sysdeps/linux/or1k/Makefile.arch2
-rw-r--r--libc/sysdeps/linux/or1k/syscall.c32
2 files changed, 33 insertions, 1 deletions
diff --git a/libc/sysdeps/linux/or1k/Makefile.arch b/libc/sysdeps/linux/or1k/Makefile.arch
index f6758fa63..191eebafd 100644
--- a/libc/sysdeps/linux/or1k/Makefile.arch
+++ b/libc/sysdeps/linux/or1k/Makefile.arch
@@ -5,5 +5,5 @@
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
-CSRC-y := __syscall_error.c __init_brk.c brk.c sbrk.c clone.c
+CSRC-y := __syscall_error.c __init_brk.c brk.c sbrk.c clone.c syscall.c
SSRC-y := __longjmp.S setjmp.S or1k_clone.S
diff --git a/libc/sysdeps/linux/or1k/syscall.c b/libc/sysdeps/linux/or1k/syscall.c
new file mode 100644
index 000000000..2f4356737
--- /dev/null
+++ b/libc/sysdeps/linux/or1k/syscall.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2017 Joel Stanley <joel@jms.id.au>
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <stdarg.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+long int syscall (long num, ...)
+{
+ unsigned long arg1 = 0;
+ unsigned long arg2 = 0;
+ unsigned long arg3 = 0;
+ unsigned long arg4 = 0;
+ unsigned long arg5 = 0;
+ unsigned long arg6 = 0;
+ va_list arg;
+
+ va_start (arg, num);
+ arg1 = va_arg (arg, unsigned long);
+ arg2 = va_arg (arg, unsigned long);
+ arg3 = va_arg (arg, unsigned long);
+ arg4 = va_arg (arg, unsigned long);
+ arg5 = va_arg (arg, unsigned long);
+ arg6 = va_arg (arg, unsigned long);
+ va_end (arg);
+
+ __asm__ volatile ( "" ::: "memory" );
+
+ return INLINE_SYSCALL_NCS(num, 6, arg1, arg2, arg3, arg4, arg5, arg6);
+}