aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitchell Horne <mhorne@FreeBSD.org>2023-02-06 18:23:42 +0000
committerMitchell Horne <mhorne@FreeBSD.org>2023-02-15 16:41:39 +0000
commit3b0fb298fec6f1e82bec178e78be6072f310c28d (patch)
tree93f28f414eb574031070cb3659ba6a0fae8da89b
parented44d21ee8473f7b73d8160287e2012e2f797bea (diff)
downloadsrc-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.c31
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);
}