diff options
author | Mitchell Horne <mhorne@FreeBSD.org> | 2023-02-06 18:23:42 +0000 |
---|---|---|
committer | Mitchell Horne <mhorne@FreeBSD.org> | 2023-02-15 16:41:39 +0000 |
commit | 3b0fb298fec6f1e82bec178e78be6072f310c28d (patch) | |
tree | 93f28f414eb574031070cb3659ba6a0fae8da89b | |
parent | ed44d21ee8473f7b73d8160287e2012e2f797bea (diff) | |
download | src-3b0fb298fec6f1e82bec178e78be6072f310c28d.tar.gz src-3b0fb298fec6f1e82bec178e78be6072f310c28d.zip |
dtrace: implement riscv dtrace_getustackdepth()
Pretty trivial following other implementations. The existing
dtrace_getustack_common() does most of the work.
Reviewed by: markj
MFC after: 1 week
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D38303
(cherry picked from commit c6943b44f7d73176acd2e36e0615e1b2ded02c0a)
-rw-r--r-- | sys/cddl/dev/dtrace/riscv/dtrace_isa.c | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/sys/cddl/dev/dtrace/riscv/dtrace_isa.c b/sys/cddl/dev/dtrace/riscv/dtrace_isa.c index 6d44a0cee9ee..6e6459a8ce74 100644 --- a/sys/cddl/dev/dtrace/riscv/dtrace_isa.c +++ b/sys/cddl/dev/dtrace/riscv/dtrace_isa.c @@ -169,7 +169,7 @@ dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit) { volatile uint16_t *flags; struct trapframe *tf; - uintptr_t pc, sp, fp; + uintptr_t pc, fp; proc_t *p; int n; @@ -195,7 +195,6 @@ dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit) return; pc = tf->tf_sepc; - sp = tf->tf_sp; fp = tf->tf_s[0]; if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) { @@ -207,7 +206,6 @@ dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit) * at the current stack pointer address since the call * instruction puts it there right before the branch. */ - *pcstack++ = (uint64_t)pc; pcstack_limit--; if (pcstack_limit <= 0) @@ -231,8 +229,33 @@ zero: int dtrace_getustackdepth(void) { + struct trapframe *tf; + uintptr_t pc, fp; + int n = 0; - printf("IMPLEMENT ME: %s\n", __func__); + if (curproc == NULL || (tf = curthread->td_frame) == NULL) + return (0); + + if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_FAULT)) + return (-1); + + pc = tf->tf_sepc; + fp = tf->tf_s[0]; + + if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) { + /* + * In an entry probe. The frame pointer has not yet been + * pushed (that happens in the function prologue). The + * best approach is to add the current pc as a missing top + * of stack and back the pc up to the caller, which is stored + * at the current stack pointer address since the call + * instruction puts it there right before the branch. + */ + pc = tf->tf_ra; + n++; + } + + n += dtrace_getustack_common(NULL, 0, pc, fp); return (0); } |