chiark / gitweb /
eglibc (2.11.3-4+deb6u3) squeeze-lts; urgency=medium
[eglibc.git] / sysdeps / mach / hurd / i386 / intr-msg.h
1 /* Machine-dependent details of interruptible RPC messaging.  i386 version.
2    Copyright (C) 1995,96,97,99,2001 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20
21 /* Note that we must mark OPTION and TIMEOUT as outputs of this operation,
22    to indicate that the signal thread might mutate them as part
23    of sending us to a signal handler.  */
24 #define INTR_MSG_TRAP(msg, option, send_size, rcv_size, rcv_name, timeout, notify) \
25 ({                                                                            \
26   error_t err;                                                                \
27   asm (".globl _hurd_intr_rpc_msg_do_trap\n"                                  \
28        ".globl _hurd_intr_rpc_msg_in_trap\n"                                  \
29        ".globl _hurd_intr_rpc_msg_cx_sp\n"                                    \
30        ".globl _hurd_intr_rpc_msg_sp_restored\n"                              \
31        "                                movl %%esp, %%ecx\n"                  \
32        "                                leal %3, %%esp\n"                     \
33        "_hurd_intr_rpc_msg_cx_sp:       movl $-25, %%eax\n"                   \
34        "_hurd_intr_rpc_msg_do_trap:     lcall $7, $0 # status in %0\n"        \
35        "_hurd_intr_rpc_msg_in_trap:     movl %%ecx, %%esp\n"                  \
36        "_hurd_intr_rpc_msg_sp_restored:"                                      \
37        : "=a" (err), "=m" (option), "=m" (timeout)                            \
38        : "m" ((&msg)[-1]), "1" (option), "2" (timeout)                        \
39        : "%ecx");                                                             \
40   err;                                                                        \
41 })
42
43
44 static void inline
45 INTR_MSG_BACK_OUT (struct i386_thread_state *state)
46 {
47   extern const void _hurd_intr_rpc_msg_cx_sp;
48   if (state->eip >= (natural_t) &_hurd_intr_rpc_msg_cx_sp)
49     state->uesp = state->ecx;
50   else
51     state->ecx = state->uesp;
52 }
53 \f
54 #include "hurdfault.h"
55
56 /* This cannot be an inline function because it calls setjmp.  */
57 #define SYSCALL_EXAMINE(state, callno)                                        \
58 ({                                                                            \
59   struct { unsigned int c[2]; } *p = (void *) ((state)->eip - 7);             \
60   int result;                                                                 \
61   if (_hurdsig_catch_memory_fault (p))                                        \
62     return 0;                                                                 \
63   if (result = p->c[0] == 0x0000009a && (p->c[1] & 0x00ffffff) == 0x00000700) \
64     /* The PC is just after an `lcall $7,$0' instruction.                     \
65        This is a system call in progress; %eax holds the call number.  */     \
66     *(callno) = (state)->eax;                                                 \
67   _hurdsig_end_catch_fault ();                                                \
68   result;                                                                     \
69 })
70
71
72 struct mach_msg_trap_args
73   {
74     void *retaddr;              /* Address mach_msg_trap will return to.  */
75     /* This is the order of arguments to mach_msg_trap.  */
76     mach_msg_header_t *msg;
77     mach_msg_option_t option;
78     mach_msg_size_t send_size;
79     mach_msg_size_t rcv_size;
80     mach_port_t rcv_name;
81     mach_msg_timeout_t timeout;
82     mach_port_t notify;
83   };
84
85
86 /* This cannot be an inline function because it calls setjmp.  */
87 #define MSG_EXAMINE(state, msgid, rcvname, send_name, opt, tmout)             \
88 ({                                                                            \
89   const struct mach_msg_trap_args *args = (const void *) (state)->uesp;       \
90   mach_msg_header_t *msg;                                                     \
91   _hurdsig_catch_memory_fault (args) ? -1 :                                   \
92     ({                                                                        \
93       msg = args->msg;                                                        \
94       *(opt) = args->option;                                                  \
95       *(tmout) = args->timeout;                                               \
96       *(rcvname) = args->rcv_name;                                            \
97       _hurdsig_end_catch_fault ();                                            \
98       if (msg == 0)                                                           \
99         {                                                                     \
100           *(send_name) = MACH_PORT_NULL;                                      \
101           *(msgid) = 0;                                                       \
102         }                                                                     \
103       else                                                                    \
104         {                                                                     \
105           if (_hurdsig_catch_memory_fault (msg))                              \
106             return -1;                                                        \
107           *(send_name) = msg->msgh_remote_port;                               \
108           *(msgid) = msg->msgh_id;                                            \
109           _hurdsig_end_catch_fault ();                                        \
110         }                                                                     \
111       0;                                                                      \
112     });                                                                       \
113 })