浏览代码

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>
Joel Stanley 8 年之前
父节点
当前提交
f764bcffed
共有 2 个文件被更改,包括 33 次插入1 次删除
  1. 1 1
      libc/sysdeps/linux/or1k/Makefile.arch
  2. 32 0
      libc/sysdeps/linux/or1k/syscall.c

+ 1 - 1
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

+ 32 - 0
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);
+}