2009-04-18 Maciej W. Rozycki <macro@codesourcery.com>
authorJoseph Myers <joseph@codesourcery.com>
Sat, 18 Apr 2009 17:32:04 +0000 (17:32 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Sat, 18 Apr 2009 17:32:04 +0000 (17:32 +0000)
* sysdeps/unix/sysv/linux/mips/getcontext.S: New file.
* sysdeps/unix/sysv/linux/mips/makecontext.S: New file.
* sysdeps/unix/sysv/linux/mips/setcontext.S: New file.
* sysdeps/unix/sysv/linux/mips/swapcontext.S: New file.
* sysdeps/unix/sysv/linux/mips/sys/ucontext.h (mcontext_t):
Update comment.
* sysdeps/unix/sysv/linux/mips/kernel_rt_sigframe.h: New file.
* sysdeps/unix/sysv/linux/mips/ucontext_i.sym: New file.
* sysdeps/unix/sysv/linux/mips/Makefile (gen-as-const-headers):
Add ucontext_i.sym.

ChangeLog.mips
sysdeps/unix/sysv/linux/mips/Makefile
sysdeps/unix/sysv/linux/mips/getcontext.S [new file with mode: 0644]
sysdeps/unix/sysv/linux/mips/kernel_rt_sigframe.h [new file with mode: 0644]
sysdeps/unix/sysv/linux/mips/makecontext.S [new file with mode: 0644]
sysdeps/unix/sysv/linux/mips/setcontext.S [new file with mode: 0644]
sysdeps/unix/sysv/linux/mips/swapcontext.S [new file with mode: 0644]
sysdeps/unix/sysv/linux/mips/sys/ucontext.h
sysdeps/unix/sysv/linux/mips/ucontext_i.sym [new file with mode: 0644]

index e8a7a11..5887530 100644 (file)
@@ -1,3 +1,16 @@
+2009-04-18  Maciej W. Rozycki  <macro@codesourcery.com>
+
+       * sysdeps/unix/sysv/linux/mips/getcontext.S: New file.
+       * sysdeps/unix/sysv/linux/mips/makecontext.S: New file.
+       * sysdeps/unix/sysv/linux/mips/setcontext.S: New file.
+       * sysdeps/unix/sysv/linux/mips/swapcontext.S: New file.
+       * sysdeps/unix/sysv/linux/mips/sys/ucontext.h (mcontext_t):
+       Update comment.
+       * sysdeps/unix/sysv/linux/mips/kernel_rt_sigframe.h: New file.
+       * sysdeps/unix/sysv/linux/mips/ucontext_i.sym: New file.
+       * sysdeps/unix/sysv/linux/mips/Makefile (gen-as-const-headers): 
+       Add ucontext_i.sym.
+
 2009-04-18  Joseph Myers  <joseph@codesourcery.com>
 
        * sysdeps/unix/sysv/linux/mips/kernel-features.h (__ASSUME_PREADV,
index 110fccb..162f1b9 100644 (file)
@@ -135,3 +135,7 @@ sysdep_routines += dl-static
 sysdep-rtld-routines += dl-static
 endif
 endif
+
+ifeq ($(subdir),stdlib)
+gen-as-const-headers += ucontext_i.sym
+endif
diff --git a/sysdeps/unix/sysv/linux/mips/getcontext.S b/sysdeps/unix/sysv/linux/mips/getcontext.S
new file mode 100644 (file)
index 0000000..1e77467
--- /dev/null
@@ -0,0 +1,149 @@
+/* Save current context.
+   Copyright (C) 2009 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Maciej W. Rozycki <macro@codesourcery.com>.
+
+   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, 51 Franklin Street - Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+#include <sys/fpregdef.h>
+#include <sys/regdef.h>
+
+#include "ucontext_i.h"
+
+/* int getcontext (ucontext_t *ucp) */
+
+       .text
+LOCALSZ = 0
+MASK = 0x00000000
+#ifdef __PIC__
+LOCALSZ = 1                                            /* save gp */
+# if _MIPS_SIM != _ABIO32
+MASK = 0x10000000
+# endif
+#endif
+FRAMESZ = ((LOCALSZ * SZREG) + ALSZ) & ALMASK
+GPOFF = FRAMESZ - (1 * SZREG)
+
+NESTED (__getcontext, FRAMESZ, ra)
+       .mask   MASK, 0
+       .fmask  0x00000000, 0
+
+#ifdef __PIC__
+       SETUP_GP
+
+       move    a2, sp
+# define _SP a2
+
+# if _MIPS_SIM != _ABIO32
+       move    a3, gp
+#  define _GP a3
+# endif
+
+       PTR_ADDIU sp, -FRAMESZ
+       SETUP_GP64 (GPOFF, __getcontext)
+       SAVE_GP (GPOFF)
+
+#else  /* ! __PIC__ */
+# define _SP sp
+# define _GP gp
+
+#endif /* ! __PIC__ */
+
+#ifdef PROF
+       .set    noat
+       move    AT, ra
+       jal     _mcount
+       .set    at
+#endif
+
+       /* Store a magic flag.  */
+       li      v1, 1
+       REG_S   v1, (0 * SZREG + MCONTEXT_GREGS)(a0)    /* zero */
+
+       REG_S   s0, (16 * SZREG + MCONTEXT_GREGS)(a0)
+       REG_S   s1, (17 * SZREG + MCONTEXT_GREGS)(a0)
+       REG_S   s2, (18 * SZREG + MCONTEXT_GREGS)(a0)
+       REG_S   s3, (19 * SZREG + MCONTEXT_GREGS)(a0)
+       REG_S   s4, (20 * SZREG + MCONTEXT_GREGS)(a0)
+       REG_S   s5, (21 * SZREG + MCONTEXT_GREGS)(a0)
+       REG_S   s6, (22 * SZREG + MCONTEXT_GREGS)(a0)
+       REG_S   s7, (23 * SZREG + MCONTEXT_GREGS)(a0)
+#if ! defined (__PIC__) || _MIPS_SIM != _ABIO32
+       REG_S   _GP, (28 * SZREG + MCONTEXT_GREGS)(a0)
+#endif
+       REG_S   _SP, (29 * SZREG + MCONTEXT_GREGS)(a0)
+       REG_S   fp, (30 * SZREG + MCONTEXT_GREGS)(a0)
+       REG_S   ra, (31 * SZREG + MCONTEXT_GREGS)(a0)
+       REG_S   ra, MCONTEXT_PC(a0)
+
+#ifdef __mips_hard_float
+# if _MIPS_SIM == _ABI64
+       s.d     fs0, (24 * SZREG + MCONTEXT_FPREGS)(a0)
+       s.d     fs1, (25 * SZREG + MCONTEXT_FPREGS)(a0)
+       s.d     fs2, (26 * SZREG + MCONTEXT_FPREGS)(a0)
+       s.d     fs3, (27 * SZREG + MCONTEXT_FPREGS)(a0)
+       s.d     fs4, (28 * SZREG + MCONTEXT_FPREGS)(a0)
+       s.d     fs5, (29 * SZREG + MCONTEXT_FPREGS)(a0)
+       s.d     fs6, (30 * SZREG + MCONTEXT_FPREGS)(a0)
+       s.d     fs7, (31 * SZREG + MCONTEXT_FPREGS)(a0)
+
+# else  /* _MIPS_SIM != _ABI64 */
+       s.d     fs0, (20 * SZREG + MCONTEXT_FPREGS)(a0)
+       s.d     fs1, (22 * SZREG + MCONTEXT_FPREGS)(a0)
+       s.d     fs2, (24 * SZREG + MCONTEXT_FPREGS)(a0)
+       s.d     fs3, (26 * SZREG + MCONTEXT_FPREGS)(a0)
+       s.d     fs4, (28 * SZREG + MCONTEXT_FPREGS)(a0)
+       s.d     fs5, (30 * SZREG + MCONTEXT_FPREGS)(a0)
+
+# endif /* _MIPS_SIM != _ABI64 */
+
+       cfc1    v1, fcr31
+       sw      v1, MCONTEXT_FPC_CSR(a0)
+#endif /* __mips_hard_float */
+
+/* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */
+       li      a3, _NSIG8
+       PTR_ADDU a2, a0, UCONTEXT_SIGMASK
+       move    a1, zero
+       li      a0, SIG_BLOCK
+
+       li      v0, SYS_ify (rt_sigprocmask)
+       syscall
+       bnez    a3, 99f
+
+#ifdef __PIC__
+       RESTORE_GP64
+       PTR_ADDIU sp, FRAMESZ
+#endif
+       move    v0, zero
+       jr      ra
+
+99:
+#ifdef __PIC__
+       PTR_LA  t9, JUMPTARGET (__syscall_error)
+       RESTORE_GP64
+       PTR_ADDIU sp, FRAMESZ
+       jr      t9
+
+#else  /* ! __PIC__ */
+
+       j       JUMPTARGET (__syscall_error)
+#endif /* ! __PIC__ */
+PSEUDO_END (__getcontext)
+
+weak_alias (__getcontext, getcontext)
diff --git a/sysdeps/unix/sysv/linux/mips/kernel_rt_sigframe.h b/sysdeps/unix/sysv/linux/mips/kernel_rt_sigframe.h
new file mode 100644 (file)
index 0000000..edf8d45
--- /dev/null
@@ -0,0 +1,10 @@
+/* Linux kernel RT signal frame. */
+typedef struct kernel_rt_sigframe
+  {
+    uint32_t rs_ass[4];
+    uint32_t rs_code[2];
+    struct siginfo rs_info;
+    struct ucontext rs_uc;
+    uint32_t rs_altcode[8] __attribute__ ((__aligned__ (1 << 7)));
+  }
+kernel_rt_sigframe_t;
diff --git a/sysdeps/unix/sysv/linux/mips/makecontext.S b/sysdeps/unix/sysv/linux/mips/makecontext.S
new file mode 100644 (file)
index 0000000..cceee3f
--- /dev/null
@@ -0,0 +1,189 @@
+/* Modify saved context.
+   Copyright (C) 2009 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Maciej W. Rozycki <macro@codesourcery.com>.
+
+   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, 51 Franklin Street - Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+#include <sys/fpregdef.h>
+#include <sys/regdef.h>
+
+#include "ucontext_i.h"
+
+/* int makecontext (ucontext_t *ucp, (void *func) (), int argc, ...) */
+
+       .text
+LOCALSZ = 0
+ARGSZ = 0
+MASK = 0x00000000
+#ifdef __PIC__
+LOCALSZ = 1                                            /* save gp */
+#endif
+#if _MIPS_SIM != _ABIO32
+ARGSZ = 5                                              /* save a3-a7 */
+# ifdef __PIC__
+MASK = 0x10000000
+# endif
+#endif
+FRAMESZ = (((ARGSZ + LOCALSZ) * SZREG) + ALSZ) & ALMASK
+GPOFF = FRAMESZ - ((ARGSZ + 1) * SZREG)
+#if _MIPS_SIM != _ABIO32
+A3OFF = FRAMESZ - (5 * SZREG)                          /* callee-allocated */
+A4OFF = FRAMESZ - (4 * SZREG)
+A5OFF = FRAMESZ - (3 * SZREG)
+A6OFF = FRAMESZ - (2 * SZREG)
+A7OFF = FRAMESZ - (1 * SZREG)
+NARGREGS = 8
+#else
+A3OFF = FRAMESZ + (3 * SZREG)                          /* caller-allocated */
+NARGREGS = 4
+#endif
+
+NESTED (__makecontext, FRAMESZ, ra)
+       .mask   MASK, -(ARGSZ * SZREG)
+       .fmask  0x00000000, 0
+
+98:
+#ifdef __PIC__
+       SETUP_GP
+#endif
+
+       PTR_ADDIU sp, -FRAMESZ
+
+#ifdef __PIC__
+       SETUP_GP64 (GPOFF, __makecontext)
+       SAVE_GP (GPOFF)
+#endif
+
+#ifdef PROF
+       .set    noat
+       move    AT, ra
+       jal     _mcount
+       .set    at
+#endif
+
+       /* Store args to be passed.  */
+       REG_S   a3, A3OFF(sp)
+#if _MIPS_SIM != _ABIO32
+       REG_S   a4, A4OFF(sp)
+       REG_S   a5, A5OFF(sp)
+       REG_S   a6, A6OFF(sp)
+       REG_S   a7, A7OFF(sp)
+#endif
+
+       /* Store a magic flag.  */
+       li      v1, 1
+       REG_S   v1, (0 * SZREG + MCONTEXT_GREGS)(a0)    /* zero */
+
+       /* Set up the stack.  */
+       PTR_L   t0, STACK_SP(a0)
+       PTR_L   t2, STACK_SIZE(a0)
+       PTR_ADDIU t1, sp, A3OFF
+       PTR_ADDU t0, t2
+       and     t0, ALMASK
+       blez    a2, 2f                                  /* no arguments */
+
+       /* Store register arguments.  */
+       PTR_ADDIU t2, a0, MCONTEXT_GREGS + 4 * SZREG
+       move    t3, zero
+0:
+       addiu   t3, 1
+       REG_L   v1, (t1)
+       PTR_ADDIU t1, SZREG
+       REG_S   v1, (t2)
+       PTR_ADDIU t2, SZREG
+       bgeu    t3, a2, 2f                              /* all done */
+       bltu    t3, NARGREGS, 0b                        /* next */
+
+       /* Make room for stack arguments.  */
+       PTR_SUBU t2, a2, t3
+       PTR_SLL t2, 3
+       PTR_SUBU t0, t2
+       and     t0, ALMASK
+
+       /* Store stack arguments.  */
+       move    t2, t0
+1:
+       addiu   t3, 1
+       REG_L   v1, (t1)
+       PTR_ADDIU t1, SZREG
+       REG_S   v1, (t2)
+       PTR_ADDIU t2, SZREG
+       bltu    t3, a2, 1b                              /* next */
+
+2:
+#if _MIPS_SIM == _ABIO32
+       /* Make room for a0-a3 storage.  */
+       PTR_ADDIU t0, -(NARGSAVE * SZREG)
+#endif
+       PTR_L   v1, UCONTEXT_LINK(a0)
+#ifdef __PIC__
+       PTR_ADDIU t9, 99f - 98b
+#else
+       PTR_LA  t9, 99f
+#endif
+       REG_S   t0, (29 * SZREG + MCONTEXT_GREGS)(a0)   /* sp */
+       REG_S   v1, (16 * SZREG + MCONTEXT_GREGS)(a0)   /* s0 */
+#ifdef __PIC__
+       REG_S   gp, (17 * SZREG + MCONTEXT_GREGS)(a0)   /* s1 */
+#endif
+       REG_S   t9, (31 * SZREG + MCONTEXT_GREGS)(a0)   /* ra */
+       REG_S   a1, MCONTEXT_PC(a0)
+
+#ifdef __PIC__
+       RESTORE_GP64
+       PTR_ADDIU sp, FRAMESZ
+#endif
+       jr      ra
+
+99:
+#ifdef __PIC__
+       move    gp, s1
+#endif
+       move    a0, zero
+       beqz    s0, 0f
+
+       /* setcontext (ucp) */
+       move    a0, s0
+#ifdef __PIC__
+       PTR_LA  t9, JUMPTARGET (__setcontext)
+       jalr    t9
+# if _MIPS_SIM == _ABIO32
+       move    gp, s1
+# endif
+#else
+       jal     JUMPTARGET (__setcontext)
+#endif
+       move    a0, v0
+
+0:
+       /* exit (a0) */
+#ifdef __PIC__
+       PTR_LA  t9, HIDDEN_JUMPTARGET (exit)
+       jalr    t9
+#else
+       jal     HIDDEN_JUMPTARGET (exit)
+#endif
+
+       /* You don't exist, you won't feel anything.  */
+1:
+       lb      zero, (zero)
+       b       1b
+PSEUDO_END (__makecontext)
+
+weak_alias (__makecontext, makecontext)
diff --git a/sysdeps/unix/sysv/linux/mips/setcontext.S b/sysdeps/unix/sysv/linux/mips/setcontext.S
new file mode 100644 (file)
index 0000000..186f3a7
--- /dev/null
@@ -0,0 +1,192 @@
+/* Set current context.
+   Copyright (C) 2009 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Maciej W. Rozycki <macro@codesourcery.com>.
+
+   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, 51 Franklin Street - Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+#include <sys/fpregdef.h>
+#include <sys/regdef.h>
+
+#include "ucontext_i.h"
+
+/* int setcontext (const ucontext_t *ucp) */
+
+       .text
+LOCALSZ = 0
+ARGSZ = 0
+MASK = 0x00000000
+#ifdef __PIC__
+LOCALSZ = 1                                            /* save gp */
+#endif
+#if _MIPS_SIM != _ABIO32
+ARGSZ = 1                                              /* save a0 */
+# ifdef __PIC__
+MASK = 0x10000000
+# endif
+#endif
+FRAMESZ = (((ARGSZ + LOCALSZ) * SZREG) + ALSZ) & ALMASK
+GPOFF = FRAMESZ - ((ARGSZ + 1) * SZREG)
+#if _MIPS_SIM != _ABIO32
+A0OFF = FRAMESZ - (1 * SZREG)                          /* callee-allocated */
+#else
+A0OFF = FRAMESZ + (0 * SZREG)                          /* caller-allocated */
+#endif
+
+NESTED (__setcontext, FRAMESZ, ra)
+       .mask   MASK, -(ARGSZ * SZREG)
+       .fmask  0x00000000, 0
+
+#ifdef __PIC__
+       SETUP_GP
+#endif
+
+       PTR_ADDIU sp, -FRAMESZ
+
+#ifdef __PIC__
+       SETUP_GP64 (GPOFF, __setcontext)
+       SAVE_GP (GPOFF)
+#endif
+
+#ifdef PROF
+       .set    noat
+       move    AT, ra
+       jal     _mcount
+       .set    at
+#endif
+
+       /* Check for the magic flag.  */
+       li      v0, 1
+       REG_L   v1, (0 * SZREG + MCONTEXT_GREGS)(a0)    /* zero */
+       bne     v0, v1, 98f
+
+       REG_S   a0, A0OFF(sp)
+
+/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, NULL, _NSIG8) */
+       li      a3, _NSIG8
+       move    a2, zero
+       PTR_ADDU a1, a0, UCONTEXT_SIGMASK
+       li      a0, SIG_SETMASK
+
+       li      v0, SYS_ify (rt_sigprocmask)
+       syscall
+       bnez    a3, 99f
+
+       REG_L   v0, A0OFF(sp)
+
+#ifdef __mips_hard_float
+# if _MIPS_SIM == _ABI64
+       l.d     fs0, (24 * SZREG + MCONTEXT_FPREGS)(v0)
+       l.d     fs1, (25 * SZREG + MCONTEXT_FPREGS)(v0)
+       l.d     fs2, (26 * SZREG + MCONTEXT_FPREGS)(v0)
+       l.d     fs3, (27 * SZREG + MCONTEXT_FPREGS)(v0)
+       l.d     fs4, (28 * SZREG + MCONTEXT_FPREGS)(v0)
+       l.d     fs5, (29 * SZREG + MCONTEXT_FPREGS)(v0)
+       l.d     fs6, (30 * SZREG + MCONTEXT_FPREGS)(v0)
+       l.d     fs7, (31 * SZREG + MCONTEXT_FPREGS)(v0)
+
+# else  /* _MIPS_SIM != _ABI64 */
+       l.d     fs0, (20 * SZREG + MCONTEXT_FPREGS)(v0)
+       l.d     fs1, (22 * SZREG + MCONTEXT_FPREGS)(v0)
+       l.d     fs2, (24 * SZREG + MCONTEXT_FPREGS)(v0)
+       l.d     fs3, (26 * SZREG + MCONTEXT_FPREGS)(v0)
+       l.d     fs4, (28 * SZREG + MCONTEXT_FPREGS)(v0)
+       l.d     fs5, (30 * SZREG + MCONTEXT_FPREGS)(v0)
+
+# endif /* _MIPS_SIM != _ABI64 */
+
+       lw      v1, MCONTEXT_FPC_CSR(v0)
+       ctc1    v1, fcr31
+#endif /* __mips_hard_float */
+
+       /* Note the contents of argument registers will be random
+          unless makecontext() has been called.  */
+       REG_L   a0, (4 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   a1, (5 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   a2, (6 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   a3, (7 * SZREG + MCONTEXT_GREGS)(v0)
+#if _MIPS_SIM != _ABIO32
+       REG_L   a4, (8 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   a5, (9 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   a6, (10 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   a7, (11 * SZREG + MCONTEXT_GREGS)(v0)
+#endif
+
+       REG_L   s0, (16 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   s1, (17 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   s2, (18 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   s3, (19 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   s4, (20 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   s5, (21 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   s6, (22 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   s7, (23 * SZREG + MCONTEXT_GREGS)(v0)
+#if ! defined (__PIC__) || _MIPS_SIM != _ABIO32
+       REG_L   gp, (28 * SZREG + MCONTEXT_GREGS)(v0)
+#endif
+       REG_L   sp, (29 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   fp, (30 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   ra, (31 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   t9, MCONTEXT_PC(v0)
+
+       move    v0, zero
+       jr      t9
+
+98:
+       /* This is a context obtained from a signal handler.
+          Perform a full restore by pushing the context
+          passed onto a simulated signal frame on the stack
+          and call the signal return syscall as if a signal
+          handler exited normally.  */
+       PTR_ADDIU sp, -((RT_SIGFRAME_SIZE + ALSZ) & ALMASK)
+
+       /* Only ucontext is referred to from rt_sigreturn,
+          copy it.  */
+       PTR_ADDIU t1, sp, RT_SIGFRAME_UCONTEXT
+       li      t3, ((UCONTEXT_SIZE + SZREG - 1) / SZREG) - 1
+0:
+       REG_L   t2, (a0)
+       PTR_ADDIU a0, SZREG
+       REG_S   t2, (t1)
+       PTR_ADDIU t1, SZREG
+       .set    noreorder
+       bgtz    t3, 0b
+        addiu  t3, -1
+       .set    reorder
+
+/* rt_sigreturn () -- no arguments, sp points to struct rt_sigframe.  */
+       li      v0, SYS_ify (rt_sigreturn)
+       syscall
+
+       /* Restore the stack and fall through to the error
+          path.  Successful rt_sigreturn never returns to
+          its calling place.  */
+       PTR_ADDIU sp, ((RT_SIGFRAME_SIZE + ALSZ) & ALMASK)
+99:
+#ifdef __PIC__
+       PTR_LA  t9, JUMPTARGET (__syscall_error)
+       RESTORE_GP64
+       PTR_ADDIU sp, FRAMESZ
+       jr      t9
+
+#else  /* ! __PIC__ */
+
+       j       JUMPTARGET (__syscall_error)
+#endif /* ! __PIC__ */
+PSEUDO_END (__setcontext)
+
+weak_alias (__setcontext, setcontext)
diff --git a/sysdeps/unix/sysv/linux/mips/swapcontext.S b/sysdeps/unix/sysv/linux/mips/swapcontext.S
new file mode 100644 (file)
index 0000000..b0b8417
--- /dev/null
@@ -0,0 +1,212 @@
+/* Save and set current context.
+   Copyright (C) 2009 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Maciej W. Rozycki <macro@codesourcery.com>.
+
+   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, 51 Franklin Street - Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+#include <sys/fpregdef.h>
+#include <sys/regdef.h>
+
+#include "ucontext_i.h"
+
+/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */
+
+       .text
+LOCALSZ = 0
+ARGSZ = 0
+MASK = 0x00000000
+#ifdef __PIC__
+LOCALSZ = 1                                            /* save gp */
+#endif
+#if _MIPS_SIM != _ABIO32
+ARGSZ = 1                                              /* save a1 */
+# ifdef __PIC__
+MASK = 0x10000000
+# endif
+#endif
+FRAMESZ = (((ARGSZ + LOCALSZ) * SZREG) + ALSZ) & ALMASK
+GPOFF = FRAMESZ - ((ARGSZ + 1) * SZREG)
+#if _MIPS_SIM != _ABIO32
+A1OFF = FRAMESZ - (1 * SZREG)                          /* callee-allocated */
+#else
+A1OFF = FRAMESZ + (1 * SZREG)                          /* caller-allocated */
+#endif
+
+NESTED (__swapcontext, FRAMESZ, ra)
+       .mask   MASK, -(ARGSZ * SZREG)
+       .fmask  0x00000000, 0
+
+#ifdef __PIC__
+       SETUP_GP
+
+       move    a2, sp
+# define _SP a2
+
+# if _MIPS_SIM != _ABIO32
+       move    a3, gp
+#  define _GP a3
+# endif
+
+       PTR_ADDIU sp, -FRAMESZ
+       SETUP_GP64 (GPOFF, __swapcontext)
+       SAVE_GP (GPOFF)
+
+#else  /* ! __PIC__ */
+# define _SP sp
+# define _GP gp
+
+#endif /* ! __PIC__ */
+
+#ifdef PROF
+       .set    noat
+       move    AT, ra
+       jal     _mcount
+       .set    at
+#endif
+
+       /* Store a magic flag.  */
+       li      v1, 1
+       REG_S   v1, (0 * SZREG + MCONTEXT_GREGS)(a0)    /* zero */
+
+       REG_S   s0, (16 * SZREG + MCONTEXT_GREGS)(a0)
+       REG_S   s1, (17 * SZREG + MCONTEXT_GREGS)(a0)
+       REG_S   s2, (18 * SZREG + MCONTEXT_GREGS)(a0)
+       REG_S   s3, (19 * SZREG + MCONTEXT_GREGS)(a0)
+       REG_S   s4, (20 * SZREG + MCONTEXT_GREGS)(a0)
+       REG_S   s5, (21 * SZREG + MCONTEXT_GREGS)(a0)
+       REG_S   s6, (22 * SZREG + MCONTEXT_GREGS)(a0)
+       REG_S   s7, (23 * SZREG + MCONTEXT_GREGS)(a0)
+#if ! defined (__PIC__) || _MIPS_SIM != _ABIO32
+       REG_S   _GP, (28 * SZREG + MCONTEXT_GREGS)(a0)
+#endif
+       REG_S   _SP, (29 * SZREG + MCONTEXT_GREGS)(a0)
+       REG_S   fp, (30 * SZREG + MCONTEXT_GREGS)(a0)
+       REG_S   ra, (31 * SZREG + MCONTEXT_GREGS)(a0)
+       REG_S   ra, MCONTEXT_PC(a0)
+
+#ifdef __mips_hard_float
+# if _MIPS_SIM == _ABI64
+       s.d     fs0, (24 * SZREG + MCONTEXT_FPREGS)(a0)
+       s.d     fs1, (25 * SZREG + MCONTEXT_FPREGS)(a0)
+       s.d     fs2, (26 * SZREG + MCONTEXT_FPREGS)(a0)
+       s.d     fs3, (27 * SZREG + MCONTEXT_FPREGS)(a0)
+       s.d     fs4, (28 * SZREG + MCONTEXT_FPREGS)(a0)
+       s.d     fs5, (29 * SZREG + MCONTEXT_FPREGS)(a0)
+       s.d     fs6, (30 * SZREG + MCONTEXT_FPREGS)(a0)
+       s.d     fs7, (31 * SZREG + MCONTEXT_FPREGS)(a0)
+
+# else  /* _MIPS_SIM != _ABI64 */
+       s.d     fs0, (20 * SZREG + MCONTEXT_FPREGS)(a0)
+       s.d     fs1, (22 * SZREG + MCONTEXT_FPREGS)(a0)
+       s.d     fs2, (24 * SZREG + MCONTEXT_FPREGS)(a0)
+       s.d     fs3, (26 * SZREG + MCONTEXT_FPREGS)(a0)
+       s.d     fs4, (28 * SZREG + MCONTEXT_FPREGS)(a0)
+       s.d     fs5, (30 * SZREG + MCONTEXT_FPREGS)(a0)
+
+# endif /* _MIPS_SIM != _ABI64 */
+
+       cfc1    v1, fcr31
+       sw      v1, MCONTEXT_FPC_CSR(a0)
+#endif /* __mips_hard_float */
+
+       REG_S   a1, A1OFF(sp)
+
+/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask, _NSIG8) */
+       li      a3, _NSIG8
+       PTR_ADDU a2, a0, UCONTEXT_SIGMASK
+       PTR_ADDU a1, a1, UCONTEXT_SIGMASK
+       li      a0, SIG_SETMASK
+
+       li      v0, SYS_ify (rt_sigprocmask)
+       syscall
+       bnez    a3, 99f
+
+       REG_L   v0, A1OFF(sp)
+
+#ifdef __mips_hard_float
+# if _MIPS_SIM == _ABI64
+       l.d     fs0, (24 * SZREG + MCONTEXT_FPREGS)(v0)
+       l.d     fs1, (25 * SZREG + MCONTEXT_FPREGS)(v0)
+       l.d     fs2, (26 * SZREG + MCONTEXT_FPREGS)(v0)
+       l.d     fs3, (27 * SZREG + MCONTEXT_FPREGS)(v0)
+       l.d     fs4, (28 * SZREG + MCONTEXT_FPREGS)(v0)
+       l.d     fs5, (29 * SZREG + MCONTEXT_FPREGS)(v0)
+       l.d     fs6, (30 * SZREG + MCONTEXT_FPREGS)(v0)
+       l.d     fs7, (31 * SZREG + MCONTEXT_FPREGS)(v0)
+
+# else  /* _MIPS_SIM != _ABI64 */
+       l.d     fs0, (20 * SZREG + MCONTEXT_FPREGS)(v0)
+       l.d     fs1, (22 * SZREG + MCONTEXT_FPREGS)(v0)
+       l.d     fs2, (24 * SZREG + MCONTEXT_FPREGS)(v0)
+       l.d     fs3, (26 * SZREG + MCONTEXT_FPREGS)(v0)
+       l.d     fs4, (28 * SZREG + MCONTEXT_FPREGS)(v0)
+       l.d     fs5, (30 * SZREG + MCONTEXT_FPREGS)(v0)
+
+# endif /* _MIPS_SIM != _ABI64 */
+
+       lw      v1, MCONTEXT_FPC_CSR(v0)
+       ctc1    v1, fcr31
+#endif /* __mips_hard_float */
+
+       /* Note the contents of argument registers will be random
+          unless makecontext() has been called.  */
+       REG_L   a0, (4 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   a1, (5 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   a2, (6 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   a3, (7 * SZREG + MCONTEXT_GREGS)(v0)
+#if _MIPS_SIM != _ABIO32
+       REG_L   a4, (8 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   a5, (9 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   a6, (10 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   a7, (11 * SZREG + MCONTEXT_GREGS)(v0)
+#endif
+
+       REG_L   s0, (16 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   s1, (17 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   s2, (18 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   s3, (19 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   s4, (20 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   s5, (21 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   s6, (22 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   s7, (23 * SZREG + MCONTEXT_GREGS)(v0)
+#if ! defined (__PIC__) || _MIPS_SIM != _ABIO32
+       REG_L   gp, (28 * SZREG + MCONTEXT_GREGS)(v0)
+#endif
+       REG_L   sp, (29 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   fp, (30 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   ra, (31 * SZREG + MCONTEXT_GREGS)(v0)
+       REG_L   t9, MCONTEXT_PC(v0)
+
+       move    v0, zero
+       jr      t9
+
+99:
+#ifdef __PIC__
+       PTR_LA  t9, JUMPTARGET (__syscall_error)
+       RESTORE_GP64
+       PTR_ADDIU sp, FRAMESZ
+       jr      t9
+
+#else  /* ! __PIC__ */
+
+       j       JUMPTARGET (__syscall_error)
+#endif /* ! __PIC__ */
+PSEUDO_END (__swapcontext)
+
+weak_alias (__swapcontext, swapcontext)
index ac496f3..251f0c8 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998, 2000, 2003, 2004, 2006 Free Software
+/* Copyright (C) 1997, 1998, 2000, 2003, 2004, 2006, 2009 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
@@ -56,12 +56,9 @@ typedef struct fpregset {
 #if _MIPS_SIM == _ABIO32
 /* Earlier versions of glibc for mips had an entirely different
    definition of mcontext_t, that didn't even resemble the
-   corresponding kernel data structure.  Since all legitimate uses of
-   ucontext_t in glibc mustn't have accessed anything beyond
-   uc_mcontext and, even then, taking a pointer to it, casting it to
-   sigcontext_t, and accessing it as such, which is what it has always
-   been, this can still be rectified.  Fortunately, makecontext,
-   [gs]etcontext et all have never been implemented.  */
+   corresponding kernel data structure.  Fortunately, makecontext,
+   [gs]etcontext et all were not implemented back then, so this can
+   still be rectified.  */
 typedef struct
   {
     unsigned int regmask;
diff --git a/sysdeps/unix/sysv/linux/mips/ucontext_i.sym b/sysdeps/unix/sysv/linux/mips/ucontext_i.sym
new file mode 100644 (file)
index 0000000..f14b886
--- /dev/null
@@ -0,0 +1,52 @@
+#include <inttypes.h>
+#include <signal.h>
+#include <stddef.h>
+#include <sys/ucontext.h>
+
+#include <kernel_rt_sigframe.h>
+
+-- Constants used by the rt_sigprocmask call.
+
+SIG_BLOCK
+SIG_SETMASK
+
+_NSIG8                         (_NSIG / 8)
+
+-- Offsets of the fields in the kernel rt_sigframe_t structure.
+#define rt_sigframe(member)    offsetof (kernel_rt_sigframe_t, member)
+
+RT_SIGFRAME_UCONTEXT           rt_sigframe (rs_uc)
+
+RT_SIGFRAME_SIZE               sizeof (kernel_rt_sigframe_t)
+
+-- Offsets of the fields in the ucontext_t structure.
+#define ucontext(member)       offsetof (ucontext_t, member)
+#define stack(member)          ucontext (uc_stack.member)
+#define mcontext(member)       ucontext (uc_mcontext.member)
+
+UCONTEXT_FLAGS                 ucontext (uc_flags)
+UCONTEXT_LINK                  ucontext (uc_link)
+UCONTEXT_STACK                 ucontext (uc_stack)
+UCONTEXT_MCONTEXT              ucontext (uc_mcontext)
+UCONTEXT_SIGMASK               ucontext (uc_sigmask)
+
+STACK_SP                       stack (ss_sp)
+STACK_SIZE                     stack (ss_size)
+STACK_FLAGS                    stack (ss_flags)
+
+MCONTEXT_GREGS                 mcontext (gregs)
+MCONTEXT_FPREGS                        mcontext (fpregs)
+MCONTEXT_MDHI                  mcontext (mdhi)
+MCONTEXT_HI1                   mcontext (hi1)
+MCONTEXT_HI2                   mcontext (hi2)
+MCONTEXT_HI3                   mcontext (hi3)
+MCONTEXT_MDLO                  mcontext (mdlo)
+MCONTEXT_LO1                   mcontext (lo1)
+MCONTEXT_LO2                   mcontext (lo2)
+MCONTEXT_LO3                   mcontext (lo3)
+MCONTEXT_PC                    mcontext (pc)
+MCONTEXT_FPC_CSR               mcontext (fpc_csr)
+MCONTEXT_USED_MATH             mcontext (used_math)
+MCONTEXT_DSP                   mcontext (dsp)
+
+UCONTEXT_SIZE                  sizeof (ucontext_t)