Deleted Added
sdiff udiff text old ( 291961 ) new ( 296479 )
full compact
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 ---