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> |
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; |
293 fasttrap_tracepoint_t *tp; 294 fasttrap_bucket_t *bucket; 295 fasttrap_id_t *id; 296 |
297 rm_rlock(&fasttrap_tp_lock, &tracker); |
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); |
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); |
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; |
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 |
390 rm_rlock(&fasttrap_tp_lock, &tracker); |
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) { |
409 rm_runlock(&fasttrap_tp_lock, &tracker); |
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; |
463 rm_runlock(&fasttrap_tp_lock, &tracker); |
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 --- |