signal.h revision 1.13 1 /* $NetBSD: signal.h,v 1.13 2003/08/07 16:28:15 agc Exp $ */
2
3 /*
4 * Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * @(#)signal.h 7.16 (Berkeley) 3/17/91
32 */
33
34 #ifndef _M68K_SIGNAL_H_
35 #define _M68K_SIGNAL_H_
36
37 #include <sys/featuretest.h>
38
39 typedef int sig_atomic_t;
40
41 #if defined(_NETBSD_SOURCE)
42 /*
43 * Get the "code" values
44 */
45 #include <machine/trap.h>
46
47 /*
48 * Information pushed on stack when a signal is delivered.
49 * This is used by the kernel to restore state following
50 * execution of the signal handler. It is also made available
51 * to the handler to allow it to restore state properly if
52 * a non-standard exit is performed.
53 */
54 #if defined(__LIBC12_SOURCE__) || defined(_KERNEL)
55 struct sigcontext13 {
56 int sc_onstack; /* sigstack state to restore */
57 int sc_mask; /* signal mask to restore (old style) */
58 int sc_sp; /* sp to restore */
59 int sc_fp; /* fp to restore */
60 int sc_ap; /* ap to restore */
61 int sc_pc; /* pc to restore */
62 int sc_ps; /* psl to restore */
63 };
64 #endif /* __LIBC12_SOURCE__ || _KERNEL */
65
66 struct sigcontext {
67 int sc_onstack; /* sigstack state to restore */
68 int __sc_mask13; /* signal mask to restore (old style) */
69 int sc_sp; /* sp to restore */
70 int sc_fp; /* fp to restore */
71 int sc_ap; /* ap to restore */
72 int sc_pc; /* pc to restore */
73 int sc_ps; /* psl to restore */
74 sigset_t sc_mask; /* signal mask to restore (new style) */
75 };
76
77 /*
78 * The following macros are used to convert from a ucontext to sigcontext,
79 * and vice-versa. This is for building a sigcontext to deliver to old-style
80 * signal handlers, and converting back (in the event the handler modifies
81 * the context).
82 *
83 * On m68k, we also need the sigstate conversion macros below.
84 */
85 #define _MCONTEXT_TO_SIGCONTEXT(uc, sc) \
86 do { \
87 (sc)->sc_sp = (uc)->uc_mcontext.__gregs[_REG_A7]; \
88 (sc)->sc_fp = (uc)->uc_mcontext.__gregs[_REG_A6]; \
89 /* sc_ap points to sigstate */ \
90 (sc)->sc_pc = (uc)->uc_mcontext.__gregs[_REG_PC]; \
91 (sc)->sc_ps = (uc)->uc_mcontext.__gregs[_REG_PS]; \
92 } while (/*CONSTCOND*/0)
93
94 #define _SIGCONTEXT_TO_MCONTEXT(sc, uc) \
95 do { \
96 (uc)->uc_mcontext.__gregs[_REG_A7] = (sc)->sc_sp; \
97 (uc)->uc_mcontext.__gregs[_REG_A6] = (sc)->sc_fp; \
98 (uc)->uc_mcontext.__gregs[_REG_PC] = (sc)->sc_pc; \
99 (uc)->uc_mcontext.__gregs[_REG_PS] = (sc)->sc_ps; \
100 } while (/*CONSTCOND*/0)
101
102 #if defined(__M68K_SIGNAL_PRIVATE)
103 #include <m68k/frame.h>
104
105 /*
106 * Register state saved while kernel delivers a signal.
107 */
108 struct sigstate {
109 int ss_flags; /* which of the following are valid */
110 struct frame ss_frame; /* original exception frame */
111 struct fpframe ss_fpstate; /* 68881/68882 state info */
112 };
113
114 #define SS_RTEFRAME 0x01
115 #define SS_FPSTATE 0x02
116 #define SS_USERREGS 0x04
117
118 #ifdef _KERNEL
119 #define _SIGSTATE_EXFRAMESIZE(fmt) exframesize[(fmt)]
120 #endif
121
122 #define _MCONTEXT_TO_SIGSTATE(uc, ss) \
123 do { \
124 (ss)->ss_flags = SS_USERREGS; \
125 memcpy(&(ss)->ss_frame.f_regs, &(uc)->uc_mcontext.__gregs, \
126 16 * sizeof(unsigned int)); \
127 (ss)->ss_frame.f_pc = (uc)->uc_mcontext.__gregs[_REG_PC]; \
128 (ss)->ss_frame.f_sr = (uc)->uc_mcontext.__gregs[_REG_PS]; \
129 (ss)->ss_frame.f_pad = 0; \
130 (ss)->ss_frame.f_stackadj = 0; \
131 (ss)->ss_frame.f_format = \
132 (uc)->uc_mcontext.__mc_pad.__mc_frame.__mcf_format; \
133 if ((ss)->ss_frame.f_format >= FMT4) { \
134 (ss)->ss_flags |= SS_RTEFRAME; \
135 (ss)->ss_frame.f_vector = \
136 (uc)->uc_mcontext.__mc_pad.__mc_frame.__mcf_vector; \
137 memcpy(&(ss)->ss_frame.F_u, \
138 &(uc)->uc_mcontext.__mc_pad.__mc_frame.__mcf_exframe,\
139 _SIGSTATE_EXFRAMESIZE((ss)->ss_frame.f_format)); \
140 } \
141 \
142 (ss)->ss_fpstate.FPF_u1 = \
143 (uc)->uc_mcontext.__mc_pad.__mc_frame.__mcf_fpf_u1; \
144 if ((uc)->uc_flags & _UC_FPU) { /* non-null FP frame */ \
145 (ss)->ss_fpstate.FPF_u2 = \
146 (uc)->uc_mcontext.__mc_pad.__mc_frame.__mcf_fpf_u2; \
147 memcpy(&(ss)->ss_fpstate.fpf_regs, \
148 &(uc)->uc_mcontext.__fpregs.__fp_fpregs, \
149 sizeof((ss)->ss_fpstate.fpf_regs)); \
150 (ss)->ss_fpstate.fpf_fpcr = \
151 (uc)->uc_mcontext.__fpregs.__fp_pcr; \
152 (ss)->ss_fpstate.fpf_fpsr = \
153 (uc)->uc_mcontext.__fpregs.__fp_psr; \
154 (ss)->ss_fpstate.fpf_fpiar = \
155 (uc)->uc_mcontext.__fpregs.__fp_piaddr; \
156 (ss)->ss_flags |= SS_FPSTATE; \
157 } \
158 } while (/*CONSTCOND*/0)
159
160 #define _SIGSTATE_TO_MCONTEXT(ss, uc) \
161 do { \
162 memcpy(&(uc)->uc_mcontext.__gregs, &(ss)->ss_frame.f_regs, \
163 16 * sizeof(unsigned int)); \
164 (uc)->uc_mcontext.__gregs[_REG_PC] = (ss)->ss_frame.f_pc; \
165 (uc)->uc_mcontext.__gregs[_REG_PS] = (ss)->ss_frame.f_sr; \
166 (uc)->uc_mcontext.__mc_pad.__mc_frame.__mcf_format = \
167 (ss)->ss_frame.f_format; \
168 if ((ss)->ss_flags & SS_RTEFRAME) { \
169 (uc)->uc_mcontext.__mc_pad.__mc_frame.__mcf_vector = \
170 (ss)->ss_frame.f_vector; \
171 memcpy(&(uc)->uc_mcontext.__mc_pad.__mc_frame.__mcf_exframe,\
172 &(ss)->ss_frame.F_u, \
173 _SIGSTATE_EXFRAMESIZE((ss)->ss_frame.f_format)); \
174 } \
175 \
176 (uc)->uc_mcontext.__mc_pad.__mc_frame.__mcf_fpf_u1 = \
177 (ss)->ss_fpstate.FPF_u1; \
178 if ((ss)->ss_flags & SS_FPSTATE) { \
179 (uc)->uc_mcontext.__mc_pad.__mc_frame.__mcf_fpf_u2 = \
180 (ss)->ss_fpstate.FPF_u2; \
181 memcpy(&(uc)->uc_mcontext.__fpregs.__fp_fpregs, \
182 &(ss)->ss_fpstate.fpf_regs, \
183 sizeof((ss)->ss_fpstate.fpf_regs)); \
184 (uc)->uc_mcontext.__fpregs.__fp_pcr = \
185 (ss)->ss_fpstate.fpf_fpcr; \
186 (uc)->uc_mcontext.__fpregs.__fp_psr = \
187 (ss)->ss_fpstate.fpf_fpsr; \
188 (uc)->uc_mcontext.__fpregs.__fp_piaddr = \
189 (ss)->ss_fpstate.fpf_fpiar; \
190 (uc)->uc_flags |= _UC_FPU; \
191 } else \
192 (uc)->uc_flags &= ~_UC_FPU; \
193 } while (/*CONSTCOND*/0)
194
195 /*
196 * Stack frame layout when delivering a signal.
197 */
198 struct sigframe {
199 int sf_ra; /* handler return address */
200 int sf_signum; /* signal number for handler */
201 int sf_code; /* additional info for handler */
202 struct sigcontext *sf_scp; /* context pointer for handler */
203 struct sigcontext sf_sc; /* actual context */
204 struct sigstate sf_state; /* state of the hardware */
205 };
206 #endif /* _KERNEL && __M68K_SIGNAL_PRIVATE */
207
208 #endif /* _NETBSD_SOURCE */
209 #endif /* !_M68K_SIGNAL_H_ */
210