14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * CDDL HEADER START
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * The contents of this file are subject to the terms of the
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Common Development and Distribution License (the "License").
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * You may not use this file except in compliance with the License.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * See the License for the specific language governing permissions
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * and limitations under the License.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * When distributing Covered Code, include this CDDL HEADER in each
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * If applicable, add the following below this CDDL HEADER, with the
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * fields enclosed by brackets "[]" replaced with your own identifying
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * information: Portions Copyright [yyyy] [name of copyright owner]
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * CDDL HEADER END
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Use is subject to license terms.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync int (*dtih_func)(uintptr_t, uintptr_t *, uintptr_t);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncdtrace_invop(uintptr_t addr, uintptr_t *stack, uintptr_t eax)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync for (hdlr = dtrace_invop_hdlr; hdlr != NULL; hdlr = hdlr->dtih_next) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if ((rval = hdlr->dtih_func(addr, stack, eax)) != 0)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return (0);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncdtrace_invop_add(int (*func)(uintptr_t, uintptr_t *, uintptr_t))
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync hdlr = kmem_alloc(sizeof (dtrace_invop_hdlr_t), KM_SLEEP);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncdtrace_invop_remove(int (*func)(uintptr_t, uintptr_t *, uintptr_t))
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync dtrace_invop_hdlr_t *hdlr = dtrace_invop_hdlr, *prev = NULL;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync panic("attempt to remove non-existent invop handler");
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*ARGSUSED*/
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncdtrace_toxic_ranges(void (*func)(uintptr_t base, uintptr_t limit))
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync extern void *device_arena_contains(void *, size_t, size_t *);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync for (vaddr = (caddr_t)kernelbase; vaddr < (caddr_t)KERNEL_TEXT;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return (0);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*ARGSUSED*/
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncdtrace_xcall(processorid_t cpu, dtrace_xcall_t func, void *arg)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync xc_sync((xc_arg_t)func, (xc_arg_t)arg, 0, CPUSET2BV(set),
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync dtrace_xcall(DTRACE_CPUALL, (dtrace_xcall_t)dtrace_sync_func, NULL);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncdtrace_user_probe(struct regs *rp, caddr_t addr, processorid_t cpuid)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync extern void trap(struct regs *, caddr_t, processorid_t);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * DTrace accesses t_cred in probe context. t_cred
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * must always be either NULL, or point to a valid,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * allocated cred structure.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Clear all user tracing flags.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * If we weren't expecting to take a return probe trap, kill
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * the process as though it had just executed an unassigned
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * trap instruction.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (step == 0) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * If we hit this trap unrelated to a return probe, we're
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * just here to reset the AST flag since we deferred a signal
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * until after we logically single-stepped the instruction we
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * copied out.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (ret == 0) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * We need to wait until after we've called the
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * dtrace_return_probe_ptr function pointer to set %pc.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * The DTrace fasttrap provider uses the breakpoint trap
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * (int 3). We let DTrace take the first crack at handling
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * this trap; if it's not a probe that DTrace knowns about,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * we call into the trap() routine to handle it like a
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * breakpoint placed by a conventional debugger.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * If the instruction that caused the breakpoint trap doesn't
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * look like an int 3 anymore, it may be that this tracepoint
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * was removed just after the user thread executed it. In
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * that case, return to user land to retry the instuction.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Note that we assume the length of the instruction to retry
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * is 1 byte because that's the length of FASTTRAP_INSTR.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * We check for r_pc > 0 and > 2 so that we don't have to
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * deal with segment wraparound.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (rp->r_pc > 0 && fuword8(linearpc - 1, &instr) == 0 &&
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (fuword8(linearpc - 2, &instr2) != 0 || instr2 != 0xCD)))) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * If we're not in the range of scratch addresses, we're not actually
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * tracing user instructions so turn off the flags. If the instruction
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * we copied out caused a synchonous trap, reset the pc back to its
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * original value and turn off the flags.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * If we're not in the range of scratch addresses, we're not actually
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * tracing user instructions so turn off the flags.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return (0);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * If we've executed the original instruction, but haven't performed
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * the jmp back to t->t_dtrace_npc or the clean up of any registers
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * used to emulate %rip-relative instructions in 64-bit mode, do that
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * here and take the signal right away. We detect this condition by
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * seeing if the program counter is the range [scrpc + isz, astpc).
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * If there is a scratch register and we're on the
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * instruction immediately after the modified instruction,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * restore the value of that scratch register.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (t->t_dtrace_reg != 0 &&
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync switch (t->t_dtrace_reg) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return (0);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Otherwise, make sure we'll return to the kernel after executing
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * the copied out instruction and defer the signal.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return (1);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Additional artificial frames for the machine type. For i86pc, we're already
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * accounted for, so return 0. On the hypervisor, we have an additional frame
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * (xen_callback_handler).
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return (1);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return (0);