This source file includes following definitions.
- freebsd_sendsig
- freebsd_sys_sigreturn
- netbsd_to_freebsd_ptrace_regs
- freebsd_to_netbsd_ptrace_regs
- freebsd_ptrace_getregs
- freebsd_ptrace_setregs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/signalvar.h>
43 #include <sys/proc.h>
44 #include <sys/user.h>
45 #include <sys/exec.h>
46 #include <sys/mount.h>
47
48 #include <uvm/uvm_extern.h>
49
50 #include <machine/cpufunc.h>
51 #include <machine/npx.h>
52 #include <machine/reg.h>
53 #include <machine/vm86.h>
54 #include <machine/freebsd_machdep.h>
55
56 #include <compat/freebsd/freebsd_signal.h>
57 #include <compat/freebsd/freebsd_syscallargs.h>
58 #include <compat/freebsd/freebsd_exec.h>
59 #include <compat/freebsd/freebsd_ptrace.h>
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75 void
76 freebsd_sendsig(sig_t catcher, int sig, int mask, u_long code, int type,
77 union sigval val)
78 {
79 struct proc *p = curproc;
80 struct trapframe *tf;
81 struct freebsd_sigframe *fp, frame;
82 struct sigacts *psp = p->p_sigacts;
83 int oonstack;
84
85
86
87
88 frame.sf_signum = sig;
89
90 tf = p->p_md.md_regs;
91 oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
92
93
94
95
96 if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack &&
97 (psp->ps_sigonstack & sigmask(sig))) {
98 fp = (struct freebsd_sigframe *)((char *)psp->ps_sigstk.ss_sp +
99 psp->ps_sigstk.ss_size - sizeof(struct freebsd_sigframe));
100 psp->ps_sigstk.ss_flags |= SS_ONSTACK;
101 } else {
102 fp = (struct freebsd_sigframe *)tf->tf_esp - 1;
103 }
104
105 frame.sf_code = code;
106 frame.sf_scp = &fp->sf_sc;
107 frame.sf_addr = (char *)rcr2();
108 frame.sf_handler = catcher;
109
110
111
112
113 frame.sf_sc.sc_onstack = oonstack;
114 frame.sf_sc.sc_mask = mask;
115 #ifdef VM86
116 if (tf->tf_eflags & PSL_VM) {
117 frame.sf_sc.sc_es = tf->tf_vm86_es;
118 frame.sf_sc.sc_ds = tf->tf_vm86_ds;
119 frame.sf_sc.sc_eflags = get_vflags(p);
120 } else
121 #endif
122 {
123 frame.sf_sc.sc_es = tf->tf_es;
124 frame.sf_sc.sc_ds = tf->tf_ds;
125 frame.sf_sc.sc_eflags = tf->tf_eflags;
126 }
127 frame.sf_sc.sc_edi = tf->tf_edi;
128 frame.sf_sc.sc_esi = tf->tf_esi;
129 frame.sf_sc.sc_ebp = tf->tf_ebp;
130 frame.sf_sc.sc_isp = 0;
131 frame.sf_sc.sc_ebx = tf->tf_ebx;
132 frame.sf_sc.sc_edx = tf->tf_edx;
133 frame.sf_sc.sc_ecx = tf->tf_ecx;
134 frame.sf_sc.sc_eax = tf->tf_eax;
135 frame.sf_sc.sc_eip = tf->tf_eip;
136 frame.sf_sc.sc_cs = tf->tf_cs;
137 frame.sf_sc.sc_esp = tf->tf_esp;
138 frame.sf_sc.sc_ss = tf->tf_ss;
139
140 if (copyout(&frame, fp, sizeof(frame)) != 0) {
141
142
143
144
145 sigexit(p, SIGILL);
146
147 }
148
149
150
151
152 tf->tf_es = GSEL(GUDATA_SEL, SEL_UPL);
153 tf->tf_ds = GSEL(GUDATA_SEL, SEL_UPL);
154 tf->tf_eip = p->p_sigcode;
155 tf->tf_cs = GSEL(GUCODE_SEL, SEL_UPL);
156 tf->tf_eflags &= ~(PSL_T|PSL_VM|PSL_AC);
157 tf->tf_esp = (int)fp;
158 tf->tf_ss = GSEL(GUDATA_SEL, SEL_UPL);
159 }
160
161
162
163
164
165
166
167
168
169
170
171 int
172 freebsd_sys_sigreturn(struct proc *p, void *v, register_t *retval)
173 {
174 struct freebsd_sys_sigreturn_args
175
176 *uap = v;
177 struct freebsd_sigcontext *scp, context;
178 struct trapframe *tf;
179
180 tf = p->p_md.md_regs;
181
182
183
184
185
186
187 scp = SCARG(uap, scp);
188 if (copyin((caddr_t)scp, &context, sizeof(*scp)) != 0)
189 return (EFAULT);
190
191
192
193
194 #ifdef VM86
195 if (context.sc_eflags & PSL_VM) {
196 tf->tf_vm86_es = context.sc_es;
197 tf->tf_vm86_ds = context.sc_ds;
198 set_vflags(p, context.sc_eflags);
199 } else
200 #endif
201 {
202
203
204
205
206
207
208 if (((context.sc_eflags ^ tf->tf_eflags) & PSL_USERSTATIC) != 0 ||
209 !USERMODE(context.sc_cs, context.sc_eflags))
210 return (EINVAL);
211
212 tf->tf_es = context.sc_es;
213 tf->tf_ds = context.sc_ds;
214 tf->tf_eflags = context.sc_eflags;
215 }
216 tf->tf_edi = context.sc_edi;
217 tf->tf_esi = context.sc_esi;
218 tf->tf_ebp = context.sc_ebp;
219
220 tf->tf_ebx = context.sc_ebx;
221 tf->tf_edx = context.sc_edx;
222 tf->tf_ecx = context.sc_ecx;
223 tf->tf_eax = context.sc_eax;
224 tf->tf_eip = context.sc_eip;
225 tf->tf_cs = context.sc_cs;
226 tf->tf_esp = context.sc_esp;
227 tf->tf_ss = context.sc_ss;
228
229 if (context.sc_onstack & 01)
230 p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
231 else
232 p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
233 p->p_sigmask = context.sc_mask & ~sigcantmask;
234
235 return (EJUSTRETURN);
236 }
237
238
239
240
241
242
243 void
244 netbsd_to_freebsd_ptrace_regs(struct reg *nregs, struct fpreg *nfpregs,
245 struct freebsd_ptrace_reg *fregs)
246 {
247 struct save87 *nframe = (struct save87 *)nfpregs;
248
249 fregs->freebsd_ptrace_regs.tf_es = nregs->r_es;
250 fregs->freebsd_ptrace_regs.tf_ds = nregs->r_ds;
251 fregs->freebsd_ptrace_regs.tf_edi = nregs->r_edi;
252 fregs->freebsd_ptrace_regs.tf_esi = nregs->r_esi;
253 fregs->freebsd_ptrace_regs.tf_ebp = nregs->r_ebp;
254 fregs->freebsd_ptrace_regs.tf_isp = 0;
255 fregs->freebsd_ptrace_regs.tf_ebx = nregs->r_ebx;
256 fregs->freebsd_ptrace_regs.tf_edx = nregs->r_edx;
257 fregs->freebsd_ptrace_regs.tf_ecx = nregs->r_ecx;
258 fregs->freebsd_ptrace_regs.tf_eax = nregs->r_eax;
259 fregs->freebsd_ptrace_regs.tf_trapno = 0;
260
261 fregs->freebsd_ptrace_regs.tf_err = 0;
262 fregs->freebsd_ptrace_regs.tf_eip = nregs->r_eip;
263 fregs->freebsd_ptrace_regs.tf_cs = nregs->r_cs;
264 fregs->freebsd_ptrace_regs.tf_eflags = nregs->r_eflags;
265
266 fregs->freebsd_ptrace_regs.tf_esp = nregs->r_esp;
267 fregs->freebsd_ptrace_regs.tf_ss = nregs->r_ss;
268
269 fregs->freebsd_ptrace_fpregs.sv_env =
270 *(struct freebsd_env87 *)&nframe->sv_env;
271 bcopy(nframe->sv_ac, fregs->freebsd_ptrace_fpregs.sv_ac,
272 sizeof(fregs->freebsd_ptrace_fpregs.sv_ac));
273 fregs->freebsd_ptrace_fpregs.sv_ex_sw =
274 nframe->sv_ex_sw;
275 #if 0
276
277
278
279 #ifdef DIAGNOSTIC
280 if (sizeof(fregs->freebsd_ptrace_fpregs.sv_pad) <
281 sizeof(nframe->sv_ex_tw) + sizeof(nframe->sv_pad)) {
282 panic("netbsd_to_freebsd_ptrace_regs: %s",
283 "sizeof(freebsd_save87) >= sizeof(save87)");
284 }
285 #endif
286 #endif
287 bcopy(&nframe->sv_ex_tw, fregs->freebsd_ptrace_fpregs.sv_pad,
288 sizeof(nframe->sv_ex_tw));
289 #if 0
290 bcopy(nframe->sv_pad,
291 (caddr_t)fregs->freebsd_ptrace_fpregs.sv_pad +
292 sizeof(nframe->sv_ex_tw),
293 sizeof(nframe->sv_pad));
294 bzero((caddr_t)fregs->freebsd_ptrace_fpregs.sv_pad +
295 sizeof(nframe->sv_ex_tw) + sizeof(nframe->sv_pad),
296 sizeof(fregs->freebsd_ptrace_fpregs.sv_pad) -
297 sizeof(nframe->sv_ex_tw) - sizeof(nframe->sv_pad));
298 #endif
299 }
300
301 void
302 freebsd_to_netbsd_ptrace_regs(struct freebsd_ptrace_reg *fregs,
303 struct reg *nregs, struct fpreg *nfpregs)
304 {
305 struct save87 *nframe = (struct save87 *)nfpregs;
306
307 nregs->r_es = fregs->freebsd_ptrace_regs.tf_es;
308 nregs->r_ds = fregs->freebsd_ptrace_regs.tf_ds;
309 nregs->r_edi = fregs->freebsd_ptrace_regs.tf_edi;
310 nregs->r_esi = fregs->freebsd_ptrace_regs.tf_esi;
311 nregs->r_ebp = fregs->freebsd_ptrace_regs.tf_ebp;
312 nregs->r_ebx = fregs->freebsd_ptrace_regs.tf_ebx;
313 nregs->r_edx = fregs->freebsd_ptrace_regs.tf_edx;
314 nregs->r_ecx = fregs->freebsd_ptrace_regs.tf_ecx;
315 nregs->r_eax = fregs->freebsd_ptrace_regs.tf_eax;
316
317 nregs->r_eip = fregs->freebsd_ptrace_regs.tf_eip;
318 nregs->r_cs = fregs->freebsd_ptrace_regs.tf_cs;
319 nregs->r_eflags = fregs->freebsd_ptrace_regs.tf_eflags;
320
321 nregs->r_esp = fregs->freebsd_ptrace_regs.tf_esp;
322 nregs->r_ss = fregs->freebsd_ptrace_regs.tf_ss;
323
324 nframe->sv_env =
325 *(struct env87 *)&fregs->freebsd_ptrace_fpregs.sv_env;
326 bcopy(fregs->freebsd_ptrace_fpregs.sv_ac, nframe->sv_ac,
327 sizeof(nframe->sv_ac));
328 nframe->sv_ex_sw =
329 fregs->freebsd_ptrace_fpregs.sv_ex_sw;
330
331
332
333 bcopy(fregs->freebsd_ptrace_fpregs.sv_pad, &nframe->sv_ex_tw,
334 sizeof(nframe->sv_ex_tw));
335 #if 0
336 bcopy((caddr_t)fregs->freebsd_ptrace_fpregs.sv_pad +
337 sizeof(nframe->sv_ex_tw),
338 nframe->sv_pad, sizeof(nframe->sv_pad));
339 #endif
340 }
341
342
343 #define FREEBSD_REGS_OFFSET 0x2000
344
345 int
346 freebsd_ptrace_getregs(struct freebsd_ptrace_reg *fregs, caddr_t addr,
347 register_t *datap)
348 {
349 vaddr_t offset = (vaddr_t)addr;
350
351 if (offset == FREEBSD_U_AR0_OFFSET) {
352 *datap = FREEBSD_REGS_OFFSET + FREEBSD_USRSTACK;
353 return 0;
354 } else if (offset >= FREEBSD_REGS_OFFSET &&
355 offset <= FREEBSD_REGS_OFFSET +
356 sizeof(fregs->freebsd_ptrace_regs)-sizeof(register_t)) {
357 *datap = *(register_t *)&((caddr_t)&fregs->freebsd_ptrace_regs)
358 [(vaddr_t) addr - FREEBSD_REGS_OFFSET];
359 return 0;
360 } else if (offset >= FREEBSD_U_SAVEFP_OFFSET &&
361 offset <= FREEBSD_U_SAVEFP_OFFSET +
362 sizeof(fregs->freebsd_ptrace_fpregs)-sizeof(register_t)){
363 *datap= *(register_t *)&((caddr_t)&fregs->freebsd_ptrace_fpregs)
364 [offset - FREEBSD_U_SAVEFP_OFFSET];
365 return 0;
366 }
367 #ifdef DIAGNOSTIC
368 printf("freebsd_ptrace_getregs: *(0x%08lx)\n", offset);
369 #endif
370 return EFAULT;
371 }
372
373 int
374 freebsd_ptrace_setregs(struct freebsd_ptrace_reg *fregs, caddr_t addr, int data)
375 {
376 vaddr_t offset = (vaddr_t)addr;
377
378 if (offset >= FREEBSD_REGS_OFFSET &&
379 offset <= FREEBSD_REGS_OFFSET +
380 sizeof(fregs->freebsd_ptrace_regs) - sizeof(int)) {
381 *(int *)&((caddr_t)&fregs->freebsd_ptrace_regs)
382 [offset - FREEBSD_REGS_OFFSET] = data;
383 return 0;
384 } else if (offset >= FREEBSD_U_SAVEFP_OFFSET &&
385 offset <= FREEBSD_U_SAVEFP_OFFSET +
386 sizeof(fregs->freebsd_ptrace_fpregs) - sizeof(int)) {
387 *(int *)&((caddr_t)&fregs->freebsd_ptrace_fpregs)
388 [offset - FREEBSD_U_SAVEFP_OFFSET] = data;
389 return 0;
390 }
391 #ifdef DIAGNOSTIC
392 printf("freebsd_ptrace_setregs: *(0x%08lx) = 0x%08x\n", offset, data);
393 #endif
394 return EFAULT;
395 }