*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
- * #pragma ident "@(#)fasttrap_isa.c 1.23 06/09/19 SMI"
+ * #pragma ident "@(#)fasttrap_isa.c 1.27 08/04/09 SMI"
*/
#ifdef KERNEL
#include <sys/dtrace_ptss.h>
#include <kern/debug.h>
-#define proc_t struct proc
+#include <machine/pal_routines.h>
+
+/* Solaris proc_t is the struct. Darwin's proc_t is a pointer to it. */
+#define proc_t struct proc /* Steer clear of the Darwin typedef for proc_t */
/*
* Lossless User-Land Tracing on x86
value = dtrace_fuword64(stack);
DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT | CPU_DTRACE_BADADDR);
} else {
- uint32_t *stack = (uint32_t *)regs32->uesp;
+ uint32_t *stack = (uint32_t *)(uintptr_t)(regs32->uesp);
DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
value = dtrace_fuword32((user_addr_t)(unsigned long)&stack[argno + shift]);
DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT | CPU_DTRACE_BADADDR);
tp->ftt_type = FASTTRAP_T_JCC;
tp->ftt_code = (instr[start + 1] & 0x0f) | FASTTRAP_JO;
tp->ftt_dest = pc + tp->ftt_size +
+ /* LINTED - alignment */
*(int32_t *)&instr[start + 2];
break;
}
i = 2;
}
- if (sz == 1)
+ if (sz == 1) {
tp->ftt_dest = *(int8_t *)&instr[start + i];
- else if (sz == 4)
+ } else if (sz == 4) {
+ /* LINTED - alignment */
tp->ftt_dest = *(int32_t *)&instr[start + i];
- else
+ } else {
tp->ftt_dest = 0;
+ }
}
} else {
switch (instr[start]) {
case FASTTRAP_RET16:
tp->ftt_type = FASTTRAP_T_RET16;
+ /* LINTED - alignment */
tp->ftt_dest = *(uint16_t *)&instr[start + 1];
break;
case FASTTRAP_CALL:
tp->ftt_type = FASTTRAP_T_CALL;
tp->ftt_dest = pc + tp->ftt_size +
+ /* LINTED - alignment */
*(int32_t *)&instr[start + 1];
tp->ftt_code = 0;
break;
case FASTTRAP_JMP32:
tp->ftt_type = FASTTRAP_T_JMP;
tp->ftt_dest = pc + tp->ftt_size +
+ /* LINTED - alignment */
*(int32_t *)&instr[start + 1];
break;
case FASTTRAP_JMP8:
x86_saved_state32_t *regs32;
unsigned int p_model;
+ dtrace_icookie_t cookie;
+
if (is_saved_state64(regs)) {
regs64 = saved_state64(regs);
regs32 = NULL;
for (tp = bucket->ftb_data; tp != NULL; tp = tp->ftt_next) {
if (pid == tp->ftt_pid && pc == tp->ftt_pc &&
- !tp->ftt_proc->ftpc_defunct)
+ tp->ftt_proc->ftpc_acount != 0)
break;
}
id->fti_probe->ftp_fsize)
continue;
+ /*
+ * Provide a hint to the stack trace functions to add the
+ * following pc to the top of the stack since it's missing
+ * on a return probe yet highly desirable for consistency.
+ */
+ cookie = dtrace_interrupt_disable();
+ cpu_core[CPU->cpu_id].cpuc_missing_tos = pc;
if (ISSET(current_proc()->p_lflag, P_LNOATTACH)) {
dtrace_probe(dtrace_probeid_error, 0 /* state */, id->fti_probe->ftp_id,
1 /* ndx */, -1 /* offset */, DTRACEFLT_UPRIV);
pc - id->fti_probe->ftp_faddr,
regs32->eax, regs32->edx, 0, 0);
}
+ /* remove the hint */
+ cpu_core[CPU->cpu_id].cpuc_missing_tos = 0;
+ dtrace_interrupt_enable(cookie);
}
lck_mtx_unlock(pid_mtx);
uint32_t *argv)
{
int i, x, cap = MIN(argc, probe->ftp_nargs);
- uint32_t *stack = (uint32_t *)regs32->uesp;
+ uint32_t *stack = (uint32_t *)(uintptr_t)(regs32->uesp);
for (i = 0; i < cap; i++) {
x = probe->ftp_argmap[i];
*/
for (tp = bucket->ftb_data; tp != NULL; tp = tp->ftt_next) {
if (pid == tp->ftt_pid && pc == tp->ftt_pc &&
- !tp->ftt_proc->ftpc_defunct)
+ tp->ftt_proc->ftpc_acount != 0)
break;
}
fasttrap_id_t *id;
uint32_t s0, s1, s2, s3, s4, s5;
- uint32_t *stack = (uint32_t *)regs32->uesp;
+ uint32_t *stack = (uint32_t *)(uintptr_t)(regs32->uesp);
/*
* In 32-bit mode, all arguments are passed on the
case FASTTRAP_T_COMMON:
{
user_addr_t addr;
- uint8_t scratch[2 * FASTTRAP_MAX_INSTR_SIZE + 5 + 2];
+ uint8_t scratch[2 * FASTTRAP_MAX_INSTR_SIZE + 7];
uint_t i = 0;
/*
* the size of the traced instruction cancels out.
*/
scratch[i++] = FASTTRAP_JMP32;
+ /* LINTED - alignment */
*(uint32_t *)&scratch[i] = pc - addr - 5;
i += sizeof (uint32_t);
scratch[i++] = FASTTRAP_INT;
scratch[i++] = T_DTRACE_RET;
+ ASSERT(i <= sizeof (scratch));
+
if (fasttrap_copyout(scratch, addr, i)) {
fasttrap_sigtrap(p, uthread, pc);
new_pc = pc;
*/
for (tp = bucket->ftb_data; tp != NULL; tp = tp->ftt_next) {
if (pid == tp->ftt_pid && pc == tp->ftt_pc &&
- !tp->ftt_proc->ftpc_defunct)
+ tp->ftt_proc->ftpc_acount != 0)
break;
}
case FASTTRAP_T_COMMON:
{
user_addr_t addr;
- uint8_t scratch[2 * FASTTRAP_MAX_INSTR_SIZE + 5 + 2];
+ uint8_t scratch[2 * FASTTRAP_MAX_INSTR_SIZE + 22];
uint_t i = 0;
/*
panic("unhandled ripmode in fasttrap_pid_probe64");
}
+ /* LINTED - alignment */
*(uint64_t *)&scratch[i] = *reg;
uthread->t_dtrace_regv = *reg;
*reg = pc + tp->ftt_size;
*/
scratch[i++] = FASTTRAP_GROUP5_OP;
scratch[i++] = FASTTRAP_MODRM(0, 4, 5);
+ /* LINTED - alignment */
*(uint32_t *)&scratch[i] = 0;
i += sizeof (uint32_t);
+ /* LINTED - alignment */
*(uint64_t *)&scratch[i] = pc + tp->ftt_size;
i += sizeof (uint64_t);
scratch[i++] = FASTTRAP_INT;
scratch[i++] = T_DTRACE_RET;
+ ASSERT(i <= sizeof (scratch));
+
if (fasttrap_copyout(scratch, addr, i)) {
fasttrap_sigtrap(p, uthread, pc);
new_pc = pc;
fasttrap_pid_getarg(void *arg, dtrace_id_t id, void *parg, int argno,
int aframes)
{
+ pal_register_cache_state(current_thread(), VALID);
#pragma unused(arg, id, parg, aframes)
return (fasttrap_anarg((x86_saved_state_t *)find_user_regs(current_thread()), 1, argno));
}
fasttrap_usdt_getarg(void *arg, dtrace_id_t id, void *parg, int argno,
int aframes)
{
+ pal_register_cache_state(current_thread(), VALID);
#pragma unused(arg, id, parg, aframes)
return (fasttrap_anarg((x86_saved_state_t *)find_user_regs(current_thread()), 0, argno));
}
case REG_R13: return regs64->r13;
case REG_R14: return regs64->r14;
case REG_R15: return regs64->r15;
+ case REG_TRAPNO: return regs64->isf.trapno;
+ case REG_ERR: return regs64->isf.err;
+ case REG_RIP: return regs64->isf.rip;
+ case REG_CS: return regs64->isf.cs;
+ case REG_RFL: return regs64->isf.rflags;
+ case REG_SS: return regs64->isf.ss;
+ case REG_FS: return regs64->fs;
+ case REG_GS: return regs64->gs;
+ case REG_ES:
+ case REG_DS:
+ case REG_FSBASE:
+ case REG_GSBASE:
+ // Important to distinguish these requests (which should be legal) from other values.
+ panic("dtrace: unimplemented x86_64 getreg()");
}
panic("dtrace: unhandled x86_64 getreg() constant");