aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndriy Gapon <avg@FreeBSD.org>2020-07-21 07:41:36 +0000
committerAndriy Gapon <avg@FreeBSD.org>2020-07-21 07:41:36 +0000
commit2032c532aad7def4246282ff51cc36ac6f2c5db0 (patch)
treec94037059b92d718a3e463ac9e066ae5a2ad3cfc
parente57f9c8a9f9b9dc233428d2f86d71d9c2e6b62eb (diff)
downloadsrc-2032c532aad7def4246282ff51cc36ac6f2c5db0.tar.gz
src-2032c532aad7def4246282ff51cc36ac6f2c5db0.zip
dtrace/fbt: fix return probe arguments on arm
arg0 should be an offset of the return point within the function, arg1 should be the return value. Previously the return probe had arguments as if for the entry probe. Tested on armv7. andrew noted that the same problem seems to be present on arm64, mips, and riscv. I am not sure if I will get around to fixing those. So, platform users or anyone looking to make a contribution please be aware of this opportunity. Reviewed by: markj MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D25685
Notes
Notes: svn path=/head/; revision=363383
-rw-r--r--sys/cddl/dev/dtrace/arm/dtrace_subr.c2
-rw-r--r--sys/cddl/dev/fbt/arm/fbt_isa.c18
2 files changed, 13 insertions, 7 deletions
diff --git a/sys/cddl/dev/dtrace/arm/dtrace_subr.c b/sys/cddl/dev/dtrace/arm/dtrace_subr.c
index be999e3a07a9..8cd9c9c1f204 100644
--- a/sys/cddl/dev/dtrace/arm/dtrace_subr.c
+++ b/sys/cddl/dev/dtrace/arm/dtrace_subr.c
@@ -248,7 +248,7 @@ dtrace_invop_start(struct trapframe *frame)
register_t *r0, *sp;
int data, invop, reg, update_sp;
- invop = dtrace_invop(frame->tf_pc, frame, frame->tf_pc);
+ invop = dtrace_invop(frame->tf_pc, frame, frame->tf_r0);
switch (invop & DTRACE_INVOP_MASK) {
case DTRACE_INVOP_PUSHM:
sp = (register_t *)frame->tf_svc_sp;
diff --git a/sys/cddl/dev/fbt/arm/fbt_isa.c b/sys/cddl/dev/fbt/arm/fbt_isa.c
index dc1abf3cf786..0be28b56aa6a 100644
--- a/sys/cddl/dev/fbt/arm/fbt_isa.c
+++ b/sys/cddl/dev/fbt/arm/fbt_isa.c
@@ -56,9 +56,12 @@ fbt_invop(uintptr_t addr, struct trapframe *frame, uintptr_t rval)
register_t fifthparam;
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) {
/* Get 5th parameter from stack */
DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
fifthparam = *(register_t *)frame->tf_svc_sp;
@@ -67,11 +70,13 @@ fbt_invop(uintptr_t addr, struct trapframe *frame, uintptr_t rval)
dtrace_probe(fbt->fbtp_id, frame->tf_r0,
frame->tf_r1, frame->tf_r2,
frame->tf_r3, fifthparam);
-
- cpu->cpu_dtrace_caller = 0;
-
- return (fbt->fbtp_rval | (fbt->fbtp_savedval << DTRACE_INVOP_SHIFT));
+ } else {
+ dtrace_probe(fbt->fbtp_id, fbt->fbtp_roffset, rval,
+ 0, 0, 0);
}
+
+ cpu->cpu_dtrace_caller = 0;
+ return (fbt->fbtp_rval | (fbt->fbtp_savedval << DTRACE_INVOP_SHIFT));
}
return (0);
@@ -178,6 +183,7 @@ again:
fbt->fbtp_rval = DTRACE_INVOP_B;
else
fbt->fbtp_rval = DTRACE_INVOP_POPM;
+ fbt->fbtp_roffset = (uintptr_t)instr - (uintptr_t)symval->value;
fbt->fbtp_savedval = *instr;
fbt->fbtp_patchval = FBT_BREAKPOINT;
fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];