1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License.  See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 1998, 1999, 2001 Ralf Baechle
7 * Copyright (C) 2000, 2001 Silicon Graphics, Inc.
8 */
9#ifndef _ASM_SIGINFO_H
10#define _ASM_SIGINFO_H
11
12#include <linux/types.h>
13
14/* This structure matches IRIX 32/n32 ABIs for binary compatibility. */
15
16typedef union sigval {
17	int sival_int;
18	void *sival_ptr;
19} sigval_t;
20
21#ifdef __KERNEL__
22
23typedef union sigval32 {
24	int sival_int;
25	s32 sival_ptr;
26} sigval_t32;
27
28#endif /* __KERNEL__ */
29
30/* This structure matches IRIX 32/n32 ABIs for binary compatibility but
31   has Linux extensions.  */
32
33#define SI_MAX_SIZE	128
34#define SI_PAD_SIZE	((SI_MAX_SIZE/sizeof(int)) - 4)
35#define SI_PAD_SIZE32	((SI_MAX_SIZE/sizeof(int)) - 3)
36
37typedef struct siginfo {
38	int si_signo;
39	int si_code;
40	int si_errno;
41
42	union {
43		int _pad[SI_PAD_SIZE];
44
45		/* kill() */
46		struct {
47			pid_t _pid;		/* sender's pid */
48			uid_t _uid;		/* sender's uid */
49		} _kill;
50
51		/* SIGCHLD */
52		struct {
53			pid_t _pid;		/* which child */
54			uid_t _uid;		/* sender's uid */
55			clock_t _utime;
56			int _status;		/* exit code */
57			clock_t _stime;
58		} _sigchld;
59
60		/* IRIX SIGCHLD */
61		struct {
62			pid_t _pid;		/* which child */
63			clock_t _utime;
64			int _status;		/* exit code */
65			clock_t _stime;
66		} _irix_sigchld;
67
68		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
69		struct {
70			void *_addr; /* faulting insn/memory ref. */
71		} _sigfault;
72
73		/* SIGPOLL, SIGXFSZ (To do ...)  */
74		struct {
75			long _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
76			int _fd;
77		} _sigpoll;
78
79		/* POSIX.1b timers */
80		struct {
81			unsigned int _timer1;
82			unsigned int _timer2;
83		} _timer;
84
85		/* POSIX.1b signals */
86		struct {
87			pid_t _pid;		/* sender's pid */
88			uid_t _uid;		/* sender's uid */
89			sigval_t _sigval;
90		} _rt;
91
92	} _sifields;
93} siginfo_t;
94
95#ifdef __KERNEL__
96
97typedef struct siginfo32 {
98	int si_signo;
99	int si_code;
100	int si_errno;
101
102	union {
103		int _pad[SI_PAD_SIZE32];
104
105		/* kill() */
106		struct {
107			__kernel_pid_t32 _pid;	/* sender's pid */
108			__kernel_uid_t32 _uid;	/* sender's uid */
109		} _kill;
110
111		/* SIGCHLD */
112		struct {
113			__kernel_pid_t32 _pid;	/* which child */
114			__kernel_uid_t32 _uid;	/* sender's uid */
115			__kernel_clock_t32 _utime;
116			int _status;		/* exit code */
117			__kernel_clock_t32 _stime;
118		} _sigchld;
119
120		/* IRIX SIGCHLD */
121		struct {
122			__kernel_pid_t32 _pid;	/* which child */
123			__kernel_clock_t32 _utime;
124			int _status;		/* exit code */
125			__kernel_clock_t32 _stime;
126		} _irix_sigchld;
127
128		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
129		struct {
130			s32 _addr; /* faulting insn/memory ref. */
131		} _sigfault;
132
133		/* SIGPOLL, SIGXFSZ (To do ...)  */
134		struct {
135			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
136			int _fd;
137		} _sigpoll;
138
139		/* POSIX.1b timers */
140		struct {
141			unsigned int _timer1;
142			unsigned int _timer2;
143		} _timer;
144
145		/* POSIX.1b signals */
146		struct {
147			__kernel_pid_t32 _pid;	/* sender's pid */
148			__kernel_uid_t32 _uid;	/* sender's uid */
149			sigval_t32 _sigval;
150		} _rt;
151
152	} _sifields;
153} siginfo_t32;
154
155#endif /* __KERNEL__ */
156
157/*
158 * How these fields are to be accessed.
159 */
160#define si_pid		_sifields._kill._pid
161#define si_uid		_sifields._kill._uid
162#define si_status	_sifields._sigchld._status
163#define si_utime	_sifields._sigchld._utime
164#define si_stime	_sifields._sigchld._stime
165#define si_value	_sifields._rt._sigval
166#define si_int		_sifields._rt._sigval.sival_int
167#define si_ptr		_sifields._rt._sigval.sival_ptr
168#define si_addr		_sifields._sigfault._addr
169#define si_band		_sifields._sigpoll._band
170#define si_fd		_sifields._sigpoll._fd
171
172#ifdef __KERNEL__
173#define __SI_MASK	0xffff0000
174#define __SI_KILL	(0 << 16)
175#define __SI_TIMER	(1 << 16)
176#define __SI_POLL	(2 << 16)
177#define __SI_FAULT	(3 << 16)
178#define __SI_CHLD	(4 << 16)
179#define __SI_RT		(5 << 16)
180#define __SI_CODE(T,N)	((T) << 16 | ((N) & 0xffff))
181#else
182#define __SI_KILL	0
183#define __SI_TIMER	0
184#define __SI_POLL	0
185#define __SI_FAULT	0
186#define __SI_CHLD	0
187#define __SI_RT		0
188#define __SI_CODE(T,N)	(N)
189#endif
190
191/*
192 * si_code values
193 * Again these have been choosen to be IRIX compatible.
194 */
195#define SI_USER		0	/* sent by kill, sigsend, raise */
196#define SI_KERNEL	0x80	/* sent by the kernel from somewhere */
197#define SI_QUEUE	-1	/* sent by sigqueue */
198#define SI_ASYNCIO	-2	/* sent by AIO completion */
199#define SI_TIMER __SI_CODE(__SI_TIMER,-3) /* sent by timer expiration */
200#define SI_MESGQ	-4	/* sent by real time mesq state change */
201#define SI_SIGIO	-5	/* sent by queued SIGIO */
202#define SI_TKILL	-6	/* sent by tkill system call */
203
204#define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
205#define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
206
207/*
208 * SIGILL si_codes
209 */
210#define ILL_ILLOPC	(__SI_FAULT|1)	/* illegal opcode */
211#define ILL_ILLOPN	(__SI_FAULT|2)	/* illegal operand */
212#define ILL_ILLADR	(__SI_FAULT|3)	/* illegal addressing mode */
213#define ILL_ILLTRP	(__SI_FAULT|4)	/* illegal trap */
214#define ILL_PRVOPC	(__SI_FAULT|5)	/* privileged opcode */
215#define ILL_PRVREG	(__SI_FAULT|6)	/* privileged register */
216#define ILL_COPROC	(__SI_FAULT|7)	/* coprocessor error */
217#define ILL_BADSTK	(__SI_FAULT|8)	/* internal stack error */
218#define NSIGILL		8
219
220/*
221 * SIGFPE si_codes
222 */
223#define FPE_INTDIV	(__SI_FAULT|1)	/* integer divide by zero */
224#define FPE_INTOVF	(__SI_FAULT|2)	/* integer overflow */
225#define FPE_FLTDIV	(__SI_FAULT|3)	/* floating point divide by zero */
226#define FPE_FLTOVF	(__SI_FAULT|4)	/* floating point overflow */
227#define FPE_FLTUND	(__SI_FAULT|5)	/* floating point underflow */
228#define FPE_FLTRES	(__SI_FAULT|6)	/* floating point inexact result */
229#define FPE_FLTINV	(__SI_FAULT|7)	/* floating point invalid operation */
230#define FPE_FLTSUB	(__SI_FAULT|8)	/* subscript out of range */
231#define NSIGFPE		8
232
233/*
234 * SIGSEGV si_codes
235 */
236#define SEGV_MAPERR	(__SI_FAULT|1)	/* address not mapped to object */
237#define SEGV_ACCERR	(__SI_FAULT|2)	/* invalid permissions for mapped object */
238#define NSIGSEGV	2
239
240/*
241 * SIGBUS si_codes
242 */
243#define BUS_ADRALN	(__SI_FAULT|1)	/* invalid address alignment */
244#define BUS_ADRERR	(__SI_FAULT|2)	/* non-existant physical address */
245#define BUS_OBJERR	(__SI_FAULT|3)	/* object specific hardware error */
246#define NSIGBUS		3
247
248/*
249 * SIGTRAP si_codes
250 */
251#define TRAP_BRKPT	(__SI_FAULT|1)	/* process breakpoint */
252#define TRAP_TRACE	(__SI_FAULT|2)	/* process trace trap */
253#define NSIGTRAP	2
254
255/*
256 * SIGCHLD si_codes
257 */
258#define CLD_EXITED	(__SI_CHLD|1)	/* child has exited */
259#define CLD_KILLED	(__SI_CHLD|2)	/* child was killed */
260#define CLD_DUMPED	(__SI_CHLD|3)	/* child terminated abnormally */
261#define CLD_TRAPPED	(__SI_CHLD|4)	/* traced child has trapped */
262#define CLD_STOPPED	(__SI_CHLD|5)	/* child has stopped */
263#define CLD_CONTINUED	(__SI_CHLD|6)	/* stopped child has continued */
264#define NSIGCHLD	6
265
266/*
267 * SIGPOLL si_codes
268 */
269#define POLL_IN		(__SI_POLL|1)	/* data input available */
270#define POLL_OUT	(__SI_POLL|2)	/* output buffers available */
271#define POLL_MSG	(__SI_POLL|3)	/* input message available */
272#define POLL_ERR	(__SI_POLL|4)	/* i/o error */
273#define POLL_PRI	(__SI_POLL|5)	/* high priority input available */
274#define POLL_HUP	(__SI_POLL|6)	/* device disconnected */
275#define NSIGPOLL	6
276
277/*
278 * sigevent definitions
279 *
280 * It seems likely that SIGEV_THREAD will have to be handled from
281 * userspace, libpthread transmuting it to SIGEV_SIGNAL, which the
282 * thread manager then catches and does the appropriate nonsense.
283 * However, everything is written out here so as to not get lost.
284 */
285#define SIGEV_NONE	128	/* other notification: meaningless */
286#define SIGEV_SIGNAL	129	/* notify via signal */
287#define SIGEV_CALLBACK	130	/* ??? */
288#define SIGEV_THREAD	131	/* deliver via thread creation */
289
290#define SIGEV_MAX_SIZE	64
291#define SIGEV_PAD_SIZE	((SIGEV_MAX_SIZE/sizeof(int)) - 4)
292
293typedef struct sigevent {
294	int sigev_notify;
295	sigval_t sigev_value;
296	int sigev_signo;
297	union {
298		int _pad[SIGEV_PAD_SIZE];
299
300		struct {
301			void (*_function)(sigval_t);
302			void *_attribute;	/* really pthread_attr_t */
303		} _sigev_thread;
304	} _sigev_un;
305} sigevent_t;
306
307#define sigev_notify_function	_sigev_un._sigev_thread._function
308#define sigev_notify_attributes	_sigev_un._sigev_thread._attribute
309
310#ifdef __KERNEL__
311#include <linux/string.h>
312
313static inline void copy_siginfo(siginfo_t *to, siginfo_t *from)
314{
315	if (from->si_code < 0)
316		memcpy(to, from, sizeof(siginfo_t));
317	else
318		/* _sigchld is currently the largest know union member */
319		memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld));
320}
321
322extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from);
323
324#endif /* __KERNEL__ */
325
326#endif /* _ASM_SIGINFO_H */
327