diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c @@ -482,9 +482,11 @@ static const dt_ident_t _dtrace_globals[ #if defined(sun) { "ustack", DT_IDENT_ACTFUNC, 0, DT_ACT_USTACK, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_func, "stack(...)" }, +#endif { "ustackdepth", DT_IDENT_SCALAR, 0, DIF_VAR_USTACKDEPTH, DT_ATTR_STABCMN, DT_VERS_1_2, &dt_idops_type, "uint32_t" }, +#if defined(sun) { "usym", DT_IDENT_ACTFUNC, 0, DT_ACT_USYM, DT_ATTR_STABCMN, DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" }, #endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c --- a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c +++ b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c @@ -2854,7 +2854,6 @@ dtrace_dif_variable(dtrace_mstate_t *mst } return (mstate->dtms_stackdepth); -#if defined(sun) case DIF_VAR_USTACKDEPTH: if (!dtrace_priv_proc(state)) return (0); @@ -2874,7 +2873,6 @@ dtrace_dif_variable(dtrace_mstate_t *mst mstate->dtms_present |= DTRACE_MSTATE_USTACKDEPTH; } return (mstate->dtms_ustackdepth); -#endif case DIF_VAR_CALLER: if (!dtrace_priv_kernel(state)) diff --git a/sys/cddl/dev/dtrace/amd64/dtrace_isa.c b/sys/cddl/dev/dtrace/amd64/dtrace_isa.c --- a/sys/cddl/dev/dtrace/amd64/dtrace_isa.c +++ b/sys/cddl/dev/dtrace/amd64/dtrace_isa.c @@ -104,12 +104,11 @@ dtrace_getustack_common(uint64_t *pcstac { volatile uint16_t *flags = (volatile uint16_t *)&cpu_core[curcpu].cpuc_dtrace_flags; - struct amd64_frame *frame; int ret = 0; ASSERT(pcstack == NULL || pcstack_limit > 0); - while (pc != 0 && sp != 0) { + while (pc != 0) { ret++; if (pcstack != NULL) { *pcstack++ = (uint64_t)pc; @@ -118,10 +117,12 @@ dtrace_getustack_common(uint64_t *pcstac break; } - frame = (struct amd64_frame *) sp; + if (sp == 0) + break; - pc = dtrace_fulword(&frame->f_retaddr); - sp = dtrace_fulword(&frame->f_frame); + pc = dtrace_fuword64((void *)(sp + + offsetof(struct amd64_frame, f_retaddr))); + sp = dtrace_fuword64((void *)sp); /* * This is totally bogus: if we faulted, we're going to clear @@ -194,7 +195,7 @@ dtrace_getustackdepth(void) { proc_t *p = curproc; struct trapframe *tf; - uintptr_t pc, sp; + uintptr_t pc, fp, sp; int n = 0; if (p == NULL || (tf = curthread->td_frame) == NULL) @@ -204,15 +205,24 @@ dtrace_getustackdepth(void) return (-1); pc = tf->tf_rip; + fp = tf->tf_rbp; sp = tf->tf_rsp; if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) { + /* + * In an entry probe. The frame pointer has not yet been + * pushed (that happens in the function prologue). The + * best approach is to add the current pc as a missing top + * of stack and back the pc up to the caller, which is stored + * at the current stack pointer address since the call + * instruction puts it there right before the branch. + */ + + pc = dtrace_fuword64((void *) sp); n++; - - pc = dtrace_fulword((void *) sp); } - n += dtrace_getustack_common(NULL, 0, pc, sp); + n += dtrace_getustack_common(NULL, 0, pc, fp); return (n); } diff --git a/sys/cddl/dev/dtrace/i386/dtrace_isa.c b/sys/cddl/dev/dtrace/i386/dtrace_isa.c --- a/sys/cddl/dev/dtrace/i386/dtrace_isa.c +++ b/sys/cddl/dev/dtrace/i386/dtrace_isa.c @@ -104,21 +104,22 @@ dtrace_getpcstack(pc_t *pcstack, int pcs } } -#ifdef notyet static int dtrace_getustack_common(uint64_t *pcstack, int pcstack_limit, uintptr_t pc, uintptr_t sp) { - klwp_t *lwp = ttolwp(curthread); +#ifdef notyet proc_t *p = curproc; - uintptr_t oldcontext = lwp->lwp_oldcontext; + uintptr_t oldcontext = lwp->lwp_oldcontext; /* XXX signal stack. */ + size_t s1, s2; +#endif volatile uint16_t *flags = (volatile uint16_t *)&cpu_core[curcpu].cpuc_dtrace_flags; - size_t s1, s2; int ret = 0; ASSERT(pcstack == NULL || pcstack_limit > 0); +#ifdef notyet /* XXX signal stack. */ if (p->p_model == DATAMODEL_NATIVE) { s1 = sizeof (struct frame) + 2 * sizeof (long); s2 = s1 + sizeof (siginfo_t); @@ -126,8 +127,9 @@ dtrace_getustack_common(uint64_t *pcstac s1 = sizeof (struct frame32) + 3 * sizeof (int); s2 = s1 + sizeof (siginfo32_t); } +#endif - while (pc != 0 && sp != 0) { + while (pc != 0) { ret++; if (pcstack != NULL) { *pcstack++ = (uint64_t)pc; @@ -136,6 +138,10 @@ dtrace_getustack_common(uint64_t *pcstac break; } + if (sp == 0) + break; + +#ifdef notyet /* XXX signal stack. */ if (oldcontext == sp + s1 || oldcontext == sp + s2) { if (p->p_model == DATAMODEL_NATIVE) { ucontext_t *ucp = (ucontext_t *)oldcontext; @@ -167,6 +173,11 @@ dtrace_getustack_common(uint64_t *pcstac sp = dtrace_fuword32(&fr->fr_savfp); } } +#else + pc = dtrace_fuword32((void *)(sp + + offsetof(struct i386_frame, f_retaddr))); + sp = dtrace_fuword32((void *)sp); +#endif /* ! notyet */ /* * This is totally bogus: if we faulted, we're going to clear @@ -182,6 +193,7 @@ dtrace_getustack_common(uint64_t *pcstac return (ret); } +#ifdef notyet void dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit) { @@ -237,12 +249,46 @@ zero: while (pcstack_limit-- > 0) *pcstack++ = NULL; } +#endif /* notyet */ int dtrace_getustackdepth(void) { + proc_t *p = curproc; + struct trapframe *tf; + uintptr_t pc, fp, sp; + int n = 0; + + if (p == NULL || (tf = curthread->td_frame) == NULL) + return (0); + + if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_FAULT)) + return (-1); + + pc = tf->tf_eip; + fp = tf->tf_ebp; + sp = tf->tf_esp; + + if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) { + /* + * In an entry probe. The frame pointer has not yet been + * pushed (that happens in the function prologue). The + * best approach is to add the current pc as a missing top + * of stack and back the pc up to the caller, which is stored + * at the current stack pointer address since the call + * instruction puts it there right before the branch. + */ + + pc = dtrace_fuword32((void *) sp); + n++; + } + + n += dtrace_getustack_common(NULL, 0, pc, fp); + + return (n); } +#ifdef notyet void dtrace_getufpstack(uint64_t *pcstack, uint64_t *fpstack, int pcstack_limit) { @@ -351,7 +397,7 @@ zero: while (pcstack_limit-- > 0) *pcstack++ = NULL; } -#endif +#endif /* notyet */ uint64_t dtrace_getarg(int arg, int aframes)