Pass the trap frame to fasttrap hooks.
The DTrace fasttrap entry points expect a struct reg containing the register values of the calling thread. Perform the conversion in fasttrap rather than in the trap handler: this reduces the number of ifdefs and avoids wasting stack space for traps that don't involve DTrace. MFC after: 2 weeks
This commit is contained in:
parent
6625e5aad4
commit
b0b9b4fcf4
@ -164,9 +164,6 @@ SYSCTL_INT(_machdep, OID_AUTO, uprintf_signal, CTLFLAG_RWTUN,
|
||||
void
|
||||
trap(struct trapframe *frame)
|
||||
{
|
||||
#ifdef KDTRACE_HOOKS
|
||||
struct reg regs;
|
||||
#endif
|
||||
ksiginfo_t ksi;
|
||||
struct thread *td;
|
||||
struct proc *p;
|
||||
@ -278,9 +275,8 @@ trap(struct trapframe *frame)
|
||||
enable_intr();
|
||||
#ifdef KDTRACE_HOOKS
|
||||
if (type == T_BPTFLT) {
|
||||
fill_frame_regs(frame, ®s);
|
||||
if (dtrace_pid_probe_ptr != NULL &&
|
||||
dtrace_pid_probe_ptr(®s) == 0)
|
||||
dtrace_pid_probe_ptr(frame) == 0)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@ -406,9 +402,8 @@ trap(struct trapframe *frame)
|
||||
#ifdef KDTRACE_HOOKS
|
||||
case T_DTRACE_RET:
|
||||
enable_intr();
|
||||
fill_frame_regs(frame, ®s);
|
||||
if (dtrace_return_probe_ptr != NULL)
|
||||
dtrace_return_probe_ptr(®s);
|
||||
dtrace_return_probe_ptr(frame);
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
@ -221,9 +221,9 @@ extern int fasttrap_tracepoint_init(proc_t *, fasttrap_tracepoint_t *,
|
||||
extern int fasttrap_tracepoint_install(proc_t *, fasttrap_tracepoint_t *);
|
||||
extern int fasttrap_tracepoint_remove(proc_t *, fasttrap_tracepoint_t *);
|
||||
|
||||
struct reg;
|
||||
extern int fasttrap_pid_probe(struct reg *);
|
||||
extern int fasttrap_return_probe(struct reg *);
|
||||
struct trapframe;
|
||||
extern int fasttrap_pid_probe(struct trapframe *);
|
||||
extern int fasttrap_return_probe(struct trapframe *);
|
||||
|
||||
extern uint64_t fasttrap_pid_getarg(void *, dtrace_id_t, void *, int, int);
|
||||
extern uint64_t fasttrap_usdt_getarg(void *, dtrace_id_t, void *, int, int);
|
||||
|
@ -961,14 +961,12 @@ fasttrap_do_seg(fasttrap_tracepoint_t *tp, struct reg *rp, uintptr_t *addr)
|
||||
}
|
||||
|
||||
int
|
||||
fasttrap_pid_probe(struct reg *rp)
|
||||
fasttrap_pid_probe(struct trapframe *tf)
|
||||
{
|
||||
proc_t *p = curproc;
|
||||
#ifndef illumos
|
||||
struct reg reg, *rp;
|
||||
proc_t *p = curproc, *pp;
|
||||
struct rm_priotracker tracker;
|
||||
proc_t *pp;
|
||||
#endif
|
||||
uintptr_t pc = rp->r_rip - 1;
|
||||
uintptr_t pc;
|
||||
uintptr_t new_pc = 0;
|
||||
fasttrap_bucket_t *bucket;
|
||||
#ifdef illumos
|
||||
@ -979,6 +977,11 @@ fasttrap_pid_probe(struct reg *rp)
|
||||
dtrace_icookie_t cookie;
|
||||
uint_t is_enabled = 0;
|
||||
|
||||
fill_frame_regs(tf, ®);
|
||||
rp = ®
|
||||
|
||||
pc = rp->r_rip - 1;
|
||||
|
||||
/*
|
||||
* It's possible that a user (in a veritable orgy of bad planning)
|
||||
* could redirect this thread's flow of control before it reached the
|
||||
@ -1783,12 +1786,16 @@ fasttrap_pid_probe(struct reg *rp)
|
||||
}
|
||||
|
||||
int
|
||||
fasttrap_return_probe(struct reg *rp)
|
||||
fasttrap_return_probe(struct trapframe *tf)
|
||||
{
|
||||
struct reg reg, *rp;
|
||||
proc_t *p = curproc;
|
||||
uintptr_t pc = curthread->t_dtrace_pc;
|
||||
uintptr_t npc = curthread->t_dtrace_npc;
|
||||
|
||||
fill_frame_regs(tf, ®);
|
||||
rp = ®
|
||||
|
||||
curthread->t_dtrace_pc = 0;
|
||||
curthread->t_dtrace_npc = 0;
|
||||
curthread->t_dtrace_scrpc = 0;
|
||||
@ -1808,9 +1815,7 @@ fasttrap_return_probe(struct reg *rp)
|
||||
/*
|
||||
* We set rp->r_rip to the address of the traced instruction so
|
||||
* that it appears to dtrace_probe() that we're on the original
|
||||
* instruction, and so that the user can't easily detect our
|
||||
* complex web of lies. dtrace_return_probe() (our caller)
|
||||
* will correctly set %pc after we return.
|
||||
* instruction.
|
||||
*/
|
||||
rp->r_rip = pc;
|
||||
|
||||
|
@ -328,8 +328,9 @@ fasttrap_branch_taken(int bo, int bi, struct reg *regs)
|
||||
|
||||
|
||||
int
|
||||
fasttrap_pid_probe(struct reg *rp)
|
||||
fasttrap_pid_probe(struct trapframe *frame)
|
||||
{
|
||||
struct reg reg, *rp;
|
||||
struct rm_priotracker tracker;
|
||||
proc_t *p = curproc;
|
||||
uintptr_t pc = rp->pc;
|
||||
@ -340,6 +341,9 @@ fasttrap_pid_probe(struct reg *rp)
|
||||
dtrace_icookie_t cookie;
|
||||
uint_t is_enabled = 0;
|
||||
|
||||
fill_regs(curthread, ®);
|
||||
rp = ®
|
||||
|
||||
/*
|
||||
* It's possible that a user (in a veritable orgy of bad planning)
|
||||
* could redirect this thread's flow of control before it reached the
|
||||
@ -515,8 +519,9 @@ fasttrap_pid_probe(struct reg *rp)
|
||||
}
|
||||
|
||||
int
|
||||
fasttrap_return_probe(struct reg *rp)
|
||||
fasttrap_return_probe(struct trapframe *tf)
|
||||
{
|
||||
struct reg reg, *rp;
|
||||
proc_t *p = curproc;
|
||||
uintptr_t pc = curthread->t_dtrace_pc;
|
||||
uintptr_t npc = curthread->t_dtrace_npc;
|
||||
@ -526,12 +531,13 @@ fasttrap_return_probe(struct reg *rp)
|
||||
curthread->t_dtrace_scrpc = 0;
|
||||
curthread->t_dtrace_astpc = 0;
|
||||
|
||||
fill_regs(curthread, ®);
|
||||
rp = ®
|
||||
|
||||
/*
|
||||
* We set rp->pc to the address of the traced instruction so
|
||||
* that it appears to dtrace_probe() that we're on the original
|
||||
* instruction, and so that the user can't easily detect our
|
||||
* complex web of lies. dtrace_return_probe() (our caller)
|
||||
* will correctly set %pc after we return.
|
||||
* instruction.
|
||||
*/
|
||||
rp->pc = pc;
|
||||
|
||||
@ -539,4 +545,3 @@ fasttrap_return_probe(struct reg *rp)
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -177,9 +177,6 @@ SYSCTL_INT(_machdep, OID_AUTO, uprintf_signal, CTLFLAG_RW,
|
||||
void
|
||||
trap(struct trapframe *frame)
|
||||
{
|
||||
#ifdef KDTRACE_HOOKS
|
||||
struct reg regs;
|
||||
#endif
|
||||
ksiginfo_t ksi;
|
||||
struct thread *td;
|
||||
struct proc *p;
|
||||
@ -327,9 +324,8 @@ trap(struct trapframe *frame)
|
||||
enable_intr();
|
||||
#ifdef KDTRACE_HOOKS
|
||||
if (type == T_BPTFLT) {
|
||||
fill_frame_regs(frame, ®s);
|
||||
if (dtrace_pid_probe_ptr != NULL &&
|
||||
dtrace_pid_probe_ptr(®s) == 0)
|
||||
dtrace_pid_probe_ptr(frame) == 0)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@ -497,9 +493,8 @@ trap(struct trapframe *frame)
|
||||
#ifdef KDTRACE_HOOKS
|
||||
case T_DTRACE_RET:
|
||||
enable_intr();
|
||||
fill_frame_regs(frame, ®s);
|
||||
if (dtrace_return_probe_ptr != NULL)
|
||||
dtrace_return_probe_ptr(®s);
|
||||
dtrace_return_probe_ptr(frame);
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
@ -303,9 +303,7 @@ trap(struct trapframe *frame)
|
||||
inst = fuword32((const void *)frame->srr0);
|
||||
if (inst == 0x0FFFDDDD &&
|
||||
dtrace_pid_probe_ptr != NULL) {
|
||||
struct reg regs;
|
||||
fill_regs(td, ®s);
|
||||
(*dtrace_pid_probe_ptr)(®s);
|
||||
(*dtrace_pid_probe_ptr)(frame);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
@ -39,7 +39,6 @@ struct trapframe;
|
||||
struct thread;
|
||||
struct vattr;
|
||||
struct vnode;
|
||||
struct reg;
|
||||
|
||||
int dtrace_trap(struct trapframe *, u_int);
|
||||
|
||||
@ -60,9 +59,9 @@ typedef void (*dtrace_doubletrap_func_t)(void);
|
||||
extern dtrace_doubletrap_func_t dtrace_doubletrap_func;
|
||||
|
||||
/* Pid provider hooks */
|
||||
typedef int (*dtrace_pid_probe_ptr_t)(struct reg *);
|
||||
typedef int (*dtrace_pid_probe_ptr_t)(struct trapframe *);
|
||||
extern dtrace_pid_probe_ptr_t dtrace_pid_probe_ptr;
|
||||
typedef int (*dtrace_return_probe_ptr_t)(struct reg *);
|
||||
typedef int (*dtrace_return_probe_ptr_t)(struct trapframe *);
|
||||
extern dtrace_return_probe_ptr_t dtrace_return_probe_ptr;
|
||||
|
||||
/* Virtual time hook function type. */
|
||||
|
Loading…
Reference in New Issue
Block a user