182 /* 183 * This is totally bogus: if we faulted, we're going to clear 184 * the fault and break. This is to deal with the apparently 185 * broken Java stacks on x86. 186 */ 187 if (*flags & CPU_DTRACE_FAULT) { 188 *flags &= ~CPU_DTRACE_FAULT; 189 break; 190 } 191 } 192 193 return (ret); 194} 195 196void 197dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit) 198{ 199 proc_t *p = curproc; 200 struct trapframe *tf; 201 uintptr_t pc, sp, fp; 202 volatile uint16_t *flags = 203 (volatile uint16_t *)&cpu_core[curcpu].cpuc_dtrace_flags; 204 int n; 205 206 if (*flags & CPU_DTRACE_FAULT) 207 return; 208 209 if (pcstack_limit <= 0) 210 return; 211 212 /* 213 * If there's no user context we still need to zero the stack. 214 */ 215 if (p == NULL || (tf = curthread->td_frame) == NULL) 216 goto zero; 217 218 *pcstack++ = (uint64_t)p->p_pid; 219 pcstack_limit--; 220 221 if (pcstack_limit <= 0) 222 return; 223 224 pc = tf->tf_eip; 225 fp = tf->tf_ebp; 226 sp = tf->tf_esp; 227 228 if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) { 229 /* 230 * In an entry probe. The frame pointer has not yet been 231 * pushed (that happens in the function prologue). The 232 * best approach is to add the current pc as a missing top 233 * of stack and back the pc up to the caller, which is stored 234 * at the current stack pointer address since the call 235 * instruction puts it there right before the branch. 236 */ 237 238 *pcstack++ = (uint64_t)pc; 239 pcstack_limit--; 240 if (pcstack_limit <= 0) 241 return; 242 243 pc = dtrace_fuword32((void *) sp); 244 } 245 246 n = dtrace_getustack_common(pcstack, pcstack_limit, pc, sp); 247 ASSERT(n >= 0); 248 ASSERT(n <= pcstack_limit); 249 250 pcstack += n; 251 pcstack_limit -= n; 252 253zero: 254 while (pcstack_limit-- > 0) 255 *pcstack++ = 0; 256} 257 258int 259dtrace_getustackdepth(void) 260{ 261 proc_t *p = curproc; 262 struct trapframe *tf; 263 uintptr_t pc, fp, sp; 264 int n = 0; 265 266 if (p == NULL || (tf = curthread->td_frame) == NULL) 267 return (0); 268 269 if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_FAULT)) 270 return (-1); 271 272 pc = tf->tf_eip; 273 fp = tf->tf_ebp; 274 sp = tf->tf_esp; 275 276 if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) { 277 /* 278 * In an entry probe. The frame pointer has not yet been 279 * pushed (that happens in the function prologue). The 280 * best approach is to add the current pc as a missing top 281 * of stack and back the pc up to the caller, which is stored 282 * at the current stack pointer address since the call 283 * instruction puts it there right before the branch. 284 */ 285 286 pc = dtrace_fuword32((void *) sp); 287 n++; 288 } 289 290 n += dtrace_getustack_common(NULL, 0, pc, fp); 291 292 return (n); 293} 294 295void 296dtrace_getufpstack(uint64_t *pcstack, uint64_t *fpstack, int pcstack_limit) 297{ 298 proc_t *p = curproc; 299 struct trapframe *tf; 300 uintptr_t pc, sp, fp; 301 volatile uint16_t *flags = 302 (volatile uint16_t *)&cpu_core[curcpu].cpuc_dtrace_flags; 303#ifdef notyet /* XXX signal stack */ 304 uintptr_t oldcontext; 305 size_t s1, s2; 306#endif 307 308 if (*flags & CPU_DTRACE_FAULT) 309 return; 310 311 if (pcstack_limit <= 0) 312 return; 313 314 /* 315 * If there's no user context we still need to zero the stack. 316 */ 317 if (p == NULL || (tf = curthread->td_frame) == NULL) 318 goto zero; 319 320 *pcstack++ = (uint64_t)p->p_pid; 321 pcstack_limit--; 322 323 if (pcstack_limit <= 0) 324 return; 325 326 pc = tf->tf_eip; 327 fp = tf->tf_ebp; 328 sp = tf->tf_esp; 329 330#ifdef notyet /* XXX signal stack */ 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#endif 341 342 if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) { 343 *pcstack++ = (uint64_t)pc; 344 *fpstack++ = 0; 345 pcstack_limit--; 346 if (pcstack_limit <= 0) 347 return; 348 349 pc = dtrace_fuword32((void *)sp); 350 } 351 352 while (pc != 0) { 353 *pcstack++ = (uint64_t)pc; 354 *fpstack++ = fp; 355 pcstack_limit--; 356 if (pcstack_limit <= 0) 357 break; 358 359 if (fp == 0) 360 break; 361 362#ifdef notyet /* XXX signal stack */ 363 if (oldcontext == sp + s1 || oldcontext == sp + s2) { 364 if (p->p_model == DATAMODEL_NATIVE) { 365 ucontext_t *ucp = (ucontext_t *)oldcontext; 366 greg_t *gregs = ucp->uc_mcontext.gregs; 367 368 sp = dtrace_fulword(&gregs[REG_FP]); 369 pc = dtrace_fulword(&gregs[REG_PC]); 370 371 oldcontext = dtrace_fulword(&ucp->uc_link); 372 } else { 373 ucontext_t *ucp = (ucontext_t *)oldcontext; 374 greg_t *gregs = ucp->uc_mcontext.gregs; 375 376 sp = dtrace_fuword32(&gregs[EBP]); 377 pc = dtrace_fuword32(&gregs[EIP]); 378 379 oldcontext = dtrace_fuword32(&ucp->uc_link); 380 } 381 } else 382#endif /* XXX */ 383 { 384 pc = dtrace_fuword32((void *)(fp + 385 offsetof(struct i386_frame, f_retaddr))); 386 fp = dtrace_fuword32((void *)fp); 387 } 388 389 /* 390 * This is totally bogus: if we faulted, we're going to clear 391 * the fault and break. This is to deal with the apparently 392 * broken Java stacks on x86. 393 */ 394 if (*flags & CPU_DTRACE_FAULT) { 395 *flags &= ~CPU_DTRACE_FAULT; 396 break; 397 } 398 } 399 400zero: 401 while (pcstack_limit-- > 0) 402 *pcstack++ = 0; 403} 404 405uint64_t 406dtrace_getarg(int arg, int aframes) 407{ 408 uintptr_t val; 409 struct i386_frame *fp = (struct i386_frame *)dtrace_getfp(); 410 uintptr_t *stack; 411 int i; 412 413 for (i = 1; i <= aframes; i++) { 414 fp = fp->f_frame; 415 416 if (P2ROUNDUP(fp->f_retaddr, 4) == 417 (long)dtrace_invop_callsite) { 418 /* 419 * If we pass through the invalid op handler, we will 420 * use the pointer that it passed to the stack as the 421 * second argument to dtrace_invop() as the pointer to 422 * the stack. When using this stack, we must step 423 * beyond the EIP/RIP that was pushed when the trap was 424 * taken -- hence the "+ 1" below. 425 */ 426 stack = ((uintptr_t **)&fp[1])[0] + 1; 427 goto load; 428 } 429 430 } 431 432 /* 433 * We know that we did not come through a trap to get into 434 * dtrace_probe() -- the provider simply called dtrace_probe() 435 * directly. As this is the case, we need to shift the argument 436 * that we're looking for: the probe ID is the first argument to 437 * dtrace_probe(), so the argument n will actually be found where 438 * one would expect to find argument (n + 1). 439 */ 440 arg++; 441 442 stack = (uintptr_t *)fp + 2; 443 444load: 445 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT); 446 val = stack[arg]; 447 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT); 448 449 return (val); 450} 451 452int 453dtrace_getstackdepth(int aframes) 454{ 455 int depth = 0; 456 struct i386_frame *frame; 457 vm_offset_t ebp; 458 459 aframes++; 460 ebp = dtrace_getfp(); 461 frame = (struct i386_frame *)ebp; 462 depth++; 463 for(;;) { 464 if (!INKERNEL((long) frame)) 465 break; 466 if (!INKERNEL((long) frame->f_frame)) 467 break; 468 depth++; 469 if (frame->f_frame <= frame || 470 (vm_offset_t)frame->f_frame >= 471 (vm_offset_t)ebp + KSTACK_PAGES * PAGE_SIZE) 472 break; 473 frame = frame->f_frame; 474 } 475 if (depth < aframes) 476 return 0; 477 else 478 return depth - aframes; 479} 480 481ulong_t 482dtrace_getreg(struct trapframe *rp, uint_t reg) 483{ 484 struct pcb *pcb; 485 int regmap[] = { /* Order is dependent on reg.d */ 486 REG_GS, /* 0 GS */ 487 REG_FS, /* 1 FS */ 488 REG_ES, /* 2 ES */ 489 REG_DS, /* 3 DS */ 490 REG_RDI, /* 4 EDI */ 491 REG_RSI, /* 5 ESI */ 492 REG_RBP, /* 6 EBP, REG_FP */ 493 REG_RSP, /* 7 ESP */ 494 REG_RBX, /* 8 EBX */ 495 REG_RDX, /* 9 EDX, REG_R1 */ 496 REG_RCX, /* 10 ECX */ 497 REG_RAX, /* 11 EAX, REG_R0 */ 498 REG_TRAPNO, /* 12 TRAPNO */ 499 REG_ERR, /* 13 ERR */ 500 REG_RIP, /* 14 EIP, REG_PC */ 501 REG_CS, /* 15 CS */ 502 REG_RFL, /* 16 EFL, REG_PS */ 503 REG_RSP, /* 17 UESP, REG_SP */ 504 REG_SS /* 18 SS */ 505 }; 506 507 if (reg > SS) { 508 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP); 509 return (0); 510 } 511 512 if (reg >= sizeof (regmap) / sizeof (int)) { 513 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP); 514 return (0); 515 } 516 517 reg = regmap[reg]; 518 519 switch(reg) { 520 case REG_GS: 521 if ((pcb = curthread->td_pcb) == NULL) { 522 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP); 523 return (0); 524 } 525 return (pcb->pcb_gs); 526 case REG_FS: 527 return (rp->tf_fs); 528 case REG_ES: 529 return (rp->tf_es); 530 case REG_DS: 531 return (rp->tf_ds); 532 case REG_RDI: 533 return (rp->tf_edi); 534 case REG_RSI: 535 return (rp->tf_esi); 536 case REG_RBP: 537 return (rp->tf_ebp); 538 case REG_RSP: 539 return (rp->tf_isp); 540 case REG_RBX: 541 return (rp->tf_ebx); 542 case REG_RCX: 543 return (rp->tf_ecx); 544 case REG_RAX: 545 return (rp->tf_eax); 546 case REG_TRAPNO: 547 return (rp->tf_trapno); 548 case REG_ERR: 549 return (rp->tf_err); 550 case REG_RIP: 551 return (rp->tf_eip); 552 case REG_CS: 553 return (rp->tf_cs); 554 case REG_RFL: 555 return (rp->tf_eflags); 556#if 0 557 case REG_RSP: 558 return (rp->tf_esp); 559#endif 560 case REG_SS: 561 return (rp->tf_ss); 562 default: 563 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP); 564 return (0); 565 } 566} 567 568static int 569dtrace_copycheck(uintptr_t uaddr, uintptr_t kaddr, size_t size) 570{ 571 ASSERT(kaddr >= kernelbase && kaddr + size >= kaddr); 572 573 if (uaddr + size >= kernelbase || uaddr + size < uaddr) { 574 DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 575 cpu_core[curcpu].cpuc_dtrace_illval = uaddr; 576 return (0); 577 } 578 579 return (1); 580} 581 582void 583dtrace_copyin(uintptr_t uaddr, uintptr_t kaddr, size_t size, 584 volatile uint16_t *flags) 585{ 586 if (dtrace_copycheck(uaddr, kaddr, size)) 587 dtrace_copy(uaddr, kaddr, size); 588} 589 590void 591dtrace_copyout(uintptr_t kaddr, uintptr_t uaddr, size_t size, 592 volatile uint16_t *flags) 593{ 594 if (dtrace_copycheck(uaddr, kaddr, size)) 595 dtrace_copy(kaddr, uaddr, size); 596} 597 598void 599dtrace_copyinstr(uintptr_t uaddr, uintptr_t kaddr, size_t size, 600 volatile uint16_t *flags) 601{ 602 if (dtrace_copycheck(uaddr, kaddr, size)) 603 dtrace_copystr(uaddr, kaddr, size, flags); 604} 605 606void 607dtrace_copyoutstr(uintptr_t kaddr, uintptr_t uaddr, size_t size, 608 volatile uint16_t *flags) 609{ 610 if (dtrace_copycheck(uaddr, kaddr, size)) 611 dtrace_copystr(kaddr, uaddr, size, flags); 612} 613 614uint8_t 615dtrace_fuword8(void *uaddr) 616{ 617 if ((uintptr_t)uaddr >= kernelbase) { 618 DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 619 cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; 620 return (0); 621 } 622 return (dtrace_fuword8_nocheck(uaddr)); 623} 624 625uint16_t 626dtrace_fuword16(void *uaddr) 627{ 628 if ((uintptr_t)uaddr >= kernelbase) { 629 DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 630 cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; 631 return (0); 632 } 633 return (dtrace_fuword16_nocheck(uaddr)); 634} 635 636uint32_t 637dtrace_fuword32(void *uaddr) 638{ 639 if ((uintptr_t)uaddr >= kernelbase) { 640 DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 641 cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; 642 return (0); 643 } 644 return (dtrace_fuword32_nocheck(uaddr)); 645} 646 647uint64_t 648dtrace_fuword64(void *uaddr) 649{ 650 if ((uintptr_t)uaddr >= kernelbase) { 651 DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 652 cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; 653 return (0); 654 } 655 return (dtrace_fuword64_nocheck(uaddr)); 656}
| 203 /* 204 * This is totally bogus: if we faulted, we're going to clear 205 * the fault and break. This is to deal with the apparently 206 * broken Java stacks on x86. 207 */ 208 if (*flags & CPU_DTRACE_FAULT) { 209 *flags &= ~CPU_DTRACE_FAULT; 210 break; 211 } 212 } 213 214 return (ret); 215} 216 217void 218dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit) 219{ 220 proc_t *p = curproc; 221 struct trapframe *tf; 222 uintptr_t pc, sp, fp; 223 volatile uint16_t *flags = 224 (volatile uint16_t *)&cpu_core[curcpu].cpuc_dtrace_flags; 225 int n; 226 227 if (*flags & CPU_DTRACE_FAULT) 228 return; 229 230 if (pcstack_limit <= 0) 231 return; 232 233 /* 234 * If there's no user context we still need to zero the stack. 235 */ 236 if (p == NULL || (tf = curthread->td_frame) == NULL) 237 goto zero; 238 239 *pcstack++ = (uint64_t)p->p_pid; 240 pcstack_limit--; 241 242 if (pcstack_limit <= 0) 243 return; 244 245 pc = tf->tf_eip; 246 fp = tf->tf_ebp; 247 sp = tf->tf_esp; 248 249 if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) { 250 /* 251 * In an entry probe. The frame pointer has not yet been 252 * pushed (that happens in the function prologue). The 253 * best approach is to add the current pc as a missing top 254 * of stack and back the pc up to the caller, which is stored 255 * at the current stack pointer address since the call 256 * instruction puts it there right before the branch. 257 */ 258 259 *pcstack++ = (uint64_t)pc; 260 pcstack_limit--; 261 if (pcstack_limit <= 0) 262 return; 263 264 pc = dtrace_fuword32((void *) sp); 265 } 266 267 n = dtrace_getustack_common(pcstack, pcstack_limit, pc, sp); 268 ASSERT(n >= 0); 269 ASSERT(n <= pcstack_limit); 270 271 pcstack += n; 272 pcstack_limit -= n; 273 274zero: 275 while (pcstack_limit-- > 0) 276 *pcstack++ = 0; 277} 278 279int 280dtrace_getustackdepth(void) 281{ 282 proc_t *p = curproc; 283 struct trapframe *tf; 284 uintptr_t pc, fp, sp; 285 int n = 0; 286 287 if (p == NULL || (tf = curthread->td_frame) == NULL) 288 return (0); 289 290 if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_FAULT)) 291 return (-1); 292 293 pc = tf->tf_eip; 294 fp = tf->tf_ebp; 295 sp = tf->tf_esp; 296 297 if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) { 298 /* 299 * In an entry probe. The frame pointer has not yet been 300 * pushed (that happens in the function prologue). The 301 * best approach is to add the current pc as a missing top 302 * of stack and back the pc up to the caller, which is stored 303 * at the current stack pointer address since the call 304 * instruction puts it there right before the branch. 305 */ 306 307 pc = dtrace_fuword32((void *) sp); 308 n++; 309 } 310 311 n += dtrace_getustack_common(NULL, 0, pc, fp); 312 313 return (n); 314} 315 316void 317dtrace_getufpstack(uint64_t *pcstack, uint64_t *fpstack, int pcstack_limit) 318{ 319 proc_t *p = curproc; 320 struct trapframe *tf; 321 uintptr_t pc, sp, fp; 322 volatile uint16_t *flags = 323 (volatile uint16_t *)&cpu_core[curcpu].cpuc_dtrace_flags; 324#ifdef notyet /* XXX signal stack */ 325 uintptr_t oldcontext; 326 size_t s1, s2; 327#endif 328 329 if (*flags & CPU_DTRACE_FAULT) 330 return; 331 332 if (pcstack_limit <= 0) 333 return; 334 335 /* 336 * If there's no user context we still need to zero the stack. 337 */ 338 if (p == NULL || (tf = curthread->td_frame) == NULL) 339 goto zero; 340 341 *pcstack++ = (uint64_t)p->p_pid; 342 pcstack_limit--; 343 344 if (pcstack_limit <= 0) 345 return; 346 347 pc = tf->tf_eip; 348 fp = tf->tf_ebp; 349 sp = tf->tf_esp; 350 351#ifdef notyet /* XXX signal stack */ 352 oldcontext = lwp->lwp_oldcontext; 353 354 if (p->p_model == DATAMODEL_NATIVE) { 355 s1 = sizeof (struct frame) + 2 * sizeof (long); 356 s2 = s1 + sizeof (siginfo_t); 357 } else { 358 s1 = sizeof (struct frame32) + 3 * sizeof (int); 359 s2 = s1 + sizeof (siginfo32_t); 360 } 361#endif 362 363 if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) { 364 *pcstack++ = (uint64_t)pc; 365 *fpstack++ = 0; 366 pcstack_limit--; 367 if (pcstack_limit <= 0) 368 return; 369 370 pc = dtrace_fuword32((void *)sp); 371 } 372 373 while (pc != 0) { 374 *pcstack++ = (uint64_t)pc; 375 *fpstack++ = fp; 376 pcstack_limit--; 377 if (pcstack_limit <= 0) 378 break; 379 380 if (fp == 0) 381 break; 382 383#ifdef notyet /* XXX signal stack */ 384 if (oldcontext == sp + s1 || oldcontext == sp + s2) { 385 if (p->p_model == DATAMODEL_NATIVE) { 386 ucontext_t *ucp = (ucontext_t *)oldcontext; 387 greg_t *gregs = ucp->uc_mcontext.gregs; 388 389 sp = dtrace_fulword(&gregs[REG_FP]); 390 pc = dtrace_fulword(&gregs[REG_PC]); 391 392 oldcontext = dtrace_fulword(&ucp->uc_link); 393 } else { 394 ucontext_t *ucp = (ucontext_t *)oldcontext; 395 greg_t *gregs = ucp->uc_mcontext.gregs; 396 397 sp = dtrace_fuword32(&gregs[EBP]); 398 pc = dtrace_fuword32(&gregs[EIP]); 399 400 oldcontext = dtrace_fuword32(&ucp->uc_link); 401 } 402 } else 403#endif /* XXX */ 404 { 405 pc = dtrace_fuword32((void *)(fp + 406 offsetof(struct i386_frame, f_retaddr))); 407 fp = dtrace_fuword32((void *)fp); 408 } 409 410 /* 411 * This is totally bogus: if we faulted, we're going to clear 412 * the fault and break. This is to deal with the apparently 413 * broken Java stacks on x86. 414 */ 415 if (*flags & CPU_DTRACE_FAULT) { 416 *flags &= ~CPU_DTRACE_FAULT; 417 break; 418 } 419 } 420 421zero: 422 while (pcstack_limit-- > 0) 423 *pcstack++ = 0; 424} 425 426uint64_t 427dtrace_getarg(int arg, int aframes) 428{ 429 uintptr_t val; 430 struct i386_frame *fp = (struct i386_frame *)dtrace_getfp(); 431 uintptr_t *stack; 432 int i; 433 434 for (i = 1; i <= aframes; i++) { 435 fp = fp->f_frame; 436 437 if (P2ROUNDUP(fp->f_retaddr, 4) == 438 (long)dtrace_invop_callsite) { 439 /* 440 * If we pass through the invalid op handler, we will 441 * use the pointer that it passed to the stack as the 442 * second argument to dtrace_invop() as the pointer to 443 * the stack. When using this stack, we must step 444 * beyond the EIP/RIP that was pushed when the trap was 445 * taken -- hence the "+ 1" below. 446 */ 447 stack = ((uintptr_t **)&fp[1])[0] + 1; 448 goto load; 449 } 450 451 } 452 453 /* 454 * We know that we did not come through a trap to get into 455 * dtrace_probe() -- the provider simply called dtrace_probe() 456 * directly. As this is the case, we need to shift the argument 457 * that we're looking for: the probe ID is the first argument to 458 * dtrace_probe(), so the argument n will actually be found where 459 * one would expect to find argument (n + 1). 460 */ 461 arg++; 462 463 stack = (uintptr_t *)fp + 2; 464 465load: 466 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT); 467 val = stack[arg]; 468 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT); 469 470 return (val); 471} 472 473int 474dtrace_getstackdepth(int aframes) 475{ 476 int depth = 0; 477 struct i386_frame *frame; 478 vm_offset_t ebp; 479 480 aframes++; 481 ebp = dtrace_getfp(); 482 frame = (struct i386_frame *)ebp; 483 depth++; 484 for(;;) { 485 if (!INKERNEL((long) frame)) 486 break; 487 if (!INKERNEL((long) frame->f_frame)) 488 break; 489 depth++; 490 if (frame->f_frame <= frame || 491 (vm_offset_t)frame->f_frame >= 492 (vm_offset_t)ebp + KSTACK_PAGES * PAGE_SIZE) 493 break; 494 frame = frame->f_frame; 495 } 496 if (depth < aframes) 497 return 0; 498 else 499 return depth - aframes; 500} 501 502ulong_t 503dtrace_getreg(struct trapframe *rp, uint_t reg) 504{ 505 struct pcb *pcb; 506 int regmap[] = { /* Order is dependent on reg.d */ 507 REG_GS, /* 0 GS */ 508 REG_FS, /* 1 FS */ 509 REG_ES, /* 2 ES */ 510 REG_DS, /* 3 DS */ 511 REG_RDI, /* 4 EDI */ 512 REG_RSI, /* 5 ESI */ 513 REG_RBP, /* 6 EBP, REG_FP */ 514 REG_RSP, /* 7 ESP */ 515 REG_RBX, /* 8 EBX */ 516 REG_RDX, /* 9 EDX, REG_R1 */ 517 REG_RCX, /* 10 ECX */ 518 REG_RAX, /* 11 EAX, REG_R0 */ 519 REG_TRAPNO, /* 12 TRAPNO */ 520 REG_ERR, /* 13 ERR */ 521 REG_RIP, /* 14 EIP, REG_PC */ 522 REG_CS, /* 15 CS */ 523 REG_RFL, /* 16 EFL, REG_PS */ 524 REG_RSP, /* 17 UESP, REG_SP */ 525 REG_SS /* 18 SS */ 526 }; 527 528 if (reg > SS) { 529 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP); 530 return (0); 531 } 532 533 if (reg >= sizeof (regmap) / sizeof (int)) { 534 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP); 535 return (0); 536 } 537 538 reg = regmap[reg]; 539 540 switch(reg) { 541 case REG_GS: 542 if ((pcb = curthread->td_pcb) == NULL) { 543 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP); 544 return (0); 545 } 546 return (pcb->pcb_gs); 547 case REG_FS: 548 return (rp->tf_fs); 549 case REG_ES: 550 return (rp->tf_es); 551 case REG_DS: 552 return (rp->tf_ds); 553 case REG_RDI: 554 return (rp->tf_edi); 555 case REG_RSI: 556 return (rp->tf_esi); 557 case REG_RBP: 558 return (rp->tf_ebp); 559 case REG_RSP: 560 return (rp->tf_isp); 561 case REG_RBX: 562 return (rp->tf_ebx); 563 case REG_RCX: 564 return (rp->tf_ecx); 565 case REG_RAX: 566 return (rp->tf_eax); 567 case REG_TRAPNO: 568 return (rp->tf_trapno); 569 case REG_ERR: 570 return (rp->tf_err); 571 case REG_RIP: 572 return (rp->tf_eip); 573 case REG_CS: 574 return (rp->tf_cs); 575 case REG_RFL: 576 return (rp->tf_eflags); 577#if 0 578 case REG_RSP: 579 return (rp->tf_esp); 580#endif 581 case REG_SS: 582 return (rp->tf_ss); 583 default: 584 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP); 585 return (0); 586 } 587} 588 589static int 590dtrace_copycheck(uintptr_t uaddr, uintptr_t kaddr, size_t size) 591{ 592 ASSERT(kaddr >= kernelbase && kaddr + size >= kaddr); 593 594 if (uaddr + size >= kernelbase || uaddr + size < uaddr) { 595 DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 596 cpu_core[curcpu].cpuc_dtrace_illval = uaddr; 597 return (0); 598 } 599 600 return (1); 601} 602 603void 604dtrace_copyin(uintptr_t uaddr, uintptr_t kaddr, size_t size, 605 volatile uint16_t *flags) 606{ 607 if (dtrace_copycheck(uaddr, kaddr, size)) 608 dtrace_copy(uaddr, kaddr, size); 609} 610 611void 612dtrace_copyout(uintptr_t kaddr, uintptr_t uaddr, size_t size, 613 volatile uint16_t *flags) 614{ 615 if (dtrace_copycheck(uaddr, kaddr, size)) 616 dtrace_copy(kaddr, uaddr, size); 617} 618 619void 620dtrace_copyinstr(uintptr_t uaddr, uintptr_t kaddr, size_t size, 621 volatile uint16_t *flags) 622{ 623 if (dtrace_copycheck(uaddr, kaddr, size)) 624 dtrace_copystr(uaddr, kaddr, size, flags); 625} 626 627void 628dtrace_copyoutstr(uintptr_t kaddr, uintptr_t uaddr, size_t size, 629 volatile uint16_t *flags) 630{ 631 if (dtrace_copycheck(uaddr, kaddr, size)) 632 dtrace_copystr(kaddr, uaddr, size, flags); 633} 634 635uint8_t 636dtrace_fuword8(void *uaddr) 637{ 638 if ((uintptr_t)uaddr >= kernelbase) { 639 DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 640 cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; 641 return (0); 642 } 643 return (dtrace_fuword8_nocheck(uaddr)); 644} 645 646uint16_t 647dtrace_fuword16(void *uaddr) 648{ 649 if ((uintptr_t)uaddr >= kernelbase) { 650 DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 651 cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; 652 return (0); 653 } 654 return (dtrace_fuword16_nocheck(uaddr)); 655} 656 657uint32_t 658dtrace_fuword32(void *uaddr) 659{ 660 if ((uintptr_t)uaddr >= kernelbase) { 661 DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 662 cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; 663 return (0); 664 } 665 return (dtrace_fuword32_nocheck(uaddr)); 666} 667 668uint64_t 669dtrace_fuword64(void *uaddr) 670{ 671 if ((uintptr_t)uaddr >= kernelbase) { 672 DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 673 cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; 674 return (0); 675 } 676 return (dtrace_fuword64_nocheck(uaddr)); 677}
|