about summary refs log tree commit diff
path: root/sysdeps/unix
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix')
-rw-r--r--sysdeps/unix/sysv/linux/sh/Versions18
-rw-r--r--sysdeps/unix/sysv/linux/sh/bits/fcntl.h155
-rw-r--r--sysdeps/unix/sysv/linux/sh/brk.c12
-rw-r--r--sysdeps/unix/sysv/linux/sh/clone.S4
-rw-r--r--sysdeps/unix/sysv/linux/sh/fcntl.c1
-rw-r--r--sysdeps/unix/sysv/linux/sh/lockf64.c1
-rw-r--r--sysdeps/unix/sysv/linux/sh/pipe.S4
-rw-r--r--sysdeps/unix/sysv/linux/sh/socket.S4
-rw-r--r--sysdeps/unix/sysv/linux/sh/sys/user.h44
-rw-r--r--sysdeps/unix/sysv/linux/sh/syscall.S68
-rw-r--r--sysdeps/unix/sysv/linux/sh/syscalls.list52
-rw-r--r--sysdeps/unix/sysv/linux/sh/sysdep.h108
-rw-r--r--sysdeps/unix/sysv/linux/sh/vfork.S9
13 files changed, 352 insertions, 128 deletions
diff --git a/sysdeps/unix/sysv/linux/sh/Versions b/sysdeps/unix/sysv/linux/sh/Versions
index bd4b6933cf..090e938f26 100644
--- a/sysdeps/unix/sysv/linux/sh/Versions
+++ b/sysdeps/unix/sysv/linux/sh/Versions
@@ -1,6 +1,24 @@
 libc {
   GLIBC_2.2 {
+    # functions used in other libraries
+    __xstat64; __fxstat64; __lxstat64;
+
+    # a*
+    alphasort64;
+
+    # g*
+    glob64;
+
     # New rlimit interface
     getrlimit; setrlimit; getrlimit64;
+
+    # r*
+    readdir64; readdir64_r;
+
+    # s*
+    scandir64;
+
+    # v*
+    versionsort64;
   }
 }
