4df311253e356836b7d34ed4425ed2f922842a87
[kopensolaris-gnu/glibc.git] / sysdeps / mach / hurd / mips / sigreturn.c
1 /* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
8
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB.  If
16 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
17 Cambridge, MA 02139, USA.  */
18
19 #include <hurd.h>
20 #include <hurd/signal.h>
21 #include <hurd/threadvar.h>
22
23 int
24 __sigreturn (const struct sigcontext *scp)
25 {
26   struct hurd_sigstate *ss;
27   mach_port_t *reply_port;
28
29   if (scp == NULL)
30     {
31       errno = EINVAL;
32       return -1;
33     }
34
35   ss = _hurd_self_sigstate ();
36   ss->blocked = scp->sc_mask;
37   ss->intr_port = scp->sc_intr_port;
38   if (scp->sc_onstack)
39     ss->sigaltstack.ss_flags &= ~SA_ONSTACK; /* XXX threadvars */
40   __mutex_unlock (&ss->lock);
41
42   /* Destroy the MiG reply port used by the signal handler, and restore the
43      reply port in use by the thread when interrupted.  */
44   reply_port =
45     (mach_port_t *) __hurd_threadvar_location (_HURD_THREADVAR_MIG_REPLY);
46   if (*reply_port)
47     __mach_port_destroy (__mach_task_self (), *reply_port);
48   *reply_port = scp->sc_reply_port;
49
50   /* Restore registers.  */
51 #define restore_gpr(n) \
52         asm volatile ("lw $" #n ",%0" : : "m"(at->sc_gpr[(n)]))
53
54   asm volatile (".set noreorder; .set noat;");
55   {
56     register const struct sigcontext *at asm ("$1") = scp;
57
58     restore_gpr(2);
59     restore_gpr(3);
60     restore_gpr(4);
61     restore_gpr(5);
62     restore_gpr(6);
63     restore_gpr(7);
64     restore_gpr(8);
65     restore_gpr(9);
66     restore_gpr(10);
67     restore_gpr(11);
68     restore_gpr(12);
69     restore_gpr(13);
70     restore_gpr(14);
71     restore_gpr(15);
72     restore_gpr(16);
73     restore_gpr(17);
74     restore_gpr(18);
75     restore_gpr(19);
76     restore_gpr(20);
77     restore_gpr(21);
78     restore_gpr(22);
79     restore_gpr(23);
80     restore_gpr(24);
81     restore_gpr(25);
82     restore_gpr(28);
83     asm volatile ("lw $29,%0" : : "m"(scp->sc_sp));
84     asm volatile ("lw $30,%0" : : "m"(scp->sc_fp));
85     asm volatile ("lw $31,%0" : : "m"(scp->sc_pc));
86     asm volatile ("j $31");
87     restore_gpr(1);
88     asm volatile (".set reorder; .set at;");
89   }
90
91   /* NOTREACHED */
92   return -1;
93 }