fasttrap_isa.c (291961) | fasttrap_isa.c (296479) |
---|---|
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 --- 19 unchanged lines hidden (view full) --- 28#include <sys/fasttrap_impl.h> 29#include <sys/dtrace.h> 30#include <sys/dtrace_impl.h> 31#include <cddl/dev/dtrace/dtrace_cddl.h> 32#include <sys/proc.h> 33#include <sys/types.h> 34#include <sys/uio.h> 35#include <sys/ptrace.h> | 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 --- 19 unchanged lines hidden (view full) --- 28#include <sys/fasttrap_impl.h> 29#include <sys/dtrace.h> 30#include <sys/dtrace_impl.h> 31#include <cddl/dev/dtrace/dtrace_cddl.h> 32#include <sys/proc.h> 33#include <sys/types.h> 34#include <sys/uio.h> 35#include <sys/ptrace.h> |
36#include <sys/rmlock.h> |
|
36#include <sys/sysent.h> 37 38#define OP(x) ((x) >> 26) 39#define OPX(x) (((x) >> 2) & 0x3FF) 40#define OP_BO(x) (((x) & 0x03E00000) >> 21) 41#define OP_BI(x) (((x) & 0x001F0000) >> 16) 42#define OP_RS(x) (((x) & 0x03E00000) >> 21) 43#define OP_RA(x) (((x) & 0x001F0000) >> 16) --- 239 unchanged lines hidden (view full) --- 283 argv[i] = 0; 284 } 285} 286 287static void 288fasttrap_return_common(struct reg *rp, uintptr_t pc, pid_t pid, 289 uintptr_t new_pc) 290{ | 37#include <sys/sysent.h> 38 39#define OP(x) ((x) >> 26) 40#define OPX(x) (((x) >> 2) & 0x3FF) 41#define OP_BO(x) (((x) & 0x03E00000) >> 21) 42#define OP_BI(x) (((x) & 0x001F0000) >> 16) 43#define OP_RS(x) (((x) & 0x03E00000) >> 21) 44#define OP_RA(x) (((x) & 0x001F0000) >> 16) --- 239 unchanged lines hidden (view full) --- 284 argv[i] = 0; 285 } 286} 287 288static void 289fasttrap_return_common(struct reg *rp, uintptr_t pc, pid_t pid, 290 uintptr_t new_pc) 291{ |
292 struct rm_priotracker tracker; |
|
291 fasttrap_tracepoint_t *tp; 292 fasttrap_bucket_t *bucket; 293 fasttrap_id_t *id; 294 | 293 fasttrap_tracepoint_t *tp; 294 fasttrap_bucket_t *bucket; 295 fasttrap_id_t *id; 296 |
297 rm_rlock(&fasttrap_tp_lock, &tracker); |
|
295 bucket = &fasttrap_tpoints.fth_table[FASTTRAP_TPOINTS_INDEX(pid, pc)]; 296 297 for (tp = bucket->ftb_data; tp != NULL; tp = tp->ftt_next) { 298 if (pid == tp->ftt_pid && pc == tp->ftt_pc && 299 tp->ftt_proc->ftpc_acount != 0) 300 break; 301 } 302 303 /* 304 * Don't sweat it if we can't find the tracepoint again; unlike 305 * when we're in fasttrap_pid_probe(), finding the tracepoint here 306 * is not essential to the correct execution of the process. 307 */ 308 if (tp == NULL) { | 298 bucket = &fasttrap_tpoints.fth_table[FASTTRAP_TPOINTS_INDEX(pid, pc)]; 299 300 for (tp = bucket->ftb_data; tp != NULL; tp = tp->ftt_next) { 301 if (pid == tp->ftt_pid && pc == tp->ftt_pc && 302 tp->ftt_proc->ftpc_acount != 0) 303 break; 304 } 305 306 /* 307 * Don't sweat it if we can't find the tracepoint again; unlike 308 * when we're in fasttrap_pid_probe(), finding the tracepoint here 309 * is not essential to the correct execution of the process. 310 */ 311 if (tp == NULL) { |
312 rm_runlock(&fasttrap_tp_lock, &tracker); |
|
309 return; 310 } 311 312 for (id = tp->ftt_retids; id != NULL; id = id->fti_next) { 313 /* 314 * If there's a branch that could act as a return site, we 315 * need to trace it, and check here if the program counter is 316 * external to the function. 317 */ 318 /* Skip function-local branches. */ 319 if ((new_pc - id->fti_probe->ftp_faddr) < id->fti_probe->ftp_fsize) 320 continue; 321 322 dtrace_probe(id->fti_probe->ftp_id, 323 pc - id->fti_probe->ftp_faddr, 324 rp->fixreg[3], rp->fixreg[4], 0, 0); 325 } | 313 return; 314 } 315 316 for (id = tp->ftt_retids; id != NULL; id = id->fti_next) { 317 /* 318 * If there's a branch that could act as a return site, we 319 * need to trace it, and check here if the program counter is 320 * external to the function. 321 */ 322 /* Skip function-local branches. */ 323 if ((new_pc - id->fti_probe->ftp_faddr) < id->fti_probe->ftp_fsize) 324 continue; 325 326 dtrace_probe(id->fti_probe->ftp_id, 327 pc - id->fti_probe->ftp_faddr, 328 rp->fixreg[3], rp->fixreg[4], 0, 0); 329 } |
330 rm_runlock(&fasttrap_tp_lock, &tracker); |
|
326} 327 328 329static int 330fasttrap_branch_taken(int bo, int bi, struct reg *regs) 331{ 332 int crzero = 0; 333 --- 12 unchanged lines hidden (view full) --- 346 347 return (crzero | (((regs->cr >> (31 - bi)) ^ (bo >> 3)) ^ 1)); 348} 349 350 351int 352fasttrap_pid_probe(struct reg *rp) 353{ | 331} 332 333 334static int 335fasttrap_branch_taken(int bo, int bi, struct reg *regs) 336{ 337 int crzero = 0; 338 --- 12 unchanged lines hidden (view full) --- 351 352 return (crzero | (((regs->cr >> (31 - bi)) ^ (bo >> 3)) ^ 1)); 353} 354 355 356int 357fasttrap_pid_probe(struct reg *rp) 358{ |
359 struct rm_priotracker tracker; |
|
354 proc_t *p = curproc; 355 uintptr_t pc = rp->pc; 356 uintptr_t new_pc = 0; 357 fasttrap_bucket_t *bucket; 358 fasttrap_tracepoint_t *tp, tp_local; 359 pid_t pid; 360 dtrace_icookie_t cookie; 361 uint_t is_enabled = 0; --- 14 unchanged lines hidden (view full) --- 376 * Clear all user tracing flags. 377 */ 378 curthread->t_dtrace_ft = 0; 379 curthread->t_dtrace_pc = 0; 380 curthread->t_dtrace_npc = 0; 381 curthread->t_dtrace_scrpc = 0; 382 curthread->t_dtrace_astpc = 0; 383 | 360 proc_t *p = curproc; 361 uintptr_t pc = rp->pc; 362 uintptr_t new_pc = 0; 363 fasttrap_bucket_t *bucket; 364 fasttrap_tracepoint_t *tp, tp_local; 365 pid_t pid; 366 dtrace_icookie_t cookie; 367 uint_t is_enabled = 0; --- 14 unchanged lines hidden (view full) --- 382 * Clear all user tracing flags. 383 */ 384 curthread->t_dtrace_ft = 0; 385 curthread->t_dtrace_pc = 0; 386 curthread->t_dtrace_npc = 0; 387 curthread->t_dtrace_scrpc = 0; 388 curthread->t_dtrace_astpc = 0; 389 |
384 385 PROC_LOCK(p); | 390 rm_rlock(&fasttrap_tp_lock, &tracker); |
386 pid = p->p_pid; 387 bucket = &fasttrap_tpoints.fth_table[FASTTRAP_TPOINTS_INDEX(pid, pc)]; 388 389 /* 390 * Lookup the tracepoint that the process just hit. 391 */ 392 for (tp = bucket->ftb_data; tp != NULL; tp = tp->ftt_next) { 393 if (pid == tp->ftt_pid && pc == tp->ftt_pc && 394 tp->ftt_proc->ftpc_acount != 0) 395 break; 396 } 397 398 /* 399 * If we couldn't find a matching tracepoint, either a tracepoint has 400 * been inserted without using the pid<pid> ioctl interface (see 401 * fasttrap_ioctl), or somehow we have mislaid this tracepoint. 402 */ 403 if (tp == NULL) { | 391 pid = p->p_pid; 392 bucket = &fasttrap_tpoints.fth_table[FASTTRAP_TPOINTS_INDEX(pid, pc)]; 393 394 /* 395 * Lookup the tracepoint that the process just hit. 396 */ 397 for (tp = bucket->ftb_data; tp != NULL; tp = tp->ftt_next) { 398 if (pid == tp->ftt_pid && pc == tp->ftt_pc && 399 tp->ftt_proc->ftpc_acount != 0) 400 break; 401 } 402 403 /* 404 * If we couldn't find a matching tracepoint, either a tracepoint has 405 * been inserted without using the pid<pid> ioctl interface (see 406 * fasttrap_ioctl), or somehow we have mislaid this tracepoint. 407 */ 408 if (tp == NULL) { |
404 PROC_UNLOCK(p); | 409 rm_runlock(&fasttrap_tp_lock, &tracker); |
405 return (-1); 406 } 407 408 if (tp->ftt_ids != NULL) { 409 fasttrap_id_t *id; 410 411 for (id = tp->ftt_ids; id != NULL; id = id->fti_next) { 412 fasttrap_probe_t *probe = id->fti_probe; --- 37 unchanged lines hidden (view full) --- 450 } 451 452 /* 453 * We're about to do a bunch of work so we cache a local copy of 454 * the tracepoint to emulate the instruction, and then find the 455 * tracepoint again later if we need to light up any return probes. 456 */ 457 tp_local = *tp; | 410 return (-1); 411 } 412 413 if (tp->ftt_ids != NULL) { 414 fasttrap_id_t *id; 415 416 for (id = tp->ftt_ids; id != NULL; id = id->fti_next) { 417 fasttrap_probe_t *probe = id->fti_probe; --- 37 unchanged lines hidden (view full) --- 455 } 456 457 /* 458 * We're about to do a bunch of work so we cache a local copy of 459 * the tracepoint to emulate the instruction, and then find the 460 * tracepoint again later if we need to light up any return probes. 461 */ 462 tp_local = *tp; |
458 PROC_UNLOCK(p); | 463 rm_runlock(&fasttrap_tp_lock, &tracker); |
459 tp = &tp_local; 460 461 /* 462 * If there's an is-enabled probe connected to this tracepoint it 463 * means that there was a 'xor r3, r3, r3' 464 * instruction that was placed there by DTrace when the binary was 465 * linked. As this probe is, in fact, enabled, we need to stuff 1 466 * into R3. Accordingly, we can bypass all the instruction --- 97 unchanged lines hidden --- | 464 tp = &tp_local; 465 466 /* 467 * If there's an is-enabled probe connected to this tracepoint it 468 * means that there was a 'xor r3, r3, r3' 469 * instruction that was placed there by DTrace when the binary was 470 * linked. As this probe is, in fact, enabled, we need to stuff 1 471 * into R3. Accordingly, we can bypass all the instruction --- 97 unchanged lines hidden --- |