aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/unix/sysv/linux/sh
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2000-10-26 02:34:17 +0000
committerUlrich Drepper <drepper@redhat.com>2000-10-26 02:34:17 +0000
commit876f9634403d1ab7ff1860c285bfe098d81b7d04 (patch)
tree2f91b466dd8ecbdb39ef957694f0c9903ad13b8d /sysdeps/unix/sysv/linux/sh
parent85471284c726eec22a38f2652cde279678381ab9 (diff)
downloadglibc-876f9634403d1ab7ff1860c285bfe098d81b7d04.tar
glibc-876f9634403d1ab7ff1860c285bfe098d81b7d04.tar.gz
glibc-876f9634403d1ab7ff1860c285bfe098d81b7d04.tar.bz2
glibc-876f9634403d1ab7ff1860c285bfe098d81b7d04.zip
Update.
2000-10-26 Kazumoto Kojima <kkojima@rr.iij4u.or.jp> Yutaka Niibe <gniibe@chroot.org> * sysdeps/sh/dl-machine.h (elf_machine_rela): Handle in place relocation which is generated by new ld. * sysdeps/sh/elf/initfini.c (_init): Preseted __fpscr_values. (_fini): Delete an obsolete register prefix. * sysdeps/unix/sysv/linux/sh/Versions: Add __xstat64, __fxstat64, __lxstat64, alphasort64, glob64, readdir64, readdir64_r, scandir64 and versionsort64 as the 2.2-versioned symbols. * sysdeps/unix/sysv/linux/sh/bits/fcntl.h: New file. * sysdeps/unix/sysv/linux/sh/brk.c: Changes for the new system call calling convention of the kernel. * sysdeps/unix/sysv/linux/sh/pipe.S: Likewise. * sysdeps/unix/sysv/linux/sh/socket.S: Likewise. * sysdeps/unix/sysv/linux/sh/clone.S: Likewise. * sysdeps/unix/sysv/linux/sh/vfork.S: Likewise. * sysdeps/unix/sysv/linux/sh/sysdep.h: Likewise. * sysdeps/unix/sysv/linux/sh/fcntl.c: New file. * sysdeps/unix/sysv/linux/sh/lockf64.c: New file. * sysdeps/unix/sysv/linux/sh/sys/user.h: Include the kernel header file and delete the definitions of struct user and user_fp. * sysdeps/unix/sysv/linux/sh/syscall.S: New file. * sysdeps/unix/sysv/linux/sh/syscalls.list: Remove entries for s_ioctl, s_ipc, s_llseek, s_chown, s_fchown, s_lchown, s_execve, rt_sigaction, rt_sigpending, rt_sigprocmask, rt_sigqueueinfo, rt_sigsuspend, rt_sigtimedwait, s_getcwd, s_getdents, s_getgroups, s_getpriority, s_getegid, s_geteuid, s_getuid, getresgid, getresuid, s_getrlimit, s_poll, s_pread64, s_ptrace, s_pwrite64, s_reboot, s_setrlimit, s_sigaction, s_sigpending, s_sigprocmask, s_sigsuspend, s_setfsgid, s_setfsuid, s_setgid, s_setgroups, s_setregid, s_setresgid, s_setresuid, s_setreuid, s_setuid, s_sysctl, s_ugetrlimit, s_ustat, sys_fstat, sys_lstat, sys_mknod, sys_readv, sys_stat, sys_writev and syscall.
Diffstat (limited to 'sysdeps/unix/sysv/linux/sh')
-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