From 876f9634403d1ab7ff1860c285bfe098d81b7d04 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 26 Oct 2000 02:34:17 +0000 Subject: Update. 2000-10-26 Kazumoto Kojima Yutaka Niibe * 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. --- sysdeps/sh/dl-machine.h | 7 +- sysdeps/sh/elf/initfini.c | 8 +- sysdeps/unix/sysv/linux/sh/Versions | 18 ++++ sysdeps/unix/sysv/linux/sh/bits/fcntl.h | 155 +++++++++++++++++++++++++++++++ sysdeps/unix/sysv/linux/sh/brk.c | 12 +-- sysdeps/unix/sysv/linux/sh/clone.S | 4 +- sysdeps/unix/sysv/linux/sh/fcntl.c | 1 + sysdeps/unix/sysv/linux/sh/lockf64.c | 1 + sysdeps/unix/sysv/linux/sh/pipe.S | 4 +- sysdeps/unix/sysv/linux/sh/socket.S | 4 +- sysdeps/unix/sysv/linux/sh/sys/user.h | 44 +-------- sysdeps/unix/sysv/linux/sh/syscall.S | 68 ++++++++++++++ sysdeps/unix/sysv/linux/sh/syscalls.list | 52 ----------- sysdeps/unix/sysv/linux/sh/sysdep.h | 108 +++++++++++++++++---- sysdeps/unix/sysv/linux/sh/vfork.S | 9 +- 15 files changed, 365 insertions(+), 130 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/sh/bits/fcntl.h create mode 100644 sysdeps/unix/sysv/linux/sh/fcntl.c create mode 100644 sysdeps/unix/sysv/linux/sh/lockf64.c create mode 100644 sysdeps/unix/sysv/linux/sh/syscall.S (limited to 'sysdeps') diff --git a/sysdeps/sh/dl-machine.h b/sysdeps/sh/dl-machine.h index dd21dfbb9c..99109f7a83 100644 --- a/sysdeps/sh/dl-machine.h +++ b/sysdeps/sh/dl-machine.h @@ -433,7 +433,12 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, #ifndef RTLD_BOOTSTRAP if (map != &_dl_rtld_map) /* Already done in rtld itself. */ #endif - *reloc_addr = map->l_addr + reloc->r_addend; + { + if (reloc->r_addend) + *reloc_addr = map->l_addr + reloc->r_addend; + else + *reloc_addr += map->l_addr; + } } else if (ELF32_R_TYPE (reloc->r_info) != R_SH_NONE) { diff --git a/sysdeps/sh/elf/initfini.c b/sysdeps/sh/elf/initfini.c index 0660c2cd8c..e1ec92176e 100644 --- a/sysdeps/sh/elf/initfini.c +++ b/sysdeps/sh/elf/initfini.c @@ -80,6 +80,12 @@ _init: .L23: .long __gmon_start__ #endif + .data + .global __fpscr_values +__fpscr_values: + .long 0 + .long 0x80000 + .previous 1: ALIGN END_INIT @@ -114,7 +120,7 @@ __gmon_start__: .global _fini .type _fini,@function _fini: - mov.l r12,@-$r15 + mov.l r12,@-r15 mov.l r14,@-r15 sts.l pr,@-r15 #ifdef SHARED 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 directly; include instead." +#endif + + +#include + +/* 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 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 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 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 -/* and 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 here. */ -#include - -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 #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 + +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 -- cgit 1.4.1