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.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
21 /* Portions Copyright 2013 Justin Hibbits */
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #include <sys/fasttrap_isa.h>
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>
33 #include <sys/types.h>
35 #include <sys/ptrace.h>
36 #include <sys/sysent.h>
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)
44 #define OP_RB(x) (((x) & 0x0000F100) >> 11)
48 proc_ops(int op, proc_t *p, void *kaddr, off_t uaddr, size_t len)
55 uio.uio_offset = uaddr;
59 uio.uio_segflg = UIO_SYSSPACE;
60 uio.uio_td = curthread;
63 if (proc_rwmem(p, &uio) != 0) {
73 uread(proc_t *p, void *kaddr, size_t len, uintptr_t uaddr)
76 return (proc_ops(UIO_READ, p, kaddr, uaddr, len));
80 uwrite(proc_t *p, void *kaddr, size_t len, uintptr_t uaddr)
83 return (proc_ops(UIO_WRITE, p, kaddr, uaddr, len));
87 fasttrap_tracepoint_install(proc_t *p, fasttrap_tracepoint_t *tp)
89 fasttrap_instr_t instr = FASTTRAP_INSTR;
91 if (uwrite(p, &instr, 4, tp->ftt_pc) != 0)
98 fasttrap_tracepoint_remove(proc_t *p, fasttrap_tracepoint_t *tp)
103 * Distinguish between read or write failures and a changed
106 if (uread(p, &instr, 4, tp->ftt_pc) != 0)
108 if (instr != FASTTRAP_INSTR)
110 if (uwrite(p, &tp->ftt_instr, 4, tp->ftt_pc) != 0)
117 fasttrap_tracepoint_init(proc_t *p, fasttrap_tracepoint_t *tp, uintptr_t pc,
118 fasttrap_probe_type_t type)
124 * Read the instruction at the given address out of the process's
125 * address space. We don't have to worry about a debugger
126 * changing this instruction before we overwrite it with our trap
127 * instruction since P_PR_LOCK is set.
129 if (uread(p, &instr, 4, pc) != 0)
133 * Decode the instruction to fill in the probe flags. We can have
134 * the process execute most instructions on its own using a pc/npc
135 * trick, but pc-relative control transfer present a problem since
136 * we're relocating the instruction. We emulate these instructions
137 * in the kernel. We assume a default type and over-write that as
140 * pc-relative instructions must be emulated for correctness;
141 * other instructions (which represent a large set of commonly traced
142 * instructions) are emulated or otherwise optimized for performance.
144 tp->ftt_type = FASTTRAP_T_COMMON;
145 tp->ftt_instr = instr;
148 /* The following are invalid for trapping (invalid opcodes, tw/twi). */
164 else if (OPX(instr) == 444 && OP_RS(instr) == OP_RA(instr) &&
165 OP_RS(instr) == OP_RB(instr))
166 tp->ftt_type = FASTTRAP_T_NOP;
169 tp->ftt_type = FASTTRAP_T_BC;
170 tp->ftt_dest = instr & 0x0000FFFC; /* Extract target address */
171 if (instr & 0x00008000)
172 tp->ftt_dest |= 0xFFFF0000;
173 /* Use as offset if not absolute address. */
176 tp->ftt_bo = OP_BO(instr);
177 tp->ftt_bi = OP_BI(instr);
180 tp->ftt_type = FASTTRAP_T_B;
181 tp->ftt_dest = instr & 0x03FFFFFC; /* Extract target address */
182 if (instr & 0x02000000)
183 tp->ftt_dest |= 0xFC000000;
184 /* Use as offset if not absolute address. */
189 switch (OPX(instr)) {
190 case 528: /* bcctr */
191 tp->ftt_type = FASTTRAP_T_BCTR;
192 tp->ftt_bo = OP_BO(instr);
193 tp->ftt_bi = OP_BI(instr);
196 tp->ftt_type = FASTTRAP_T_BCTR;
197 tp->ftt_bo = OP_BO(instr);
198 tp->ftt_bi = OP_BI(instr);
203 if (OP_RS(instr) == OP_RA(instr) &&
204 (instr & 0x0000FFFF) == 0)
205 tp->ftt_type = FASTTRAP_T_NOP;
210 * We don't know how this tracepoint is going to be used, but in case
211 * it's used as part of a function return probe, we need to indicate
212 * whether it's always a return site or only potentially a return
213 * site. If it's part of a return probe, it's always going to be a
214 * return from that function if it's a restore instruction or if
215 * the previous instruction was a return. If we could reliably
216 * distinguish jump tables from return sites, this wouldn't be
220 if (tp->ftt_type != FASTTRAP_T_RESTORE &&
221 (uread(p, &instr, 4, pc - sizeof (instr)) != 0 ||
222 !(OP(instr) == 2 && OP3(instr) == OP3_RETURN)))
223 tp->ftt_flags |= FASTTRAP_F_RETMAYBE;
230 fasttrap_anarg(struct reg *rp, int argno)
235 /* The first 8 arguments are in registers. */
237 return rp->fixreg[argno + 3];
239 /* Arguments on stack start after SP+LR (2 register slots). */
240 if (SV_PROC_FLAG(p, SV_ILP32)) {
241 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
242 value = dtrace_fuword32((void *)(rp->fixreg[1] + 8 +
243 ((argno - 8) * sizeof(uint32_t))));
244 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT | CPU_DTRACE_BADADDR);
246 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
247 value = dtrace_fuword64((void *)(rp->fixreg[1] + 16 +
248 ((argno - 8) * sizeof(uint32_t))));
249 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT | CPU_DTRACE_BADADDR);
255 fasttrap_pid_getarg(void *arg, dtrace_id_t id, void *parg, int argno,
260 fill_regs(curthread, &r);
262 return (fasttrap_anarg(&r, argno));
266 fasttrap_usdt_getarg(void *arg, dtrace_id_t id, void *parg, int argno,
271 fill_regs(curthread, &r);
273 return (fasttrap_anarg(&r, argno));
277 fasttrap_usdt_args(fasttrap_probe_t *probe, struct reg *rp, int argc,
280 int i, x, cap = MIN(argc, probe->ftp_nargs);
282 for (i = 0; i < cap; i++) {
283 x = probe->ftp_argmap[i];
286 argv[i] = rp->fixreg[x];
288 if (SV_PROC_FLAG(curproc, SV_ILP32))
289 argv[i] = fuword32((void *)(rp->fixreg[1] + 8 +
290 (x * sizeof(uint32_t))));
292 argv[i] = fuword32((void *)(rp->fixreg[1] + 16 +
293 (x * sizeof(uint64_t))));
296 for (; i < argc; i++) {
302 fasttrap_return_common(struct reg *rp, uintptr_t pc, pid_t pid,
305 fasttrap_tracepoint_t *tp;
306 fasttrap_bucket_t *bucket;
309 bucket = &fasttrap_tpoints.fth_table[FASTTRAP_TPOINTS_INDEX(pid, pc)];
311 for (tp = bucket->ftb_data; tp != NULL; tp = tp->ftt_next) {
312 if (pid == tp->ftt_pid && pc == tp->ftt_pc &&
313 tp->ftt_proc->ftpc_acount != 0)
318 * Don't sweat it if we can't find the tracepoint again; unlike
319 * when we're in fasttrap_pid_probe(), finding the tracepoint here
320 * is not essential to the correct execution of the process.
326 for (id = tp->ftt_retids; id != NULL; id = id->fti_next) {
328 * If there's a branch that could act as a return site, we
329 * need to trace it, and check here if the program counter is
330 * external to the function.
332 /* Skip function-local branches. */
333 if ((new_pc - id->fti_probe->ftp_faddr) < id->fti_probe->ftp_fsize)
336 dtrace_probe(id->fti_probe->ftp_id,
337 pc - id->fti_probe->ftp_faddr,
338 rp->fixreg[3], rp->fixreg[4], 0, 0);
344 fasttrap_branch_taken(int bo, int bi, struct reg *regs)
349 if ((bo & 0x14) == 0x14)
352 /* Handle decrementing ctr */
355 crzero = (regs->ctr == 0);
357 return (!(crzero ^ (bo >> 1)));
361 return (crzero | (((regs->cr >> (31 - bi)) ^ (bo >> 3)) ^ 1));
366 fasttrap_pid_probe(struct reg *rp)
369 uintptr_t pc = rp->pc;
370 uintptr_t new_pc = 0;
371 fasttrap_bucket_t *bucket;
372 fasttrap_tracepoint_t *tp, tp_local;
374 dtrace_icookie_t cookie;
375 uint_t is_enabled = 0;
378 * It's possible that a user (in a veritable orgy of bad planning)
379 * could redirect this thread's flow of control before it reached the
380 * return probe fasttrap. In this case we need to kill the process
381 * since it's in a unrecoverable state.
383 if (curthread->t_dtrace_step) {
384 ASSERT(curthread->t_dtrace_on);
385 fasttrap_sigtrap(p, curthread, pc);
390 * Clear all user tracing flags.
392 curthread->t_dtrace_ft = 0;
393 curthread->t_dtrace_pc = 0;
394 curthread->t_dtrace_npc = 0;
395 curthread->t_dtrace_scrpc = 0;
396 curthread->t_dtrace_astpc = 0;
401 bucket = &fasttrap_tpoints.fth_table[FASTTRAP_TPOINTS_INDEX(pid, pc)];
404 * Lookup the tracepoint that the process just hit.
406 for (tp = bucket->ftb_data; tp != NULL; tp = tp->ftt_next) {
407 if (pid == tp->ftt_pid && pc == tp->ftt_pc &&
408 tp->ftt_proc->ftpc_acount != 0)
413 * If we couldn't find a matching tracepoint, either a tracepoint has
414 * been inserted without using the pid<pid> ioctl interface (see
415 * fasttrap_ioctl), or somehow we have mislaid this tracepoint.
422 if (tp->ftt_ids != NULL) {
425 for (id = tp->ftt_ids; id != NULL; id = id->fti_next) {
426 fasttrap_probe_t *probe = id->fti_probe;
428 if (id->fti_ptype == DTFTP_ENTRY) {
430 * We note that this was an entry
431 * probe to help ustack() find the
434 cookie = dtrace_interrupt_disable();
435 DTRACE_CPUFLAG_SET(CPU_DTRACE_ENTRY);
436 dtrace_probe(probe->ftp_id, rp->fixreg[3],
437 rp->fixreg[4], rp->fixreg[5], rp->fixreg[6],
439 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_ENTRY);
440 dtrace_interrupt_enable(cookie);
441 } else if (id->fti_ptype == DTFTP_IS_ENABLED) {
443 * Note that in this case, we don't
444 * call dtrace_probe() since it's only
445 * an artificial probe meant to change
446 * the flow of control so that it
447 * encounters the true probe.
450 } else if (probe->ftp_argmap == NULL) {
451 dtrace_probe(probe->ftp_id, rp->fixreg[3],
452 rp->fixreg[4], rp->fixreg[5], rp->fixreg[6],
457 fasttrap_usdt_args(probe, rp,
458 sizeof (t) / sizeof (t[0]), t);
460 dtrace_probe(probe->ftp_id, t[0], t[1],
467 * We're about to do a bunch of work so we cache a local copy of
468 * the tracepoint to emulate the instruction, and then find the
469 * tracepoint again later if we need to light up any return probes.
476 * If there's an is-enabled probe connected to this tracepoint it
477 * means that there was a 'xor r3, r3, r3'
478 * instruction that was placed there by DTrace when the binary was
479 * linked. As this probe is, in fact, enabled, we need to stuff 1
480 * into R3. Accordingly, we can bypass all the instruction
481 * emulation logic since we know the inevitable result. It's possible
482 * that a user could construct a scenario where the 'is-enabled'
483 * probe was on some other instruction, but that would be a rather
484 * exotic way to shoot oneself in the foot.
493 switch (tp->ftt_type) {
498 if (!fasttrap_branch_taken(tp->ftt_bo, tp->ftt_bi, rp))
502 if (tp->ftt_instr & 0x01)
504 new_pc = tp->ftt_dest;
507 case FASTTRAP_T_BCTR:
508 if (!fasttrap_branch_taken(tp->ftt_bo, tp->ftt_bi, rp))
511 if (tp->ftt_type == FASTTRAP_T_BCTR)
515 if (tp->ftt_instr & 0x01)
518 case FASTTRAP_T_COMMON:
523 * If there were no return probes when we first found the tracepoint,
524 * we should feel no obligation to honor any return probes that were
525 * subsequently enabled -- they'll just have to wait until the next
528 if (tp->ftt_retids != NULL) {
530 * We need to wait until the results of the instruction are
531 * apparent before invoking any return probes. If this
532 * instruction was emulated we can just call
533 * fasttrap_return_common(); if it needs to be executed, we
534 * need to wait until the user thread returns to the kernel.
536 if (tp->ftt_type != FASTTRAP_T_COMMON) {
537 fasttrap_return_common(rp, pc, pid, new_pc);
539 ASSERT(curthread->t_dtrace_ret != 0);
540 ASSERT(curthread->t_dtrace_pc == pc);
541 ASSERT(curthread->t_dtrace_scrpc != 0);
542 ASSERT(new_pc == curthread->t_dtrace_astpc);
547 set_regs(curthread, rp);
553 fasttrap_return_probe(struct reg *rp)
556 uintptr_t pc = curthread->t_dtrace_pc;
557 uintptr_t npc = curthread->t_dtrace_npc;
559 curthread->t_dtrace_pc = 0;
560 curthread->t_dtrace_npc = 0;
561 curthread->t_dtrace_scrpc = 0;
562 curthread->t_dtrace_astpc = 0;
565 * We set rp->pc to the address of the traced instruction so
566 * that it appears to dtrace_probe() that we're on the original
567 * instruction, and so that the user can't easily detect our
568 * complex web of lies. dtrace_return_probe() (our caller)
569 * will correctly set %pc after we return.
573 fasttrap_return_common(rp, pc, p->p_pid, npc);