git: c6943b44f7d7 - main - dtrace: implement riscv dtrace_getustackdepth()

From: Mitchell Horne <mhorne_at_FreeBSD.org>
Date: Mon, 06 Feb 2023 19:28:09 UTC
The branch main has been updated by mhorne:

URL: https://cgit.FreeBSD.org/src/commit/?id=c6943b44f7d73176acd2e36e0615e1b2ded02c0a

commit c6943b44f7d73176acd2e36e0615e1b2ded02c0a
Author:     Mitchell Horne <mhorne@FreeBSD.org>
AuthorDate: 2023-02-06 18:23:42 +0000
Commit:     Mitchell Horne <mhorne@FreeBSD.org>
CommitDate: 2023-02-06 19:26:53 +0000

    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
---
 sys/cddl/dev/dtrace/riscv/dtrace_isa.c | 31 +++++++++++++++++++++++++++----
 1 file 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);
 }