1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * Copyright (c) 2013, 2014 by Delphix. All rights reserved.
29 */
30
31 #include <sys/dtrace_impl.h>
32 #include <sys/stack.h>
33 #include <sys/frame.h>
34 #include <sys/cmn_err.h>
35 #include <sys/privregs.h>
36 #include <sys/sysmacros.h>
37
38 extern uintptr_t kernelbase;
39
40 int dtrace_ustackdepth_max = 2048;
41
42 void
dtrace_getpcstack(pc_t * pcstack,int pcstack_limit,int aframes,uint32_t * intrpc)43 dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes,
44 uint32_t *intrpc)
45 {
46 struct frame *fp = (struct frame *)dtrace_getfp();
47 struct frame *nextfp, *minfp, *stacktop;
48 int depth = 0;
49 int on_intr, last = 0;
50 uintptr_t pc;
51 uintptr_t caller = CPU->cpu_dtrace_caller;
52
53 if ((on_intr = CPU_ON_INTR(CPU)) != 0)
54 stacktop = (struct frame *)(CPU->cpu_intr_stack + SA(MINFRAME));
55 else
56 stacktop = (struct frame *)curthread->t_stk;
57 minfp = fp;
58
59 aframes++;
60
61 if (intrpc != NULL && depth < pcstack_limit)
62 pcstack[depth++] = (pc_t)intrpc;
63
64 while (depth < pcstack_limit) {
65 nextfp = (struct frame *)fp->fr_savfp;
66 pc = fp->fr_savpc;
67
68 if (nextfp <= minfp || nextfp >= stacktop) {
69 if (on_intr) {
70 /*
71 * Hop from interrupt stack to thread stack.
72 */
73 stacktop = (struct frame *)curthread->t_stk;
74 minfp = (struct frame *)curthread->t_stkbase;
75 on_intr = 0;
76 continue;
77 }
78
79 /*
80 * This is the last frame we can process; indicate
81 * that we should return after processing this frame.
82 */
83 last = 1;
84 }
85
86 if (aframes > 0) {
87 if (--aframes == 0 && caller != NULL) {
88 /*
89 * We've just run out of artificial frames,
90 * and we have a valid caller -- fill it in
91 * now.
92 */
93 ASSERT(depth < pcstack_limit);
94 pcstack[depth++] = (pc_t)caller;
95 caller = NULL;
96 }
97 } else {
98 if (depth < pcstack_limit)
99 pcstack[depth++] = (pc_t)pc;
100 }
101
102 if (last) {
103 while (depth < pcstack_limit)
104 pcstack[depth++] = NULL;
105 return;
106 }
107
108 fp = nextfp;
109 minfp = fp;
110 }
111 }
112
113 static int
dtrace_getustack_common(uint64_t * pcstack,int pcstack_limit,uintptr_t pc,uintptr_t sp)114 dtrace_getustack_common(uint64_t *pcstack, int pcstack_limit, uintptr_t pc,
115 uintptr_t sp)
116 {
117 klwp_t *lwp = ttolwp(curthread);
118 proc_t *p = curproc;
119 uintptr_t oldcontext = lwp->lwp_oldcontext;
120 uintptr_t oldsp;
121 volatile uint16_t *flags =
122 (volatile uint16_t *)&cpu_core[CPU->cpu_id].cpuc_dtrace_flags;
123 size_t s1, s2;
124 int ret = 0;
125
126 ASSERT(pcstack == NULL || pcstack_limit > 0);
127 ASSERT(dtrace_ustackdepth_max > 0);
128
129 if (p->p_model == DATAMODEL_NATIVE) {
130 s1 = sizeof (struct frame) + 2 * sizeof (long);
131 s2 = s1 + sizeof (siginfo_t);
132 } else {
133 s1 = sizeof (struct frame32) + 3 * sizeof (int);
134 s2 = s1 + sizeof (siginfo32_t);
135 }
136
137 while (pc != 0) {
138 /*
139 * We limit the number of times we can go around this
140 * loop to account for a circular stack.
141 */
142 if (ret++ >= dtrace_ustackdepth_max) {
143 *flags |= CPU_DTRACE_BADSTACK;
144 cpu_core[CPU->cpu_id].cpuc_dtrace_illval = sp;
145 break;
146 }
147
148 if (pcstack != NULL) {
149 *pcstack++ = (uint64_t)pc;
150 pcstack_limit--;
151 if (pcstack_limit <= 0)
152 break;
153 }
154
155 if (sp == 0)
156 break;
157
158 oldsp = sp;
159
160 if (oldcontext == sp + s1 || oldcontext == sp + s2) {
161 if (p->p_model == DATAMODEL_NATIVE) {
162 ucontext_t *ucp = (ucontext_t *)oldcontext;
163 greg_t *gregs = ucp->uc_mcontext.gregs;
164
165 sp = dtrace_fulword(&gregs[REG_FP]);
166 pc = dtrace_fulword(&gregs[REG_PC]);
167
168 oldcontext = dtrace_fulword(&ucp->uc_link);
169 } else {
170 ucontext32_t *ucp = (ucontext32_t *)oldcontext;
171 greg32_t *gregs = ucp->uc_mcontext.gregs;
172
173 sp = dtrace_fuword32(&gregs[EBP]);
174 pc = dtrace_fuword32(&gregs[EIP]);
175
176 oldcontext = dtrace_fuword32(&ucp->uc_link);
177 }
178 } else {
179 if (p->p_model == DATAMODEL_NATIVE) {
180 struct frame *fr = (struct frame *)sp;
181
182 pc = dtrace_fulword(&fr->fr_savpc);
183 sp = dtrace_fulword(&fr->fr_savfp);
184 } else {
185 struct frame32 *fr = (struct frame32 *)sp;
186
187 pc = dtrace_fuword32(&fr->fr_savpc);
188 sp = dtrace_fuword32(&fr->fr_savfp);
189 }
190 }
191
192 if (sp == oldsp) {
193 *flags |= CPU_DTRACE_BADSTACK;
194 cpu_core[CPU->cpu_id].cpuc_dtrace_illval = sp;
195 break;
196 }
197
198 /*
199 * This is totally bogus: if we faulted, we're going to clear
200 * the fault and break. This is to deal with the apparently
201 * broken Java stacks on x86.
202 */
203 if (*flags & CPU_DTRACE_FAULT) {
204 *flags &= ~CPU_DTRACE_FAULT;
205 break;
206 }
207 }
208
209 return (ret);
210 }
211
212 void
dtrace_getupcstack(uint64_t * pcstack,int pcstack_limit)213 dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit)
214 {
215 klwp_t *lwp = ttolwp(curthread);
216 proc_t *p = curproc;
217 struct regs *rp;
218 uintptr_t pc, sp;
219 int n;
220
221 ASSERT(DTRACE_CPUFLAG_ISSET(CPU_DTRACE_NOFAULT));
222
223 if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_FAULT))
224 return;
225
226 if (pcstack_limit <= 0)
227 return;
228
229 /*
230 * If there's no user context we still need to zero the stack.
231 */
232 if (lwp == NULL || p == NULL || (rp = lwp->lwp_regs) == NULL)
233 goto zero;
234
235 *pcstack++ = (uint64_t)p->p_pid;
236 pcstack_limit--;
237
238 if (pcstack_limit <= 0)
239 return;
240
241 pc = rp->r_pc;
242 sp = rp->r_fp;
243
244 if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) {
245 *pcstack++ = (uint64_t)pc;
246 pcstack_limit--;
247 if (pcstack_limit <= 0)
248 return;
249
250 if (p->p_model == DATAMODEL_NATIVE)
251 pc = dtrace_fulword((void *)rp->r_sp);
252 else
253 pc = dtrace_fuword32((void *)rp->r_sp);
254 }
255
256 n = dtrace_getustack_common(pcstack, pcstack_limit, pc, sp);
257 ASSERT(n >= 0);
258 ASSERT(n <= pcstack_limit);
259
260 pcstack += n;
261 pcstack_limit -= n;
262
263 zero:
264 while (pcstack_limit-- > 0)
265 *pcstack++ = NULL;
266 }
267
268 int
dtrace_getustackdepth(void)269 dtrace_getustackdepth(void)
270 {
271 klwp_t *lwp = ttolwp(curthread);
272 proc_t *p = curproc;
273 struct regs *rp;
274 uintptr_t pc, sp;
275 int n = 0;
276
277 if (lwp == NULL || p == NULL || (rp = lwp->lwp_regs) == NULL)
278 return (0);
279
280 if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_FAULT))
281 return (-1);
282
283 pc = rp->r_pc;
284 sp = rp->r_fp;
285
286 if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) {
287 n++;
288
289 if (p->p_model == DATAMODEL_NATIVE)
290 pc = dtrace_fulword((void *)rp->r_sp);
291 else
292 pc = dtrace_fuword32((void *)rp->r_sp);
293 }
294
295 n += dtrace_getustack_common(NULL, 0, pc, sp);
296
297 return (n);
298 }
299
300 void
dtrace_getufpstack(uint64_t * pcstack,uint64_t * fpstack,int pcstack_limit)301 dtrace_getufpstack(uint64_t *pcstack, uint64_t *fpstack, int pcstack_limit)
302 {
303 klwp_t *lwp = ttolwp(curthread);
304 proc_t *p = curproc;
305 struct regs *rp;
306 uintptr_t pc, sp, oldcontext;
307 volatile uint16_t *flags =
308 (volatile uint16_t *)&cpu_core[CPU->cpu_id].cpuc_dtrace_flags;
309 size_t s1, s2;
310
311 if (*flags & CPU_DTRACE_FAULT)
312 return;
313
314 if (pcstack_limit <= 0)
315 return;
316
317 /*
318 * If there's no user context we still need to zero the stack.
319 */
320 if (lwp == NULL || p == NULL || (rp = lwp->lwp_regs) == NULL)
321 goto zero;
322
323 *pcstack++ = (uint64_t)p->p_pid;
324 pcstack_limit--;
325
326 if (pcstack_limit <= 0)
327 return;
328
329 pc = rp->r_pc;
330 sp = rp->r_fp;
331 oldcontext = lwp->lwp_oldcontext;
332
333 if (p->p_model == DATAMODEL_NATIVE) {
334 s1 = sizeof (struct frame) + 2 * sizeof (long);
335 s2 = s1 + sizeof (siginfo_t);
336 } else {
337 s1 = sizeof (struct frame32) + 3 * sizeof (int);
338 s2 = s1 + sizeof (siginfo32_t);
339 }
340
341 if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) {
342 *pcstack++ = (uint64_t)pc;
343 *fpstack++ = 0;
344 pcstack_limit--;
345 if (pcstack_limit <= 0)
346 return;
347
348 if (p->p_model == DATAMODEL_NATIVE)
349 pc = dtrace_fulword((void *)rp->r_sp);
350 else
351 pc = dtrace_fuword32((void *)rp->r_sp);
352 }
353
354 while (pc != 0) {
355 *pcstack++ = (uint64_t)pc;
356 *fpstack++ = sp;
357 pcstack_limit--;
358 if (pcstack_limit <= 0)
359 break;
360
361 if (sp == 0)
362 break;
363
364 if (oldcontext == sp + s1 || oldcontext == sp + s2) {
365 if (p->p_model == DATAMODEL_NATIVE) {
366 ucontext_t *ucp = (ucontext_t *)oldcontext;
367 greg_t *gregs = ucp->uc_mcontext.gregs;
368
369 sp = dtrace_fulword(&gregs[REG_FP]);
370 pc = dtrace_fulword(&gregs[REG_PC]);
371
372 oldcontext = dtrace_fulword(&ucp->uc_link);
373 } else {
374 ucontext_t *ucp = (ucontext_t *)oldcontext;
375 greg_t *gregs = ucp->uc_mcontext.gregs;
376
377 sp = dtrace_fuword32(&gregs[EBP]);
378 pc = dtrace_fuword32(&gregs[EIP]);
379
380 oldcontext = dtrace_fuword32(&ucp->uc_link);
381 }
382 } else {
383 if (p->p_model == DATAMODEL_NATIVE) {
384 struct frame *fr = (struct frame *)sp;
385
386 pc = dtrace_fulword(&fr->fr_savpc);
387 sp = dtrace_fulword(&fr->fr_savfp);
388 } else {
389 struct frame32 *fr = (struct frame32 *)sp;
390
391 pc = dtrace_fuword32(&fr->fr_savpc);
392 sp = dtrace_fuword32(&fr->fr_savfp);
393 }
394 }
395
396 /*
397 * This is totally bogus: if we faulted, we're going to clear
398 * the fault and break. This is to deal with the apparently
399 * broken Java stacks on x86.
400 */
401 if (*flags & CPU_DTRACE_FAULT) {
402 *flags &= ~CPU_DTRACE_FAULT;
403 break;
404 }
405 }
406
407 zero:
408 while (pcstack_limit-- > 0)
409 *pcstack++ = NULL;
410 }
411
412 /*ARGSUSED*/
413 uint64_t
dtrace_getarg(int arg,int aframes)414 dtrace_getarg(int arg, int aframes)
415 {
416 uintptr_t val;
417 struct frame *fp = (struct frame *)dtrace_getfp();
418 uintptr_t *stack;
419 int i;
420 #if defined(__amd64)
421 /*
422 * A total of 6 arguments are passed via registers; any argument with
423 * index of 5 or lower is therefore in a register.
424 */
425 int inreg = 5;
426 #endif
427
428 for (i = 1; i <= aframes; i++) {
429 fp = (struct frame *)(fp->fr_savfp);
430
431 if (fp->fr_savpc == (pc_t)dtrace_invop_callsite) {
432 #if !defined(__amd64)
433 /*
434 * If we pass through the invalid op handler, we will
435 * use the pointer that it passed to the stack as the
436 * second argument to dtrace_invop() as the pointer to
437 * the stack. When using this stack, we must step
438 * beyond the EIP that was pushed when the trap was
439 * taken -- hence the "+ 1" below.
440 */
441 stack = ((uintptr_t **)&fp[1])[1] + 1;
442 #else
443 /*
444 * In the case of amd64, we will use the pointer to the
445 * regs structure that was pushed when we took the
446 * trap. To get this structure, we must increment
447 * beyond the frame structure, the calling RIP, and
448 * padding stored in dtrace_invop(). If the argument
449 * that we're seeking is passed on the stack, we'll
450 * pull the true stack pointer out of the saved
451 * registers and decrement our argument by the number
452 * of arguments passed in registers; if the argument
453 * we're seeking is passed in regsiters, we can just
454 * load it directly.
455 */
456 struct regs *rp = (struct regs *)((uintptr_t)&fp[1] +
457 sizeof (uintptr_t) * 2);
458
459 if (arg <= inreg) {
460 stack = (uintptr_t *)&rp->r_rdi;
461 } else {
462 stack = (uintptr_t *)(rp->r_rsp);
463 arg -= inreg;
464 }
465 #endif
466 goto load;
467 }
468
469 }
470
471 /*
472 * We know that we did not come through a trap to get into
473 * dtrace_probe() -- the provider simply called dtrace_probe()
474 * directly. As this is the case, we need to shift the argument
475 * that we're looking for: the probe ID is the first argument to
476 * dtrace_probe(), so the argument n will actually be found where
477 * one would expect to find argument (n + 1).
478 */
479 arg++;
480
481 #if defined(__amd64)
482 if (arg <= inreg) {
483 /*
484 * This shouldn't happen. If the argument is passed in a
485 * register then it should have been, well, passed in a
486 * register...
487 */
488 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
489 return (0);
490 }
491
492 arg -= (inreg + 1);
493 #endif
494 stack = (uintptr_t *)&fp[1];
495
496 load:
497 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
498 val = stack[arg];
499 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
500
501 return (val);
502 }
503
504 /*ARGSUSED*/
505 int
dtrace_getstackdepth(int aframes)506 dtrace_getstackdepth(int aframes)
507 {
508 struct frame *fp = (struct frame *)dtrace_getfp();
509 struct frame *nextfp, *minfp, *stacktop;
510 int depth = 0;
511 int on_intr;
512
513 if ((on_intr = CPU_ON_INTR(CPU)) != 0)
514 stacktop = (struct frame *)(CPU->cpu_intr_stack + SA(MINFRAME));
515 else
516 stacktop = (struct frame *)curthread->t_stk;
517 minfp = fp;
518
519 aframes++;
520
521 for (;;) {
522 depth++;
523
524 nextfp = (struct frame *)fp->fr_savfp;
525
526 if (nextfp <= minfp || nextfp >= stacktop) {
527 if (on_intr) {
528 /*
529 * Hop from interrupt stack to thread stack.
530 */
531 stacktop = (struct frame *)curthread->t_stk;
532 minfp = (struct frame *)curthread->t_stkbase;
533 on_intr = 0;
534 continue;
535 }
536 break;
537 }
538
539 fp = nextfp;
540 minfp = fp;
541 }
542
543 if (depth <= aframes)
544 return (0);
545
546 return (depth - aframes);
547 }
548
549 ulong_t
dtrace_getreg(struct regs * rp,uint_t reg)550 dtrace_getreg(struct regs *rp, uint_t reg)
551 {
552 #if defined(__amd64)
553 int regmap[] = {
554 REG_GS, /* GS */
555 REG_FS, /* FS */
556 REG_ES, /* ES */
557 REG_DS, /* DS */
558 REG_RDI, /* EDI */
559 REG_RSI, /* ESI */
560 REG_RBP, /* EBP */
561 REG_RSP, /* ESP */
562 REG_RBX, /* EBX */
563 REG_RDX, /* EDX */
564 REG_RCX, /* ECX */
565 REG_RAX, /* EAX */
566 REG_TRAPNO, /* TRAPNO */
567 REG_ERR, /* ERR */
568 REG_RIP, /* EIP */
569 REG_CS, /* CS */
570 REG_RFL, /* EFL */
571 REG_RSP, /* UESP */
572 REG_SS /* SS */
573 };
574
575 if (reg <= SS) {
576 if (reg >= sizeof (regmap) / sizeof (int)) {
577 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
578 return (0);
579 }
580
581 reg = regmap[reg];
582 } else {
583 reg -= SS + 1;
584 }
585
586 switch (reg) {
587 case REG_RDI:
588 return (rp->r_rdi);
589 case REG_RSI:
590 return (rp->r_rsi);
591 case REG_RDX:
592 return (rp->r_rdx);
593 case REG_RCX:
594 return (rp->r_rcx);
595 case REG_R8:
596 return (rp->r_r8);
597 case REG_R9:
598 return (rp->r_r9);
599 case REG_RAX:
600 return (rp->r_rax);
601 case REG_RBX:
602 return (rp->r_rbx);
603 case REG_RBP:
604 return (rp->r_rbp);
605 case REG_R10:
606 return (rp->r_r10);
607 case REG_R11:
608 return (rp->r_r11);
609 case REG_R12:
610 return (rp->r_r12);
611 case REG_R13:
612 return (rp->r_r13);
613 case REG_R14:
614 return (rp->r_r14);
615 case REG_R15:
616 return (rp->r_r15);
617 case REG_DS:
618 return (rp->r_ds);
619 case REG_ES:
620 return (rp->r_es);
621 case REG_FS:
622 return (rp->r_fs);
623 case REG_GS:
624 return (rp->r_gs);
625 case REG_TRAPNO:
626 return (rp->r_trapno);
627 case REG_ERR:
628 return (rp->r_err);
629 case REG_RIP:
630 return (rp->r_rip);
631 case REG_CS:
632 return (rp->r_cs);
633 case REG_SS:
634 return (rp->r_ss);
635 case REG_RFL:
636 return (rp->r_rfl);
637 case REG_RSP:
638 return (rp->r_rsp);
639 default:
640 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
641 return (0);
642 }
643
644 #else
645 if (reg > SS) {
646 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
647 return (0);
648 }
649
650 return ((&rp->r_gs)[reg]);
651 #endif
652 }
653
654 static int
dtrace_copycheck(uintptr_t uaddr,uintptr_t kaddr,size_t size)655 dtrace_copycheck(uintptr_t uaddr, uintptr_t kaddr, size_t size)
656 {
657 ASSERT(kaddr >= kernelbase && kaddr + size >= kaddr);
658
659 if (uaddr + size >= kernelbase || uaddr + size < uaddr) {
660 DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
661 cpu_core[CPU->cpu_id].cpuc_dtrace_illval = uaddr;
662 return (0);
663 }
664
665 return (1);
666 }
667
668 /*ARGSUSED*/
669 void
dtrace_copyin(uintptr_t uaddr,uintptr_t kaddr,size_t size,volatile uint16_t * flags)670 dtrace_copyin(uintptr_t uaddr, uintptr_t kaddr, size_t size,
671 volatile uint16_t *flags)
672 {
673 if (dtrace_copycheck(uaddr, kaddr, size))
674 dtrace_copy(uaddr, kaddr, size);
675 }
676
677 /*ARGSUSED*/
678 void
dtrace_copyout(uintptr_t kaddr,uintptr_t uaddr,size_t size,volatile uint16_t * flags)679 dtrace_copyout(uintptr_t kaddr, uintptr_t uaddr, size_t size,
680 volatile uint16_t *flags)
681 {
682 if (dtrace_copycheck(uaddr, kaddr, size))
683 dtrace_copy(kaddr, uaddr, size);
684 }
685
686 void
dtrace_copyinstr(uintptr_t uaddr,uintptr_t kaddr,size_t size,volatile uint16_t * flags)687 dtrace_copyinstr(uintptr_t uaddr, uintptr_t kaddr, size_t size,
688 volatile uint16_t *flags)
689 {
690 if (dtrace_copycheck(uaddr, kaddr, size))
691 dtrace_copystr(uaddr, kaddr, size, flags);
692 }
693
694 void
dtrace_copyoutstr(uintptr_t kaddr,uintptr_t uaddr,size_t size,volatile uint16_t * flags)695 dtrace_copyoutstr(uintptr_t kaddr, uintptr_t uaddr, size_t size,
696 volatile uint16_t *flags)
697 {
698 if (dtrace_copycheck(uaddr, kaddr, size))
699 dtrace_copystr(kaddr, uaddr, size, flags);
700 }
701
702 uint8_t
dtrace_fuword8(void * uaddr)703 dtrace_fuword8(void *uaddr)
704 {
705 extern uint8_t dtrace_fuword8_nocheck(void *);
706 if ((uintptr_t)uaddr >= _userlimit) {
707 DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
708 cpu_core[CPU->cpu_id].cpuc_dtrace_illval = (uintptr_t)uaddr;
709 return (0);
710 }
711 return (dtrace_fuword8_nocheck(uaddr));
712 }
713
714 uint16_t
dtrace_fuword16(void * uaddr)715 dtrace_fuword16(void *uaddr)
716 {
717 extern uint16_t dtrace_fuword16_nocheck(void *);
718 if ((uintptr_t)uaddr >= _userlimit) {
719 DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
720 cpu_core[CPU->cpu_id].cpuc_dtrace_illval = (uintptr_t)uaddr;
721 return (0);
722 }
723 return (dtrace_fuword16_nocheck(uaddr));
724 }
725
726 uint32_t
dtrace_fuword32(void * uaddr)727 dtrace_fuword32(void *uaddr)
728 {
729 extern uint32_t dtrace_fuword32_nocheck(void *);
730 if ((uintptr_t)uaddr >= _userlimit) {
731 DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
732 cpu_core[CPU->cpu_id].cpuc_dtrace_illval = (uintptr_t)uaddr;
733 return (0);
734 }
735 return (dtrace_fuword32_nocheck(uaddr));
736 }
737
738 uint64_t
dtrace_fuword64(void * uaddr)739 dtrace_fuword64(void *uaddr)
740 {
741 extern uint64_t dtrace_fuword64_nocheck(void *);
742 if ((uintptr_t)uaddr >= _userlimit) {
743 DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
744 cpu_core[CPU->cpu_id].cpuc_dtrace_illval = (uintptr_t)uaddr;
745 return (0);
746 }
747 return (dtrace_fuword64_nocheck(uaddr));
748 }
749