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/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{
291 fasttrap_tracepoint_t *tp;
292 fasttrap_bucket_t *bucket;
293 fasttrap_id_t *id;
294
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) {
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 }
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{
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
384
385 PROC_LOCK(p);
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) {
404 PROC_UNLOCK(p);
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;
458 PROC_UNLOCK(p);
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 ---
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/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{
291 fasttrap_tracepoint_t *tp;
292 fasttrap_bucket_t *bucket;
293 fasttrap_id_t *id;
294
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) {
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 }
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{
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
384
385 PROC_LOCK(p);
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) {
404 PROC_UNLOCK(p);
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;
458 PROC_UNLOCK(p);
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 ---