diff options
author | Andrew Turner <andrew@FreeBSD.org> | 2021-12-14 15:49:07 +0000 |
---|---|---|
committer | Andrew Turner <andrew@FreeBSD.org> | 2021-12-14 16:32:12 +0000 |
commit | e3ccf4f9dee9ae39774639407264199a07fa41ff (patch) | |
tree | cd1230b73608fc2b2627b245251478cff7c04c3d /sys/cddl/dev | |
parent | 06c95f1facd191ad62fb5c1854342d02d084166d (diff) | |
download | src-e3ccf4f9dee9ae39774639407264199a07fa41ff.tar.gz src-e3ccf4f9dee9ae39774639407264199a07fa41ff.zip |
Fix dtrace fbt return probes on arm64
As with arm and riscv fix return fbt probes on arm64. arg0 should be
the offset within the function of the return instruction and arg1
should be the return value.
Reviewed by: kp, markj
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D33440
Diffstat (limited to 'sys/cddl/dev')
-rw-r--r-- | sys/cddl/dev/dtrace/aarch64/dtrace_subr.c | 2 | ||||
-rw-r--r-- | sys/cddl/dev/fbt/aarch64/fbt_isa.c | 16 |
2 files changed, 12 insertions, 6 deletions
diff --git a/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c b/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c index 58d33511560b..74b3bf7ed7d1 100644 --- a/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c +++ b/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c @@ -270,7 +270,7 @@ dtrace_invop_start(struct trapframe *frame) int tmp; int i; - invop = dtrace_invop(frame->tf_elr, frame, frame->tf_elr); + invop = dtrace_invop(frame->tf_elr, frame, frame->tf_x[0]); tmp = (invop & LDP_STP_MASK); if (tmp == STP_64 || tmp == LDP_64) { diff --git a/sys/cddl/dev/fbt/aarch64/fbt_isa.c b/sys/cddl/dev/fbt/aarch64/fbt_isa.c index 4d22f1d584d3..d00aabf0cc81 100644 --- a/sys/cddl/dev/fbt/aarch64/fbt_isa.c +++ b/sys/cddl/dev/fbt/aarch64/fbt_isa.c @@ -56,16 +56,21 @@ fbt_invop(uintptr_t addr, struct trapframe *frame, uintptr_t rval) fbt = fbt_probetab[FBT_ADDR2NDX(addr)]; for (; fbt != NULL; fbt = fbt->fbtp_hashnext) { - if ((uintptr_t)fbt->fbtp_patchpoint == addr) { - cpu->cpu_dtrace_caller = addr; + if ((uintptr_t)fbt->fbtp_patchpoint != addr) + continue; + cpu->cpu_dtrace_caller = addr; + + if (fbt->fbtp_roffset == 0) { dtrace_probe(fbt->fbtp_id, frame->tf_x[0], frame->tf_x[1], frame->tf_x[2], frame->tf_x[3], frame->tf_x[4]); - - cpu->cpu_dtrace_caller = 0; - return (fbt->fbtp_savedval); + } else { + dtrace_probe(fbt->fbtp_id, fbt->fbtp_roffset, rval, + 0, 0, 0); } + cpu->cpu_dtrace_caller = 0; + return (fbt->fbtp_savedval); } return (0); @@ -216,6 +221,7 @@ again: fbt->fbtp_rval = DTRACE_INVOP_B; else fbt->fbtp_rval = DTRACE_INVOP_RET; + fbt->fbtp_roffset = (uintptr_t)instr - (uintptr_t)symval->value; fbt->fbtp_savedval = *instr; fbt->fbtp_patchval = FBT_PATCHVAL; fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)]; |