dtrace: Fix up %rip for invop probes on x86
When a breakpoint exception is raised, the saved value of %rip points to the instruction following the breakpoint. However, when fetching the value of %rip using regs[], it's more natural to provide the address of the breakpoint itself, so modify the kinst and fbt providers accordingly. Reported by: khng Reviewed by: christos, khng MFC after: 2 months Differential Revision: https://reviews.freebsd.org/D37218
This commit is contained in:
parent
05e640dc9e
commit
0e69c95915
@ -84,6 +84,12 @@ fbt_invop(uintptr_t addr, struct trapframe *frame, uintptr_t scratch __unused)
|
||||
if ((uintptr_t)fbt->fbtp_patchpoint != addr)
|
||||
continue;
|
||||
fbtrval = fbt->fbtp_rval;
|
||||
|
||||
/*
|
||||
* Report the address of the breakpoint for the benefit
|
||||
* of consumers fetching register values with regs[].
|
||||
*/
|
||||
frame->tf_rip--;
|
||||
for (; fbt != NULL; fbt = fbt->fbtp_tracenext) {
|
||||
ASSERT(fbt->fbtp_rval == fbtrval);
|
||||
if (fbt->fbtp_roffset == 0) {
|
||||
@ -143,6 +149,8 @@ fbt_invop(uintptr_t addr, struct trapframe *frame, uintptr_t scratch __unused)
|
||||
cpu->cpu_dtrace_caller = 0;
|
||||
}
|
||||
}
|
||||
/* Advance to the instruction following the breakpoint. */
|
||||
frame->tf_rip++;
|
||||
return (fbtrval);
|
||||
}
|
||||
|
||||
|
@ -139,6 +139,12 @@ kinst_invop(uintptr_t addr, struct trapframe *frame, uintptr_t scratch)
|
||||
if (kp == NULL)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Report the address of the breakpoint for the benefit of consumers
|
||||
* fetching register values with regs[].
|
||||
*/
|
||||
frame->tf_rip--;
|
||||
|
||||
DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
|
||||
cpu->cpu_dtrace_caller = stack[0];
|
||||
DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT | CPU_DTRACE_BADADDR);
|
||||
@ -162,7 +168,7 @@ kinst_invop(uintptr_t addr, struct trapframe *frame, uintptr_t scratch)
|
||||
|
||||
if (kpmd->reg1 == -1 && kpmd->reg2 == -1) {
|
||||
/* rip-relative */
|
||||
rval = frame->tf_rip - 1 + kpmd->instlen;
|
||||
rval = frame->tf_rip + kpmd->instlen;
|
||||
} else {
|
||||
/* indirect */
|
||||
rval = kinst_regval(frame, kpmd->reg1) +
|
||||
|
Loading…
Reference in New Issue
Block a user