diff options
Diffstat (limited to 'sysdeps/unix/sysv/linux/sh')
25 files changed, 1759 insertions, 49 deletions
diff --git a/sysdeps/unix/sysv/linux/sh/Dist b/sysdeps/unix/sysv/linux/sh/Dist deleted file mode 100644 index 8a1cdff7c5..0000000000 --- a/sysdeps/unix/sysv/linux/sh/Dist +++ /dev/null @@ -1,8 +0,0 @@ -clone.S -pipe.S -setresuid.c -setresgid.c -setfsuid.c -setfsgid.c -sys/io.h -sys/user.h diff --git a/sysdeps/unix/sysv/linux/sh/Makefile b/sysdeps/unix/sysv/linux/sh/Makefile index e8544b5dc6..6d72cb0294 100644 --- a/sysdeps/unix/sysv/linux/sh/Makefile +++ b/sysdeps/unix/sysv/linux/sh/Makefile @@ -5,3 +5,7 @@ endif ifeq ($(subdir),misc) sysdep_headers += sys/io.h endif + +ifeq ($(subdir),stdlib) +gen-as-const-headers += ucontext_i.sym +endif diff --git a/sysdeps/unix/sysv/linux/sh/bits/fcntl.h b/sysdeps/unix/sysv/linux/sh/bits/fcntl.h index c883002641..6de33302ee 100644 --- a/sysdeps/unix/sysv/linux/sh/bits/fcntl.h +++ b/sysdeps/unix/sysv/linux/sh/bits/fcntl.h @@ -1,5 +1,5 @@ /* O_*, F_*, FD_* bit values for Linux. - Copyright (C) 1995, 1996, 1997, 1998, 2000, 2004 + Copyright (C) 1995, 1996, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -22,8 +22,11 @@ # error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead." #endif - #include <sys/types.h> +#ifdef __USE_GNU +# include <bits/uio.h> +#endif + /* open/fcntl - O_SYNC is only implemented on blocks devices and on files located on an ext2 file system */ @@ -43,18 +46,18 @@ #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. */ +# define O_DIRECT 040000 /* Direct disk access. */ +# define O_DIRECTORY 0200000 /* Must be a directory. */ +# define O_NOFOLLOW 0400000 /* Do not follow links. */ # define O_NOATIME 01000000 /* Do not set atime. */ #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. */ + 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. */ +# define O_RSYNC O_SYNC /* Synchronize read operations. */ #endif #ifdef __USE_LARGEFILE64 @@ -70,15 +73,15 @@ #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). */ +# define F_SETLKW 7 /* Set record locking info (blocking). */ #else -# define F_GETLK F_GETLK64 /* Get record locking info. */ +# 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). */ +#define F_SETLKW64 14 /* Set record locking info (blocking). */ #if defined __USE_BSD || defined __USE_UNIX98 # define F_SETOWN 8 /* Get owner of socket (receiver of SIGIO). */ @@ -90,20 +93,26 @@ # define F_GETSIG 11 /* Get number of signal to be sent. */ #endif -/* For F_[GET|SET]FL. */ +#ifdef __USE_GNU +# define F_SETLEASE 1024 /* Set a lease. */ +# define F_GETLEASE 1025 /* Enquire what lease is active. */ +# define F_NOTIFY 1026 /* Request notfications on a directory. */ +#endif + +/* For F_[GET|SET]FD. */ #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. */ +#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. */ +/* 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 @@ -111,9 +120,27 @@ # define LOCK_UN 8 /* remove lock */ #endif +#ifdef __USE_GNU +# define LOCK_MAND 32 /* This is a mandatory flock: */ +# define LOCK_READ 64 /* ... which allows concurrent read operations. */ +# define LOCK_WRITE 128 /* ... which allows concurrent write operations. */ +# define LOCK_RW 192 /* ... Which allows concurrent read & write operations. */ +#endif + +#ifdef __USE_GNU +/* Types of directory notifications that may be requested with F_NOTIFY. */ +# define DN_ACCESS 0x00000001 /* File accessed. */ +# define DN_MODIFY 0x00000002 /* File modified. */ +# define DN_CREATE 0x00000004 /* File created. */ +# define DN_DELETE 0x00000008 /* File removed. */ +# define DN_RENAME 0x00000010 /* File renamed. */ +# define DN_ATTRIB 0x00000020 /* File changed attibutes. */ +# define DN_MULTISHOT 0x80000000 /* Don't remove notifier. */ +#endif + struct flock { - short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */ + 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. */ @@ -128,7 +155,7 @@ struct flock #ifdef __USE_LARGEFILE64 struct flock64 { - short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */ + 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. */ @@ -150,16 +177,61 @@ struct flock64 #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_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 + +#ifdef __USE_GNU +/* Flags for SYNC_FILE_RANGE. */ +# define SYNC_FILE_RANGE_WAIT_BEFORE 1 /* Wait upon writeout of all pages + in the range before performing the + write. */ +# define SYNC_FILE_RANGE_WRITE 2 /* Initiate writeout of all those + dirty pages in the range which are + not presently under writeback. */ +# define SYNC_FILE_RANGE_WAIT_AFTER 4 /* Wait upon writeout of all pages in + the range after performing the + write. */ + +/* Flags for SPLICE and VMSPLICE. */ +# define SPLICE_F_MOVE 1 /* Move pages instead of copying. */ +# define SPLICE_F_NONBLOCK 2 /* Don't block on the pipe splicing + (but we may still block on the fd + we splice from/to). */ +# define SPLICE_F_MORE 4 /* Expect more data. */ +# define SPLICE_F_GIFT 8 /* Pages passed in are a gift. */ +#endif + __BEGIN_DECLS +#ifdef __USE_GNU + /* Provide kernel hint to read ahead. */ extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count) __THROW; + +/* Selective file content synch'ing. */ +extern int sync_file_range (int __fd, __off64_t __from, __off64_t __to, + unsigned int __flags); + + +/* Splice address range into a pipe. */ +extern int vmsplice (int __fdout, const struct iovec *__iov, size_t __count, + unsigned int __flags); + +/* Splice two files together. */ +extern int splice (int __fdin, __off64_t *__offin, int __fdout, + __off64_t *__offout, size_t __len, unsigned int __flags) + __THROW; + +/* In-kernel implementation of tee for pipe buffers. */ +extern int tee (int __fdin, int __fdout, size_t __len, unsigned int __flags) + __THROW; + +#endif + __END_DECLS diff --git a/sysdeps/unix/sysv/linux/sh/bits/mman.h b/sysdeps/unix/sysv/linux/sh/bits/mman.h index 673c7295fb..7a6b572a4e 100644 --- a/sysdeps/unix/sysv/linux/sh/bits/mman.h +++ b/sysdeps/unix/sysv/linux/sh/bits/mman.h @@ -1,5 +1,5 @@ /* Definitions for POSIX memory map interface. Linux/SH version. - Copyright (C) 1997, 1999, 2000, 2003 Free Software Foundation, Inc. + Copyright (C) 1997,1999,2000,2003,2005,2006 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 @@ -61,6 +61,8 @@ # define MAP_EXECUTABLE 0x1000 /* Mark it as an executable. */ # define MAP_LOCKED 0x2000 /* Lock the mapping. */ # define MAP_NORESERVE 0x4000 /* Don't check for reservations. */ +# define MAP_POPULATE 0x8000 /* Populate (prefault) pagetables. */ +# define MAP_NONBLOCK 0x10000 /* Do not block on IO. */ #endif /* Flags to `msync'. */ @@ -76,6 +78,7 @@ /* Flags for `mremap'. */ #ifdef __USE_GNU # define MREMAP_MAYMOVE 1 +# define MREMAP_FIXED 2 #endif /* Advice to `madvise'. */ @@ -85,6 +88,9 @@ # define MADV_SEQUENTIAL 2 /* Expect sequential page references. */ # define MADV_WILLNEED 3 /* Will need these pages. */ # define MADV_DONTNEED 4 /* Don't need these pages. */ +# define MADV_REMOVE 9 /* Remove these pages and resources. */ +# define MADV_DONTFORK 10 /* Do not inherit across fork. */ +# define MADV_DOFORK 11 /* Do inherit across fork. */ #endif /* The POSIX people had to invent similar names for the same things. */ diff --git a/sysdeps/unix/sysv/linux/sh/chown.c b/sysdeps/unix/sysv/linux/sh/chown.c index 1961622564..e7193dc23b 100644 --- a/sysdeps/unix/sysv/linux/sh/chown.c +++ b/sysdeps/unix/sysv/linux/sh/chown.c @@ -1 +1,69 @@ -#include <sysdeps/unix/sysv/linux/m68k/chown.c> +/* Copyright (C) 1998,2000,2002,2003,2006 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <unistd.h> + +#include <sysdep.h> +#include <sys/syscall.h> +#include <bp-checks.h> + +#include <linux/posix_types.h> +#include <kernel-features.h> + +#ifdef __NR_chown32 +# if __ASSUME_32BITUIDS == 0 +/* This variable is shared with all files that need to check for 32bit + uids. */ +extern int __libc_missing_32bit_uids; +# endif +#endif /* __NR_chown32 */ + +int +__chown (const char *file, uid_t owner, gid_t group) +{ +#if __ASSUME_32BITUIDS > 0 + return INLINE_SYSCALL (chown32, 3, CHECK_STRING (file), owner, group); +#else +# ifdef __NR_chown32 + if (__libc_missing_32bit_uids <= 0) + { + int result; + int saved_errno = errno; + + result = INLINE_SYSCALL (chown32, 3, CHECK_STRING (file), owner, group); + if (result == 0 || errno != ENOSYS) + return result; + + __set_errno (saved_errno); + __libc_missing_32bit_uids = 1; + } +# endif /* __NR_chown32 */ + + if (((owner + 1) > (gid_t) ((__kernel_uid_t) -1U)) + || ((group + 1) > (gid_t) ((__kernel_gid_t) -1U))) + { + __set_errno (EINVAL); + return -1; + } + + return INLINE_SYSCALL (chown, 3, CHECK_STRING (file), owner, group); +#endif +} +libc_hidden_def (__chown) +weak_alias (__chown, chown) diff --git a/sysdeps/unix/sysv/linux/sh/fchownat.c b/sysdeps/unix/sysv/linux/sh/fchownat.c new file mode 100644 index 0000000000..dfed76aeb4 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sh/fchownat.c @@ -0,0 +1 @@ +#include <sysdeps/unix/sysv/linux/i386/fchownat.c> diff --git a/sysdeps/unix/sysv/linux/sh/fxstatat.c b/sysdeps/unix/sysv/linux/sh/fxstatat.c new file mode 100644 index 0000000000..0f8b3135d8 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sh/fxstatat.c @@ -0,0 +1 @@ +#include <sysdeps/unix/sysv/linux/i386/fxstatat.c> diff --git a/sysdeps/unix/sysv/linux/sh/makecontext.S b/sysdeps/unix/sysv/linux/sh/makecontext.S new file mode 100644 index 0000000000..877d78d396 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sh/makecontext.S @@ -0,0 +1,145 @@ +/* Create new context. + Copyright (C) 2005 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep.h> + +#include "ucontext_i.h" + +/* void __makecontext (struct ucontext *ucp, void (*func)(), int argc, ...); + __makecontext sets up a stack and registers for context to run a given + function. The registers are set up like this: + r4-r7: parameters 1 to 4 + r8 : uc_link from ucontext structure + pc : (*func) pointer + pr : address of exitcode + r15 : stack pointer for func. */ + + .text + .align 5 +ENTRY(__makecontext) + mov #4, r3 + mov.l @(oSS_SP,r4), r1 + mov.l @(oSS_SIZE,r4), r2 + add r1, r2 + cmp/gt r6, r3 + bf/s 1f + shlr2 r2 + sub r6, r2 + add r3, r2 +1: + shll2 r2 + mov #oR15, r0 + mov.l @(oLINK,r4), r1 + mov.l r2, @(r0,r4) + mov.l r1, @(oR8,r4) + mov #oPC, r0 + mov.l r5, @(r0,r4) + + cmp/pl r6 + bf/s .L1 + dt r6 + mov.l r7, @(oR4,r4) + cmp/pl r6 + bf/s .L1 + dt r6 + mov.l @(0,r15), r1 + mov.l r1, @(oR5,r4) + cmp/pl r6 + bf/s .L1 + dt r6 + mov.l @(4,r15), r1 + mov.l r1, @(oR6,r4) + cmp/pl r6 + bf/s .L1 + dt r6 + mov.l @(8,r15), r1 + mov.l r1, @(oR7,r4) + mov #12,r0 +.L0: + cmp/pl r6 + bf/s .L1 + dt r6 + mov.l @(r0,r15), r1 + mov.l r1, @r2 + add #4, r0 + bra .L0 + add #4, r2 +.L1: +#ifdef PIC + mova .Lexitcode, r0 +#else + mov.l .L2, r0 +#endif + add #oPR, r4 + rts + mov.l r0, @r4 +#ifndef PIC + .align 2 +.L2: + .long .Lexitcode +#endif + cfi_endproc + + .align 5 +.Lexitcode: + tst r8, r8 + bt/s 2f + mov r8, r4 +#ifdef PIC + mova .Lgot, r0 + mov.l .Lgot, r12 + add r0, r12 + mov.l .L3, r1 + bsrf r1 +.LPCS0: + nop +#else + mov.l .L3, r1 + jsr @r1 + nop +#endif +2: + mov.l .L4, r1 +#ifdef PIC + add r12, r1 +#endif + jsr @r1 + mov r0, r4 +0: + bra 0b + nop + + .align 2 +#ifdef PIC +.Lgot: + .long _GLOBAL_OFFSET_TABLE_ +.L3: + .long __setcontext@PLT-(.LPCS0+2-(.)) +.L4: + .long HIDDEN_JUMPTARGET(exit)@GOTOFF +#else +.L3: + .long __setcontext +.L4: + .long HIDDEN_JUMPTARGET(exit) +#endif + cfi_startproc +PSEUDO_END(__makecontext) + +weak_alias (__makecontext, makecontext) diff --git a/sysdeps/unix/sysv/linux/sh/pread.c b/sysdeps/unix/sysv/linux/sh/pread.c index 9ded53ebaa..0186e40c9c 100644 --- a/sysdeps/unix/sysv/linux/sh/pread.c +++ b/sysdeps/unix/sysv/linux/sh/pread.c @@ -1,3 +1,93 @@ -#define NO_SGIDEFS_H -#define _MIPS_SIM -1 -#include <sysdeps/unix/sysv/linux/mips/pread.c> +/* Copyright (C) 1997, 1998, 2000, 2002, 2003, 2004, 2006 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <assert.h> +#include <errno.h> +#include <unistd.h> +#include <endian.h> + +#include <sysdep-cancel.h> +#include <sys/syscall.h> +#include <bp-checks.h> + +#include <kernel-features.h> + +#ifdef __NR_pread64 /* Newer kernels renamed but it's the same. */ +# ifdef __NR_pread +# error "__NR_pread and __NR_pread64 both defined???" +# endif +# define __NR_pread __NR_pread64 +#endif + +#if defined __NR_pread || __ASSUME_PREAD_SYSCALL > 0 + +# if __ASSUME_PREAD_SYSCALL == 0 +static ssize_t __emulate_pread (int fd, void *buf, size_t count, + off_t offset) internal_function; +# endif + +ssize_t +__libc_pread (fd, buf, count, offset) + int fd; + void *buf; + size_t count; + off_t offset; +{ + ssize_t result; + + if (SINGLE_THREAD_P) + { + /* First try the syscall. */ + result = INLINE_SYSCALL (pread, 6, fd, CHECK_N (buf, count), count, 0, + __LONG_LONG_PAIR (offset >> 31, offset)); +# if __ASSUME_PREAD_SYSCALL == 0 + if (result == -1 && errno == ENOSYS) + /* No system call available. Use the emulation. */ + result = __emulate_pread (fd, buf, count, offset); +# endif + return result; + } + + int oldtype = LIBC_CANCEL_ASYNC (); + + /* First try the syscall. */ + result = INLINE_SYSCALL (pread, 6, fd, CHECK_N (buf, count), count, 0, + __LONG_LONG_PAIR (offset >> 31, offset)); +# if __ASSUME_PREAD_SYSCALL == 0 + if (result == -1 && errno == ENOSYS) + /* No system call available. Use the emulation. */ + result = __emulate_pread (fd, buf, count, offset); +# endif + + LIBC_CANCEL_RESET (oldtype); + + return result; +} + +strong_alias (__libc_pread, __pread) +weak_alias (__libc_pread, pread) + +# define __libc_pread(fd, buf, count, offset) \ + static internal_function __emulate_pread (fd, buf, count, offset) +#endif + +#if __ASSUME_PREAD_SYSCALL == 0 +# include <sysdeps/posix/pread.c> +#endif diff --git a/sysdeps/unix/sysv/linux/sh/pread64.c b/sysdeps/unix/sysv/linux/sh/pread64.c index 5b22a395ec..f23d619090 100644 --- a/sysdeps/unix/sysv/linux/sh/pread64.c +++ b/sysdeps/unix/sysv/linux/sh/pread64.c @@ -1,3 +1,94 @@ -#define NO_SGIDEFS_H -#define _MIPS_SIM -1 -#include <sysdeps/unix/sysv/linux/mips/pread64.c> +/* Copyright (C) 1997, 1998, 2000, 2002, 2003, 2004, 2006 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <unistd.h> +#include <endian.h> + +#include <sysdep-cancel.h> +#include <sys/syscall.h> +#include <bp-checks.h> + +#include <kernel-features.h> + +#ifdef __NR_pread64 /* Newer kernels renamed but it's the same. */ +# ifdef __NR_pread +# error "__NR_pread and __NR_pread64 both defined???" +# endif +# define __NR_pread __NR_pread64 +#endif + +#if defined __NR_pread || __ASSUME_PREAD_SYSCALL > 0 + +# if __ASSUME_PREAD_SYSCALL == 0 +static ssize_t __emulate_pread64 (int fd, void *buf, size_t count, + off64_t offset) internal_function; +# endif + +ssize_t +__libc_pread64 (fd, buf, count, offset) + int fd; + void *buf; + size_t count; + off64_t offset; +{ + ssize_t result; + + if (SINGLE_THREAD_P) + { + /* First try the syscall. */ + result = INLINE_SYSCALL (pread, 6, fd, CHECK_N (buf, count), count, 0, + __LONG_LONG_PAIR ((off_t) (offset >> 32), + (off_t) (offset & 0xffffffff))); +# if __ASSUME_PREAD_SYSCALL == 0 + if (result == -1 && errno == ENOSYS) + /* No system call available. Use the emulation. */ + result = __emulate_pread64 (fd, buf, count, offset); +# endif + return result; + } + + int oldtype = LIBC_CANCEL_ASYNC (); + + /* First try the syscall. */ + result = INLINE_SYSCALL (pread, 6, fd, CHECK_N (buf, count), count, 0, + __LONG_LONG_PAIR ((off_t) (offset >> 32), + (off_t) (offset & 0xffffffff))); +# if __ASSUME_PREAD_SYSCALL == 0 + if (result == -1 && errno == ENOSYS) + /* No system call available. Use the emulation. */ + result = __emulate_pread64 (fd, buf, count, offset); +# endif + + LIBC_CANCEL_RESET (oldtype); + + return result; +} + +weak_alias (__libc_pread64, __pread64) +weak_alias (__libc_pread64, pread64) + +# define __libc_pread64(fd, buf, count, offset) \ + static internal_function __emulate_pread64 (fd, buf, count, offset) +#endif + +#if __ASSUME_PREAD_SYSCALL == 0 +# include <sysdeps/posix/pread64.c> +#endif diff --git a/sysdeps/unix/sysv/linux/sh/pwrite.c b/sysdeps/unix/sysv/linux/sh/pwrite.c index b75a6a968e..f0e2bc7e0f 100644 --- a/sysdeps/unix/sysv/linux/sh/pwrite.c +++ b/sysdeps/unix/sysv/linux/sh/pwrite.c @@ -1,3 +1,93 @@ -#define NO_SGIDEFS_H -#define _MIPS_SIM -1 -#include <sysdeps/unix/sysv/linux/mips/pwrite.c> +/* Copyright (C) 1997, 1998, 2000, 2002, 2003, 2004, 2006 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <assert.h> +#include <errno.h> +#include <unistd.h> +#include <endian.h> + +#include <sysdep-cancel.h> +#include <sys/syscall.h> +#include <bp-checks.h> + +#include <kernel-features.h> + +#ifdef __NR_pwrite64 /* Newer kernels renamed but it's the same. */ +# ifdef __NR_pwrite +# error "__NR_pwrite and __NR_pwrite64 both defined???" +# endif +# define __NR_pwrite __NR_pwrite64 +#endif + +#if defined __NR_pwrite || __ASSUME_PWRITE_SYSCALL > 0 + +# if __ASSUME_PWRITE_SYSCALL == 0 +static ssize_t __emulate_pwrite (int fd, const void *buf, size_t count, + off_t offset) internal_function; +# endif + +ssize_t +__libc_pwrite (fd, buf, count, offset) + int fd; + const void *buf; + size_t count; + off_t offset; +{ + ssize_t result; + + if (SINGLE_THREAD_P) + { + /* First try the syscall. */ + result = INLINE_SYSCALL (pwrite, 6, fd, CHECK_N (buf, count), count, 0, + __LONG_LONG_PAIR (offset >> 31, offset)); +# if __ASSUME_PWRITE_SYSCALL == 0 + if (result == -1 && errno == ENOSYS) + /* No system call available. Use the emulation. */ + result = __emulate_pwrite (fd, buf, count, offset); +# endif + return result; + } + + int oldtype = LIBC_CANCEL_ASYNC (); + + /* First try the syscall. */ + result = INLINE_SYSCALL (pwrite, 6, fd, CHECK_N (buf, count), count, 0, + __LONG_LONG_PAIR (offset >> 31, offset)); +# if __ASSUME_PWRITE_SYSCALL == 0 + if (result == -1 && errno == ENOSYS) + /* No system call available. Use the emulation. */ + result = __emulate_pwrite (fd, buf, count, offset); +# endif + + LIBC_CANCEL_RESET (oldtype); + + return result; +} + +strong_alias (__libc_pwrite, __pwrite) +weak_alias (__libc_pwrite, pwrite) + +# define __libc_pwrite(fd, buf, count, offset) \ + static internal_function __emulate_pwrite (fd, buf, count, offset) +#endif + +#if __ASSUME_PWRITE_SYSCALL == 0 +# include <sysdeps/posix/pwrite.c> +#endif diff --git a/sysdeps/unix/sysv/linux/sh/pwrite64.c b/sysdeps/unix/sysv/linux/sh/pwrite64.c index ae29280f85..eb1e507287 100644 --- a/sysdeps/unix/sysv/linux/sh/pwrite64.c +++ b/sysdeps/unix/sysv/linux/sh/pwrite64.c @@ -1,3 +1,96 @@ -#define NO_SGIDEFS_H -#define _MIPS_SIM -1 -#include <sysdeps/unix/sysv/linux/mips/pwrite64.c> +/* Copyright (C) 1997, 1998, 2000, 2002, 2003, 2004, 2006 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ralf Baechle <ralf@gnu.org>, 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <unistd.h> +#include <endian.h> + +#include <sysdep-cancel.h> +#include <sys/syscall.h> +#include <bp-checks.h> + +#include <kernel-features.h> + +#ifdef __NR_pwrite64 /* Newer kernels renamed but it's the same. */ +# ifdef __NR_pwrite +# error "__NR_pwrite and __NR_pwrite64 both defined???" +# endif +# define __NR_pwrite __NR_pwrite64 +#endif + +#if defined __NR_pwrite || __ASSUME_PWRITE_SYSCALL > 0 + +# if __ASSUME_PWRITE_SYSCALL == 0 +static ssize_t __emulate_pwrite64 (int fd, const void *buf, size_t count, + off64_t offset) internal_function; +# endif + +ssize_t +__libc_pwrite64 (fd, buf, count, offset) + int fd; + const void *buf; + size_t count; + off64_t offset; +{ + ssize_t result; + + if (SINGLE_THREAD_P) + { + /* First try the syscall. */ + result = INLINE_SYSCALL (pwrite, 6, fd, CHECK_N (buf, count), count, 0, + __LONG_LONG_PAIR ((off_t) (offset >> 32), + (off_t) (offset & 0xffffffff))); +# if __ASSUME_PWRITE_SYSCALL == 0 + if (result == -1 && errno == ENOSYS) + /* No system call available. Use the emulation. */ + result = __emulate_pwrite64 (fd, buf, count, offset); +# endif + + return result; + } + + int oldtype = LIBC_CANCEL_ASYNC (); + + /* First try the syscall. */ + result = INLINE_SYSCALL (pwrite, 6, fd, CHECK_N (buf, count), count, 0, + __LONG_LONG_PAIR ((off_t) (offset >> 32), + (off_t) (offset & 0xffffffff))); +# if __ASSUME_PWRITE_SYSCALL == 0 + if (result == -1 && errno == ENOSYS) + /* No system call available. Use the emulation. */ + result = __emulate_pwrite64 (fd, buf, count, offset); +# endif + + LIBC_CANCEL_RESET (oldtype); + + return result; +} + +weak_alias (__libc_pwrite64, __pwrite64) +libc_hidden_weak (__pwrite64) +weak_alias (__libc_pwrite64, pwrite64) + +# define __libc_pwrite64(fd, buf, count, offset) \ + static internal_function __emulate_pwrite64 (fd, buf, count, offset) +#endif + +#if __ASSUME_PWRITE_SYSCALL == 0 +# include <sysdeps/posix/pwrite64.c> +#endif diff --git a/sysdeps/unix/sysv/linux/sh/sh3/getcontext.S b/sysdeps/unix/sysv/linux/sh/sh3/getcontext.S new file mode 100644 index 0000000000..66b3daaa3b --- /dev/null +++ b/sysdeps/unix/sysv/linux/sh/sh3/getcontext.S @@ -0,0 +1,88 @@ +/* Save current context. + Copyright (C) 2005 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep.h> + +#include "ucontext_i.h" + +/* int __getcontext (ucontext_t *uc); */ + + .text + .align 5 +ENTRY(__getcontext) + + /* Return value of getcontext. R0 is the only register whose + value is not preserved. */ + mov #0, r0 + mov.l r0, @(oR0,r4) + mov.l r1, @(oR1,r4) + mov.l r2, @(oR2,r4) + mov.l r3, @(oR3,r4) + mov.l r4, @(oR4,r4) + mov.l r5, @(oR5,r4) + mov.l r6, @(oR6,r4) + mov.l r7, @(oR7,r4) + mov r4, r0 + add #(oMACL+4), r0 + sts.l macl, @-r0 + sts.l mach, @-r0 + stc.l gbr, @-r0 + + /* Save T flag to SR. */ + movt r1 + mov.l r1, @-r0 + sts.l pr, @-r0 + + /* The return address of getcontext is the restart pc. */ + sts.l pr, @-r0 + + mov.l r15, @-r0 + mov.l r14, @-r0 + mov.l r13, @-r0 + mov.l r12, @-r0 + mov.l r11, @-r0 + mov.l r10, @-r0 + mov.l r9, @-r0 + mov.l r8, @-r0 + + /* sigprocmask (SIG_BLOCK, NULL, &uc->uc_sigmask). */ + mov r4, r6 + add #oSIGMASK, r6 + mov #SIG_BLOCK, r4 + mov #0, r5 + mov #+SYS_ify(sigprocmask), r3 + trapa #0x13 + 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 .Lgetcontext_end +.Lsyscall_error: + SYSCALL_ERROR_HANDLER +.Lgetcontext_end: + /* All done, return 0 for success. */ + mov #0, r0 +.Lpseudo_end: + rts + nop + +PSEUDO_END(__getcontext) + +weak_alias (__getcontext, getcontext) diff --git a/sysdeps/unix/sysv/linux/sh/sh3/setcontext.S b/sysdeps/unix/sysv/linux/sh/sh3/setcontext.S new file mode 100644 index 0000000000..3136267aca --- /dev/null +++ b/sysdeps/unix/sysv/linux/sh/sh3/setcontext.S @@ -0,0 +1,99 @@ +/* Install given context. + Copyright (C) 2005 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep.h> + +#include "ucontext_i.h" + +/* int __setcontext (const ucontext_t *uc); */ + + .text + .align 5 +ENTRY(__setcontext) + + mov r4, r8 + + /* sigprocmask (SIG_SETMASK, &uc->uc_sigmask, NULL). */ + mov r4, r5 + add #oSIGMASK, r5 + mov #SIG_SETMASK, r4 + mov #0, r6 + mov #+SYS_ify(sigprocmask), r3 + trapa #0x13 + 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 .Lsetcontext_restore +.Lsyscall_error: + SYSCALL_ERROR_HANDLER +.Lpseudo_end: + rts + nop + +.Lsetcontext_restore: + mov r8, r0 + add #(oPC), r0 + mov.l @r0+, r2 + lds.l @r0+, pr + + /* Restore T frag. */ + mov.l @r0+, r1 + shlr r1 + /* Skip GBR which is used for thread pointer. */ + add #4, r0 + + lds.l @r0+, mach + lds.l @r0+, macl + + mov r8, r0 + add #(oR9), r0 + mov.l @r0+, r9 + mov.l @r0+, r10 + mov.l @r0+, r11 + mov.l @r0+, r12 + mov.l @r0+, r13 + mov.l @r0+, r14 + mov.l @r0+, r15 + + mov r8, r0 + mov.l @(oR0,r0), r1 + mov.l r1, @-r15 + cfi_adjust_cfa_offset(4) + cfi_rel_offset (r1, 0) + mov.l r2, @-r15 + cfi_adjust_cfa_offset(4) + cfi_rel_offset (r2, 0) + + mov.l @(oR1,r0), r1 + mov.l @(oR2,r0), r2 + mov.l @(oR3,r0), r3 + mov.l @(oR4,r0), r4 + mov.l @(oR5,r0), r5 + mov.l @(oR6,r0), r6 + mov.l @(oR7,r0), r7 + mov.l @(oR8,r0), r8 + mov.l @r15+, r0 + jmp @r0 + mov.l @r15+, r0 + +PSEUDO_END(__setcontext) + +weak_alias (__setcontext, setcontext) diff --git a/sysdeps/unix/sysv/linux/sh/sh3/swapcontext.S b/sysdeps/unix/sysv/linux/sh/sh3/swapcontext.S new file mode 100644 index 0000000000..64035e5545 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sh/sh3/swapcontext.S @@ -0,0 +1,132 @@ +/* Save current context and install the given one. + Copyright (C) 2005 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep.h> + +#include "ucontext_i.h" + +/* int __swapcontext (ucontext_t *ouc, const ucontext_t *uc); */ + + .text + .align 5 +ENTRY(__swapcontext) + + /* Return value of getcontext. R0 is the only register whose + value is not preserved. */ + mov #0, r0 + mov.l r0, @(oR0,r4) + mov.l r1, @(oR1,r4) + mov.l r2, @(oR2,r4) + mov.l r3, @(oR3,r4) + mov.l r4, @(oR4,r4) + mov.l r5, @(oR5,r4) + mov.l r6, @(oR6,r4) + mov.l r7, @(oR7,r4) + mov r4, r0 + add #(oMACL+4), r0 + sts.l macl, @-r0 + sts.l mach, @-r0 + stc.l gbr, @-r0 + + /* Save T flag to SR. */ + movt r1 + mov.l r1, @-r0 + sts.l pr, @-r0 + + /* The return address of getcontext is the restart pc. */ + sts.l pr, @-r0 + + mov.l r15, @-r0 + mov.l r14, @-r0 + mov.l r13, @-r0 + mov.l r12, @-r0 + mov.l r11, @-r0 + mov.l r10, @-r0 + mov.l r9, @-r0 + mov.l r8, @-r0 + + mov r5, r8 + + /* sigprocmask (SIG_SETMASK, &uc->uc_sigmask, &ouc->uc_sigmask). */ + add #oSIGMASK, r5 + mov r4, r6 + add #oSIGMASK, r6 + mov #SIG_SETMASK, r4 + mov #+SYS_ify(sigprocmask), r3 + trapa #0x13 + 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 .Lswapcontext_restore +.Lsyscall_error: + SYSCALL_ERROR_HANDLER +.Lpseudo_end: + rts + nop +.Lswapcontext_restore: + mov r8, r0 + add #(oPC), r0 + mov.l @r0+, r2 + lds.l @r0+, pr + + /* Restore T frag. */ + mov.l @r0+, r1 + shlr r1 + /* Skip GBR which is used for thread pointer. */ + add #4, r0 + + lds.l @r0+, mach + lds.l @r0+, macl + + mov r8, r0 + add #(oR9), r0 + mov.l @r0+, r9 + mov.l @r0+, r10 + mov.l @r0+, r11 + mov.l @r0+, r12 + mov.l @r0+, r13 + mov.l @r0+, r14 + mov.l @r0+, r15 + + mov r8, r0 + mov.l @(oR0,r0), r1 + mov.l r1, @-r15 + cfi_adjust_cfa_offset(4) + cfi_rel_offset (r1, 0) + mov.l r2, @-r15 + cfi_adjust_cfa_offset(4) + cfi_rel_offset (r2, 0) + + mov.l @(oR1,r0), r1 + mov.l @(oR2,r0), r2 + mov.l @(oR3,r0), r3 + mov.l @(oR4,r0), r4 + mov.l @(oR5,r0), r5 + mov.l @(oR6,r0), r6 + mov.l @(oR7,r0), r7 + mov.l @(oR8,r0), r8 + mov.l @r15+, r0 + jmp @r0 + mov.l @r15+, r0 + +PSEUDO_END(__swapcontext) + +weak_alias (__swapcontext, swapcontext) diff --git a/sysdeps/unix/sysv/linux/sh/sh3/sys/ucontext.h b/sysdeps/unix/sysv/linux/sh/sh3/sys/ucontext.h new file mode 100644 index 0000000000..946df0dfd6 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sh/sh3/sys/ucontext.h @@ -0,0 +1,102 @@ +/* Copyright (C) 1999, 2000, 2001, 2005 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* Where is System V/SH ABI? */ + +#ifndef _SYS_UCONTEXT_H +#define _SYS_UCONTEXT_H 1 + +#include <features.h> +#include <signal.h> + +/* We need the signal context definitions even if they are not used + included in <signal.h>. */ +#include <bits/sigcontext.h> + + +typedef int greg_t; + +/* Number of general registers. */ +#define NFPREG 16 + +/* Container for all general registers. */ +typedef greg_t gregset_t[NFPREG]; + +#ifdef __USE_GNU +/* Number of each register is the `gregset_t' array. */ +enum +{ + R0 = 0, +#define R0 R0 + R1 = 1, +#define R1 R1 + R2 = 2, +#define R2 R2 + R3 = 3, +#define R3 R3 + R4 = 4, +#define R4 R4 + R5 = 5, +#define R5 R5 + R6 = 6, +#define R6 R6 + R7 = 7, +#define R7 R7 + R8 = 8, +#define R8 R8 + R9 = 9, +#define R9 R9 + R10 = 10, +#define R10 R10 + R11 = 11, +#define R11 R11 + R12 = 12, +#define R12 R12 + R13 = 13, +#define R13 R13 + R14 = 14, +#define R14 R14 + R15 = 15, +#define R15 R15 +}; +#endif + +/* Context to describe whole processor state. */ +typedef struct + { + unsigned int oldmask; + gregset_t gregs; + unsigned int pc; + unsigned int pr; + unsigned int sr; + unsigned int gbr; + unsigned int mach; + unsigned int macl; + } mcontext_t; + +/* Userlevel context. */ +typedef struct ucontext + { + unsigned long int uc_flags; + struct ucontext *uc_link; + stack_t uc_stack; + mcontext_t uc_mcontext; + __sigset_t uc_sigmask; + } ucontext_t; + +#endif /* sys/ucontext.h */ diff --git a/sysdeps/unix/sysv/linux/sh/sh3/ucontext_i.sym b/sysdeps/unix/sysv/linux/sh/sh3/ucontext_i.sym new file mode 100644 index 0000000000..17397c5511 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sh/sh3/ucontext_i.sym @@ -0,0 +1,38 @@ +#include <stddef.h> +#include <signal.h> +#include <sys/ucontext.h> + +-- + +SIG_BLOCK +SIG_SETMASK + +#define ucontext(member) offsetof (ucontext_t, member) +#define mcontext(member) ucontext (uc_mcontext.member) + +oLINK ucontext (uc_link) +oSS_SP ucontext (uc_stack.ss_sp) +oSS_SIZE ucontext (uc_stack.ss_size) +oR0 mcontext (gregs[R0]) +oR1 mcontext (gregs[R1]) +oR2 mcontext (gregs[R2]) +oR3 mcontext (gregs[R3]) +oR4 mcontext (gregs[R4]) +oR5 mcontext (gregs[R5]) +oR6 mcontext (gregs[R6]) +oR7 mcontext (gregs[R7]) +oR8 mcontext (gregs[R8]) +oR9 mcontext (gregs[R9]) +oR10 mcontext (gregs[R10]) +oR11 mcontext (gregs[R11]) +oR12 mcontext (gregs[R12]) +oR13 mcontext (gregs[R13]) +oR14 mcontext (gregs[R14]) +oR15 mcontext (gregs[R15]) +oPC mcontext (pc) +oPR mcontext (pr) +oSR mcontext (sr) +oGBR mcontext (gbr) +oMACH mcontext (mach) +oMACL mcontext (macl) +oSIGMASK ucontext (uc_sigmask) diff --git a/sysdeps/unix/sysv/linux/sh/sh4/getcontext.S b/sysdeps/unix/sysv/linux/sh/sh4/getcontext.S new file mode 100644 index 0000000000..68bc235bcf --- /dev/null +++ b/sysdeps/unix/sysv/linux/sh/sh4/getcontext.S @@ -0,0 +1,131 @@ +/* Save current context. + Copyright (C) 2005 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep.h> + +#include "ucontext_i.h" + +/* int __getcontext (ucontext_t *uc); */ + + .text + .align 5 +ENTRY(__getcontext) + + /* Return value of getcontext. R0 is the only register whose + value is not preserved. */ + mov #0, r0 + mov.l r0, @(oR0,r4) + mov.l r1, @(oR1,r4) + mov.l r2, @(oR2,r4) + mov.l r3, @(oR3,r4) + mov.l r4, @(oR4,r4) + mov.l r5, @(oR5,r4) + mov.l r6, @(oR6,r4) + mov.l r7, @(oR7,r4) + mov r4, r0 + add #(oMACL+4), r0 + sts.l macl, @-r0 + sts.l mach, @-r0 + stc.l gbr, @-r0 + + /* Save T flag to SR. */ + movt r1 + mov.l r1, @-r0 + sts.l pr, @-r0 + + /* The return address of getcontext is the restart pc. */ + sts.l pr, @-r0 + + mov.l r15, @-r0 + mov.l r14, @-r0 + mov.l r13, @-r0 + mov.l r12, @-r0 + mov.l r11, @-r0 + mov.l r10, @-r0 + mov.l r9, @-r0 + mov.l r8, @-r0 + + mov r4, r0 + /* We need 2 add instruction because oFPUL+4 > 127. */ + add #124,r0 + add #(oFPUL+4-124),r0 + sts.l fpul, @-r0 + sts.l fpscr, @-r0 + frchg + fmov.s fr15, @-r0 + fmov.s fr14, @-r0 + fmov.s fr13, @-r0 + fmov.s fr12, @-r0 + fmov.s fr11, @-r0 + fmov.s fr10, @-r0 + fmov.s fr9, @-r0 + fmov.s fr8, @-r0 + fmov.s fr7, @-r0 + fmov.s fr6, @-r0 + fmov.s fr5, @-r0 + fmov.s fr4, @-r0 + fmov.s fr3, @-r0 + fmov.s fr2, @-r0 + fmov.s fr1, @-r0 + fmov.s fr0, @-r0 + frchg + fmov.s fr15, @-r0 + fmov.s fr14, @-r0 + fmov.s fr13, @-r0 + fmov.s fr12, @-r0 + fmov.s fr11, @-r0 + fmov.s fr10, @-r0 + fmov.s fr9, @-r0 + fmov.s fr8, @-r0 + fmov.s fr7, @-r0 + fmov.s fr6, @-r0 + fmov.s fr5, @-r0 + fmov.s fr4, @-r0 + fmov.s fr3, @-r0 + fmov.s fr2, @-r0 + fmov.s fr1, @-r0 + fmov.s fr0, @-r0 + + /* sigprocmask (SIG_BLOCK, NULL, &uc->uc_sigmask). */ + mov r4, r6 + /* We need 2 add instruction because oSIGMASK > 127. */ + add #(oSIGMASK/2), r6 + add #(oSIGMASK/2), r6 + mov #SIG_BLOCK, r4 + mov #0, r5 + mov #+SYS_ify(sigprocmask), r3 + trapa #0x13 + 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 .Lgetcontext_end +.Lsyscall_error: + SYSCALL_ERROR_HANDLER +.Lgetcontext_end: + /* All done, return 0 for success. */ + mov #0, r0 +.Lpseudo_end: + rts + nop + +PSEUDO_END(__getcontext) + +weak_alias (__getcontext, getcontext) diff --git a/sysdeps/unix/sysv/linux/sh/sh4/setcontext.S b/sysdeps/unix/sysv/linux/sh/sh4/setcontext.S new file mode 100644 index 0000000000..2bc546d1a1 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sh/sh4/setcontext.S @@ -0,0 +1,139 @@ +/* Install given context. + Copyright (C) 2005 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep.h> + +#include "ucontext_i.h" + +/* int __setcontext (const ucontext_t *uc); */ + + .text + .align 5 +ENTRY(__setcontext) + + mov r4, r8 + + /* sigprocmask (SIG_SETMASK, &uc->uc_sigmask, NULL). */ + mov r4, r5 + add #(oSIGMASK/2), r5 + add #(oSIGMASK/2), r5 + mov #SIG_SETMASK, r4 + mov #0, r6 + mov #+SYS_ify(sigprocmask), r3 + trapa #0x13 + 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 .Lsetcontext_restore +.Lsyscall_error: + SYSCALL_ERROR_HANDLER +.Lpseudo_end: + rts + nop + +.Lsetcontext_restore: + mov r8, r0 + add #(oFR0),r0 + fmov.s @r0+, fr0 + fmov.s @r0+, fr1 + fmov.s @r0+, fr2 + fmov.s @r0+, fr3 + fmov.s @r0+, fr4 + fmov.s @r0+, fr5 + fmov.s @r0+, fr6 + fmov.s @r0+, fr7 + fmov.s @r0+, fr8 + fmov.s @r0+, fr9 + fmov.s @r0+, fr10 + fmov.s @r0+, fr11 + fmov.s @r0+, fr12 + fmov.s @r0+, fr13 + fmov.s @r0+, fr14 + fmov.s @r0+, fr15 + frchg + fmov.s @r0+, fr0 + fmov.s @r0+, fr1 + fmov.s @r0+, fr2 + fmov.s @r0+, fr3 + fmov.s @r0+, fr4 + fmov.s @r0+, fr5 + fmov.s @r0+, fr6 + fmov.s @r0+, fr7 + fmov.s @r0+, fr8 + fmov.s @r0+, fr9 + fmov.s @r0+, fr10 + fmov.s @r0+, fr11 + fmov.s @r0+, fr12 + fmov.s @r0+, fr13 + fmov.s @r0+, fr14 + fmov.s @r0+, fr15 + frchg + lds.l @r0+, fpscr + lds.l @r0+, fpul + + mov r8, r0 + add #(oPC), r0 + mov.l @r0+, r2 + lds.l @r0+, pr + + /* Restore T frag. */ + mov.l @r0+, r1 + shlr r1 + /* Skip GBR which is used for thread pointer. */ + add #4, r0 + + lds.l @r0+, mach + lds.l @r0+, macl + + mov r8, r0 + add #(oR9), r0 + mov.l @r0+, r9 + mov.l @r0+, r10 + mov.l @r0+, r11 + mov.l @r0+, r12 + mov.l @r0+, r13 + mov.l @r0+, r14 + mov.l @r0+, r15 + + mov r8, r0 + mov.l @(oR0,r0), r1 + mov.l r1, @-r15 + cfi_adjust_cfa_offset(4) + cfi_rel_offset (r1, 0) + mov.l r2, @-r15 + cfi_adjust_cfa_offset(4) + cfi_rel_offset (r2, 0) + + mov.l @(oR1,r0), r1 + mov.l @(oR2,r0), r2 + mov.l @(oR3,r0), r3 + mov.l @(oR4,r0), r4 + mov.l @(oR5,r0), r5 + mov.l @(oR6,r0), r6 + mov.l @(oR7,r0), r7 + mov.l @(oR8,r0), r8 + mov.l @r15+, r0 + jmp @r0 + mov.l @r15+, r0 + +PSEUDO_END(__setcontext) + +weak_alias (__setcontext, setcontext) diff --git a/sysdeps/unix/sysv/linux/sh/sh4/swapcontext.S b/sysdeps/unix/sysv/linux/sh/sh4/swapcontext.S new file mode 100644 index 0000000000..1aeca1b1a7 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sh/sh4/swapcontext.S @@ -0,0 +1,214 @@ +/* Save current context and install the given one. + Copyright (C) 2005 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep.h> + +#include "ucontext_i.h" + +/* int __swapcontext (ucontext_t *ouc, const ucontext_t *uc); */ + + .text + .align 5 +ENTRY(__swapcontext) + + /* Return value of getcontext. R0 is the only register whose + value is not preserved. */ + mov #0, r0 + mov.l r0, @(oR0,r4) + mov.l r1, @(oR1,r4) + mov.l r2, @(oR2,r4) + mov.l r3, @(oR3,r4) + mov.l r4, @(oR4,r4) + mov.l r5, @(oR5,r4) + mov.l r6, @(oR6,r4) + mov.l r7, @(oR7,r4) + mov r4, r0 + add #(oMACL+4), r0 + sts.l macl, @-r0 + sts.l mach, @-r0 + stc.l gbr, @-r0 + + /* Save T flag to SR. */ + movt r1 + mov.l r1, @-r0 + sts.l pr, @-r0 + + /* The return address of getcontext is the restart pc. */ + sts.l pr, @-r0 + + mov.l r15, @-r0 + mov.l r14, @-r0 + mov.l r13, @-r0 + mov.l r12, @-r0 + mov.l r11, @-r0 + mov.l r10, @-r0 + mov.l r9, @-r0 + mov.l r8, @-r0 + + mov r4, r0 + /* We need 2 add instruction because oFPUL+4 >= 127. */ + add #124,r0 + add #(oFPUL+4-124),r0 + sts.l fpul, @-r0 + sts.l fpscr, @-r0 + frchg + fmov.s fr15, @-r0 + fmov.s fr14, @-r0 + fmov.s fr13, @-r0 + fmov.s fr12, @-r0 + fmov.s fr11, @-r0 + fmov.s fr10, @-r0 + fmov.s fr9, @-r0 + fmov.s fr8, @-r0 + fmov.s fr7, @-r0 + fmov.s fr6, @-r0 + fmov.s fr5, @-r0 + fmov.s fr4, @-r0 + fmov.s fr3, @-r0 + fmov.s fr2, @-r0 + fmov.s fr1, @-r0 + fmov.s fr0, @-r0 + frchg + fmov.s fr15, @-r0 + fmov.s fr14, @-r0 + fmov.s fr13, @-r0 + fmov.s fr12, @-r0 + fmov.s fr11, @-r0 + fmov.s fr10, @-r0 + fmov.s fr9, @-r0 + fmov.s fr8, @-r0 + fmov.s fr7, @-r0 + fmov.s fr6, @-r0 + fmov.s fr5, @-r0 + fmov.s fr4, @-r0 + fmov.s fr3, @-r0 + fmov.s fr2, @-r0 + fmov.s fr1, @-r0 + fmov.s fr0, @-r0 + + mov r5, r8 + + /* sigprocmask (SIG_SETMASK, &uc->uc_sigmask, &ouc->uc_sigmask). */ + mov #oSIGMASK, r1 + extu.b r1, r1 + add r1, r5 + mov r4, r6 + add r1, r6 + mov #SIG_SETMASK, r4 + mov #+SYS_ify(sigprocmask), r3 + trapa #0x13 + 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 .Lswapcontext_restore +.Lsyscall_error: + SYSCALL_ERROR_HANDLER +.Lpseudo_end: + rts + nop +.Lswapcontext_restore: + mov r8, r0 + add #(oFR0),r0 + fmov.s @r0+, fr0 + fmov.s @r0+, fr1 + fmov.s @r0+, fr2 + fmov.s @r0+, fr3 + fmov.s @r0+, fr4 + fmov.s @r0+, fr5 + fmov.s @r0+, fr6 + fmov.s @r0+, fr7 + fmov.s @r0+, fr8 + fmov.s @r0+, fr9 + fmov.s @r0+, fr10 + fmov.s @r0+, fr11 + fmov.s @r0+, fr12 + fmov.s @r0+, fr13 + fmov.s @r0+, fr14 + fmov.s @r0+, fr15 + frchg + fmov.s @r0+, fr0 + fmov.s @r0+, fr1 + fmov.s @r0+, fr2 + fmov.s @r0+, fr3 + fmov.s @r0+, fr4 + fmov.s @r0+, fr5 + fmov.s @r0+, fr6 + fmov.s @r0+, fr7 + fmov.s @r0+, fr8 + fmov.s @r0+, fr9 + fmov.s @r0+, fr10 + fmov.s @r0+, fr11 + fmov.s @r0+, fr12 + fmov.s @r0+, fr13 + fmov.s @r0+, fr14 + fmov.s @r0+, fr15 + frchg + lds.l @r0+, fpscr + lds.l @r0+, fpul + + mov r8, r0 + add #(oPC), r0 + mov.l @r0+, r2 + lds.l @r0+, pr + + /* Restore T frag. */ + mov.l @r0+, r1 + shlr r1 + /* Skip GBR which is used for thread pointer. */ + add #4, r0 + + lds.l @r0+, mach + lds.l @r0+, macl + + mov r8, r0 + add #(oR9), r0 + mov.l @r0+, r9 + mov.l @r0+, r10 + mov.l @r0+, r11 + mov.l @r0+, r12 + mov.l @r0+, r13 + mov.l @r0+, r14 + mov.l @r0+, r15 + + mov r8, r0 + mov.l @(oR0,r0), r1 + mov.l r1, @-r15 + cfi_adjust_cfa_offset(4) + cfi_rel_offset (r1, 0) + mov.l r2, @-r15 + cfi_adjust_cfa_offset(4) + cfi_rel_offset (r2, 0) + + mov.l @(oR1,r0), r1 + mov.l @(oR2,r0), r2 + mov.l @(oR3,r0), r3 + mov.l @(oR4,r0), r4 + mov.l @(oR5,r0), r5 + mov.l @(oR6,r0), r6 + mov.l @(oR7,r0), r7 + mov.l @(oR8,r0), r8 + mov.l @r15+, r0 + jmp @r0 + mov.l @r15+, r0 + +PSEUDO_END(__swapcontext) + +weak_alias (__swapcontext, swapcontext) diff --git a/sysdeps/unix/sysv/linux/sh/sys/ucontext.h b/sysdeps/unix/sysv/linux/sh/sh4/sys/ucontext.h index 78729c48f9..cd831a7a21 100644 --- a/sysdeps/unix/sysv/linux/sh/sys/ucontext.h +++ b/sysdeps/unix/sysv/linux/sh/sh4/sys/ucontext.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. +/* Copyright (C) 1999, 2000, 2001, 2005 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 @@ -87,13 +87,19 @@ typedef freg_t fpregset_t[NFPREG]; /* Context to describe whole processor state. */ typedef struct { + unsigned int oldmask; gregset_t gregs; + unsigned int pc; + unsigned int pr; + unsigned int sr; + unsigned int gbr; + unsigned int mach; + unsigned int macl; fpregset_t fpregs; fpregset_t xfpregs; unsigned int fpscr; unsigned int fpul; - unsigned int macl; - unsigned int mach; + unsigned int ownedfp; } mcontext_t; /* Userlevel context. */ diff --git a/sysdeps/unix/sysv/linux/sh/sh4/ucontext_i.sym b/sysdeps/unix/sysv/linux/sh/sh4/ucontext_i.sym new file mode 100644 index 0000000000..65633fbcf4 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sh/sh4/ucontext_i.sym @@ -0,0 +1,73 @@ +#include <stddef.h> +#include <signal.h> +#include <sys/ucontext.h> + +-- + +SIG_BLOCK +SIG_SETMASK + +#define ucontext(member) offsetof (ucontext_t, member) +#define mcontext(member) ucontext (uc_mcontext.member) + +oLINK ucontext (uc_link) +oSS_SP ucontext (uc_stack.ss_sp) +oSS_SIZE ucontext (uc_stack.ss_size) +oR0 mcontext (gregs[R0]) +oR1 mcontext (gregs[R1]) +oR2 mcontext (gregs[R2]) +oR3 mcontext (gregs[R3]) +oR4 mcontext (gregs[R4]) +oR5 mcontext (gregs[R5]) +oR6 mcontext (gregs[R6]) +oR7 mcontext (gregs[R7]) +oR8 mcontext (gregs[R8]) +oR9 mcontext (gregs[R9]) +oR10 mcontext (gregs[R10]) +oR11 mcontext (gregs[R11]) +oR12 mcontext (gregs[R12]) +oR13 mcontext (gregs[R13]) +oR14 mcontext (gregs[R14]) +oR15 mcontext (gregs[R15]) +oPC mcontext (pc) +oPR mcontext (pr) +oSR mcontext (sr) +oGBR mcontext (gbr) +oMACH mcontext (mach) +oMACL mcontext (macl) +oFR0 mcontext (fpregs[0]) +oFR1 mcontext (fpregs[1]) +oFR2 mcontext (fpregs[2]) +oFR3 mcontext (fpregs[3]) +oFR4 mcontext (fpregs[4]) +oFR5 mcontext (fpregs[5]) +oFR6 mcontext (fpregs[6]) +oFR7 mcontext (fpregs[7]) +oFR8 mcontext (fpregs[8]) +oFR9 mcontext (fpregs[9]) +oFR10 mcontext (fpregs[10]) +oFR11 mcontext (fpregs[11]) +oFR12 mcontext (fpregs[12]) +oFR13 mcontext (fpregs[13]) +oFR14 mcontext (fpregs[14]) +oFR15 mcontext (fpregs[15]) +oXFR0 mcontext (xfpregs[0]) +oXFR1 mcontext (xfpregs[1]) +oXFR2 mcontext (xfpregs[2]) +oXFR3 mcontext (xfpregs[3]) +oXFR4 mcontext (xfpregs[4]) +oXFR5 mcontext (xfpregs[5]) +oXFR6 mcontext (xfpregs[6]) +oXFR7 mcontext (xfpregs[7]) +oXFR8 mcontext (xfpregs[8]) +oXFR9 mcontext (xfpregs[9]) +oXFR10 mcontext (xfpregs[10]) +oXFR11 mcontext (xfpregs[11]) +oXFR12 mcontext (xfpregs[12]) +oXFR13 mcontext (xfpregs[13]) +oXFR14 mcontext (xfpregs[14]) +oXFR15 mcontext (xfpregs[15]) +oFPSCR mcontext (fpscr) +oFPUL mcontext (fpul) +oOWNEDFP mcontext (ownedfp) +oSIGMASK ucontext (uc_sigmask) diff --git a/sysdeps/unix/sysv/linux/sh/socket.S b/sysdeps/unix/sysv/linux/sh/socket.S index f1369eb49b..c83b0f2601 100644 --- a/sysdeps/unix/sysv/linux/sh/socket.S +++ b/sysdeps/unix/sysv/linux/sh/socket.S @@ -1,4 +1,4 @@ -/* Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 1999, 2000, 2003, 2004, 2005 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 @@ -33,7 +33,11 @@ The .S files for the other calls just #define socket and #include this. */ #ifndef __socket +#ifndef NO_WEAK_ALIAS #define __socket P(__,socket) +#else +#define __socket socket +#endif #endif #define PUSHARGS_1 mov.l r4,@-r15; \ @@ -84,7 +88,6 @@ #endif .globl __socket - cfi_startproc ENTRY (__socket) /* This will not work in the case of a socket call being interrupted by a signal. If the signal handler uses any stack the arguments @@ -165,7 +168,6 @@ ENTRY (__socket) bra .Lsyscall_error nop #endif - cfi_endproc .align 2 .L1: @@ -173,4 +175,6 @@ ENTRY (__socket) PSEUDO_END (__socket) +#ifndef NO_WEAK_ALIAS weak_alias (__socket, socket) +#endif diff --git a/sysdeps/unix/sysv/linux/sh/sysdep.S b/sysdeps/unix/sysv/linux/sh/sysdep.S index 33fdc748b5..176d99aab7 100644 --- a/sysdeps/unix/sysv/linux/sh/sysdep.S +++ b/sysdeps/unix/sysv/linux/sh/sysdep.S @@ -1,4 +1,5 @@ -/* Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. +/* Copyright (C) 1995, 1996, 1997, 1998, 1999, 2005 + 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 @@ -27,6 +28,7 @@ ENTRY (__syscall_error) neg r4, r0 + cfi_endproc #define __syscall_error __syscall_error_1 #include <sysdeps/unix/sh/sysdep.S> diff --git a/sysdeps/unix/sysv/linux/sh/sysdep.h b/sysdeps/unix/sysv/linux/sh/sysdep.h index d56ec454f9..f0be37edc8 100644 --- a/sysdeps/unix/sysv/linux/sh/sysdep.h +++ b/sysdeps/unix/sysv/linux/sh/sysdep.h @@ -1,5 +1,5 @@ -/* Copyright (C) 1992,1993,1995,1996,1997,1998,1999,2000,2002,2003,2004 - Free Software Foundation, Inc. +/* Copyright (C) 1992,1993,1995,1996,1997,1998,1999,2000,2002,2003,2004, + 2005,2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>, August 1995. Changed by Kaz Kojima, <kkojima@rr.iij4u.or.jp>. @@ -24,6 +24,7 @@ /* There is some commonality. */ #include <sysdeps/unix/sh/sysdep.h> +#include <tls.h> /* For Linux we can use the system call table in the header file /usr/include/asm/unistd.h @@ -104,7 +105,7 @@ mova 0f,r0; \ add r0,r12; \ mov.l 1f,r0; \ - mov.l r1,@(r0,r12) + mov.l r1,@(r0,r12); \ bra .Lpseudo_end; \ mov _IMM1,r0; \ .align 2; \ @@ -140,13 +141,22 @@ # define SYSCALL_ERROR_HANDLER \ neg r0,r1; \ mov.l r14,@-r15; \ + cfi_adjust_cfa_offset (4); \ + cfi_rel_offset (r14, 0); \ mov.l r12,@-r15; \ + cfi_adjust_cfa_offset (4); \ + cfi_rel_offset (r12, 0); \ mov.l r1,@-r15; \ + cfi_adjust_cfa_offset (4); \ + cfi_rel_offset (r1, 0); \ mov.l 0f,r12; \ mova 0f,r0; \ add r0,r12; \ sts.l pr,@-r15; \ + cfi_adjust_cfa_offset (4); \ + cfi_rel_offset (pr, 0); \ mov r15,r14; \ + cfi_def_cfa_register (r14); \ mov.l 1f,r1; \ bsrf r1; \ nop; \ @@ -359,4 +369,23 @@ #endif /* __ASSEMBLER__ */ +/* Pointer mangling support. */ +#if defined NOT_IN_libc && defined IS_IN_rtld +/* We cannot use the thread descriptor because in ld.so we use setjmp + earlier than the descriptor is initialized. Using a global variable + is too complicated here since we have no PC-relative addressing mode. */ +#else +# ifdef __ASSEMBLER__ +# define PTR_MANGLE(reg, tmp) \ + stc gbr,tmp; mov.l @(POINTER_GUARD,tmp),tmp; xor tmp,reg +# define PTR_MANGLE2(reg, tmp) xor tmp,reg +# define PTR_DEMANGLE(reg, tmp) PTR_MANGLE (reg, tmp) +# define PTR_DEMANGLE2(reg, tmp) PTR_MANGLE2 (reg, tmp) +# else +# define PTR_MANGLE(var) \ + (var) = (void *) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ()) +# define PTR_DEMANGLE(var) PTR_MANGLE (var) +# endif +#endif + #endif /* linux/sh/sysdep.h */ |