Home | History | Annotate | Download | only in dtrace
      1     0   stevel /*
      2     0   stevel  * CDDL HEADER START
      3     0   stevel  *
      4     0   stevel  * The contents of this file are subject to the terms of the
      5  1710      ahl  * Common Development and Distribution License (the "License").
      6  1710      ahl  * You may not use this file except in compliance with the License.
      7     0   stevel  *
      8     0   stevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9     0   stevel  * or http://www.opensolaris.org/os/licensing.
     10     0   stevel  * See the License for the specific language governing permissions
     11     0   stevel  * and limitations under the License.
     12     0   stevel  *
     13     0   stevel  * When distributing Covered Code, include this CDDL HEADER in each
     14     0   stevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15     0   stevel  * If applicable, add the following below this CDDL HEADER, with the
     16     0   stevel  * fields enclosed by brackets "[]" replaced with your own identifying
     17     0   stevel  * information: Portions Copyright [yyyy] [name of copyright owner]
     18     0   stevel  *
     19     0   stevel  * CDDL HEADER END
     20     0   stevel  */
     21  1710      ahl 
     22     0   stevel /*
     23  6390      ahl  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     24     0   stevel  * Use is subject to license terms.
     25     0   stevel  */
     26     0   stevel 
     27     0   stevel #pragma ident	"%Z%%M%	%I%	%E% SMI"
     28     0   stevel 
     29     0   stevel #include <sys/fasttrap_isa.h>
     30     0   stevel #include <sys/fasttrap_impl.h>
     31     0   stevel #include <sys/dtrace.h>
     32     0   stevel #include <sys/dtrace_impl.h>
     33     0   stevel #include <sys/cmn_err.h>
     34     0   stevel #include <sys/regset.h>
     35     0   stevel #include <sys/privregs.h>
     36     0   stevel #include <sys/segments.h>
     37  3446      mrj #include <sys/x86_archext.h>
     38     0   stevel #include <sys/sysmacros.h>
     39     0   stevel #include <sys/trap.h>
     40  2712  nn35248 #include <sys/archsystm.h>
     41     0   stevel 
     42     0   stevel /*
     43     0   stevel  * Lossless User-Land Tracing on x86
     44     0   stevel  * ---------------------------------
     45     0   stevel  *
     46  1710      ahl  * The execution of most instructions is not dependent on the address; for
     47  1710      ahl  * these instructions it is sufficient to copy them into the user process's
     48  1710      ahl  * address space and execute them. To effectively single-step an instruction
     49  1710      ahl  * in user-land, we copy out the following sequence of instructions to scratch
     50     0   stevel  * space in the user thread's ulwp_t structure.
     51     0   stevel  *
     52     0   stevel  * We then set the program counter (%eip or %rip) to point to this scratch
     53     0   stevel  * space. Once execution resumes, the original instruction is executed and
     54     0   stevel  * then control flow is redirected to what was originally the subsequent
     55     0   stevel  * instruction. If the kernel attemps to deliver a signal while single-
     56     0   stevel  * stepping, the signal is deferred and the program counter is moved into the
     57     0   stevel  * second sequence of instructions. The second sequence ends in a trap into
     58     0   stevel  * the kernel where the deferred signal is then properly handled and delivered.
     59     0   stevel  *
     60     0   stevel  * For instructions whose execute is position dependent, we perform simple
     61     0   stevel  * emulation. These instructions are limited to control transfer
     62     0   stevel  * instructions in 32-bit mode, but in 64-bit mode there's the added wrinkle
     63     0   stevel  * of %rip-relative addressing that means that almost any instruction can be
     64     0   stevel  * position dependent. For all the details on how we emulate generic
     65     0   stevel  * instructions included %rip-relative instructions, see the code in
     66     0   stevel  * fasttrap_pid_probe() below where we handle instructions of type
     67     0   stevel  * FASTTRAP_T_COMMON (under the header: Generic Instruction Tracing).
     68     0   stevel  */
     69     0   stevel 
     70     0   stevel #define	FASTTRAP_MODRM_MOD(modrm)	(((modrm) >> 6) & 0x3)
     71     0   stevel #define	FASTTRAP_MODRM_REG(modrm)	(((modrm) >> 3) & 0x7)
     72     0   stevel #define	FASTTRAP_MODRM_RM(modrm)	((modrm) & 0x7)
     73     0   stevel #define	FASTTRAP_MODRM(mod, reg, rm)	(((mod) << 6) | ((reg) << 3) | (rm))
     74     0   stevel 
     75     0   stevel #define	FASTTRAP_SIB_SCALE(sib)		(((sib) >> 6) & 0x3)
     76     0   stevel #define	FASTTRAP_SIB_INDEX(sib)		(((sib) >> 3) & 0x7)
     77     0   stevel #define	FASTTRAP_SIB_BASE(sib)		((sib) & 0x7)
     78     0   stevel 
     79     0   stevel #define	FASTTRAP_REX_W(rex)		(((rex) >> 3) & 1)
     80     0   stevel #define	FASTTRAP_REX_R(rex)		(((rex) >> 2) & 1)
     81     0   stevel #define	FASTTRAP_REX_X(rex)		(((rex) >> 1) & 1)
     82     0   stevel #define	FASTTRAP_REX_B(rex)		((rex) & 1)
     83     0   stevel #define	FASTTRAP_REX(w, r, x, b)	\
     84     0   stevel 	(0x40 | ((w) << 3) | ((r) << 2) | ((x) << 1) | (b))
     85     0   stevel 
     86     0   stevel /*
     87     0   stevel  * Single-byte op-codes.
     88     0   stevel  */
     89     0   stevel #define	FASTTRAP_PUSHL_EBP	0x55
     90     0   stevel 
     91     0   stevel #define	FASTTRAP_JO		0x70
     92     0   stevel #define	FASTTRAP_JNO		0x71
     93     0   stevel #define	FASTTRAP_JB		0x72
     94     0   stevel #define	FASTTRAP_JAE		0x73
     95     0   stevel #define	FASTTRAP_JE		0x74
     96     0   stevel #define	FASTTRAP_JNE		0x75
     97     0   stevel #define	FASTTRAP_JBE		0x76
     98     0   stevel #define	FASTTRAP_JA		0x77
     99     0   stevel #define	FASTTRAP_JS		0x78
    100     0   stevel #define	FASTTRAP_JNS		0x79
    101     0   stevel #define	FASTTRAP_JP		0x7a
    102     0   stevel #define	FASTTRAP_JNP		0x7b
    103     0   stevel #define	FASTTRAP_JL		0x7c
    104     0   stevel #define	FASTTRAP_JGE		0x7d
    105     0   stevel #define	FASTTRAP_JLE		0x7e
    106     0   stevel #define	FASTTRAP_JG		0x7f
    107  2769      ahl 
    108  2769      ahl #define	FASTTRAP_NOP		0x90
    109     0   stevel 
    110     0   stevel #define	FASTTRAP_MOV_EAX	0xb8
    111     0   stevel #define	FASTTRAP_MOV_ECX	0xb9
    112     0   stevel 
    113     0   stevel #define	FASTTRAP_RET16		0xc2
    114     0   stevel #define	FASTTRAP_RET		0xc3
    115     0   stevel 
    116     0   stevel #define	FASTTRAP_LOOPNZ		0xe0
    117     0   stevel #define	FASTTRAP_LOOPZ		0xe1
    118     0   stevel #define	FASTTRAP_LOOP		0xe2
    119     0   stevel #define	FASTTRAP_JCXZ		0xe3
    120     0   stevel 
    121     0   stevel #define	FASTTRAP_CALL		0xe8
    122     0   stevel #define	FASTTRAP_JMP32		0xe9
    123     0   stevel #define	FASTTRAP_JMP8		0xeb
    124     0   stevel 
    125     0   stevel #define	FASTTRAP_INT3		0xcc
    126     0   stevel #define	FASTTRAP_INT		0xcd
    127     0   stevel 
    128     0   stevel #define	FASTTRAP_2_BYTE_OP	0x0f
    129     0   stevel #define	FASTTRAP_GROUP5_OP	0xff
    130     0   stevel 
    131     0   stevel /*
    132     0   stevel  * Two-byte op-codes (second byte only).
    133     0   stevel  */
    134     0   stevel #define	FASTTRAP_0F_JO		0x80
    135     0   stevel #define	FASTTRAP_0F_JNO		0x81
    136     0   stevel #define	FASTTRAP_0F_JB		0x82
    137     0   stevel #define	FASTTRAP_0F_JAE		0x83
    138     0   stevel #define	FASTTRAP_0F_JE		0x84
    139     0   stevel #define	FASTTRAP_0F_JNE		0x85
    140     0   stevel #define	FASTTRAP_0F_JBE		0x86
    141     0   stevel #define	FASTTRAP_0F_JA		0x87
    142     0   stevel #define	FASTTRAP_0F_JS		0x88
    143     0   stevel #define	FASTTRAP_0F_JNS		0x89
    144     0   stevel #define	FASTTRAP_0F_JP		0x8a
    145     0   stevel #define	FASTTRAP_0F_JNP		0x8b
    146     0   stevel #define	FASTTRAP_0F_JL		0x8c
    147     0   stevel #define	FASTTRAP_0F_JGE		0x8d
    148     0   stevel #define	FASTTRAP_0F_JLE		0x8e
    149     0   stevel #define	FASTTRAP_0F_JG		0x8f
    150     0   stevel 
    151     0   stevel #define	FASTTRAP_EFLAGS_OF	0x800
    152     0   stevel #define	FASTTRAP_EFLAGS_DF	0x400
    153     0   stevel #define	FASTTRAP_EFLAGS_SF	0x080
    154     0   stevel #define	FASTTRAP_EFLAGS_ZF	0x040
    155     0   stevel #define	FASTTRAP_EFLAGS_AF	0x010
    156     0   stevel #define	FASTTRAP_EFLAGS_PF	0x004
    157     0   stevel #define	FASTTRAP_EFLAGS_CF	0x001
    158     0   stevel 
    159     0   stevel /*
    160     0   stevel  * Instruction prefixes.
    161     0   stevel  */
    162     0   stevel #define	FASTTRAP_PREFIX_OPERAND	0x66
    163     0   stevel #define	FASTTRAP_PREFIX_ADDRESS	0x67
    164     0   stevel #define	FASTTRAP_PREFIX_CS	0x2E
    165     0   stevel #define	FASTTRAP_PREFIX_DS	0x3E
    166     0   stevel #define	FASTTRAP_PREFIX_ES	0x26
    167     0   stevel #define	FASTTRAP_PREFIX_FS	0x64
    168     0   stevel #define	FASTTRAP_PREFIX_GS	0x65
    169     0   stevel #define	FASTTRAP_PREFIX_SS	0x36
    170     0   stevel #define	FASTTRAP_PREFIX_LOCK	0xF0
    171     0   stevel #define	FASTTRAP_PREFIX_REP	0xF3
    172     0   stevel #define	FASTTRAP_PREFIX_REPNE	0xF2
    173     0   stevel 
    174     0   stevel #define	FASTTRAP_NOREG	0xff
    175     0   stevel 
    176     0   stevel /*
    177     0   stevel  * Map between instruction register encodings and the kernel constants which
    178     0   stevel  * correspond to indicies into struct regs.
    179     0   stevel  */
    180     0   stevel #ifdef __amd64
    181     0   stevel static const uint8_t regmap[16] = {
    182     0   stevel 	REG_RAX, REG_RCX, REG_RDX, REG_RBX, REG_RSP, REG_RBP, REG_RSI, REG_RDI,
    183     0   stevel 	REG_R8, REG_R9, REG_R10, REG_R11, REG_R12, REG_R13, REG_R14, REG_R15,
    184     0   stevel };
    185     0   stevel #else
    186     0   stevel static const uint8_t regmap[8] = {
    187     0   stevel 	EAX, ECX, EDX, EBX, UESP, EBP, ESI, EDI
    188     0   stevel };
    189     0   stevel #endif
    190     0   stevel 
    191     0   stevel static ulong_t fasttrap_getreg(struct regs *, uint_t);
    192     0   stevel 
    193     0   stevel static uint64_t
    194     0   stevel fasttrap_anarg(struct regs *rp, int function_entry, int argno)
    195     0   stevel {
    196     0   stevel 	uint64_t value;
    197     0   stevel 	int shift = function_entry ? 1 : 0;
    198     0   stevel 
    199     0   stevel #ifdef __amd64
    200     0   stevel 	if (curproc->p_model == DATAMODEL_LP64) {
    201     0   stevel 		uintptr_t *stack;
    202     0   stevel 
    203     0   stevel 		/*
    204     0   stevel 		 * In 64-bit mode, the first six arguments are stored in
    205     0   stevel 		 * registers.
    206     0   stevel 		 */
    207     0   stevel 		if (argno < 6)
    208     0   stevel 			return ((&rp->r_rdi)[argno]);
    209     0   stevel 
    210     0   stevel 		stack = (uintptr_t *)rp->r_sp;
    211     0   stevel 		DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
    212     0   stevel 		value = dtrace_fulword(&stack[argno - 6 + shift]);
    213     0   stevel 		DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT | CPU_DTRACE_BADADDR);
    214     0   stevel 	} else {
    215     0   stevel #endif
    216     0   stevel 		uint32_t *stack = (uint32_t *)rp->r_sp;
    217     0   stevel 		DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
    218     0   stevel 		value = dtrace_fuword32(&stack[argno + shift]);
    219     0   stevel 		DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT | CPU_DTRACE_BADADDR);
    220     0   stevel #ifdef __amd64
    221     0   stevel 	}
    222     0   stevel #endif
    223     0   stevel 
    224     0   stevel 	return (value);
    225     0   stevel }
    226     0   stevel 
    227     0   stevel /*ARGSUSED*/
    228     0   stevel int
    229  1710      ahl fasttrap_tracepoint_init(proc_t *p, fasttrap_tracepoint_t *tp, uintptr_t pc,
    230  1710      ahl     fasttrap_probe_type_t type)
    231     0   stevel {
    232     0   stevel 	uint8_t instr[FASTTRAP_MAX_INSTR_SIZE + 10];
    233     0   stevel 	size_t len = FASTTRAP_MAX_INSTR_SIZE;
    234     0   stevel 	size_t first = MIN(len, PAGESIZE - (pc & PAGEOFFSET));
    235     0   stevel 	uint_t start = 0;
    236  2769      ahl 	int rmindex, size;
    237  2712  nn35248 	uint8_t seg, rex = 0;
    238     0   stevel 
    239     0   stevel 	/*
    240     0   stevel 	 * Read the instruction at the given address out of the process's
    241     0   stevel 	 * address space. We don't have to worry about a debugger
    242     0   stevel 	 * changing this instruction before we overwrite it with our trap
    243     0   stevel 	 * instruction since P_PR_LOCK is set. Since instructions can span
    244     0   stevel 	 * pages, we potentially read the instruction in two parts. If the
    245     0   stevel 	 * second part fails, we just zero out that part of the instruction.
    246     0   stevel 	 */
    247     0   stevel 	if (uread(p, &instr[0], first, pc) != 0)
    248     0   stevel 		return (-1);
    249     0   stevel 	if (len > first &&
    250     0   stevel 	    uread(p, &instr[first], len - first, pc + first) != 0) {
    251     0   stevel 		bzero(&instr[first], len - first);
    252     0   stevel 		len = first;
    253     0   stevel 	}
    254     0   stevel 
    255     0   stevel 	/*
    256     0   stevel 	 * If the disassembly fails, then we have a malformed instruction.
    257     0   stevel 	 */
    258  2769      ahl 	if ((size = dtrace_instr_size_isa(instr, p->p_model, &rmindex)) <= 0)
    259     0   stevel 		return (-1);
    260     0   stevel 
    261     0   stevel 	/*
    262     0   stevel 	 * Make sure the disassembler isn't completely broken.
    263     0   stevel 	 */
    264  2769      ahl 	ASSERT(-1 <= rmindex && rmindex < size);
    265     0   stevel 
    266     0   stevel 	/*
    267     0   stevel 	 * If the computed size is greater than the number of bytes read,
    268     0   stevel 	 * then it was a malformed instruction possibly because it fell on a
    269     0   stevel 	 * page boundary and the subsequent page was missing or because of
    270     0   stevel 	 * some malicious user.
    271     0   stevel 	 */
    272  2769      ahl 	if (size > len)
    273     0   stevel 		return (-1);
    274     0   stevel 
    275  2769      ahl 	tp->ftt_size = (uint8_t)size;
    276  2712  nn35248 	tp->ftt_segment = FASTTRAP_SEG_NONE;
    277  2712  nn35248 
    278     0   stevel 	/*
    279     0   stevel 	 * Find the start of the instruction's opcode by processing any
    280     0   stevel 	 * legacy prefixes.
    281     0   stevel 	 */
    282     0   stevel 	for (;;) {
    283  2712  nn35248 		seg = 0;
    284     0   stevel 		switch (instr[start]) {
    285  2712  nn35248 		case FASTTRAP_PREFIX_SS:
    286  2712  nn35248 			seg++;
    287  2712  nn35248 			/*FALLTHRU*/
    288  2712  nn35248 		case FASTTRAP_PREFIX_GS:
    289  2712  nn35248 			seg++;
    290  2712  nn35248 			/*FALLTHRU*/
    291  2712  nn35248 		case FASTTRAP_PREFIX_FS:
    292  2712  nn35248 			seg++;
    293  2712  nn35248 			/*FALLTHRU*/
    294  2712  nn35248 		case FASTTRAP_PREFIX_ES:
    295  2712  nn35248 			seg++;
    296  2712  nn35248 			/*FALLTHRU*/
    297  2712  nn35248 		case FASTTRAP_PREFIX_DS:
    298  2712  nn35248 			seg++;
    299  2712  nn35248 			/*FALLTHRU*/
    300  2712  nn35248 		case FASTTRAP_PREFIX_CS:
    301  2712  nn35248 			seg++;
    302  2712  nn35248 			/*FALLTHRU*/
    303     0   stevel 		case FASTTRAP_PREFIX_OPERAND:
    304     0   stevel 		case FASTTRAP_PREFIX_ADDRESS:
    305     0   stevel 		case FASTTRAP_PREFIX_LOCK:
    306     0   stevel 		case FASTTRAP_PREFIX_REP:
    307     0   stevel 		case FASTTRAP_PREFIX_REPNE:
    308  2712  nn35248 			if (seg != 0) {
    309  2712  nn35248 				/*
    310  2712  nn35248 				 * It's illegal for an instruction to specify
    311  2712  nn35248 				 * two segment prefixes -- give up on this
    312  2712  nn35248 				 * illegal instruction.
    313  2712  nn35248 				 */
    314  2712  nn35248 				if (tp->ftt_segment != FASTTRAP_SEG_NONE)
    315  2712  nn35248 					return (-1);
    316  2712  nn35248 
    317  2712  nn35248 				tp->ftt_segment = seg;
    318  2712  nn35248 			}
    319     0   stevel 			start++;
    320     0   stevel 			continue;
    321     0   stevel 		}
    322     0   stevel 		break;
    323     0   stevel 	}
    324     0   stevel 
    325     0   stevel #ifdef __amd64
    326     0   stevel 	/*
    327     0   stevel 	 * Identify the REX prefix on 64-bit processes.
    328     0   stevel 	 */
    329     0   stevel 	if (p->p_model == DATAMODEL_LP64 && (instr[start] & 0xf0) == 0x40)
    330     0   stevel 		rex = instr[start++];
    331     0   stevel #endif
    332     0   stevel 
    333     0   stevel 	/*
    334     0   stevel 	 * Now that we're pretty sure that the instruction is okay, copy the
    335     0   stevel 	 * valid part to the tracepoint.
    336     0   stevel 	 */
    337     0   stevel 	bcopy(instr, tp->ftt_instr, FASTTRAP_MAX_INSTR_SIZE);
    338     0   stevel 
    339     0   stevel 	tp->ftt_type = FASTTRAP_T_COMMON;
    340     0   stevel 	if (instr[start] == FASTTRAP_2_BYTE_OP) {
    341     0   stevel 		switch (instr[start + 1]) {
    342     0   stevel 		case FASTTRAP_0F_JO:
    343     0   stevel 		case FASTTRAP_0F_JNO:
    344     0   stevel 		case FASTTRAP_0F_JB:
    345     0   stevel 		case FASTTRAP_0F_JAE:
    346     0   stevel 		case FASTTRAP_0F_JE:
    347     0   stevel 		case FASTTRAP_0F_JNE:
    348     0   stevel 		case FASTTRAP_0F_JBE:
    349     0   stevel 		case FASTTRAP_0F_JA:
    350     0   stevel 		case FASTTRAP_0F_JS:
    351     0   stevel 		case FASTTRAP_0F_JNS:
    352     0   stevel 		case FASTTRAP_0F_JP:
    353     0   stevel 		case FASTTRAP_0F_JNP:
    354     0   stevel 		case FASTTRAP_0F_JL:
    355     0   stevel 		case FASTTRAP_0F_JGE:
    356     0   stevel 		case FASTTRAP_0F_JLE:
    357     0   stevel 		case FASTTRAP_0F_JG:
    358     0   stevel 			tp->ftt_type = FASTTRAP_T_JCC;
    359     0   stevel 			tp->ftt_code = (instr[start + 1] & 0x0f) | FASTTRAP_JO;
    360     0   stevel 			tp->ftt_dest = pc + tp->ftt_size +
    361  3944      ahl 			    /* LINTED - alignment */
    362     0   stevel 			    *(int32_t *)&instr[start + 2];
    363     0   stevel 			break;
    364     0   stevel 		}
    365     0   stevel 	} else if (instr[start] == FASTTRAP_GROUP5_OP) {
    366     0   stevel 		uint_t mod = FASTTRAP_MODRM_MOD(instr[start + 1]);
    367     0   stevel 		uint_t reg = FASTTRAP_MODRM_REG(instr[start + 1]);
    368     0   stevel 		uint_t rm = FASTTRAP_MODRM_RM(instr[start + 1]);
    369     0   stevel 
    370     0   stevel 		if (reg == 2 || reg == 4) {
    371     0   stevel 			uint_t i, sz;
    372     0   stevel 
    373     0   stevel 			if (reg == 2)
    374     0   stevel 				tp->ftt_type = FASTTRAP_T_CALL;
    375     0   stevel 			else
    376     0   stevel 				tp->ftt_type = FASTTRAP_T_JMP;
    377     0   stevel 
    378     0   stevel 			if (mod == 3)
    379     0   stevel 				tp->ftt_code = 2;
    380     0   stevel 			else
    381     0   stevel 				tp->ftt_code = 1;
    382     0   stevel 
    383     0   stevel 			ASSERT(p->p_model == DATAMODEL_LP64 || rex == 0);
    384     0   stevel 
    385     0   stevel 			/*
    386     0   stevel 			 * See AMD x86-64 Architecture Programmer's Manual
    387     0   stevel 			 * Volume 3, Section 1.2.7, Table 1-12, and
    388     0   stevel 			 * Appendix A.3.1, Table A-15.
    389     0   stevel 			 */
    390     0   stevel 			if (mod != 3 && rm == 4) {
    391     0   stevel 				uint8_t sib = instr[start + 2];
    392     0   stevel 				uint_t index = FASTTRAP_SIB_INDEX(sib);
    393     0   stevel 				uint_t base = FASTTRAP_SIB_BASE(sib);
    394     0   stevel 
    395     0   stevel 				tp->ftt_scale = FASTTRAP_SIB_SCALE(sib);
    396     0   stevel 
    397     0   stevel 				tp->ftt_index = (index == 4) ?
    398     0   stevel 				    FASTTRAP_NOREG :
    399     0   stevel 				    regmap[index | (FASTTRAP_REX_X(rex) << 3)];
    400     0   stevel 				tp->ftt_base = (mod == 0 && base == 5) ?
    401     0   stevel 				    FASTTRAP_NOREG :
    402     0   stevel 				    regmap[base | (FASTTRAP_REX_B(rex) << 3)];
    403     0   stevel 
    404     0   stevel 				i = 3;
    405     0   stevel 				sz = mod == 1 ? 1 : 4;
    406     0   stevel 			} else {
    407     0   stevel 				/*
    408     0   stevel 				 * In 64-bit mode, mod == 0 and r/m == 5
    409     0   stevel 				 * denotes %rip-relative addressing; in 32-bit
    410     0   stevel 				 * mode, the base register isn't used. In both
    411     0   stevel 				 * modes, there is a 32-bit operand.
    412     0   stevel 				 */
    413     0   stevel 				if (mod == 0 && rm == 5) {
    414     0   stevel #ifdef __amd64
    415     0   stevel 					if (p->p_model == DATAMODEL_LP64)
    416     0   stevel 						tp->ftt_base = REG_RIP;
    417     0   stevel 					else
    418     0   stevel #endif
    419     0   stevel 						tp->ftt_base = FASTTRAP_NOREG;
    420     0   stevel 					sz = 4;
    421     0   stevel 				} else  {
    422     0   stevel 					uint8_t base = rm |
    423     0   stevel 					    (FASTTRAP_REX_B(rex) << 3);
    424     0   stevel 
    425     0   stevel 					tp->ftt_base = regmap[base];
    426     0   stevel 					sz = mod == 1 ? 1 : mod == 2 ? 4 : 0;
    427     0   stevel 				}
    428     0   stevel 				tp->ftt_index = FASTTRAP_NOREG;
    429     0   stevel 				i = 2;
    430     0   stevel 			}
    431     0   stevel 
    432  3944      ahl 			if (sz == 1) {
    433     0   stevel 				tp->ftt_dest = *(int8_t *)&instr[start + i];
    434  3944      ahl 			} else if (sz == 4) {
    435  3944      ahl 				/* LINTED - alignment */
    436     0   stevel 				tp->ftt_dest = *(int32_t *)&instr[start + i];
    437  3944      ahl 			} else {
    438     0   stevel 				tp->ftt_dest = 0;
    439  3944      ahl 			}
    440     0   stevel 		}
    441     0   stevel 	} else {
    442     0   stevel 		switch (instr[start]) {
    443     0   stevel 		case FASTTRAP_RET:
    444     0   stevel 			tp->ftt_type = FASTTRAP_T_RET;
    445     0   stevel 			break;
    446     0   stevel 
    447     0   stevel 		case FASTTRAP_RET16:
    448     0   stevel 			tp->ftt_type = FASTTRAP_T_RET16;
    449  3944      ahl 			/* LINTED - alignment */
    450     0   stevel 			tp->ftt_dest = *(uint16_t *)&instr[start + 1];
    451     0   stevel 			break;
    452     0   stevel 
    453     0   stevel 		case FASTTRAP_JO:
    454     0   stevel 		case FASTTRAP_JNO:
    455     0   stevel 		case FASTTRAP_JB:
    456     0   stevel 		case FASTTRAP_JAE:
    457     0   stevel 		case FASTTRAP_JE:
    458     0   stevel 		case FASTTRAP_JNE:
    459     0   stevel 		case FASTTRAP_JBE:
    460     0   stevel 		case FASTTRAP_JA:
    461     0   stevel 		case FASTTRAP_JS:
    462     0   stevel 		case FASTTRAP_JNS:
    463     0   stevel 		case FASTTRAP_JP:
    464     0   stevel 		case FASTTRAP_JNP:
    465     0   stevel 		case FASTTRAP_JL:
    466     0   stevel 		case FASTTRAP_JGE:
    467     0   stevel 		case FASTTRAP_JLE:
    468     0   stevel 		case FASTTRAP_JG:
    469     0   stevel 			tp->ftt_type = FASTTRAP_T_JCC;
    470     0   stevel 			tp->ftt_code = instr[start];
    471     0   stevel 			tp->ftt_dest = pc + tp->ftt_size +
    472     0   stevel 			    (int8_t)instr[start + 1];
    473     0   stevel 			break;
    474     0   stevel 
    475     0   stevel 		case FASTTRAP_LOOPNZ:
    476     0   stevel 		case FASTTRAP_LOOPZ:
    477     0   stevel 		case FASTTRAP_LOOP:
    478     0   stevel 			tp->ftt_type = FASTTRAP_T_LOOP;
    479     0   stevel 			tp->ftt_code = instr[start];
    480     0   stevel 			tp->ftt_dest = pc + tp->ftt_size +
    481     0   stevel 			    (int8_t)instr[start + 1];
    482     0   stevel 			break;
    483     0   stevel 
    484     0   stevel 		case FASTTRAP_JCXZ:
    485     0   stevel 			tp->ftt_type = FASTTRAP_T_JCXZ;
    486     0   stevel 			tp->ftt_dest = pc + tp->ftt_size +
    487     0   stevel 			    (int8_t)instr[start + 1];
    488     0   stevel 			break;
    489     0   stevel 
    490     0   stevel 		case FASTTRAP_CALL:
    491     0   stevel 			tp->ftt_type = FASTTRAP_T_CALL;
    492     0   stevel 			tp->ftt_dest = pc + tp->ftt_size +
    493  3944      ahl 			    /* LINTED - alignment */
    494     0   stevel 			    *(int32_t *)&instr[start + 1];
    495     0   stevel 			tp->ftt_code = 0;
    496     0   stevel 			break;
    497     0   stevel 
    498     0   stevel 		case FASTTRAP_JMP32:
    499     0   stevel 			tp->ftt_type = FASTTRAP_T_JMP;
    500     0   stevel 			tp->ftt_dest = pc + tp->ftt_size +
    501  3944      ahl 			    /* LINTED - alignment */
    502     0   stevel 			    *(int32_t *)&instr[start + 1];
    503     0   stevel 			break;
    504     0   stevel 		case FASTTRAP_JMP8:
    505     0   stevel 			tp->ftt_type = FASTTRAP_T_JMP;
    506     0   stevel 			tp->ftt_dest = pc + tp->ftt_size +
    507     0   stevel 			    (int8_t)instr[start + 1];
    508     0   stevel 			break;
    509     0   stevel 
    510     0   stevel 		case FASTTRAP_PUSHL_EBP:
    511     0   stevel 			if (start == 0)
    512     0   stevel 				tp->ftt_type = FASTTRAP_T_PUSHL_EBP;
    513  2769      ahl 			break;
    514  2769      ahl 
    515  2769      ahl 		case FASTTRAP_NOP:
    516  2769      ahl #ifdef __amd64
    517  2769      ahl 			ASSERT(p->p_model == DATAMODEL_LP64 || rex == 0);
    518  2769      ahl 
    519  2769      ahl 			/*
    520  2769      ahl 			 * On amd64 we have to be careful not to confuse a nop
    521  2769      ahl 			 * (actually xchgl %eax, %eax) with an instruction using
    522  2769      ahl 			 * the same opcode, but that does something different
    523  2769      ahl 			 * (e.g. xchgl %r8d, %eax or xcghq %r8, %rax).
    524  2769      ahl 			 */
    525  2769      ahl 			if (FASTTRAP_REX_B(rex) == 0)
    526  2769      ahl #endif
    527  2769      ahl 				tp->ftt_type = FASTTRAP_T_NOP;
    528     0   stevel 			break;
    529     0   stevel 
    530     0   stevel 		case FASTTRAP_INT3:
    531     0   stevel 			/*
    532     0   stevel 			 * The pid provider shares the int3 trap with debugger
    533     0   stevel 			 * breakpoints so we can't instrument them.
    534     0   stevel 			 */
    535     0   stevel 			ASSERT(instr[start] == FASTTRAP_INSTR);
    536  2712  nn35248 			return (-1);
    537  2712  nn35248 
    538  2712  nn35248 		case FASTTRAP_INT:
    539  2712  nn35248 			/*
    540  2712  nn35248 			 * Interrupts seem like they could be traced with
    541  2712  nn35248 			 * no negative implications, but it's possible that
    542  2712  nn35248 			 * a thread could be redirected by the trap handling
    543  2712  nn35248 			 * code which would eventually return to the
    544  2712  nn35248 			 * instruction after the interrupt. If the interrupt
    545  2712  nn35248 			 * were in our scratch space, the subsequent
    546  2712  nn35248 			 * instruction might be overwritten before we return.
    547  2712  nn35248 			 * Accordingly we refuse to instrument any interrupt.
    548  2712  nn35248 			 */
    549     0   stevel 			return (-1);
    550     0   stevel 		}
    551     0   stevel 	}
    552     0   stevel 
    553     0   stevel #ifdef __amd64
    554     0   stevel 	if (p->p_model == DATAMODEL_LP64 && tp->ftt_type == FASTTRAP_T_COMMON) {
    555     0   stevel 		/*
    556     0   stevel 		 * If the process is 64-bit and the instruction type is still
    557     0   stevel 		 * FASTTRAP_T_COMMON -- meaning we're going to copy it out an
    558     0   stevel 		 * execute it -- we need to watch for %rip-relative
    559     0   stevel 		 * addressing mode. See the portion of fasttrap_pid_probe()
    560     0   stevel 		 * below where we handle tracepoints with type
    561     0   stevel 		 * FASTTRAP_T_COMMON for how we emulate instructions that
    562     0   stevel 		 * employ %rip-relative addressing.
    563     0   stevel 		 */
    564     0   stevel 		if (rmindex != -1) {
    565     0   stevel 			uint_t mod = FASTTRAP_MODRM_MOD(instr[rmindex]);
    566     0   stevel 			uint_t reg = FASTTRAP_MODRM_REG(instr[rmindex]);
    567     0   stevel 			uint_t rm = FASTTRAP_MODRM_RM(instr[rmindex]);
    568     0   stevel 
    569     0   stevel 			ASSERT(rmindex > start);
    570     0   stevel 
    571     0   stevel 			if (mod == 0 && rm == 5) {
    572     0   stevel 				/*
    573     0   stevel 				 * We need to be sure to avoid other
    574     0   stevel 				 * registers used by this instruction. While
    575     0   stevel 				 * the reg field may determine the op code
    576     0   stevel 				 * rather than denoting a register, assuming
    577     0   stevel 				 * that it denotes a register is always safe.
    578     0   stevel 				 * We leave the REX field intact and use
    579     0   stevel 				 * whatever value's there for simplicity.
    580     0   stevel 				 */
    581     0   stevel 				if (reg != 0) {
    582     0   stevel 					tp->ftt_ripmode = FASTTRAP_RIP_1 |
    583     0   stevel 					    (FASTTRAP_RIP_X *
    584     0   stevel 					    FASTTRAP_REX_B(rex));
    585     0   stevel 					rm = 0;
    586     0   stevel 				} else {
    587     0   stevel 					tp->ftt_ripmode = FASTTRAP_RIP_2 |
    588     0   stevel 					    (FASTTRAP_RIP_X *
    589     0   stevel 					    FASTTRAP_REX_B(rex));
    590     0   stevel 					rm = 1;
    591     0   stevel 				}
    592     0   stevel 
    593     0   stevel 				tp->ftt_modrm = tp->ftt_instr[rmindex];
    594     0   stevel 				tp->ftt_instr[rmindex] =
    595     0   stevel 				    FASTTRAP_MODRM(2, reg, rm);
    596     0   stevel 			}
    597     0   stevel 		}
    598     0   stevel 	}
    599     0   stevel #endif
    600     0   stevel 
    601     0   stevel 	return (0);
    602     0   stevel }
    603     0   stevel 
    604     0   stevel int
    605     0   stevel fasttrap_tracepoint_install(proc_t *p, fasttrap_tracepoint_t *tp)
    606     0   stevel {
    607     0   stevel 	fasttrap_instr_t instr = FASTTRAP_INSTR;
    608     0   stevel 
    609     0   stevel 	if (uwrite(p, &instr, 1, tp->ftt_pc) != 0)
    610     0   stevel 		return (-1);
    611     0   stevel 
    612     0   stevel 	return (0);
    613     0   stevel }
    614     0   stevel 
    615     0   stevel int
    616     0   stevel fasttrap_tracepoint_remove(proc_t *p, fasttrap_tracepoint_t *tp)
    617     0   stevel {
    618     0   stevel 	uint8_t instr;
    619     0   stevel 
    620     0   stevel 	/*
    621     0   stevel 	 * Distinguish between read or write failures and a changed
    622     0   stevel 	 * instruction.
    623     0   stevel 	 */
    624     0   stevel 	if (uread(p, &instr, 1, tp->ftt_pc) != 0)
    625     0   stevel 		return (0);
    626     0   stevel 	if (instr != FASTTRAP_INSTR)
    627     0   stevel 		return (0);
    628     0   stevel 	if (uwrite(p, &tp->ftt_instr[0], 1, tp->ftt_pc) != 0)
    629     0   stevel 		return (-1);
    630     0   stevel 
    631     0   stevel 	return (0);
    632     0   stevel }
    633     0   stevel 
    634  3944      ahl #ifdef __amd64
    635     0   stevel static uintptr_t
    636     0   stevel fasttrap_fulword_noerr(const void *uaddr)
    637     0   stevel {
    638     0   stevel 	uintptr_t ret;
    639     0   stevel 
    640     0   stevel 	if (fasttrap_fulword(uaddr, &ret) == 0)
    641     0   stevel 		return (ret);
    642     0   stevel 
    643     0   stevel 	return (0);
    644     0   stevel }
    645  3944      ahl #endif
    646     0   stevel 
    647     0   stevel static uint32_t
    648     0   stevel fasttrap_fuword32_noerr(const void *uaddr)
    649     0   stevel {
    650     0   stevel 	uint32_t ret;
    651     0   stevel 
    652     0   stevel 	if (fasttrap_fuword32(uaddr, &ret) == 0)
    653     0   stevel 		return (ret);
    654     0   stevel 
    655     0   stevel 	return (0);
    656     0   stevel }
    657     0   stevel 
    658     0   stevel static void
    659     0   stevel fasttrap_return_common(struct regs *rp, uintptr_t pc, pid_t pid,
    660     0   stevel     uintptr_t new_pc)
    661     0   stevel {
    662     0   stevel 	fasttrap_tracepoint_t *tp;
    663     0   stevel 	fasttrap_bucket_t *bucket;
    664     0   stevel 	fasttrap_id_t *id;
    665     0   stevel 	kmutex_t *pid_mtx;
    666     0   stevel 
    667     0   stevel 	pid_mtx = &cpu_core[CPU->cpu_id].cpuc_pid_lock;
    668     0   stevel 	mutex_enter(pid_mtx);
    669     0   stevel 	bucket = &fasttrap_tpoints.fth_table[FASTTRAP_TPOINTS_INDEX(pid, pc)];
    670     0   stevel 
    671     0   stevel 	for (tp = bucket->ftb_data; tp != NULL; tp = tp->ftt_next) {
    672     0   stevel 		if (pid == tp->ftt_pid && pc == tp->ftt_pc &&
    673  4821      ahl 		    tp->ftt_proc->ftpc_acount != 0)
    674     0   stevel 			break;
    675     0   stevel 	}
    676     0   stevel 
    677     0   stevel 	/*
    678     0   stevel 	 * Don't sweat it if we can't find the tracepoint again; unlike
    679     0   stevel 	 * when we're in fasttrap_pid_probe(), finding the tracepoint here
    680     0   stevel 	 * is not essential to the correct execution of the process.
    681     0   stevel 	 */
    682     0   stevel 	if (tp == NULL) {
    683     0   stevel 		mutex_exit(pid_mtx);
    684     0   stevel 		return;
    685     0   stevel 	}
    686     0   stevel 
    687     0   stevel 	for (id = tp->ftt_retids; id != NULL; id = id->fti_next) {
    688     0   stevel 		/*
    689     0   stevel 		 * If there's a branch that could act as a return site, we
    690     0   stevel 		 * need to trace it, and check here if the program counter is
    691     0   stevel 		 * external to the function.
    692     0   stevel 		 */
    693     0   stevel 		if (tp->ftt_type != FASTTRAP_T_RET &&
    694     0   stevel 		    tp->ftt_type != FASTTRAP_T_RET16 &&
    695     0   stevel 		    new_pc - id->fti_probe->ftp_faddr <
    696     0   stevel 		    id->fti_probe->ftp_fsize)
    697     0   stevel 			continue;
    698     0   stevel 
    699     0   stevel 		dtrace_probe(id->fti_probe->ftp_id,
    700     0   stevel 		    pc - id->fti_probe->ftp_faddr,
    701     0   stevel 		    rp->r_r0, rp->r_r1, 0, 0);
    702     0   stevel 	}
    703     0   stevel 
    704     0   stevel 	mutex_exit(pid_mtx);
    705     0   stevel }
    706     0   stevel 
    707     0   stevel static void
    708     0   stevel fasttrap_sigsegv(proc_t *p, kthread_t *t, uintptr_t addr)
    709     0   stevel {
    710     0   stevel 	sigqueue_t *sqp = kmem_zalloc(sizeof (sigqueue_t), KM_SLEEP);
    711     0   stevel 
    712     0   stevel 	sqp->sq_info.si_signo = SIGSEGV;
    713     0   stevel 	sqp->sq_info.si_code = SEGV_MAPERR;
    714     0   stevel 	sqp->sq_info.si_addr = (caddr_t)addr;
    715     0   stevel 
    716     0   stevel 	mutex_enter(&p->p_lock);
    717     0   stevel 	sigaddqa(p, t, sqp);
    718     0   stevel 	mutex_exit(&p->p_lock);
    719     0   stevel 
    720     0   stevel 	if (t != NULL)
    721     0   stevel 		aston(t);
    722     0   stevel }
    723     0   stevel 
    724     0   stevel #ifdef __amd64
    725     0   stevel static void
    726     0   stevel fasttrap_usdt_args64(fasttrap_probe_t *probe, struct regs *rp, int argc,
    727     0   stevel     uintptr_t *argv)
    728     0   stevel {
    729     0   stevel 	int i, x, cap = MIN(argc, probe->ftp_nargs);
    730     0   stevel 	uintptr_t *stack = (uintptr_t *)rp->r_sp;
    731     0   stevel 
    732     0   stevel 	for (i = 0; i < cap; i++) {
    733     0   stevel 		x = probe->ftp_argmap[i];
    734     0   stevel 
    735     0   stevel 		if (x < 6)
    736     0   stevel 			argv[i] = (&rp->r_rdi)[x];
    737     0   stevel 		else
    738     0   stevel 			argv[i] = fasttrap_fulword_noerr(&stack[x]);
    739     0   stevel 	}
    740     0   stevel 
    741     0   stevel 	for (; i < argc; i++) {
    742     0   stevel 		argv[i] = 0;
    743     0   stevel 	}
    744     0   stevel }
    745     0   stevel #endif
    746     0   stevel 
    747     0   stevel static void
    748     0   stevel fasttrap_usdt_args32(fasttrap_probe_t *probe, struct regs *rp, int argc,
    749     0   stevel     uint32_t *argv)
    750     0   stevel {
    751     0   stevel 	int i, x, cap = MIN(argc, probe->ftp_nargs);
    752     0   stevel 	uint32_t *stack = (uint32_t *)rp->r_sp;
    753     0   stevel 
    754     0   stevel 	for (i = 0; i < cap; i++) {
    755     0   stevel 		x = probe->ftp_argmap[i];
    756     0   stevel 
    757     0   stevel 		argv[i] = fasttrap_fuword32_noerr(&stack[x]);
    758     0   stevel 	}
    759     0   stevel 
    760     0   stevel 	for (; i < argc; i++) {
    761     0   stevel 		argv[i] = 0;
    762     0   stevel 	}
    763  2712  nn35248 }
    764  2712  nn35248 
    765  2712  nn35248 static int
    766  2712  nn35248 fasttrap_do_seg(fasttrap_tracepoint_t *tp, struct regs *rp, uintptr_t *addr)
    767  2712  nn35248 {
    768  2712  nn35248 	proc_t *p = curproc;
    769  2712  nn35248 	user_desc_t *desc;
    770  2712  nn35248 	uint16_t sel, ndx, type;
    771  2712  nn35248 	uintptr_t limit;
    772  2712  nn35248 
    773  2712  nn35248 	switch (tp->ftt_segment) {
    774  2712  nn35248 	case FASTTRAP_SEG_CS:
    775  2712  nn35248 		sel = rp->r_cs;
    776  2712  nn35248 		break;
    777  2712  nn35248 	case FASTTRAP_SEG_DS:
    778  2712  nn35248 		sel = rp->r_ds;
    779  2712  nn35248 		break;
    780  2712  nn35248 	case FASTTRAP_SEG_ES:
    781  2712  nn35248 		sel = rp->r_es;
    782  2712  nn35248 		break;
    783  2712  nn35248 	case FASTTRAP_SEG_FS:
    784  2712  nn35248 		sel = rp->r_fs;
    785  2712  nn35248 		break;
    786  2712  nn35248 	case FASTTRAP_SEG_GS:
    787  2712  nn35248 		sel = rp->r_gs;
    788  2712  nn35248 		break;
    789  2712  nn35248 	case FASTTRAP_SEG_SS:
    790  2712  nn35248 		sel = rp->r_ss;
    791  2712  nn35248 		break;
    792  2712  nn35248 	}
    793  2712  nn35248 
    794  2712  nn35248 	/*
    795  2712  nn35248 	 * Make sure the given segment register specifies a user priority
    796  2712  nn35248 	 * selector rather than a kernel selector.
    797  2712  nn35248 	 */
    798  2712  nn35248 	if (!SELISUPL(sel))
    799  2712  nn35248 		return (-1);
    800  2712  nn35248 
    801  2712  nn35248 	ndx = SELTOIDX(sel);
    802  2712  nn35248 
    803  2712  nn35248 	/*
    804  2712  nn35248 	 * Check the bounds and grab the descriptor out of the specified
    805  2712  nn35248 	 * descriptor table.
    806  2712  nn35248 	 */
    807  2712  nn35248 	if (SELISLDT(sel)) {
    808  2712  nn35248 		if (ndx > p->p_ldtlimit)
    809  2712  nn35248 			return (-1);
    810  2712  nn35248 
    811  2712  nn35248 		desc = p->p_ldt + ndx;
    812  2712  nn35248 
    813  2712  nn35248 	} else {
    814  2712  nn35248 		if (ndx >= NGDT)
    815  2712  nn35248 			return (-1);
    816  2712  nn35248 
    817  2712  nn35248 		desc = cpu_get_gdt() + ndx;
    818  2712  nn35248 	}
    819  2712  nn35248 
    820  2712  nn35248 	/*
    821  2712  nn35248 	 * The descriptor must have user privilege level and it must be
    822  2712  nn35248 	 * present in memory.
    823  2712  nn35248 	 */
    824  2712  nn35248 	if (desc->usd_dpl != SEL_UPL || desc->usd_p != 1)
    825  2712  nn35248 		return (-1);
    826  2712  nn35248 
    827  2712  nn35248 	type = desc->usd_type;
    828  2712  nn35248 
    829  2712  nn35248 	/*
    830  2712  nn35248 	 * If the S bit in the type field is not set, this descriptor can
    831  2712  nn35248 	 * only be used in system context.
    832  2712  nn35248 	 */
    833  2712  nn35248 	if ((type & 0x10) != 0x10)
    834  2712  nn35248 		return (-1);
    835  2712  nn35248 
    836  2712  nn35248 	limit = USEGD_GETLIMIT(desc) * (desc->usd_gran ? PAGESIZE : 1);
    837  2712  nn35248 
    838  2712  nn35248 	if (tp->ftt_segment == FASTTRAP_SEG_CS) {
    839  2712  nn35248 		/*
    840  2712  nn35248 		 * The code/data bit and readable bit must both be set.
    841  2712  nn35248 		 */
    842  2712  nn35248 		if ((type & 0xa) != 0xa)
    843  2712  nn35248 			return (-1);
    844  2712  nn35248 
    845  2712  nn35248 		if (*addr > limit)
    846  2712  nn35248 			return (-1);
    847  2712  nn35248 	} else {
    848  2712  nn35248 		/*
    849  2712  nn35248 		 * The code/data bit must be clear.
    850  2712  nn35248 		 */
    851  2712  nn35248 		if ((type & 0x8) != 0)
    852  2712  nn35248 			return (-1);
    853  2712  nn35248 
    854  2712  nn35248 		/*
    855  2712  nn35248 		 * If the expand-down bit is clear, we just check the limit as
    856  2712  nn35248 		 * it would naturally be applied. Otherwise, we need to check
    857  2712  nn35248 		 * that the address is the range [limit + 1 .. 0xffff] or
    858  2712  nn35248 		 * [limit + 1 ... 0xffffffff] depending on if the default
    859  2712  nn35248 		 * operand size bit is set.
    860  2712  nn35248 		 */
    861  2712  nn35248 		if ((type & 0x4) == 0) {
    862  2712  nn35248 			if (*addr > limit)
    863  2712  nn35248 				return (-1);
    864  2712  nn35248 		} else if (desc->usd_def32) {
    865  2712  nn35248 			if (*addr < limit + 1 || 0xffff < *addr)
    866  2712  nn35248 				return (-1);
    867  2712  nn35248 		} else {
    868  2712  nn35248 			if (*addr < limit + 1 || 0xffffffff < *addr)
    869  2712  nn35248 				return (-1);
    870  2712  nn35248 		}
    871  2712  nn35248 	}
    872  2712  nn35248 
    873  2712  nn35248 	*addr += USEGD_GETBASE(desc);
    874  2712  nn35248 
    875  2712  nn35248 	return (0);
    876     0   stevel }
    877     0   stevel 
    878     0   stevel int
    879     0   stevel fasttrap_pid_probe(struct regs *rp)
    880     0   stevel {
    881     0   stevel 	proc_t *p = curproc;
    882     0   stevel 	uintptr_t pc = rp->r_pc - 1, new_pc = 0;
    883     0   stevel 	fasttrap_bucket_t *bucket;
    884     0   stevel 	kmutex_t *pid_mtx;
    885     0   stevel 	fasttrap_tracepoint_t *tp, tp_local;
    886     0   stevel 	pid_t pid;
    887     0   stevel 	dtrace_icookie_t cookie;
    888  1710      ahl 	uint_t is_enabled = 0;
    889     0   stevel 
    890     0   stevel 	/*
    891     0   stevel 	 * It's possible that a user (in a veritable orgy of bad planning)
    892     0   stevel 	 * could redirect this thread's flow of control before it reached the
    893     0   stevel 	 * return probe fasttrap. In this case we need to kill the process
    894     0   stevel 	 * since it's in a unrecoverable state.
    895     0   stevel 	 */
    896     0   stevel 	if (curthread->t_dtrace_step) {
    897     0   stevel 		ASSERT(curthread->t_dtrace_on);
    898     0   stevel 		fasttrap_sigtrap(p, curthread, pc);
    899     0   stevel 		return (0);
    900     0   stevel 	}
    901     0   stevel 
    902     0   stevel 	/*
    903     0   stevel 	 * Clear all user tracing flags.
    904     0   stevel 	 */
    905     0   stevel 	curthread->t_dtrace_ft = 0;
    906     0   stevel 	curthread->t_dtrace_pc = 0;
    907     0   stevel 	curthread->t_dtrace_npc = 0;
    908     0   stevel 	curthread->t_dtrace_scrpc = 0;
    909     0   stevel 	curthread->t_dtrace_astpc = 0;
    910     0   stevel #ifdef __amd64
    911     0   stevel 	curthread->t_dtrace_regv = 0;
    912     0   stevel #endif
    913     0   stevel 
    914     0   stevel 	/*
    915     0   stevel 	 * Treat a child created by a call to vfork(2) as if it were its
    916     0   stevel 	 * parent. We know that there's only one thread of control in such a
    917     0   stevel 	 * process: this one.
    918     0   stevel 	 */
    919     0   stevel 	while (p->p_flag & SVFORK) {
    920     0   stevel 		p = p->p_parent;
    921     0   stevel 	}
    922     0   stevel 
    923     0   stevel 	pid = p->p_pid;
    924     0   stevel 	pid_mtx = &cpu_core[CPU->cpu_id].cpuc_pid_lock;
    925     0   stevel 	mutex_enter(pid_mtx);
    926     0   stevel 	bucket = &fasttrap_tpoints.fth_table[FASTTRAP_TPOINTS_INDEX(pid, pc)];
    927     0   stevel 
    928     0   stevel 	/*
    929     0   stevel 	 * Lookup the tracepoint that the process just hit.
    930     0   stevel 	 */
    931     0   stevel 	for (tp = bucket->ftb_data; tp != NULL; tp = tp->ftt_next) {
    932     0   stevel 		if (pid == tp->ftt_pid && pc == tp->ftt_pc &&
    933  4821      ahl 		    tp->ftt_proc->ftpc_acount != 0)
    934     0   stevel 			break;
    935     0   stevel 	}
    936     0   stevel 
    937     0   stevel 	/*
    938     0   stevel 	 * If we couldn't find a matching tracepoint, either a tracepoint has
    939     0   stevel 	 * been inserted without using the pid<pid> ioctl interface (see
    940     0   stevel 	 * fasttrap_ioctl), or somehow we have mislaid this tracepoint.
    941     0   stevel 	 */
    942     0   stevel 	if (tp == NULL) {
    943     0   stevel 		mutex_exit(pid_mtx);
    944     0   stevel 		return (-1);
    945     0   stevel 	}
    946     0   stevel 
    947     0   stevel 	/*
    948     0   stevel 	 * Set the program counter to the address of the traced instruction
    949     0   stevel 	 * so that it looks right in ustack() output.
    950     0   stevel 	 */
    951     0   stevel 	rp->r_pc = pc;
    952     0   stevel 
    953     0   stevel 	if (tp->ftt_ids != NULL) {
    954     0   stevel 		fasttrap_id_t *id;
    955     0   stevel 
    956     0   stevel #ifdef __amd64
    957     0   stevel 		if (p->p_model == DATAMODEL_LP64) {
    958     0   stevel 			for (id = tp->ftt_ids; id != NULL; id = id->fti_next) {
    959     0   stevel 				fasttrap_probe_t *probe = id->fti_probe;
    960     0   stevel 
    961  1710      ahl 				if (id->fti_ptype == DTFTP_ENTRY) {
    962     0   stevel 					/*
    963     0   stevel 					 * We note that this was an entry
    964     0   stevel 					 * probe to help ustack() find the
    965     0   stevel 					 * first caller.
    966     0   stevel 					 */
    967     0   stevel 					cookie = dtrace_interrupt_disable();
    968     0   stevel 					DTRACE_CPUFLAG_SET(CPU_DTRACE_ENTRY);
    969     0   stevel 					dtrace_probe(probe->ftp_id, rp->r_rdi,
    970     0   stevel 					    rp->r_rsi, rp->r_rdx, rp->r_rcx,
    971     0   stevel 					    rp->r_r8);
    972     0   stevel 					DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_ENTRY);
    973     0   stevel 					dtrace_interrupt_enable(cookie);
    974  1710      ahl 				} else if (id->fti_ptype == DTFTP_IS_ENABLED) {
    975  1710      ahl 					/*
    976  1710      ahl 					 * Note that in this case, we don't
    977  1710      ahl 					 * call dtrace_probe() since it's only
    978  1710      ahl 					 * an artificial probe meant to change
    979  1710      ahl 					 * the flow of control so that it
    980  1710      ahl 					 * encounters the true probe.
    981  1710      ahl 					 */
    982  1710      ahl 					is_enabled = 1;
    983     0   stevel 				} else if (probe->ftp_argmap == NULL) {
    984     0   stevel 					dtrace_probe(probe->ftp_id, rp->r_rdi,
    985     0   stevel 					    rp->r_rsi, rp->r_rdx, rp->r_rcx,
    986     0   stevel 					    rp->r_r8);
    987     0   stevel 				} else {
    988     0   stevel 					uintptr_t t[5];
    989     0   stevel 
    990     0   stevel 					fasttrap_usdt_args64(probe, rp,
    991     0   stevel 					    sizeof (t) / sizeof (t[0]), t);
    992     0   stevel 
    993     0   stevel 					dtrace_probe(probe->ftp_id, t[0], t[1],
    994     0   stevel 					    t[2], t[3], t[4]);
    995     0   stevel 				}
    996     0   stevel 			}
    997     0   stevel 		} else {
    998     0   stevel #endif
    999     0   stevel 			uintptr_t s0, s1, s2, s3, s4, s5;
   1000     0   stevel 			uint32_t *stack = (uint32_t *)rp->r_sp;
   1001     0   stevel 
   1002     0   stevel 			/*
   1003     0   stevel 			 * In 32-bit mode, all arguments are passed on the
   1004     0   stevel 			 * stack. If this is a function entry probe, we need
   1005     0   stevel 			 * to skip the first entry on the stack as it
   1006     0   stevel 			 * represents the return address rather than a
   1007     0   stevel 			 * parameter to the function.
   1008     0   stevel 			 */
   1009     0   stevel 			s0 = fasttrap_fuword32_noerr(&stack[0]);
   1010     0   stevel 			s1 = fasttrap_fuword32_noerr(&stack[1]);
   1011     0   stevel 			s2 = fasttrap_fuword32_noerr(&stack[2]);
   1012     0   stevel 			s3 = fasttrap_fuword32_noerr(&stack[3]);
   1013     0   stevel 			s4 = fasttrap_fuword32_noerr(&stack[4]);
   1014     0   stevel 			s5 = fasttrap_fuword32_noerr(&stack[5]);
   1015     0   stevel 
   1016     0   stevel 			for (id = tp->ftt_ids; id != NULL; id = id->fti_next) {
   1017     0   stevel 				fasttrap_probe_t *probe = id->fti_probe;
   1018     0   stevel 
   1019  1710      ahl 				if (id->fti_ptype == DTFTP_ENTRY) {
   1020     0   stevel 					/*
   1021     0   stevel 					 * We note that this was an entry
   1022     0   stevel 					 * probe to help ustack() find the
   1023     0   stevel 					 * first caller.
   1024     0   stevel 					 */
   1025     0   stevel 					cookie = dtrace_interrupt_disable();
   1026     0   stevel 					DTRACE_CPUFLAG_SET(CPU_DTRACE_ENTRY);
   1027     0   stevel 					dtrace_probe(probe->ftp_id, s1, s2,
   1028     0   stevel 					    s3, s4, s5);
   1029     0   stevel 					DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_ENTRY);
   1030     0   stevel 					dtrace_interrupt_enable(cookie);
   1031  1710      ahl 				} else if (id->fti_ptype == DTFTP_IS_ENABLED) {
   1032  1710      ahl 					/*
   1033  1710      ahl 					 * Note that in this case, we don't
   1034  1710      ahl 					 * call dtrace_probe() since it's only
   1035  1710      ahl 					 * an artificial probe meant to change
   1036  1710      ahl 					 * the flow of control so that it
   1037  1710      ahl 					 * encounters the true probe.
   1038  1710      ahl 					 */
   1039  1710      ahl 					is_enabled = 1;
   1040     0   stevel 				} else if (probe->ftp_argmap == NULL) {
   1041     0   stevel 					dtrace_probe(probe->ftp_id, s0, s1,
   1042     0   stevel 					    s2, s3, s4);
   1043     0   stevel 				} else {
   1044     0   stevel 					uint32_t t[5];
   1045     0   stevel 
   1046     0   stevel 					fasttrap_usdt_args32(probe, rp,
   1047     0   stevel 					    sizeof (t) / sizeof (t[0]), t);
   1048     0   stevel 
   1049     0   stevel 					dtrace_probe(probe->ftp_id, t[0], t[1],
   1050     0   stevel 					    t[2], t[3], t[4]);
   1051     0   stevel 				}
   1052     0   stevel 			}
   1053     0   stevel #ifdef __amd64
   1054     0   stevel 		}
   1055     0   stevel #endif
   1056     0   stevel 	}
   1057     0   stevel 
   1058     0   stevel 	/*
   1059     0   stevel 	 * We're about to do a bunch of work so we cache a local copy of
   1060     0   stevel 	 * the tracepoint to emulate the instruction, and then find the
   1061     0   stevel 	 * tracepoint again later if we need to light up any return probes.
   1062     0   stevel 	 */
   1063     0   stevel 	tp_local = *tp;
   1064     0   stevel 	mutex_exit(pid_mtx);
   1065     0   stevel 	tp = &tp_local;
   1066     0   stevel 
   1067     0   stevel 	/*
   1068     0   stevel 	 * Set the program counter to appear as though the traced instruction
   1069     0   stevel 	 * had completely executed. This ensures that fasttrap_getreg() will
   1070     0   stevel 	 * report the expected value for REG_RIP.
   1071     0   stevel 	 */
   1072     0   stevel 	rp->r_pc = pc + tp->ftt_size;
   1073     0   stevel 
   1074  1710      ahl 	/*
   1075  1710      ahl 	 * If there's an is-enabled probe connected to this tracepoint it
   1076  1710      ahl 	 * means that there was a 'xorl %eax, %eax' or 'xorq %rax, %rax'
   1077  1710      ahl 	 * instruction that was placed there by DTrace when the binary was
   1078  1710      ahl 	 * linked. As this probe is, in fact, enabled, we need to stuff 1
   1079  1710      ahl 	 * into %eax or %rax. Accordingly, we can bypass all the instruction
   1080  1710      ahl 	 * emulation logic since we know the inevitable result. It's possible
   1081  1710      ahl 	 * that a user could construct a scenario where the 'is-enabled'
   1082  1710      ahl 	 * probe was on some other instruction, but that would be a rather
   1083  1710      ahl 	 * exotic way to shoot oneself in the foot.
   1084  1710      ahl 	 */
   1085  1710      ahl 	if (is_enabled) {
   1086  1710      ahl 		rp->r_r0 = 1;
   1087  1710      ahl 		new_pc = rp->r_pc;
   1088  1710      ahl 		goto done;
   1089  1710      ahl 	}
   1090  1710      ahl 
   1091  1710      ahl 	/*
   1092  1710      ahl 	 * We emulate certain types of instructions to ensure correctness
   1093  1710      ahl 	 * (in the case of position dependent instructions) or optimize
   1094  1710      ahl 	 * common cases. The rest we have the thread execute back in user-
   1095  1710      ahl 	 * land.
   1096  1710      ahl 	 */
   1097     0   stevel 	switch (tp->ftt_type) {
   1098     0   stevel 	case FASTTRAP_T_RET:
   1099     0   stevel 	case FASTTRAP_T_RET16:
   1100     0   stevel 	{
   1101     0   stevel 		uintptr_t dst;
   1102     0   stevel 		uintptr_t addr;
   1103     0   stevel 		int ret;
   1104     0   stevel 
   1105     0   stevel 		/*
   1106     0   stevel 		 * We have to emulate _every_ facet of the behavior of a ret
   1107     0   stevel 		 * instruction including what happens if the load from %esp
   1108     0   stevel 		 * fails; in that case, we send a SIGSEGV.
   1109     0   stevel 		 */
   1110     0   stevel #ifdef __amd64
   1111     0   stevel 		if (p->p_model == DATAMODEL_NATIVE) {
   1112     0   stevel #endif
   1113     0   stevel 			ret = fasttrap_fulword((void *)rp->r_sp, &dst);
   1114     0   stevel 			addr = rp->r_sp + sizeof (uintptr_t);
   1115     0   stevel #ifdef __amd64
   1116     0   stevel 		} else {
   1117     0   stevel 			uint32_t dst32;
   1118     0   stevel 			ret = fasttrap_fuword32((void *)rp->r_sp, &dst32);
   1119     0   stevel 			dst = dst32;
   1120     0   stevel 			addr = rp->r_sp + sizeof (uint32_t);
   1121     0   stevel 		}
   1122     0   stevel #endif
   1123     0   stevel 
   1124     0   stevel 		if (ret == -1) {
   1125     0   stevel 			fasttrap_sigsegv(p, curthread, rp->r_sp);
   1126     0   stevel 			new_pc = pc;
   1127     0   stevel 			break;
   1128     0   stevel 		}
   1129     0   stevel 
   1130     0   stevel 		if (tp->ftt_type == FASTTRAP_T_RET16)
   1131     0   stevel 			addr += tp->ftt_dest;
   1132     0   stevel 
   1133     0   stevel 		rp->r_sp = addr;
   1134     0   stevel 		new_pc = dst;
   1135     0   stevel 		break;
   1136     0   stevel 	}
   1137     0   stevel 
   1138     0   stevel 	case FASTTRAP_T_JCC:
   1139     0   stevel 	{
   1140     0   stevel 		uint_t taken;
   1141     0   stevel 
   1142     0   stevel 		switch (tp->ftt_code) {
   1143     0   stevel 		case FASTTRAP_JO:
   1144     0   stevel 			taken = (rp->r_ps & FASTTRAP_EFLAGS_OF) != 0;
   1145     0   stevel 			break;
   1146     0   stevel 		case FASTTRAP_JNO:
   1147     0   stevel 			taken = (rp->r_ps & FASTTRAP_EFLAGS_OF) == 0;
   1148     0   stevel 			break;
   1149     0   stevel 		case FASTTRAP_JB:
   1150     0   stevel 			taken = (rp->r_ps & FASTTRAP_EFLAGS_CF) != 0;
   1151     0   stevel 			break;
   1152     0   stevel 		case FASTTRAP_JAE:
   1153     0   stevel 			taken = (rp->r_ps & FASTTRAP_EFLAGS_CF) == 0;
   1154     0   stevel 			break;
   1155     0   stevel 		case FASTTRAP_JE:
   1156     0   stevel 			taken = (rp->r_ps & FASTTRAP_EFLAGS_ZF) != 0;
   1157     0   stevel 			break;
   1158     0   stevel 		case FASTTRAP_JNE:
   1159     0   stevel 			taken = (rp->r_ps & FASTTRAP_EFLAGS_ZF) == 0;
   1160     0   stevel 			break;
   1161     0   stevel 		case FASTTRAP_JBE:
   1162     0   stevel 			taken = (rp->r_ps & FASTTRAP_EFLAGS_CF) != 0 ||
   1163     0   stevel 			    (rp->r_ps & FASTTRAP_EFLAGS_ZF) != 0;
   1164     0   stevel 			break;
   1165     0   stevel 		case FASTTRAP_JA:
   1166     0   stevel 			taken = (rp->r_ps & FASTTRAP_EFLAGS_CF) == 0 &&
   1167     0   stevel 			    (rp->r_ps & FASTTRAP_EFLAGS_ZF) == 0;
   1168     0   stevel 			break;
   1169     0   stevel 		case FASTTRAP_JS:
   1170     0   stevel 			taken = (rp->r_ps & FASTTRAP_EFLAGS_SF) != 0;
   1171     0   stevel 			break;
   1172     0   stevel 		case FASTTRAP_JNS:
   1173     0   stevel 			taken = (rp->r_ps & FASTTRAP_EFLAGS_SF) == 0;
   1174     0   stevel 			break;
   1175     0   stevel 		case FASTTRAP_JP:
   1176     0   stevel 			taken = (rp->r_ps & FASTTRAP_EFLAGS_PF) != 0;
   1177     0   stevel 			break;
   1178     0   stevel 		case FASTTRAP_JNP:
   1179     0   stevel 			taken = (rp->r_ps & FASTTRAP_EFLAGS_PF) == 0;
   1180     0   stevel 			break;
   1181     0   stevel 		case FASTTRAP_JL:
   1182     0   stevel 			taken = ((rp->r_ps & FASTTRAP_EFLAGS_SF) == 0) !=
   1183     0   stevel 			    ((rp->r_ps & FASTTRAP_EFLAGS_OF) == 0);
   1184     0   stevel 			break;
   1185     0   stevel 		case FASTTRAP_JGE:
   1186     0   stevel 			taken = ((rp->r_ps & FASTTRAP_EFLAGS_SF) == 0) ==
   1187     0   stevel 			    ((rp->r_ps & FASTTRAP_EFLAGS_OF) == 0);
   1188     0   stevel 			break;
   1189     0   stevel 		case FASTTRAP_JLE:
   1190     0   stevel 			taken = (rp->r_ps & FASTTRAP_EFLAGS_ZF) != 0 ||
   1191     0   stevel 			    ((rp->r_ps & FASTTRAP_EFLAGS_SF) == 0) !=
   1192     0   stevel 			    ((rp->r_ps & FASTTRAP_EFLAGS_OF) == 0);
   1193     0   stevel 			break;
   1194     0   stevel 		case FASTTRAP_JG:
   1195     0   stevel 			taken = (rp->r_ps & FASTTRAP_EFLAGS_ZF) == 0 &&
   1196     0   stevel 			    ((rp->r_ps & FASTTRAP_EFLAGS_SF) == 0) ==
   1197     0   stevel 			    ((rp->r_ps & FASTTRAP_EFLAGS_OF) == 0);
   1198     0   stevel 			break;
   1199     0   stevel 
   1200     0   stevel 		}
   1201     0   stevel 
   1202     0   stevel 		if (taken)
   1203     0   stevel 			new_pc = tp->ftt_dest;
   1204     0   stevel 		else
   1205     0   stevel 			new_pc = pc + tp->ftt_size;
   1206     0   stevel 		break;
   1207     0   stevel 	}
   1208     0   stevel 
   1209     0   stevel 	case FASTTRAP_T_LOOP:
   1210     0   stevel 	{
   1211     0   stevel 		uint_t taken;
   1212     0   stevel #ifdef __amd64
   1213     0   stevel 		greg_t cx = rp->r_rcx--;
   1214     0   stevel #else
   1215     0   stevel 		greg_t cx = rp->r_ecx--;
   1216     0   stevel #endif
   1217     0   stevel 
   1218     0   stevel 		switch (tp->ftt_code) {
   1219     0   stevel 		case FASTTRAP_LOOPNZ:
   1220     0   stevel 			taken = (rp->r_ps & FASTTRAP_EFLAGS_ZF) == 0 &&
   1221     0   stevel 			    cx != 0;
   1222     0   stevel 			break;
   1223     0   stevel 		case FASTTRAP_LOOPZ:
   1224     0   stevel 			taken = (rp->r_ps & FASTTRAP_EFLAGS_ZF) != 0 &&
   1225     0   stevel 			    cx != 0;
   1226     0   stevel 			break;
   1227     0   stevel 		case FASTTRAP_LOOP:
   1228     0   stevel 			taken = (cx != 0);
   1229     0   stevel 			break;
   1230     0   stevel 		}
   1231     0   stevel 
   1232     0   stevel 		if (taken)
   1233     0   stevel 			new_pc = tp->ftt_dest;
   1234     0   stevel 		else
   1235     0   stevel 			new_pc = pc + tp->ftt_size;
   1236     0   stevel 		break;
   1237     0   stevel 	}
   1238     0   stevel 
   1239     0   stevel 	case FASTTRAP_T_JCXZ:
   1240     0   stevel 	{
   1241     0   stevel #ifdef __amd64
   1242     0   stevel 		greg_t cx = rp->r_rcx;
   1243     0   stevel #else
   1244     0   stevel 		greg_t cx = rp->r_ecx;
   1245     0   stevel #endif
   1246     0   stevel 
   1247     0   stevel 		if (cx == 0)
   1248     0   stevel 			new_pc = tp->ftt_dest;
   1249     0   stevel 		else
   1250     0   stevel 			new_pc = pc + tp->ftt_size;
   1251     0   stevel 		break;
   1252     0   stevel 	}
   1253     0   stevel 
   1254     0   stevel 	case FASTTRAP_T_PUSHL_EBP:
   1255     0   stevel 	{
   1256     0   stevel 		int ret;
   1257     0   stevel 		uintptr_t addr;
   1258     0   stevel #ifdef __amd64
   1259     0   stevel 		if (p->p_model == DATAMODEL_NATIVE) {
   1260     0   stevel #endif
   1261     0   stevel 			addr = rp->r_sp - sizeof (uintptr_t);
   1262     0   stevel 			ret = fasttrap_sulword((void *)addr, rp->r_fp);
   1263     0   stevel #ifdef __amd64
   1264     0   stevel 		} else {
   1265     0   stevel 			addr = rp->r_sp - sizeof (uint32_t);
   1266     0   stevel 			ret = fasttrap_suword32((void *)addr,
   1267     0   stevel 			    (uint32_t)rp->r_fp);
   1268     0   stevel 		}
   1269     0   stevel #endif
   1270     0   stevel 
   1271     0   stevel 		if (ret == -1) {
   1272     0   stevel 			fasttrap_sigsegv(p, curthread, addr);
   1273     0   stevel 			new_pc = pc;
   1274     0   stevel 			break;
   1275     0   stevel 		}
   1276     0   stevel 
   1277     0   stevel 		rp->r_sp = addr;
   1278     0   stevel 		new_pc = pc + tp->ftt_size;
   1279     0   stevel 		break;
   1280     0   stevel 	}
   1281     0   stevel 
   1282  2769      ahl 	case FASTTRAP_T_NOP:
   1283  2769      ahl 		new_pc = pc + tp->ftt_size;
   1284  2769      ahl 		break;
   1285  2769      ahl 
   1286     0   stevel 	case FASTTRAP_T_JMP:
   1287     0   stevel 	case FASTTRAP_T_CALL:
   1288     0   stevel 		if (tp->ftt_code == 0) {
   1289     0   stevel 			new_pc = tp->ftt_dest;
   1290     0   stevel 		} else {
   1291  2712  nn35248 			uintptr_t value, addr = tp->ftt_dest;
   1292     0   stevel 
   1293     0   stevel 			if (tp->ftt_base != FASTTRAP_NOREG)
   1294     0   stevel 				addr += fasttrap_getreg(rp, tp->ftt_base);
   1295     0   stevel 			if (tp->ftt_index != FASTTRAP_NOREG)
   1296     0   stevel 				addr += fasttrap_getreg(rp, tp->ftt_index) <<
   1297     0   stevel 				    tp->ftt_scale;
   1298     0   stevel 
   1299     0   stevel 			if (tp->ftt_code == 1) {
   1300  2712  nn35248 				/*
   1301  2712  nn35248 				 * If there's a segment prefix for this
   1302  2712  nn35248 				 * instruction, we'll need to check permissions
   1303  2712  nn35248 				 * and bounds on the given selector, and adjust
   1304  2712  nn35248 				 * the address accordingly.
   1305  2712  nn35248 				 */
   1306  2712  nn35248 				if (tp->ftt_segment != FASTTRAP_SEG_NONE &&
   1307  2712  nn35248 				    fasttrap_do_seg(tp, rp, &addr) != 0) {
   1308  2712  nn35248 					fasttrap_sigsegv(p, curthread, addr);
   1309  2712  nn35248 					new_pc = pc;
   1310  2712  nn35248 					break;
   1311  2712  nn35248 				}
   1312  2712  nn35248 
   1313     0   stevel #ifdef __amd64
   1314     0   stevel 				if (p->p_model == DATAMODEL_NATIVE) {
   1315     0   stevel #endif
   1316     0   stevel 					if (fasttrap_fulword((void *)addr,
   1317     0   stevel 					    &value) == -1) {
   1318     0   stevel 						fasttrap_sigsegv(p, curthread,
   1319     0   stevel 						    addr);
   1320     0   stevel 						new_pc = pc;
   1321     0   stevel 						break;
   1322     0   stevel 					}
   1323     0   stevel 					new_pc = value;
   1324     0   stevel #ifdef __amd64
   1325     0   stevel 				} else {
   1326  2712  nn35248 					uint32_t value32;
   1327  2712  nn35248 					addr = (uintptr_t)(uint32_t)addr;
   1328     0   stevel 					if (fasttrap_fuword32((void *)addr,
   1329  2712  nn35248 					    &value32) == -1) {
   1330     0   stevel 						fasttrap_sigsegv(p, curthread,
   1331     0   stevel 						    addr);
   1332     0   stevel 						new_pc = pc;
   1333     0   stevel 						break;
   1334     0   stevel 					}
   1335  2712  nn35248 					new_pc = value32;
   1336     0   stevel 				}
   1337     0   stevel #endif
   1338     0   stevel 			} else {
   1339     0   stevel 				new_pc = addr;
   1340     0   stevel 			}
   1341     0   stevel 		}
   1342     0   stevel 
   1343     0   stevel 		/*
   1344     0   stevel 		 * If this is a call instruction, we need to push the return
   1345     0   stevel 		 * address onto the stack. If this fails, we send the process
   1346     0   stevel 		 * a SIGSEGV and reset the pc to emulate what would happen if
   1347     0   stevel 		 * this instruction weren't traced.
   1348     0   stevel 		 */
   1349     0   stevel 		if (tp->ftt_type == FASTTRAP_T_CALL) {
   1350     0   stevel 			int ret;
   1351     0   stevel 			uintptr_t addr;
   1352     0   stevel #ifdef __amd64
   1353     0   stevel 			if (p->p_model == DATAMODEL_NATIVE) {
   1354     0   stevel 				addr = rp->r_sp - sizeof (uintptr_t);
   1355     0   stevel 				ret = fasttrap_sulword((void *)addr,
   1356     0   stevel 				    pc + tp->ftt_size);
   1357     0   stevel 			} else {
   1358     0   stevel #endif
   1359     0   stevel 				addr = rp->r_sp - sizeof (uint32_t);
   1360     0   stevel 				ret = fasttrap_suword32((void *)addr,
   1361     0   stevel 				    (uint32_t)(pc + tp->ftt_size));
   1362     0   stevel #ifdef __amd64
   1363     0   stevel 			}
   1364     0   stevel #endif
   1365     0   stevel 
   1366     0   stevel 			if (ret == -1) {
   1367     0   stevel 				fasttrap_sigsegv(p, curthread, addr);
   1368     0   stevel 				new_pc = pc;
   1369     0   stevel 				break;
   1370     0   stevel 			}
   1371     0   stevel 
   1372     0   stevel 			rp->r_sp = addr;
   1373     0   stevel 		}
   1374     0   stevel 
   1375     0   stevel 		break;
   1376     0   stevel 
   1377     0   stevel 	case FASTTRAP_T_COMMON:
   1378     0   stevel 	{
   1379     0   stevel 		uintptr_t addr;
   1380  6390      ahl #if defined(__amd64)
   1381  6390      ahl 		uint8_t scratch[2 * FASTTRAP_MAX_INSTR_SIZE + 22];
   1382  6390      ahl #else
   1383  6390      ahl 		uint8_t scratch[2 * FASTTRAP_MAX_INSTR_SIZE + 7];
   1384  6390      ahl #endif
   1385     0   stevel 		uint_t i = 0;
   1386     0   stevel 		klwp_t *lwp = ttolwp(curthread);
   1387     0   stevel 
   1388     0   stevel 		/*
   1389     0   stevel 		 * Compute the address of the ulwp_t and step over the
   1390     0   stevel 		 * ul_self pointer. The method used to store the user-land
   1391     0   stevel 		 * thread pointer is very different on 32- and 64-bit
   1392     0   stevel 		 * kernels.
   1393     0   stevel 		 */
   1394     0   stevel #if defined(__amd64)
   1395     0   stevel 		if (p->p_model == DATAMODEL_LP64) {
   1396     0   stevel 			addr = lwp->lwp_pcb.pcb_fsbase;
   1397     0   stevel 			addr += sizeof (void *);
   1398     0   stevel 		} else {
   1399     0   stevel 			addr = lwp->lwp_pcb.pcb_gsbase;
   1400     0   stevel 			addr += sizeof (caddr32_t);
   1401     0   stevel 		}
   1402  6390      ahl #else
   1403     0   stevel 		addr = USEGD_GETBASE(&lwp->lwp_pcb.pcb_gsdesc);
   1404     0   stevel 		addr += sizeof (void *);
   1405     0   stevel #endif
   1406     0   stevel 
   1407     0   stevel 		/*
   1408     0   stevel 		 * Generic Instruction Tracing
   1409     0   stevel 		 * ---------------------------
   1410     0   stevel 		 *
   1411     0   stevel 		 * This is the layout of the scratch space in the user-land
   1412     0   stevel 		 * thread structure for our generated instructions.
   1413     0   stevel 		 *
   1414     0   stevel 		 *	32-bit mode			bytes
   1415     0   stevel 		 *	------------------------	-----
   1416     0   stevel 		 * a:	<original instruction>		<= 15
   1417     0   stevel 		 *	jmp	<pc + tp->ftt_size>	    5
   1418     0   stevel 		 * b:	<original instrction>		<= 15
   1419     0   stevel 		 *	int	T_DTRACE_RET		    2
   1420     0   stevel 		 *					-----
   1421     0   stevel 		 *					<= 37
   1422     0   stevel 		 *
   1423     0   stevel 		 *	64-bit mode			bytes
   1424     0   stevel 		 *	------------------------	-----
   1425     0   stevel 		 * a:	<original instruction>		<= 15
   1426     0   stevel 		 *	jmp	0(%rip)			    6
   1427     0   stevel 		 *	<pc + tp->ftt_size>		    8
   1428     0   stevel 		 * b:	<original instruction>		<= 15
   1429     0   stevel 		 * 	int	T_DTRACE_RET		    2
   1430     0   stevel 		 * 					-----
   1431     0   stevel 		 * 					<= 46
   1432     0   stevel 		 *
   1433     0   stevel 		 * The %pc is set to a, and curthread->t_dtrace_astpc is set
   1434     0   stevel 		 * to b. If we encounter a signal on the way out of the
   1435     0   stevel 		 * kernel, trap() will set %pc to curthread->t_dtrace_astpc
   1436     0   stevel 		 * so that we execute the original instruction and re-enter
   1437     0   stevel 		 * the kernel rather than redirecting to the next instruction.
   1438     0   stevel 		 *
   1439     0   stevel 		 * If there are return probes (so we know that we're going to
   1440     0   stevel 		 * need to reenter the kernel after executing the original
   1441     0   stevel 		 * instruction), the scratch space will just contain the
   1442     0   stevel 		 * original instruction followed by an interrupt -- the same
   1443     0   stevel 		 * data as at b.
   1444     0   stevel 		 *
   1445     0   stevel 		 * %rip-relative Addressing
   1446     0   stevel 		 * ------------------------
   1447     0   stevel 		 *
   1448     0   stevel 		 * There's a further complication in 64-bit mode due to %rip-
   1449     0   stevel 		 * relative addressing. While this is clearly a beneficial
   1450     0   stevel 		 * architectural decision for position independent code, it's
   1451     0   stevel 		 * hard not to see it as a personal attack against the pid
   1452     0   stevel 		 * provider since before there was a relatively small set of
   1453     0   stevel 		 * instructions to emulate; with %rip-relative addressing,
   1454     0   stevel 		 * almost every instruction can potentially depend on the
   1455     0   stevel 		 * address at which it's executed. Rather than emulating
   1456     0   stevel 		 * the broad spectrum of instructions that can now be
   1457     0   stevel 		 * position dependent, we emulate jumps and others as in
   1458     0   stevel 		 * 32-bit mode, and take a different tack for instructions
   1459     0   stevel 		 * using %rip-relative addressing.
   1460     0   stevel 		 *
   1461     0   stevel 		 * For every instruction that uses the ModRM byte, the
   1462     0   stevel 		 * in-kernel disassembler reports its location. We use the
   1463     0   stevel 		 * ModRM byte to identify that an instruction uses
   1464     0   stevel 		 * %rip-relative addressing and to see what other registers
   1465     0   stevel 		 * the instruction uses. To emulate those instructions,
   1466     0   stevel 		 * we modify the instruction to be %rax-relative rather than
   1467     0   stevel 		 * %rip-relative (or %rcx-relative if the instruction uses
   1468     0   stevel 		 * %rax; or %r8- or %r9-relative if the REX.B is present so
   1469     0   stevel 		 * we don't have to rewrite the REX prefix). We then load
   1470     0   stevel 		 * the value that %rip would have been into the scratch
   1471     0   stevel 		 * register and generate an instruction to reset the scratch
   1472     0   stevel 		 * register back to its original value. The instruction
   1473     0   stevel 		 * sequence looks like this:
   1474     0   stevel 		 *
   1475     0   stevel 		 *	64-mode %rip-relative		bytes
   1476     0   stevel 		 *	------------------------	-----
   1477     0   stevel 		 * a:	<modified instruction>		<= 15
   1478     0   stevel 		 *	movq	$<value>, %<scratch>	    6
   1479     0   stevel 		 *	jmp	0(%rip)			    6
   1480     0   stevel 		 *	<pc + tp->ftt_size>		    8
   1481     0   stevel 		 * b:	<modified instruction>  	<= 15
   1482     0   stevel 		 * 	int	T_DTRACE_RET		    2
   1483     0   stevel 		 * 					-----
   1484     0   stevel 		 *					   52
   1485     0   stevel 		 *
   1486     0   stevel 		 * We set curthread->t_dtrace_regv so that upon receiving
   1487     0   stevel 		 * a signal we can reset the value of the scratch register.
   1488     0   stevel 		 */
   1489     0   stevel 
   1490     0   stevel 		ASSERT(tp->ftt_size < FASTTRAP_MAX_INSTR_SIZE);
   1491     0   stevel 
   1492     0   stevel 		curthread->t_dtrace_scrpc = addr;
   1493     0   stevel 		bcopy(tp->ftt_instr, &scratch[i], tp->ftt_size);
   1494     0   stevel 		i += tp->ftt_size;
   1495     0   stevel 
   1496     0   stevel #ifdef __amd64
   1497     0   stevel 		if (tp->ftt_ripmode != 0) {
   1498     0   stevel 			greg_t *reg;
   1499     0   stevel 
   1500     0   stevel 			ASSERT(p->p_model == DATAMODEL_LP64);
   1501     0   stevel 			ASSERT(tp->ftt_ripmode &
   1502     0   stevel 			    (FASTTRAP_RIP_1 | FASTTRAP_RIP_2));
   1503     0   stevel 
   1504     0   stevel 			/*
   1505     0   stevel 			 * If this was a %rip-relative instruction, we change
   1506     0   stevel 			 * it to be either a %rax- or %rcx-relative
   1507     0   stevel 			 * instruction (depending on whether those registers
   1508     0   stevel 			 * are used as another operand; or %r8- or %r9-
   1509     0   stevel 			 * relative depending on the value of REX.B). We then
   1510     0   stevel 			 * set that register and generate a movq instruction
   1511     0   stevel 			 * to reset the value.
   1512     0   stevel 			 */
   1513     0   stevel 			if (tp->ftt_ripmode & FASTTRAP_RIP_X)
   1514     0   stevel 				scratch[i++] = FASTTRAP_REX(1, 0, 0, 1);
   1515     0   stevel 			else
   1516     0   stevel 				scratch[i++] = FASTTRAP_REX(1, 0, 0, 0);
   1517     0   stevel 
   1518     0   stevel 			if (tp->ftt_ripmode & FASTTRAP_RIP_1)
   1519     0   stevel 				scratch[i++] = FASTTRAP_MOV_EAX;
   1520     0   stevel 			else
   1521     0   stevel 				scratch[i++] = FASTTRAP_MOV_ECX;
   1522     0   stevel 
   1523     0   stevel 			switch (tp->ftt_ripmode) {
   1524     0   stevel 			case FASTTRAP_RIP_1:
   1525     0   stevel 				reg = &rp->r_rax;
   1526     0   stevel 				curthread->t_dtrace_reg = REG_RAX;
   1527     0   stevel 				break;
   1528     0   stevel 			case FASTTRAP_RIP_2:
   1529     0   stevel 				reg = &rp->r_rcx;
   1530     0   stevel 				curthread->t_dtrace_reg = REG_RCX;
   1531     0   stevel 				break;
   1532     0   stevel 			case FASTTRAP_RIP_1 | FASTTRAP_RIP_X:
   1533     0   stevel 				reg = &rp->r_r8;
   1534     0   stevel 				curthread->t_dtrace_reg = REG_R8;
   1535     0   stevel 				break;
   1536     0   stevel 			case FASTTRAP_RIP_2 | FASTTRAP_RIP_X:
   1537     0   stevel 				reg = &rp->r_r9;
   1538     0   stevel 				curthread->t_dtrace_reg = REG_R9;
   1539     0   stevel 				break;
   1540     0   stevel 			}
   1541     0   stevel 
   1542  3944      ahl 			/* LINTED - alignment */
   1543     0   stevel 			*(uint64_t *)&scratch[i] = *reg;
   1544     0   stevel 			curthread->t_dtrace_regv = *reg;
   1545     0   stevel 			*reg = pc + tp->ftt_size;
   1546     0   stevel 			i += sizeof (uint64_t);
   1547     0   stevel 		}
   1548     0   stevel #endif
   1549     0   stevel 
   1550     0   stevel 		/*
   1551     0   stevel 		 * Generate the branch instruction to what would have
   1552     0   stevel 		 * normally been the subsequent instruction. In 32-bit mode,
   1553     0   stevel 		 * this is just a relative branch; in 64-bit mode this is a
   1554     0   stevel 		 * %rip-relative branch that loads the 64-bit pc value
   1555     0   stevel 		 * immediately after the jmp instruction.
   1556     0   stevel 		 */
   1557     0   stevel #ifdef __amd64
   1558     0   stevel 		if (p->p_model == DATAMODEL_LP64) {
   1559     0   stevel 			scratch[i++] = FASTTRAP_GROUP5_OP;
   1560     0   stevel 			scratch[i++] = FASTTRAP_MODRM(0, 4, 5);
   1561  3944      ahl 			/* LINTED - alignment */
   1562     0   stevel 			*(uint32_t *)&scratch[i] = 0;
   1563     0   stevel 			i += sizeof (uint32_t);
   1564  3944      ahl 			/* LINTED - alignment */
   1565     0   stevel 			*(uint64_t *)&scratch[i] = pc + tp->ftt_size;
   1566     0   stevel 			i += sizeof (uint64_t);
   1567     0   stevel 		} else {
   1568     0   stevel #endif
   1569     0   stevel 			/*
   1570     0   stevel 			 * Set up the jmp to the next instruction; note that
   1571     0   stevel 			 * the size of the traced instruction cancels out.
   1572     0   stevel 			 */
   1573     0   stevel 			scratch[i++] = FASTTRAP_JMP32;
   1574  3944      ahl 			/* LINTED - alignment */
   1575     0   stevel 			*(uint32_t *)&scratch[i] = pc - addr - 5;
   1576     0   stevel 			i += sizeof (uint32_t);
   1577     0   stevel #ifdef __amd64
   1578     0   stevel 		}
   1579     0   stevel #endif
   1580     0   stevel 
   1581     0   stevel 		curthread->t_dtrace_astpc = addr + i;
   1582     0   stevel 		bcopy(tp->ftt_instr, &scratch[i], tp->ftt_size);
   1583     0   stevel 		i += tp->ftt_size;
   1584     0   stevel 		scratch[i++] = FASTTRAP_INT;
   1585     0   stevel 		scratch[i++] = T_DTRACE_RET;
   1586     0   stevel 
   1587  6390      ahl 		ASSERT(i <= sizeof (scratch));
   1588  6390      ahl 
   1589     0   stevel 		if (fasttrap_copyout(scratch, (char *)addr, i)) {
   1590     0   stevel 			fasttrap_sigtrap(p, curthread, pc);
   1591     0   stevel 			new_pc = pc;
   1592     0   stevel 			break;
   1593     0   stevel 		}
   1594     0   stevel 
   1595     0   stevel 		if (tp->ftt_retids != NULL) {
   1596     0   stevel 			curthread->t_dtrace_step = 1;
   1597     0   stevel 			curthread->t_dtrace_ret = 1;
   1598     0   stevel 			new_pc = curthread->t_dtrace_astpc;
   1599     0   stevel 		} else {
   1600     0   stevel 			new_pc = curthread->t_dtrace_scrpc;
   1601     0   stevel 		}
   1602     0   stevel 
   1603     0   stevel 		curthread->t_dtrace_pc = pc;
   1604     0   stevel 		curthread->t_dtrace_npc = pc + tp->ftt_size;
   1605     0   stevel 		curthread->t_dtrace_on = 1;
   1606     0   stevel 		break;
   1607     0   stevel 	}
   1608     0   stevel 
   1609     0   stevel 	default:
   1610     0   stevel 		panic("fasttrap: mishandled an instruction");
   1611     0   stevel 	}
   1612     0   stevel 
   1613  1710      ahl done:
   1614     0   stevel 	/*
   1615     0   stevel 	 * If there were no return probes when we first found the tracepoint,
   1616     0   stevel 	 * we should feel no obligation to honor any return probes that were
   1617     0   stevel 	 * subsequently enabled -- they'll just have to wait until the next
   1618     0   stevel 	 * time around.
   1619     0   stevel 	 */
   1620     0   stevel 	if (tp->ftt_retids != NULL) {
   1621     0   stevel 		/*
   1622     0   stevel 		 * We need to wait until the results of the instruction are
   1623     0   stevel 		 * apparent before invoking any return probes. If this
   1624     0   stevel 		 * instruction was emulated we can just call
   1625     0   stevel 		 * fasttrap_return_common(); if it needs to be executed, we
   1626     0   stevel 		 * need to wait until the user thread returns to the kernel.
   1627     0   stevel 		 */
   1628     0   stevel 		if (tp->ftt_type != FASTTRAP_T_COMMON) {
   1629     0   stevel 			/*
   1630     0   stevel 			 * Set the program counter to the address of the traced
   1631     0   stevel 			 * instruction so that it looks right in ustack()
   1632     0   stevel 			 * output. We had previously set it to the end of the
   1633     0   stevel 			 * instruction to simplify %rip-relative addressing.
   1634     0   stevel 			 */
   1635     0   stevel 			rp->r_pc = pc;
   1636     0   stevel 
   1637     0   stevel 			fasttrap_return_common(rp, pc, pid, new_pc);
   1638     0   stevel 		} else {
   1639     0   stevel 			ASSERT(curthread->t_dtrace_ret != 0);
   1640     0   stevel 			ASSERT(curthread->t_dtrace_pc == pc);
   1641     0   stevel 			ASSERT(curthread->t_dtrace_scrpc != 0);
   1642     0   stevel 			ASSERT(new_pc == curthread->t_dtrace_astpc);
   1643     0   stevel 		}
   1644     0   stevel 	}
   1645     0   stevel 
   1646     0   stevel 	rp->r_pc = new_pc;
   1647     0   stevel 
   1648     0   stevel 	return (0);
   1649     0   stevel }
   1650     0   stevel 
   1651     0   stevel int
   1652     0   stevel fasttrap_return_probe(struct regs *rp)
   1653     0   stevel {
   1654     0   stevel 	proc_t *p = curproc;
   1655     0   stevel 	uintptr_t pc = curthread->t_dtrace_pc;
   1656     0   stevel 	uintptr_t npc = curthread->t_dtrace_npc;
   1657     0   stevel 
   1658     0   stevel 	curthread->t_dtrace_pc = 0;
   1659     0   stevel 	curthread->t_dtrace_npc = 0;
   1660     0   stevel 	curthread->t_dtrace_scrpc = 0;
   1661     0   stevel 	curthread->t_dtrace_astpc = 0;
   1662     0   stevel 
   1663     0   stevel 	/*
   1664     0   stevel 	 * Treat a child created by a call to vfork(2) as if it were its
   1665     0   stevel 	 * parent. We know that there's only one thread of control in such a
   1666     0   stevel 	 * process: this one.
   1667     0   stevel 	 */
   1668     0   stevel 	while (p->p_flag & SVFORK) {
   1669     0   stevel 		p = p->p_parent;
   1670     0   stevel 	}
   1671     0   stevel 
   1672     0   stevel 	/*
   1673     0   stevel 	 * We set rp->r_pc to the address of the traced instruction so
   1674     0   stevel 	 * that it appears to dtrace_probe() that we're on the original
   1675     0   stevel 	 * instruction, and so that the user can't easily detect our
   1676     0   stevel 	 * complex web of lies. dtrace_return_probe() (our caller)
   1677     0   stevel 	 * will correctly set %pc after we return.
   1678     0   stevel 	 */
   1679     0   stevel 	rp->r_pc = pc;
   1680     0   stevel 
   1681     0   stevel 	fasttrap_return_common(rp, pc, p->p_pid, npc);
   1682     0   stevel 
   1683     0   stevel 	return (0);
   1684     0   stevel }
   1685     0   stevel 
   1686     0   stevel /*ARGSUSED*/
   1687     0   stevel uint64_t
   1688  2179      ahl fasttrap_pid_getarg(void *arg, dtrace_id_t id, void *parg, int argno,
   1689  2179      ahl     int aframes)
   1690     0   stevel {
   1691     0   stevel 	return (fasttrap_anarg(ttolwp(curthread)->lwp_regs, 1, argno));
   1692     0   stevel }
   1693     0   stevel 
   1694     0   stevel /*ARGSUSED*/
   1695     0   stevel uint64_t
   1696     0   stevel fasttrap_usdt_getarg(void *arg, dtrace_id_t id, void *parg, int argno,
   1697     0   stevel     int aframes)
   1698     0   stevel {
   1699     0   stevel 	return (fasttrap_anarg(ttolwp(curthread)->lwp_regs, 0, argno));
   1700     0   stevel }
   1701     0   stevel 
   1702     0   stevel static ulong_t
   1703     0   stevel fasttrap_getreg(struct regs *rp, uint_t reg)
   1704     0   stevel {
   1705     0   stevel #ifdef __amd64
   1706     0   stevel 	switch (reg) {
   1707     0   stevel 	case REG_R15:		return (rp->r_r15);
   1708     0   stevel 	case REG_R14:		return (rp->r_r14);
   1709     0   stevel 	case REG_R13:		return (rp->r_r13);
   1710     0   stevel 	case REG_R12:		return (rp->r_r12);
   1711     0   stevel 	case REG_R11:		return (rp->r_r11);
   1712     0   stevel 	case REG_R10:		return (rp->r_r10);
   1713     0   stevel 	case REG_R9:		return (rp->r_r9);
   1714     0   stevel 	case REG_R8:		return (rp->r_r8);
   1715     0   stevel 	case REG_RDI:		return (rp->r_rdi);
   1716     0   stevel 	case REG_RSI:		return (rp->r_rsi);
   1717     0   stevel 	case REG_RBP:		return (rp->r_rbp);
   1718     0   stevel 	case REG_RBX:		return (rp->r_rbx);
   1719     0   stevel 	case REG_RDX:		return (rp->r_rdx);
   1720     0   stevel 	case REG_RCX:		return (rp->r_rcx);
   1721     0   stevel 	case REG_RAX:		return (rp->r_rax);
   1722     0   stevel 	case REG_TRAPNO:	return (rp->r_trapno);
   1723     0   stevel 	case REG_ERR:		return (rp->r_err);
   1724     0   stevel 	case REG_RIP:		return (rp->r_rip);
   1725     0   stevel 	case REG_CS:		return (rp->r_cs);
   1726     0   stevel 	case REG_RFL:		return (rp->r_rfl);
   1727     0   stevel 	case REG_RSP:		return (rp->r_rsp);
   1728     0   stevel 	case REG_SS:		return (rp->r_ss);
   1729     0   stevel 	case REG_FS:		return (rp->r_fs);
   1730     0   stevel 	case REG_GS:		return (rp->r_gs);
   1731     0   stevel 	case REG_DS:		return (rp->r_ds);
   1732     0   stevel 	case REG_ES:		return (rp->r_es);
   1733  3446      mrj 	case REG_FSBASE:	return (rdmsr(MSR_AMD_FSBASE));
   1734  3446      mrj 	case REG_GSBASE:	return (rdmsr(MSR_AMD_GSBASE));
   1735     0   stevel 	}
   1736     0   stevel 
   1737     0   stevel 	panic("dtrace: illegal register constant");
   1738     0   stevel 	/*NOTREACHED*/
   1739     0   stevel #else
   1740     0   stevel 	if (reg >= _NGREG)
   1741     0   stevel 		panic("dtrace: illegal register constant");
   1742     0   stevel 
   1743     0   stevel 	return (((greg_t *)&rp->r_gs)[reg]);
   1744     0   stevel #endif
   1745     0   stevel }
   1746