git: c00ec4dab276 - main - Handle using a sub instruction in the arm64 fbt

Andrew Turner andrew at FreeBSD.org
Tue Jan 12 12:48:43 UTC 2021


The branch main has been updated by andrew:

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

commit c00ec4dab276414ccc8a0712dd2f836bb17349d7
Author:     Andrew Turner <andrew at FreeBSD.org>
AuthorDate: 2021-01-12 12:14:09 +0000
Commit:     Andrew Turner <andrew at FreeBSD.org>
CommitDate: 2021-01-12 12:42:23 +0000

    Handle using a sub instruction in the arm64 fbt
    
    Some stack frames are too large for a store pair instruction we already
    detect in the arm64 fbt code. Add support for handling subtracting the
    stack pointer directly.
    
    Sponsored by:   Innovate UK
---
 sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h |  9 +++++++++
 sys/cddl/dev/dtrace/aarch64/dtrace_subr.c            |  6 ++++++
 sys/cddl/dev/fbt/aarch64/fbt_isa.c                   | 17 ++++++++++++++++-
 3 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
index 922c1a9bba9b..2bedd01cf3e7 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
@@ -2468,6 +2468,14 @@ extern void dtrace_helpers_destroy(proc_t *);
 
 #define	RET_INSTR	0xd65f03c0
 
+#define	SUB_MASK	0xffc00000
+#define	SUB_INSTR	0xd1000000
+#define	SUB_RD_SHIFT	0
+#define	SUB_RN_SHIFT	5
+#define	SUB_R_MASK	0x1f
+#define	SUB_IMM_SHIFT	10
+#define	SUB_IMM_MASK	0xfff
+
 #define	LDP_STP_MASK	0xffc00000
 #define	STP_32		0x29800000
 #define	STP_64		0xa9800000
@@ -2488,6 +2496,7 @@ extern void dtrace_helpers_destroy(proc_t *);
 #define	DTRACE_INVOP_STP	1
 #define	DTRACE_INVOP_RET	2
 #define	DTRACE_INVOP_B		3
+#define	DTRACE_INVOP_SUB	4
 
 #elif defined(__mips__)
 
diff --git a/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c b/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c
index 2d59b29b850b..6646e51fc191 100644
--- a/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c
+++ b/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c
@@ -305,6 +305,12 @@ dtrace_invop_start(struct trapframe *frame)
 		return (0);
 	}
 
+	if ((invop & SUB_MASK) == SUB_INSTR) {
+		frame->tf_sp -= (invop >> SUB_IMM_SHIFT) & SUB_IMM_MASK;
+		frame->tf_elr += INSN_SIZE;
+		return (0);
+	}
+
 	if ((invop & B_MASK) == B_INSTR) {
 		data = (invop & B_DATA_MASK);
 		/* The data is the number of 4-byte words to change the pc */
diff --git a/sys/cddl/dev/fbt/aarch64/fbt_isa.c b/sys/cddl/dev/fbt/aarch64/fbt_isa.c
index 9235af1a4c65..f15bc12291d3 100644
--- a/sys/cddl/dev/fbt/aarch64/fbt_isa.c
+++ b/sys/cddl/dev/fbt/aarch64/fbt_isa.c
@@ -121,6 +121,18 @@ fbt_provide_module_function(linker_file_t lf, int symindx,
 				found = true;
 			break;
 		}
+
+		/*
+		 * Some functions start with a "sub sp, sp, <const>"
+		 * Sometimes the compiler will have a sub instruction that
+		 * is not of the above type so don't stop if we see one.
+		 */
+		if ((*instr & SUB_MASK) == SUB_INSTR &&
+		    ((*instr >> SUB_RD_SHIFT) & SUB_R_MASK) == 31 &&
+		    ((*instr >> SUB_RN_SHIFT) & SUB_R_MASK) == 31) {
+			found = true;
+			break;
+		}
 	}
 
 	if (!found)
@@ -135,7 +147,10 @@ fbt_provide_module_function(linker_file_t lf, int symindx,
 	fbt->fbtp_loadcnt = lf->loadcnt;
 	fbt->fbtp_savedval = *instr;
 	fbt->fbtp_patchval = FBT_PATCHVAL;
-	fbt->fbtp_rval = DTRACE_INVOP_STP;
+	if ((*instr & SUB_MASK) == SUB_INSTR)
+		fbt->fbtp_rval = DTRACE_INVOP_SUB;
+	else
+		fbt->fbtp_rval = DTRACE_INVOP_STP;
 	fbt->fbtp_symindx = symindx;
 
 	fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];


More information about the dev-commits-src-all mailing list