diff --git a/sysdeps/unix/sysv/linux/sh/bits/fcntl.h b/sysdeps/unix/sysv/linux/sh/bits/fcntl.h
new file mode 100644
index 0000000000..ba15580277
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sh/bits/fcntl.h
@@ -0,0 +1,155 @@
+/* O_*, F_*, FD_* bit values for Linux.
+   Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef	_FCNTL_H
+# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
+#endif
+
+
+#include <sys/types.h>
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+   located on an ext2 file system */
+#define O_ACCMODE	   0003
+#define O_RDONLY	     00
+#define O_WRONLY	     01
+#define O_RDWR		     02
+#define O_CREAT		   0100	/* not fcntl */
+#define O_EXCL		   0200	/* not fcntl */
+#define O_NOCTTY	   0400	/* not fcntl */
+#define O_TRUNC		  01000	/* not fcntl */
+#define O_APPEND	  02000
+#define O_NONBLOCK	  04000
+#define O_NDELAY	O_NONBLOCK
+#define O_SYNC		 010000
+#define O_FSYNC		 O_SYNC
+#define O_ASYNC		 020000
+
+#ifdef __USE_GNU
+# define O_DIRECT	 040000	/* Direct disk access.  */
+# define O_DIRECTORY	0200000	/* Must be a directory.  */
+# define O_NOFOLLOW	0400000	/* Do not follow links.  */
+#endif
+
+/* For now Linux has synchronisity options for data and read operations.
+   We define the symbols here but let them do the same as O_SYNC since
+   this is a superset.  */
+#if defined __USE_POSIX199309 || defined __USE_UNIX98
+# define O_DSYNC	O_SYNC	/* Synchronize data.  */
+# define O_RSYNC	O_SYNC	/* Synchronize read operations.  */
+#endif
+
+#ifdef __USE_LARGEFILE64
+# define O_LARGEFILE	0100000
+#endif
+
+/* Values for the second argument to `fcntl'.  */
+#define F_DUPFD		0	/* Duplicate file descriptor.  */
+#define F_GETFD		1	/* Get file descriptor flags.  */
+#define F_SETFD		2	/* Set file descriptor flags.  */
+#define F_GETFL		3	/* Get file status flags.  */
+#define F_SETFL		4	/* Set file status flags.  */
+#ifndef __USE_FILE_OFFSET64
+# define F_GETLK	5	/* Get record locking info.  */
+# define F_SETLK	6	/* Set record locking info (non-blocking).  */
+# define F_SETLKW	7	/* Set record locking info (blocking).  */
+#else
+# define F_GETLK	F_GETLK64  /* Get record locking info.  */
+# define F_SETLK	F_SETLK64  /* Set record locking info (non-blocking).*/
+# define F_SETLKW	F_SETLKW64 /* Set record locking info (blocking).  */
+#endif
+#define F_GETLK64	12	/* Get record locking info.  */
+#define F_SETLK64	13	/* Set record locking info (non-blocking).  */
+#define F_SETLKW64	14	/* Set record locking info (blocking).  */
+
+#if defined __USE_BSD || defined __USE_XOPEN2K
+# define F_SETOWN	8	/* Get owner of socket (receiver of SIGIO).  */
+# define F_GETOWN	9	/* Set owner of socket (receiver of SIGIO).  */
+#endif
+
+#ifdef __USE_GNU
+# define F_SETSIG	10	/* Set number of signal to be sent.  */
+# define F_GETSIG	11	/* Get number of signal to be sent.  */
+#endif
+
+/* For F_[GET|SET]FL.  */
+#define FD_CLOEXEC	1	/* actually anything with low bit set goes */
+
+/* For posix fcntl() and `l_type' field of a `struct flock' for lockf().  */
+#define F_RDLCK		0	/* Read lock.  */
+#define F_WRLCK		1	/* Write lock.  */
+#define F_UNLCK		2	/* Remove lock.  */
+
+/* For old implementation of bsd flock().  */
+#define F_EXLCK		4	/* or 3 */
+#define F_SHLCK		8	/* or 4 */
+
+#ifdef __USE_BSD
+/* Operations for bsd flock(), also used by the kernel implementation.  */
+# define LOCK_SH	1	/* shared lock */
+# define LOCK_EX	2	/* exclusive lock */
+# define LOCK_NB	4	/* or'd with one of the above to prevent
+				   blocking */
+# define LOCK_UN	8	/* remove lock */
+#endif
+
+struct flock
+  {
+    short int l_type;	/* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK.  */
+    short int l_whence;	/* Where `l_start' is relative to (like `lseek').  */
+#ifndef __USE_FILE_OFFSET64
+    __off_t l_start;	/* Offset where the lock begins.  */
+    __off_t l_len;	/* Size of the locked area; zero means until EOF.  */
+#else
+    __off64_t l_start;	/* Offset where the lock begins.  */
+    __off64_t l_len;	/* Size of the locked area; zero means until EOF.  */
+#endif
+    __pid_t l_pid;	/* Process holding the lock.  */
+  };
+
+#ifdef __USE_LARGEFILE64
+struct flock64
+  {
+    short int l_type;	/* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK.  */
+    short int l_whence;	/* Where `l_start' is relative to (like `lseek').  */
+    __off64_t l_start;	/* Offset where the lock begins.  */
+    __off64_t l_len;	/* Size of the locked area; zero means until EOF.  */
+    __pid_t l_pid;	/* Process holding the lock.  */
+  };
+#endif
+
+/* Define some more compatibility macros to be backward compatible with
+   BSD systems which did not managed to hide these kernel macros.  */
+#ifdef	__USE_BSD
+# define FAPPEND	O_APPEND
+# define FFSYNC		O_FSYNC
+# define FASYNC		O_ASYNC
+# define FNONBLOCK	O_NONBLOCK
+# define FNDELAY	O_NDELAY
+#endif /* Use BSD.  */
+
+/* Advise to `posix_fadvise'.  */
+#ifdef __USE_XOPEN2K
+# define POSIX_FADV_NORMAL	0 /* No further special treatment.  */
+# define POSIX_FADV_RANDOM	1 /* Expect random page references.  */
+# define POSIX_FADV_SEQUENTIAL	2 /* Expect sequential page references.  */
+# define POSIX_FADV_WILLNEED	3 /* Will need these pages.  */
+# define POSIX_FADV_DONTNEED	4 /* Don't need these pages.  */
+# define POSIX_FADV_NOREUSE	5 /* Data will be accessed once.  */
+#endif
diff --git a/sysdeps/unix/sysv/linux/sh/brk.c b/sysdeps/unix/sysv/linux/sh/brk.c
index 79c43b717c..5ce67df0cb 100644
--- a/sysdeps/unix/sysv/linux/sh/brk.c
+++ b/sysdeps/unix/sysv/linux/sh/brk.c
@@ -28,14 +28,12 @@ int
 __brk (void *addr)
 {
   void *newbrk;
+  register long r3 asm ("%r3") = SYS_ify (brk);
+  register long r4 asm ("%r4") = (long)addr;
 
-  asm ("mov %1, r4\n"
-       "mov %2, r0\n"
-       "trapa #0\n"	/* do the system call */
-       "mov r0, %0;"	/* keep the return value */
-       : "=r"(newbrk) 
-       : "r"(addr), "i" (SYS_ify (brk))
-       : "r0");
+  asm volatile ("trapa #0x11"
+		: "=z"(newbrk) 
+		: "r" (r3), "r" (r4));
 
   __curbrk = newbrk;
 
diff --git a/sysdeps/unix/sysv/linux/sh/clone.S b/sysdeps/unix/sysv/linux/sh/clone.S
index e181850be3..267ebd95b0 100644
--- a/sysdeps/unix/sysv/linux/sh/clone.S
+++ b/sysdeps/unix/sysv/linux/sh/clone.S
@@ -61,8 +61,8 @@ ENTRY(__clone)
 
 	/* do the system call */
 	mov	r6, r4
-	mov	#+SYS_ify(clone), r0
-	trapa	#0
+	mov	#+SYS_ify(clone), r3
+	trapa	#0x12
 	mov     r0, r1
 	mov	#-12, r2
 	shad	r2, r1
diff --git a/sysdeps/unix/sysv/linux/sh/fcntl.c b/sysdeps/unix/sysv/linux/sh/fcntl.c
new file mode 100644
index 0000000000..ea951bc4f9
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sh/fcntl.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/fcntl.c>
diff --git a/sysdeps/unix/sysv/linux/sh/lockf64.c b/sysdeps/unix/sysv/linux/sh/lockf64.c
new file mode 100644
index 0000000000..a88f5a784a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sh/lockf64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/lockf64.c>
diff --git a/sysdeps/unix/sysv/linux/sh/pipe.S b/sysdeps/unix/sysv/linux/sh/pipe.S
index c5c87b3449..bb1f8b0981 100644
--- a/sysdeps/unix/sysv/linux/sh/pipe.S
+++ b/sysdeps/unix/sysv/linux/sh/pipe.S
@@ -19,8 +19,8 @@
 #include <sysdep.h>
 
 ENTRY (__libc_pipe)
-	mov	#+__NR_pipe, r0
-	trapa	#0
+	mov	#+__NR_pipe, r3
+	trapa	#0x10
 	mov     r0, r3
 	mov	#-12, r2
 	shad	r2, r3
diff --git a/sysdeps/unix/sysv/linux/sh/socket.S b/sysdeps/unix/sysv/linux/sh/socket.S
index 814380e61d..c9b11b941a 100644
--- a/sysdeps/unix/sysv/linux/sh/socket.S
+++ b/sysdeps/unix/sysv/linux/sh/socket.S
@@ -66,8 +66,8 @@ ENTRY (__socket)
         /* Do the system call trap.  */
 	mov #+P(SOCKOP_,socket), r4
 	mov r15, r5
-	mov.l .L1,r0
-	trapa #0
+	mov.l .L1,r3
+	trapa #0x12
 
 	/* Pop args off the stack */
 	P(POPARGS_,NARGS)
diff --git a/sysdeps/unix/sysv/linux/sh/sys/user.h b/sysdeps/unix/sysv/linux/sh/sys/user.h
index 7ea3cf67b3..741f55094b 100644
--- a/sysdeps/unix/sysv/linux/sh/sys/user.h
+++ b/sysdeps/unix/sysv/linux/sh/sys/user.h
@@ -21,48 +21,6 @@
 
 #include <features.h>
 
-/* <sys/ptrace.h> and <linux/ptrace.h> both define the PTRACE_* macros.
-   This leads to compilation problems with programs which include both
-   user.h and ptrace.h (eg: GDB).  Do not include <linux/ptrace.h> here. */
-#include <asm/ptrace.h>
-
-struct user_fp
-{
-  struct fp_reg
-  {
-    unsigned int sign1:1;
-    unsigned int unused:15;
-    unsigned int sign2:1;
-    unsigned int exponent:14;
-    unsigned int j:1;
-    unsigned int mantissa1:31;
-    unsigned int mantissa0:32;
-  } fpregs[8];
-  unsigned int fpsr:32;
-  unsigned int fpcr:32;
-};
-
-struct user
-{
-  struct pt_regs regs;		/* General registers */
-  int u_fpvalid;		/* True if math co-processor being used. */
-
-  unsigned long int u_tsize;	/* Text segment size (pages). */
-  unsigned long int u_dsize;	/* Data segment size (pages). */
-  unsigned long int u_ssize;	/* Stack segment size (pages). */
-
-  unsigned long start_code;	/* Starting virtual address of text. */
-  unsigned long start_stack;	/* Starting virtual address of stack. */
-
-  long int signal;     		/* Signal that caused the core dump. */
-  int reserved;			/* No longer used */
-  struct pt_regs *u_ar0;	/* help gdb to find the general registers. */
-
-  unsigned long magic;		/* uniquely identify a core file */
-  char u_comm[32];		/* User command that was responsible */
-  int u_debugreg[8];
-  struct user_fp u_fp;		/* Floating point registers */
-  struct user_fp_struct *u_fp0;	/* help gdb to find the FP registers. */
-};
+#include <asm/user.h>
 
 #endif  /* sys/user.h */
diff --git a/sysdeps/unix/sysv/linux/sh/syscall.S b/sysdeps/unix/sysv/linux/sh/syscall.S
new file mode 100644
index 0000000000..0250bbe7f9
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sh/syscall.S
@@ -0,0 +1,68 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <sysdep.h>
+
+ENTRY (__syscall)
+	mov	r4, r3			// syscall number
+	mov	r5, r4			// p1
+	mov	r6, r5			// p2
+	mov	r7, r6			// p3
+	mov.l	@r15, r7		// p4
+	mov.l	@(4,r15), r0		// p5
+	mov.l	@(8,r15), r1		// p6
+	mov.l	@(12,r15), r2		// p7
+	trapa	#0x17
+	mov     r0, r1
+	mov	#-12, r2
+	shad	r2, r1
+	not	r1, r1			// r1=0 means r0 = -1 to -4095
+	tst	r1, r1			// i.e. error in linux
+	bf	1f
+	mov.l	.L2, r1
+#ifdef SHARED
+	mov	r0, r4
+	mov.l	r12, @-r15
+	sts.l	pr, @-r15
+        mov.l	0f, r12
+	mova	0f, r0
+	add	r0, r12
+	mova	.L2, r0
+	add	r0, r1
+	jsr	@r1
+	 nop
+	lds.l	@r15+, pr
+	rts
+	 mov.l	@r15+, r12
+	.align 2
+0:
+	.long	_GLOBAL_OFFSET_TABLE_
+#else
+	jmp	@r1
+	 mov	r0, r4
+#endif
+1:
+	rts
+	 nop
+
+	.align	2
+.L2:
+	.long	PLTJMP(C_SYMBOL_NAME(__syscall_error))
+PSEUDO_END (__syscall)
+
+weak_alias (__syscall, syscall)
diff --git a/sysdeps/unix/sysv/linux/sh/syscalls.list b/sysdeps/unix/sysv/linux/sh/syscalls.list
index fe9bbe1f54..0ea253e3ca 100644
--- a/sysdeps/unix/sysv/linux/sh/syscalls.list
+++ b/sysdeps/unix/sysv/linux/sh/syscalls.list
@@ -1,54 +1,2 @@
 # File name	Caller	Syscall name	# args	Strong name	Weak names
 
-s_ioctl		ioctl	ioctl		3	__syscall_ioctl
-s_ipc		msgget	ipc		5	__syscall_ipc
-s_llseek	llseek _llseek		5	__syscall__llseek
-s_chown		chown	chown		3	__syscall_chown
-s_fchown	fchown	fchown		3	__syscall_fchown
-s_lchown	lchown	lchown		3	__syscall_lchown
-s_execve	execve execve		3	__syscall_execve
-rt_sigaction	-	rt_sigaction	4	__syscall_rt_sigaction
-rt_sigpending	-	rt_sigpending	2	__syscall_rt_sigpending
-rt_sigprocmask	-	rt_sigprocmask	4	__syscall_rt_sigprocmask
-rt_sigqueueinfo	-	rt_sigqueueinfo	3	__syscall_rt_sigqueueinfo
-rt_sigsuspend	-	rt_sigsuspend	2	__syscall_rt_sigsuspend
-rt_sigtimedwait	-	rt_sigtimedwait	4	__syscall_rt_sigtimedwait
-s_getcwd	getcwd getcwd		2	__syscall_getcwd
-s_getdents	getdents getdents	3	__syscall_getdents
-s_getgroups	getgroups getgroups	2	__syscall_getgroups
-s_getpriority	getpriority getpriority	2	__syscall_getpriority
-s_getegid	getegid	getegid		0	__syscall_getegid
-s_geteuid	geteuid	geteuid		0	__syscall_geteuid
-s_getuid	getuid	getuid		0	__syscall_getuid
-getresgid	-	getresgid	3	getresgid
-getresuid	-	getresuid	3	getresuid
-s_getrlimit	getrlimit getrlimit	2	__syscall_getrlimit
-s_poll		poll poll		3	__syscall_poll
-s_pread64	pread64	pread		5	__syscall_pread
-s_ptrace	ptrace	ptrace		4	__syscall_ptrace
-s_pwrite64	pwrite64 pwrite		5	__syscall_pwrite
-s_reboot	reboot	reboot		3	__syscall_reboot
-s_setrlimit	setrlimit setrlimit	2	__syscall_setrlimit
-s_sigaction	sigaction sigaction	3	__syscall_sigaction
-s_sigpending	sigpending sigpending	1	__syscall_sigpending
-s_sigprocmask	sigprocmask sigprocmask	3	__syscall_sigprocmask
-s_sigsuspend	sigsuspend sigsuspend	3	__syscall_sigsuspend
-s_setfsgid	setfsgid setfsgid	1	__syscall_setfsgid
-s_setfsuid	setfsuid setfsuid	1	__syscall_setfsuid
-s_setgid	setgid	setgid		1	__syscall_setgid
-s_setgroups	setgroups setgroups	2	__syscall_setgroups
-s_setregid	setregid setregid	2	__syscall_setregid
-s_setresgid	setresgid setresgid	3	__syscall_setresgid
-s_setresuid	setresuid setresuid	3	__syscall_setresuid
-s_setreuid	setreuid setreuid	2	__syscall_setreuid
-s_setuid	setuid	setuid		1	__syscall_setuid
-s_sysctl	sysctl	_sysctl		1	__syscall__sysctl
-s_ugetrlimit	getrlimit ugetrlimit	2	__syscall_ugetrlimit
-s_ustat		ustat	ustat		2	__syscall_ustat
-sys_fstat	fxstat fstat		2	__syscall_fstat
-sys_lstat	lxstat lstat		2	__syscall_lstat
-sys_mknod	xmknod	mknod		3	__syscall_mknod
-sys_readv	readv	readv		3	__syscall_readv
-sys_stat	xstat stat		2	__syscall_stat
-sys_writev	writev	writev		3	__syscall_writev
-syscall		-	syscall		5	syscall
diff --git a/sysdeps/unix/sysv/linux/sh/sysdep.h b/sysdeps/unix/sysv/linux/sh/sysdep.h
index 6024b9fdac..48189fa4a1 100644
--- a/sysdeps/unix/sysv/linux/sh/sysdep.h
+++ b/sysdeps/unix/sysv/linux/sh/sysdep.h
@@ -103,29 +103,105 @@
 
 #define SYSCALL_ERROR_HANDLER	/* Nothing here; code in sysdep.S is used.  */
 
-#define SYSCALL_INST0	trapa #0
-#define SYSCALL_INST1	trapa #0
-#define SYSCALL_INST2	trapa #0
-#define SYSCALL_INST3	trapa #0
-#define SYSCALL_INST4	trapa #0
-#define SYSCALL_INST5	trapa #1
-#define SYSCALL_INST6	trapa #2
+#define SYSCALL_INST0	trapa #0x10
+#define SYSCALL_INST1	trapa #0x11
+#define SYSCALL_INST2	trapa #0x12
+#define SYSCALL_INST3	trapa #0x13
+#define SYSCALL_INST4	trapa #0x14
+#define SYSCALL_INST5	mov.l @(0,r15),r0; trapa #0x15
+#define SYSCALL_INST6	mov.l @(0,r15),r0; mov.l @(4,r15),r1; trapa #0x16
 
 #undef	DO_CALL
-#define DO_CALL(args, syscall_name) \
-    mov.l 1f,r0; \
-    SYSCALL_INST##args;	\
-    bra 2f; \
-     nop; \
-    .align 2; \
- 1: .long SYS_ify(syscall_name); \
+#define DO_CALL(args, syscall_name)	\
+    mov.l 1f,r3;			\
+    SYSCALL_INST##args;			\
+    bra 2f;				\
+     nop;				\
+    .align 2;				\
+ 1: .long SYS_ify (syscall_name);	\
  2:
 
 #else /* not __ASSEMBLER__ */
 
+#define SYSCALL_INST_STR0	"trapa #0x10\n\t"
+#define SYSCALL_INST_STR1	"trapa #0x11\n\t"
+#define SYSCALL_INST_STR2	"trapa #0x12\n\t"
+#define SYSCALL_INST_STR3	"trapa #0x13\n\t"
+#define SYSCALL_INST_STR4	"trapa #0x14\n\t"
+#define SYSCALL_INST_STR5	"trapa #0x15\n\t"
+#define SYSCALL_INST_STR6	"trapa #0x16\n\t"
+
+#define ASMFMT_0
+#define ASMFMT_1 \
+	, "r" (r4)
+#define ASMFMT_2 \
+	, "r" (r4), "r" (r5)
+#define ASMFMT_3 \
+	, "r" (r4), "r" (r5), "r" (r6)
+#define ASMFMT_4 \
+	, "r" (r4), "r" (r5), "r" (r6), "r" (r7)
+#define ASMFMT_5 \
+	, "r" (r4), "r" (r5), "r" (r6), "r" (r7), "0" (r0)
+#define ASMFMT_6 \
+	, "r" (r4), "r" (r5), "r" (r6), "r" (r7), "0" (r0), "r" (r1)
+#define ASMFMT_7 \
+	, "r" (r4), "r" (r5), "r" (r6), "r" (r7), "0" (r0), "r" (r1), "r" (r2)
+
+#define SUBSTITUTE_ARGS_0()
+#define SUBSTITUTE_ARGS_1(arg1)					\
+	register long r4 asm ("%r4") = (long)(arg1)
+#define SUBSTITUTE_ARGS_2(arg1, arg2)				\
+	register long r4 asm ("%r4") = (long)(arg1);		\
+	register long r5 asm ("%r5") = (long)(arg2)
+#define SUBSTITUTE_ARGS_3(arg1, arg2, arg3)			\
+	register long r4 asm ("%r4") = (long)(arg1);		\
+	register long r5 asm ("%r5") = (long)(arg2);		\
+	register long r6 asm ("%r6") = (long)(arg3)
+#define SUBSTITUTE_ARGS_4(arg1, arg2, arg3, arg4)		\
+	register long r4 asm ("%r4") = (long)(arg1);		\
+	register long r5 asm ("%r5") = (long)(arg2);		\
+	register long r6 asm ("%r6") = (long)(arg3);		\
+	register long r7 asm ("%r7") = (long)(arg4)
+#define SUBSTITUTE_ARGS_5(arg1, arg2, arg3, arg4, arg5) 	\
+	register long r4 asm ("%r4") = (long)(arg1);		\
+	register long r5 asm ("%r5") = (long)(arg2);		\
+	register long r6 asm ("%r6") = (long)(arg3);		\
+	register long r7 asm ("%r7") = (long)(arg4);		\
+	register long r0 asm ("%r0") = (long)(arg5)
+#define SUBSTITUTE_ARGS_6(arg1, arg2, arg3, arg4, arg5, arg6)		\
+	register long r4 asm ("%r4") = (long)(arg1);			\
+	register long r5 asm ("%r5") = (long)(arg2);			\
+	register long r6 asm ("%r6") = (long)(arg3);			\
+	register long r7 asm ("%r7") = (long)(arg4);			\
+	register long r0 asm ("%r0") = (long)(arg5);			\
+	register long r1 asm ("%r1") = (long)(arg6)
+#define SUBSTITUTE_ARGS_7(arg1, arg2, arg3, arg4, arg5, arg6, arg7)	\
+	register long r4 asm ("%r4") = (long)(arg1);			\
+	register long r5 asm ("%r5") = (long)(arg2);			\
+	register long r6 asm ("%r6") = (long)(arg3);			\
+	register long r7 asm ("%r7") = (long)(arg4);			\
+	register long r0 asm ("%r0") = (long)(arg5)			\
+	register long r1 asm ("%r1") = (long)(arg6);			\
+	register long r2 asm ("%r2") = (long)(arg7)
+
 #undef INLINE_SYSCALL
-#define INLINE_SYSCALL(name, nr, args...) \
-  __syscall_##name(args)
+#define INLINE_SYSCALL(name, nr, args...) 			\
+  ({								\
+    unsigned long resultvar;					\
+    register long r3 asm ("%r3") = SYS_ify (name);		\
+    SUBSTITUTE_ARGS_##nr(args);					\
+								\
+    asm volatile (SYSCALL_INST_STR##nr				\
+		  : "=z" (resultvar)				\
+		  : "r" (r3) ASMFMT_##nr 			\
+		  : "memory");					\
+								\
+    if (resultvar >= 0xfffff001)			        \
+      {							        \
+	__set_errno (-resultvar);				\
+	resultvar = 0xffffffff;					\
+      }								\
+    (int) resultvar; })
 
 #endif	/* __ASSEMBLER__ */
 
diff --git a/sysdeps/unix/sysv/linux/sh/vfork.S b/sysdeps/unix/sysv/linux/sh/vfork.S
index 27381fb3e0..0ee7c6d43c 100644
--- a/sysdeps/unix/sysv/linux/sh/vfork.S
+++ b/sysdeps/unix/sysv/linux/sh/vfork.S
@@ -28,8 +28,8 @@
 ENTRY (__vfork)
 
 #ifdef __NR_vfork
-	mov	#+__NR_vfork, r0
-	trapa	#0
+	mov.w	.L3, r3
+	trapa	#0x10
 	mov     r0, r1
 	mov	#-12, r2
 	shad	r2, r1
@@ -63,6 +63,7 @@ ENTRY (__vfork)
 #endif
 .L1:
 	.word	-ENOSYS
+.L3:	.word	__NR_vfork
 1:
 	rts
 	 nop
@@ -70,8 +71,8 @@ ENTRY (__vfork)
 #endif
 
 	/* If we don't have vfork, fork is close enough.  */
-	mov	#+__NR_fork, r0
-	trapa	#0
+	mov	#+__NR_fork, r3
+	trapa	#0x10
 	mov     r0, r1
 	mov	#-12, r2
 	shad	r2, r1