dtrace: Add a "regs" variable
This allows invop-based providers (i.e., fbt and kinst) to expose the register file of the CPU at the point where the probe fired. It does not work for SDT providers because their probes are implemented as plain function calls and so don't save registers. It's not clear what semantics "regs" should have for them anyway. This is akin to "uregs", which nominally provides access to the userspace registers. In fact, DIF already had a DIF_VAR_REGS variable defined, it was simply unimplemented. Usage example: print the contents of %rdi upon each call to amd64_syscall(): fbt::amd64_syscall:entry {printf("%x", regs[R_RDI]);} Note that the R_* constants are defined in /usr/lib/dtrace/regs_x86.d. Currently there are no similar definitions for non-x86 platforms. Reviewed by: christos MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D36799
This commit is contained in:
parent
cba2fa7c5b
commit
bdd101c4d4
@ -416,6 +416,8 @@ static const dt_ident_t _dtrace_globals[] = {
|
||||
&dt_idops_func, "void(int)" },
|
||||
{ "rand", DT_IDENT_FUNC, 0, DIF_SUBR_RAND, DT_ATTR_STABCMN, DT_VERS_1_0,
|
||||
&dt_idops_func, "int()" },
|
||||
{ "regs", DT_IDENT_ARRAY, 0, DIF_VAR_REGS, DT_ATTR_STABCMN, DT_VERS_1_13,
|
||||
&dt_idops_regs, NULL },
|
||||
{ "rindex", DT_IDENT_FUNC, 0, DIF_SUBR_RINDEX, DT_ATTR_STABCMN, DT_VERS_1_1,
|
||||
&dt_idops_func, "int(const char *, const char *, [int])" },
|
||||
#ifdef illumos
|
||||
|
@ -3360,30 +3360,19 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v,
|
||||
|
||||
return (mstate->dtms_arg[ndx]);
|
||||
|
||||
#ifdef illumos
|
||||
case DIF_VAR_UREGS: {
|
||||
klwp_t *lwp;
|
||||
|
||||
if (!dtrace_priv_proc(state))
|
||||
return (0);
|
||||
|
||||
if ((lwp = curthread->t_lwp) == NULL) {
|
||||
DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
|
||||
cpu_core[curcpu].cpuc_dtrace_illval = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (dtrace_getreg(lwp->lwp_regs, ndx));
|
||||
return (0);
|
||||
}
|
||||
#else
|
||||
case DIF_VAR_REGS:
|
||||
case DIF_VAR_UREGS: {
|
||||
struct trapframe *tframe;
|
||||
|
||||
if (!dtrace_priv_proc(state))
|
||||
return (0);
|
||||
|
||||
if ((tframe = curthread->td_frame) == NULL) {
|
||||
if (v == DIF_VAR_REGS)
|
||||
tframe = curthread->t_dtrace_trapframe;
|
||||
else
|
||||
tframe = curthread->td_frame;
|
||||
|
||||
if (tframe == NULL) {
|
||||
DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
|
||||
cpu_core[curcpu].cpuc_dtrace_illval = 0;
|
||||
return (0);
|
||||
@ -3391,7 +3380,6 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v,
|
||||
|
||||
return (dtrace_getreg(tframe, ndx));
|
||||
}
|
||||
#endif
|
||||
|
||||
case DIF_VAR_CURTHREAD:
|
||||
if (!dtrace_priv_proc(state))
|
||||
|
@ -27,18 +27,16 @@
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/kmem.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/smp.h>
|
||||
#include <sys/dtrace_impl.h>
|
||||
#include <sys/dtrace_bsd.h>
|
||||
#include <cddl/dev/dtrace/dtrace_cddl.h>
|
||||
#include <machine/armreg.h>
|
||||
#include <machine/clock.h>
|
||||
#include <machine/frame.h>
|
||||
@ -65,17 +63,20 @@ dtrace_invop_hdlr_t *dtrace_invop_hdlr;
|
||||
int
|
||||
dtrace_invop(uintptr_t addr, struct trapframe *frame, uintptr_t eax)
|
||||
{
|
||||
struct thread *td;
|
||||
dtrace_invop_hdlr_t *hdlr;
|
||||
int rval;
|
||||
|
||||
rval = 0;
|
||||
td = curthread;
|
||||
td->t_dtrace_trapframe = frame;
|
||||
for (hdlr = dtrace_invop_hdlr; hdlr != NULL; hdlr = hdlr->dtih_next)
|
||||
if ((rval = hdlr->dtih_func(addr, frame, eax)) != 0)
|
||||
return (rval);
|
||||
|
||||
return (0);
|
||||
break;
|
||||
td->t_dtrace_trapframe = NULL;
|
||||
return (rval);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dtrace_invop_add(int (*func)(uintptr_t, struct trapframe *, uintptr_t))
|
||||
{
|
||||
|
@ -33,12 +33,13 @@
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/smp.h>
|
||||
#include <sys/dtrace_impl.h>
|
||||
#include <sys/dtrace_bsd.h>
|
||||
#include <cddl/dev/dtrace/dtrace_cddl.h>
|
||||
#include <machine/clock.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/frame.h>
|
||||
@ -65,15 +66,20 @@ dtrace_invop_hdlr_t *dtrace_invop_hdlr;
|
||||
int
|
||||
dtrace_invop(uintptr_t addr, struct trapframe *frame, void **scratch)
|
||||
{
|
||||
struct thread *td;
|
||||
dtrace_invop_hdlr_t *hdlr;
|
||||
int rval;
|
||||
|
||||
td = curthread;
|
||||
td->t_dtrace_trapframe = frame;
|
||||
rval = 0;
|
||||
for (hdlr = dtrace_invop_hdlr; hdlr != NULL; hdlr = hdlr->dtih_next) {
|
||||
rval = hdlr->dtih_func(addr, frame, (uintptr_t)scratch);
|
||||
if (rval != 0)
|
||||
return (rval);
|
||||
break;
|
||||
}
|
||||
return (0);
|
||||
td->t_dtrace_trapframe = NULL;
|
||||
return (rval);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -27,18 +27,16 @@
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/kmem.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/smp.h>
|
||||
#include <sys/dtrace_impl.h>
|
||||
#include <sys/dtrace_bsd.h>
|
||||
#include <cddl/dev/dtrace/dtrace_cddl.h>
|
||||
#include <machine/armreg.h>
|
||||
#include <machine/clock.h>
|
||||
#include <machine/frame.h>
|
||||
@ -70,14 +68,18 @@ dtrace_invop_hdlr_t *dtrace_invop_hdlr;
|
||||
int
|
||||
dtrace_invop(uintptr_t addr, struct trapframe *frame, uintptr_t eax)
|
||||
{
|
||||
struct thread *td;
|
||||
dtrace_invop_hdlr_t *hdlr;
|
||||
int rval;
|
||||
|
||||
rval = 0;
|
||||
td = curthread;
|
||||
td->t_dtrace_trapframe = frame;
|
||||
for (hdlr = dtrace_invop_hdlr; hdlr != NULL; hdlr = hdlr->dtih_next)
|
||||
if ((rval = hdlr->dtih_func(addr, frame, eax)) != 0)
|
||||
return (rval);
|
||||
|
||||
return (0);
|
||||
break;
|
||||
td->t_dtrace_trapframe = NULL;
|
||||
return (rval);
|
||||
}
|
||||
|
||||
|
||||
|
@ -87,6 +87,7 @@ typedef struct kdtrace_thread {
|
||||
void *td_dtrace_sscr; /* Saved scratch space location. */
|
||||
void *td_systrace_args; /* syscall probe arguments. */
|
||||
uint64_t td_fasttrap_tp_gen; /* Tracepoint hash table gen. */
|
||||
struct trapframe *td_dtrace_trapframe; /* Trap frame from invop. */
|
||||
} kdtrace_thread_t;
|
||||
|
||||
/*
|
||||
@ -115,6 +116,7 @@ typedef struct kdtrace_thread {
|
||||
#define t_dtrace_sscr td_dtrace->td_dtrace_sscr
|
||||
#define t_dtrace_systrace_args td_dtrace->td_systrace_args
|
||||
#define t_fasttrap_tp_gen td_dtrace->td_fasttrap_tp_gen
|
||||
#define t_dtrace_trapframe td_dtrace->td_dtrace_trapframe
|
||||
#define p_dtrace_helpers p_dtrace->p_dtrace_helpers
|
||||
#define p_dtrace_count p_dtrace->p_dtrace_count
|
||||
#define p_dtrace_probes p_dtrace->p_dtrace_probes
|
||||
|
@ -33,14 +33,15 @@
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/cpuset.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/kmem.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/smp.h>
|
||||
#include <sys/dtrace_impl.h>
|
||||
#include <sys/dtrace_bsd.h>
|
||||
#include <cddl/dev/dtrace/dtrace_cddl.h>
|
||||
#include <machine/clock.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/frame.h>
|
||||
@ -68,14 +69,18 @@ dtrace_invop_hdlr_t *dtrace_invop_hdlr;
|
||||
int
|
||||
dtrace_invop(uintptr_t addr, struct trapframe *frame, uintptr_t eax)
|
||||
{
|
||||
struct thread *td;
|
||||
dtrace_invop_hdlr_t *hdlr;
|
||||
int rval;
|
||||
|
||||
rval = 0;
|
||||
td = curthread;
|
||||
td->t_dtrace_trapframe = frame;
|
||||
for (hdlr = dtrace_invop_hdlr; hdlr != NULL; hdlr = hdlr->dtih_next)
|
||||
if ((rval = hdlr->dtih_func(addr, frame, eax)) != 0)
|
||||
return (rval);
|
||||
|
||||
return (0);
|
||||
break;
|
||||
td->t_dtrace_trapframe = NULL;
|
||||
return (rval);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -27,18 +27,16 @@
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/kmem.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/smp.h>
|
||||
#include <sys/dtrace_impl.h>
|
||||
#include <sys/dtrace_bsd.h>
|
||||
#include <cddl/dev/dtrace/dtrace_cddl.h>
|
||||
#include <machine/clock.h>
|
||||
#include <machine/frame.h>
|
||||
#include <machine/trap.h>
|
||||
@ -65,14 +63,18 @@ dtrace_invop_hdlr_t *dtrace_invop_hdlr;
|
||||
int
|
||||
dtrace_invop(uintptr_t addr, struct trapframe *frame, uintptr_t arg0)
|
||||
{
|
||||
struct thread *td;
|
||||
dtrace_invop_hdlr_t *hdlr;
|
||||
int rval;
|
||||
|
||||
rval = 0;
|
||||
td = curthread;
|
||||
td->t_dtrace_trapframe = frame;
|
||||
for (hdlr = dtrace_invop_hdlr; hdlr != NULL; hdlr = hdlr->dtih_next)
|
||||
if ((rval = hdlr->dtih_func(addr, frame, arg0)) != 0)
|
||||
return (rval);
|
||||
|
||||
return (0);
|
||||
break;
|
||||
td->t_dtrace_trapframe = NULL;
|
||||
return (rval);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -29,18 +29,16 @@
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/kmem.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/smp.h>
|
||||
#include <sys/dtrace_impl.h>
|
||||
#include <sys/dtrace_bsd.h>
|
||||
#include <cddl/dev/dtrace/dtrace_cddl.h>
|
||||
#include <machine/vmparam.h>
|
||||
#include <machine/encoding.h>
|
||||
#include <machine/riscvreg.h>
|
||||
@ -68,14 +66,18 @@ dtrace_invop_hdlr_t *dtrace_invop_hdlr;
|
||||
int
|
||||
dtrace_invop(uintptr_t addr, struct trapframe *frame)
|
||||
{
|
||||
struct thread *td;
|
||||
dtrace_invop_hdlr_t *hdlr;
|
||||
int rval;
|
||||
|
||||
rval = 0;
|
||||
td = curthread;
|
||||
td->t_dtrace_trapframe = frame;
|
||||
for (hdlr = dtrace_invop_hdlr; hdlr != NULL; hdlr = hdlr->dtih_next)
|
||||
if ((rval = hdlr->dtih_func(addr, frame, 0)) != 0)
|
||||
return (rval);
|
||||
|
||||
return (0);
|
||||
break;
|
||||
td->t_dtrace_trapframe = NULL;
|
||||
return (rval);
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user