dtrace_isa.c revision 1.2 1 1.2 darran /* $NetBSD: dtrace_isa.c,v 1.2 2010/02/21 01:46:33 darran Exp $ */
2 1.2 darran
3 1.1 darran /*
4 1.1 darran * CDDL HEADER START
5 1.1 darran *
6 1.1 darran * The contents of this file are subject to the terms of the
7 1.1 darran * Common Development and Distribution License, Version 1.0 only
8 1.1 darran * (the "License"). You may not use this file except in compliance
9 1.1 darran * with the License.
10 1.1 darran *
11 1.1 darran * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
12 1.1 darran * or http://www.opensolaris.org/os/licensing.
13 1.1 darran * See the License for the specific language governing permissions
14 1.1 darran * and limitations under the License.
15 1.1 darran *
16 1.1 darran * When distributing Covered Code, include this CDDL HEADER in each
17 1.1 darran * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
18 1.1 darran * If applicable, add the following below this CDDL HEADER, with the
19 1.1 darran * fields enclosed by brackets "[]" replaced with your own identifying
20 1.1 darran * information: Portions Copyright [yyyy] [name of copyright owner]
21 1.1 darran *
22 1.1 darran * CDDL HEADER END
23 1.1 darran *
24 1.1 darran * $FreeBSD: src/sys/cddl/dev/dtrace/i386/dtrace_isa.c,v 1.1.4.1 2009/08/03 08:13:06 kensmith Exp $
25 1.1 darran */
26 1.1 darran /*
27 1.1 darran * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
28 1.1 darran * Use is subject to license terms.
29 1.1 darran */
30 1.1 darran #include <sys/cdefs.h>
31 1.1 darran
32 1.1 darran #include <sys/param.h>
33 1.1 darran #include <sys/systm.h>
34 1.1 darran #include <sys/kernel.h>
35 1.2 darran //#include <sys/pcpu.h>
36 1.1 darran
37 1.2 darran //#include <machine/md_var.h>
38 1.2 darran //#include <machine/stack.h>
39 1.1 darran
40 1.2 darran //#include <vm/vm.h>
41 1.2 darran #include <machine/vmparam.h>
42 1.2 darran #include <machine/pmap.h>
43 1.1 darran
44 1.2 darran uintptr_t kernelbase = (uintptr_t)KERNBASE;
45 1.1 darran
46 1.1 darran #define INKERNEL(va) (((vm_offset_t)(va)) >= USRSTACK && \
47 1.1 darran ((vm_offset_t)(va)) < VM_MAX_KERNEL_ADDRESS)
48 1.1 darran
49 1.2 darran struct i386_frame {
50 1.2 darran struct i386_frame *f_frame;
51 1.2 darran int f_retaddr;
52 1.2 darran int f_arg0;
53 1.2 darran };
54 1.2 darran
55 1.2 darran typedef unsigned long vm_offset_t;
56 1.2 darran
57 1.1 darran uint8_t dtrace_fuword8_nocheck(void *);
58 1.1 darran uint16_t dtrace_fuword16_nocheck(void *);
59 1.1 darran uint32_t dtrace_fuword32_nocheck(void *);
60 1.1 darran uint64_t dtrace_fuword64_nocheck(void *);
61 1.1 darran
62 1.1 darran void
63 1.1 darran dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes,
64 1.1 darran uint32_t *intrpc)
65 1.1 darran {
66 1.1 darran int depth = 0;
67 1.1 darran register_t ebp;
68 1.1 darran struct i386_frame *frame;
69 1.1 darran vm_offset_t callpc;
70 1.2 darran #if 0 /* XXX TBD needs solaris_cpu (for fbt) */
71 1.2 darran pc_t caller = (pc_t) solaris_cpu[cpu_number()].cpu_dtrace_caller;
72 1.2 darran #else
73 1.2 darran pc_t caller = (pc_t) 0;
74 1.2 darran #endif
75 1.1 darran
76 1.1 darran if (intrpc != 0)
77 1.1 darran pcstack[depth++] = (pc_t) intrpc;
78 1.1 darran
79 1.1 darran aframes++;
80 1.1 darran
81 1.1 darran __asm __volatile("movl %%ebp,%0" : "=r" (ebp));
82 1.1 darran
83 1.1 darran frame = (struct i386_frame *)ebp;
84 1.1 darran while (depth < pcstack_limit) {
85 1.1 darran if (!INKERNEL(frame))
86 1.1 darran break;
87 1.1 darran
88 1.1 darran callpc = frame->f_retaddr;
89 1.1 darran
90 1.1 darran if (!INKERNEL(callpc))
91 1.1 darran break;
92 1.1 darran
93 1.1 darran if (aframes > 0) {
94 1.1 darran aframes--;
95 1.1 darran if ((aframes == 0) && (caller != 0)) {
96 1.1 darran pcstack[depth++] = caller;
97 1.1 darran }
98 1.1 darran }
99 1.1 darran else {
100 1.1 darran pcstack[depth++] = callpc;
101 1.1 darran }
102 1.1 darran
103 1.1 darran if (frame->f_frame <= frame ||
104 1.1 darran (vm_offset_t)frame->f_frame >=
105 1.2 darran (vm_offset_t)ebp + KSTACK_SIZE)
106 1.1 darran break;
107 1.1 darran frame = frame->f_frame;
108 1.1 darran }
109 1.1 darran
110 1.1 darran for (; depth < pcstack_limit; depth++) {
111 1.1 darran pcstack[depth] = 0;
112 1.1 darran }
113 1.1 darran }
114 1.1 darran
115 1.1 darran #ifdef notyet
116 1.1 darran static int
117 1.1 darran dtrace_getustack_common(uint64_t *pcstack, int pcstack_limit, uintptr_t pc,
118 1.1 darran uintptr_t sp)
119 1.1 darran {
120 1.1 darran klwp_t *lwp = ttolwp(curthread);
121 1.1 darran proc_t *p = curproc;
122 1.1 darran uintptr_t oldcontext = lwp->lwp_oldcontext;
123 1.1 darran volatile uint16_t *flags =
124 1.2 darran (volatile uint16_t *)&cpu_core[cpu_number()].cpuc_dtrace_flags;
125 1.1 darran size_t s1, s2;
126 1.1 darran int ret = 0;
127 1.1 darran
128 1.1 darran ASSERT(pcstack == NULL || pcstack_limit > 0);
129 1.1 darran
130 1.1 darran if (p->p_model == DATAMODEL_NATIVE) {
131 1.1 darran s1 = sizeof (struct frame) + 2 * sizeof (long);
132 1.1 darran s2 = s1 + sizeof (siginfo_t);
133 1.1 darran } else {
134 1.1 darran s1 = sizeof (struct frame32) + 3 * sizeof (int);
135 1.1 darran s2 = s1 + sizeof (siginfo32_t);
136 1.1 darran }
137 1.1 darran
138 1.1 darran while (pc != 0 && sp != 0) {
139 1.1 darran ret++;
140 1.1 darran if (pcstack != NULL) {
141 1.1 darran *pcstack++ = (uint64_t)pc;
142 1.1 darran pcstack_limit--;
143 1.1 darran if (pcstack_limit <= 0)
144 1.1 darran break;
145 1.1 darran }
146 1.1 darran
147 1.1 darran if (oldcontext == sp + s1 || oldcontext == sp + s2) {
148 1.1 darran if (p->p_model == DATAMODEL_NATIVE) {
149 1.1 darran ucontext_t *ucp = (ucontext_t *)oldcontext;
150 1.1 darran greg_t *gregs = ucp->uc_mcontext.gregs;
151 1.1 darran
152 1.1 darran sp = dtrace_fulword(&gregs[REG_FP]);
153 1.1 darran pc = dtrace_fulword(&gregs[REG_PC]);
154 1.1 darran
155 1.1 darran oldcontext = dtrace_fulword(&ucp->uc_link);
156 1.1 darran } else {
157 1.1 darran ucontext32_t *ucp = (ucontext32_t *)oldcontext;
158 1.1 darran greg32_t *gregs = ucp->uc_mcontext.gregs;
159 1.1 darran
160 1.1 darran sp = dtrace_fuword32(&gregs[EBP]);
161 1.1 darran pc = dtrace_fuword32(&gregs[EIP]);
162 1.1 darran
163 1.1 darran oldcontext = dtrace_fuword32(&ucp->uc_link);
164 1.1 darran }
165 1.1 darran } else {
166 1.1 darran if (p->p_model == DATAMODEL_NATIVE) {
167 1.1 darran struct frame *fr = (struct frame *)sp;
168 1.1 darran
169 1.1 darran pc = dtrace_fulword(&fr->fr_savpc);
170 1.1 darran sp = dtrace_fulword(&fr->fr_savfp);
171 1.1 darran } else {
172 1.1 darran struct frame32 *fr = (struct frame32 *)sp;
173 1.1 darran
174 1.1 darran pc = dtrace_fuword32(&fr->fr_savpc);
175 1.1 darran sp = dtrace_fuword32(&fr->fr_savfp);
176 1.1 darran }
177 1.1 darran }
178 1.1 darran
179 1.1 darran /*
180 1.1 darran * This is totally bogus: if we faulted, we're going to clear
181 1.1 darran * the fault and break. This is to deal with the apparently
182 1.1 darran * broken Java stacks on x86.
183 1.1 darran */
184 1.1 darran if (*flags & CPU_DTRACE_FAULT) {
185 1.1 darran *flags &= ~CPU_DTRACE_FAULT;
186 1.1 darran break;
187 1.1 darran }
188 1.1 darran }
189 1.1 darran
190 1.1 darran return (ret);
191 1.1 darran }
192 1.1 darran
193 1.1 darran void
194 1.1 darran dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit)
195 1.1 darran {
196 1.1 darran klwp_t *lwp = ttolwp(curthread);
197 1.1 darran proc_t *p = curproc;
198 1.1 darran struct regs *rp;
199 1.1 darran uintptr_t pc, sp;
200 1.1 darran volatile uint16_t *flags =
201 1.2 darran (volatile uint16_t *)&cpu_core[cpu_number()].cpuc_dtrace_flags;
202 1.1 darran int n;
203 1.1 darran
204 1.1 darran if (*flags & CPU_DTRACE_FAULT)
205 1.1 darran return;
206 1.1 darran
207 1.1 darran if (pcstack_limit <= 0)
208 1.1 darran return;
209 1.1 darran
210 1.1 darran /*
211 1.1 darran * If there's no user context we still need to zero the stack.
212 1.1 darran */
213 1.1 darran if (lwp == NULL || p == NULL || (rp = lwp->lwp_regs) == NULL)
214 1.1 darran goto zero;
215 1.1 darran
216 1.1 darran *pcstack++ = (uint64_t)p->p_pid;
217 1.1 darran pcstack_limit--;
218 1.1 darran
219 1.1 darran if (pcstack_limit <= 0)
220 1.1 darran return;
221 1.1 darran
222 1.1 darran pc = rp->r_pc;
223 1.1 darran sp = rp->r_fp;
224 1.1 darran
225 1.1 darran if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) {
226 1.1 darran *pcstack++ = (uint64_t)pc;
227 1.1 darran pcstack_limit--;
228 1.1 darran if (pcstack_limit <= 0)
229 1.1 darran return;
230 1.1 darran
231 1.1 darran if (p->p_model == DATAMODEL_NATIVE)
232 1.1 darran pc = dtrace_fulword((void *)rp->r_sp);
233 1.1 darran else
234 1.1 darran pc = dtrace_fuword32((void *)rp->r_sp);
235 1.1 darran }
236 1.1 darran
237 1.1 darran n = dtrace_getustack_common(pcstack, pcstack_limit, pc, sp);
238 1.1 darran ASSERT(n >= 0);
239 1.1 darran ASSERT(n <= pcstack_limit);
240 1.1 darran
241 1.1 darran pcstack += n;
242 1.1 darran pcstack_limit -= n;
243 1.1 darran
244 1.1 darran zero:
245 1.1 darran while (pcstack_limit-- > 0)
246 1.1 darran *pcstack++ = NULL;
247 1.1 darran }
248 1.1 darran
249 1.1 darran int
250 1.1 darran dtrace_getustackdepth(void)
251 1.1 darran {
252 1.1 darran }
253 1.1 darran
254 1.1 darran void
255 1.1 darran dtrace_getufpstack(uint64_t *pcstack, uint64_t *fpstack, int pcstack_limit)
256 1.1 darran {
257 1.1 darran klwp_t *lwp = ttolwp(curthread);
258 1.1 darran proc_t *p = curproc;
259 1.1 darran struct regs *rp;
260 1.1 darran uintptr_t pc, sp, oldcontext;
261 1.1 darran volatile uint16_t *flags =
262 1.2 darran (volatile uint16_t *)&cpu_core[cpu_number()].cpuc_dtrace_flags;
263 1.1 darran size_t s1, s2;
264 1.1 darran
265 1.1 darran if (*flags & CPU_DTRACE_FAULT)
266 1.1 darran return;
267 1.1 darran
268 1.1 darran if (pcstack_limit <= 0)
269 1.1 darran return;
270 1.1 darran
271 1.1 darran /*
272 1.1 darran * If there's no user context we still need to zero the stack.
273 1.1 darran */
274 1.1 darran if (lwp == NULL || p == NULL || (rp = lwp->lwp_regs) == NULL)
275 1.1 darran goto zero;
276 1.1 darran
277 1.1 darran *pcstack++ = (uint64_t)p->p_pid;
278 1.1 darran pcstack_limit--;
279 1.1 darran
280 1.1 darran if (pcstack_limit <= 0)
281 1.1 darran return;
282 1.1 darran
283 1.1 darran pc = rp->r_pc;
284 1.1 darran sp = rp->r_fp;
285 1.1 darran oldcontext = lwp->lwp_oldcontext;
286 1.1 darran
287 1.1 darran if (p->p_model == DATAMODEL_NATIVE) {
288 1.1 darran s1 = sizeof (struct frame) + 2 * sizeof (long);
289 1.1 darran s2 = s1 + sizeof (siginfo_t);
290 1.1 darran } else {
291 1.1 darran s1 = sizeof (struct frame32) + 3 * sizeof (int);
292 1.1 darran s2 = s1 + sizeof (siginfo32_t);
293 1.1 darran }
294 1.1 darran
295 1.1 darran if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) {
296 1.1 darran *pcstack++ = (uint64_t)pc;
297 1.1 darran *fpstack++ = 0;
298 1.1 darran pcstack_limit--;
299 1.1 darran if (pcstack_limit <= 0)
300 1.1 darran return;
301 1.1 darran
302 1.1 darran if (p->p_model == DATAMODEL_NATIVE)
303 1.1 darran pc = dtrace_fulword((void *)rp->r_sp);
304 1.1 darran else
305 1.1 darran pc = dtrace_fuword32((void *)rp->r_sp);
306 1.1 darran }
307 1.1 darran
308 1.1 darran while (pc != 0 && sp != 0) {
309 1.1 darran *pcstack++ = (uint64_t)pc;
310 1.1 darran *fpstack++ = sp;
311 1.1 darran pcstack_limit--;
312 1.1 darran if (pcstack_limit <= 0)
313 1.1 darran break;
314 1.1 darran
315 1.1 darran if (oldcontext == sp + s1 || oldcontext == sp + s2) {
316 1.1 darran if (p->p_model == DATAMODEL_NATIVE) {
317 1.1 darran ucontext_t *ucp = (ucontext_t *)oldcontext;
318 1.1 darran greg_t *gregs = ucp->uc_mcontext.gregs;
319 1.1 darran
320 1.1 darran sp = dtrace_fulword(&gregs[REG_FP]);
321 1.1 darran pc = dtrace_fulword(&gregs[REG_PC]);
322 1.1 darran
323 1.1 darran oldcontext = dtrace_fulword(&ucp->uc_link);
324 1.1 darran } else {
325 1.1 darran ucontext_t *ucp = (ucontext_t *)oldcontext;
326 1.1 darran greg_t *gregs = ucp->uc_mcontext.gregs;
327 1.1 darran
328 1.1 darran sp = dtrace_fuword32(&gregs[EBP]);
329 1.1 darran pc = dtrace_fuword32(&gregs[EIP]);
330 1.1 darran
331 1.1 darran oldcontext = dtrace_fuword32(&ucp->uc_link);
332 1.1 darran }
333 1.1 darran } else {
334 1.1 darran if (p->p_model == DATAMODEL_NATIVE) {
335 1.1 darran struct frame *fr = (struct frame *)sp;
336 1.1 darran
337 1.1 darran pc = dtrace_fulword(&fr->fr_savpc);
338 1.1 darran sp = dtrace_fulword(&fr->fr_savfp);
339 1.1 darran } else {
340 1.1 darran struct frame32 *fr = (struct frame32 *)sp;
341 1.1 darran
342 1.1 darran pc = dtrace_fuword32(&fr->fr_savpc);
343 1.1 darran sp = dtrace_fuword32(&fr->fr_savfp);
344 1.1 darran }
345 1.1 darran }
346 1.1 darran
347 1.1 darran /*
348 1.1 darran * This is totally bogus: if we faulted, we're going to clear
349 1.1 darran * the fault and break. This is to deal with the apparently
350 1.1 darran * broken Java stacks on x86.
351 1.1 darran */
352 1.1 darran if (*flags & CPU_DTRACE_FAULT) {
353 1.1 darran *flags &= ~CPU_DTRACE_FAULT;
354 1.1 darran break;
355 1.1 darran }
356 1.1 darran }
357 1.1 darran
358 1.1 darran zero:
359 1.1 darran while (pcstack_limit-- > 0)
360 1.1 darran *pcstack++ = NULL;
361 1.1 darran }
362 1.1 darran #endif
363 1.1 darran
364 1.1 darran uint64_t
365 1.1 darran dtrace_getarg(int arg, int aframes)
366 1.1 darran {
367 1.1 darran uintptr_t val;
368 1.1 darran struct i386_frame *fp = (struct i386_frame *)dtrace_getfp();
369 1.1 darran uintptr_t *stack;
370 1.2 darran
371 1.2 darran #if 0 /* XXX TBD needs ALTENTRY in dtrace_asm.S */
372 1.1 darran int i;
373 1.1 darran for (i = 1; i <= aframes; i++) {
374 1.1 darran fp = fp->f_frame;
375 1.1 darran
376 1.1 darran if (fp->f_retaddr == (long)dtrace_invop_callsite) {
377 1.1 darran /*
378 1.1 darran * If we pass through the invalid op handler, we will
379 1.1 darran * use the pointer that it passed to the stack as the
380 1.1 darran * second argument to dtrace_invop() as the pointer to
381 1.1 darran * the stack. When using this stack, we must step
382 1.1 darran * beyond the EIP/RIP that was pushed when the trap was
383 1.1 darran * taken -- hence the "+ 1" below.
384 1.1 darran */
385 1.1 darran stack = ((uintptr_t **)&fp[1])[1] + 1;
386 1.1 darran goto load;
387 1.1 darran }
388 1.1 darran }
389 1.2 darran #endif
390 1.1 darran
391 1.1 darran /*
392 1.1 darran * We know that we did not come through a trap to get into
393 1.1 darran * dtrace_probe() -- the provider simply called dtrace_probe()
394 1.1 darran * directly. As this is the case, we need to shift the argument
395 1.1 darran * that we're looking for: the probe ID is the first argument to
396 1.1 darran * dtrace_probe(), so the argument n will actually be found where
397 1.1 darran * one would expect to find argument (n + 1).
398 1.1 darran */
399 1.1 darran arg++;
400 1.1 darran
401 1.1 darran stack = (uintptr_t *)&fp[1];
402 1.1 darran
403 1.1 darran load:
404 1.1 darran DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
405 1.1 darran val = stack[arg];
406 1.1 darran DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
407 1.1 darran
408 1.1 darran return (val);
409 1.1 darran }
410 1.1 darran
411 1.1 darran int
412 1.1 darran dtrace_getstackdepth(int aframes)
413 1.1 darran {
414 1.1 darran int depth = 0;
415 1.1 darran struct i386_frame *frame;
416 1.1 darran vm_offset_t ebp;
417 1.1 darran
418 1.1 darran aframes++;
419 1.1 darran ebp = dtrace_getfp();
420 1.1 darran frame = (struct i386_frame *)ebp;
421 1.1 darran depth++;
422 1.1 darran for(;;) {
423 1.1 darran if (!INKERNEL((long) frame))
424 1.1 darran break;
425 1.1 darran if (!INKERNEL((long) frame->f_frame))
426 1.1 darran break;
427 1.1 darran depth++;
428 1.1 darran if (frame->f_frame <= frame ||
429 1.1 darran (vm_offset_t)frame->f_frame >=
430 1.2 darran (vm_offset_t)ebp + KSTACK_SIZE)
431 1.1 darran break;
432 1.1 darran frame = frame->f_frame;
433 1.1 darran }
434 1.1 darran if (depth < aframes)
435 1.1 darran return 0;
436 1.1 darran else
437 1.1 darran return depth - aframes;
438 1.1 darran }
439 1.1 darran
440 1.1 darran #ifdef notyet
441 1.1 darran ulong_t
442 1.1 darran dtrace_getreg(struct regs *rp, uint_t reg)
443 1.1 darran {
444 1.1 darran #if defined(__amd64)
445 1.1 darran int regmap[] = {
446 1.1 darran REG_GS, /* GS */
447 1.1 darran REG_FS, /* FS */
448 1.1 darran REG_ES, /* ES */
449 1.1 darran REG_DS, /* DS */
450 1.1 darran REG_RDI, /* EDI */
451 1.1 darran REG_RSI, /* ESI */
452 1.1 darran REG_RBP, /* EBP */
453 1.1 darran REG_RSP, /* ESP */
454 1.1 darran REG_RBX, /* EBX */
455 1.1 darran REG_RDX, /* EDX */
456 1.1 darran REG_RCX, /* ECX */
457 1.1 darran REG_RAX, /* EAX */
458 1.1 darran REG_TRAPNO, /* TRAPNO */
459 1.1 darran REG_ERR, /* ERR */
460 1.1 darran REG_RIP, /* EIP */
461 1.1 darran REG_CS, /* CS */
462 1.1 darran REG_RFL, /* EFL */
463 1.1 darran REG_RSP, /* UESP */
464 1.1 darran REG_SS /* SS */
465 1.1 darran };
466 1.1 darran
467 1.1 darran if (reg <= SS) {
468 1.1 darran if (reg >= sizeof (regmap) / sizeof (int)) {
469 1.1 darran DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
470 1.1 darran return (0);
471 1.1 darran }
472 1.1 darran
473 1.1 darran reg = regmap[reg];
474 1.1 darran } else {
475 1.1 darran reg -= SS + 1;
476 1.1 darran }
477 1.1 darran
478 1.1 darran switch (reg) {
479 1.1 darran case REG_RDI:
480 1.1 darran return (rp->r_rdi);
481 1.1 darran case REG_RSI:
482 1.1 darran return (rp->r_rsi);
483 1.1 darran case REG_RDX:
484 1.1 darran return (rp->r_rdx);
485 1.1 darran case REG_RCX:
486 1.1 darran return (rp->r_rcx);
487 1.1 darran case REG_R8:
488 1.1 darran return (rp->r_r8);
489 1.1 darran case REG_R9:
490 1.1 darran return (rp->r_r9);
491 1.1 darran case REG_RAX:
492 1.1 darran return (rp->r_rax);
493 1.1 darran case REG_RBX:
494 1.1 darran return (rp->r_rbx);
495 1.1 darran case REG_RBP:
496 1.1 darran return (rp->r_rbp);
497 1.1 darran case REG_R10:
498 1.1 darran return (rp->r_r10);
499 1.1 darran case REG_R11:
500 1.1 darran return (rp->r_r11);
501 1.1 darran case REG_R12:
502 1.1 darran return (rp->r_r12);
503 1.1 darran case REG_R13:
504 1.1 darran return (rp->r_r13);
505 1.1 darran case REG_R14:
506 1.1 darran return (rp->r_r14);
507 1.1 darran case REG_R15:
508 1.1 darran return (rp->r_r15);
509 1.1 darran case REG_DS:
510 1.1 darran return (rp->r_ds);
511 1.1 darran case REG_ES:
512 1.1 darran return (rp->r_es);
513 1.1 darran case REG_FS:
514 1.1 darran return (rp->r_fs);
515 1.1 darran case REG_GS:
516 1.1 darran return (rp->r_gs);
517 1.1 darran case REG_TRAPNO:
518 1.1 darran return (rp->r_trapno);
519 1.1 darran case REG_ERR:
520 1.1 darran return (rp->r_err);
521 1.1 darran case REG_RIP:
522 1.1 darran return (rp->r_rip);
523 1.1 darran case REG_CS:
524 1.1 darran return (rp->r_cs);
525 1.1 darran case REG_SS:
526 1.1 darran return (rp->r_ss);
527 1.1 darran case REG_RFL:
528 1.1 darran return (rp->r_rfl);
529 1.1 darran case REG_RSP:
530 1.1 darran return (rp->r_rsp);
531 1.1 darran default:
532 1.1 darran DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
533 1.1 darran return (0);
534 1.1 darran }
535 1.1 darran
536 1.1 darran #else
537 1.1 darran if (reg > SS) {
538 1.1 darran DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
539 1.1 darran return (0);
540 1.1 darran }
541 1.1 darran
542 1.1 darran return ((&rp->r_gs)[reg]);
543 1.1 darran #endif
544 1.1 darran }
545 1.1 darran #endif
546 1.1 darran
547 1.1 darran static int
548 1.1 darran dtrace_copycheck(uintptr_t uaddr, uintptr_t kaddr, size_t size)
549 1.1 darran {
550 1.1 darran ASSERT(kaddr >= kernelbase && kaddr + size >= kaddr);
551 1.1 darran
552 1.1 darran if (uaddr + size >= kernelbase || uaddr + size < uaddr) {
553 1.1 darran DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
554 1.2 darran cpu_core[cpu_number()].cpuc_dtrace_illval = uaddr;
555 1.1 darran return (0);
556 1.1 darran }
557 1.1 darran
558 1.1 darran return (1);
559 1.1 darran }
560 1.1 darran
561 1.1 darran void
562 1.1 darran dtrace_copyin(uintptr_t uaddr, uintptr_t kaddr, size_t size,
563 1.1 darran volatile uint16_t *flags)
564 1.1 darran {
565 1.1 darran if (dtrace_copycheck(uaddr, kaddr, size))
566 1.1 darran dtrace_copy(uaddr, kaddr, size);
567 1.1 darran }
568 1.1 darran
569 1.1 darran void
570 1.1 darran dtrace_copyout(uintptr_t kaddr, uintptr_t uaddr, size_t size,
571 1.1 darran volatile uint16_t *flags)
572 1.1 darran {
573 1.1 darran if (dtrace_copycheck(uaddr, kaddr, size))
574 1.1 darran dtrace_copy(kaddr, uaddr, size);
575 1.1 darran }
576 1.1 darran
577 1.1 darran void
578 1.1 darran dtrace_copyinstr(uintptr_t uaddr, uintptr_t kaddr, size_t size,
579 1.1 darran volatile uint16_t *flags)
580 1.1 darran {
581 1.1 darran if (dtrace_copycheck(uaddr, kaddr, size))
582 1.1 darran dtrace_copystr(uaddr, kaddr, size, flags);
583 1.1 darran }
584 1.1 darran
585 1.1 darran void
586 1.1 darran dtrace_copyoutstr(uintptr_t kaddr, uintptr_t uaddr, size_t size,
587 1.1 darran volatile uint16_t *flags)
588 1.1 darran {
589 1.1 darran if (dtrace_copycheck(uaddr, kaddr, size))
590 1.1 darran dtrace_copystr(kaddr, uaddr, size, flags);
591 1.1 darran }
592 1.1 darran
593 1.1 darran uint8_t
594 1.1 darran dtrace_fuword8(void *uaddr)
595 1.1 darran {
596 1.1 darran if ((uintptr_t)uaddr >= kernelbase) {
597 1.1 darran DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
598 1.2 darran cpu_core[cpu_number()].cpuc_dtrace_illval = (uintptr_t)uaddr;
599 1.1 darran return (0);
600 1.1 darran }
601 1.1 darran return (dtrace_fuword8_nocheck(uaddr));
602 1.1 darran }
603 1.1 darran
604 1.1 darran uint16_t
605 1.1 darran dtrace_fuword16(void *uaddr)
606 1.1 darran {
607 1.1 darran if ((uintptr_t)uaddr >= kernelbase) {
608 1.1 darran DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
609 1.2 darran cpu_core[cpu_number()].cpuc_dtrace_illval = (uintptr_t)uaddr;
610 1.1 darran return (0);
611 1.1 darran }
612 1.1 darran return (dtrace_fuword16_nocheck(uaddr));
613 1.1 darran }
614 1.1 darran
615 1.1 darran uint32_t
616 1.1 darran dtrace_fuword32(void *uaddr)
617 1.1 darran {
618 1.1 darran if ((uintptr_t)uaddr >= kernelbase) {
619 1.1 darran DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
620 1.2 darran cpu_core[cpu_number()].cpuc_dtrace_illval = (uintptr_t)uaddr;
621 1.1 darran return (0);
622 1.1 darran }
623 1.1 darran return (dtrace_fuword32_nocheck(uaddr));
624 1.1 darran }
625 1.1 darran
626 1.1 darran uint64_t
627 1.1 darran dtrace_fuword64(void *uaddr)
628 1.1 darran {
629 1.1 darran if ((uintptr_t)uaddr >= kernelbase) {
630 1.1 darran DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
631 1.2 darran cpu_core[cpu_number()].cpuc_dtrace_illval = (uintptr_t)uaddr;
632 1.1 darran return (0);
633 1.1 darran }
634 1.1 darran return (dtrace_fuword64_nocheck(uaddr));
635 1.1 darran }
636