aboutsummaryrefslogtreecommitdiff
path: root/sys/cddl
diff options
context:
space:
mode:
authorAndrew Turner <andrew@FreeBSD.org>2021-01-13 11:08:19 +0000
committerAndrew Turner <andrew@FreeBSD.org>2021-03-03 14:18:03 +0000
commit28d945204ea1014d7de6906af8470ed8b3311335 (patch)
tree34ce7d6f3c96679c9879539468a28a7690311080 /sys/cddl
parent48ba9b2669e6a92a3254ec34461d0d86fb20b9f4 (diff)
downloadsrc-28d945204ea1014d7de6906af8470ed8b3311335.tar.gz
src-28d945204ea1014d7de6906af8470ed8b3311335.zip
Handle functions that use a nop in the arm64 fbt
To trace leaf asm functions we can insert a single nop instruction as the first instruction in a function and trigger off this. Reviewed by: gnn Sponsored by: Innovate UK Differential Revision: https://reviews.freebsd.org/D28132
Diffstat (limited to 'sys/cddl')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h2
-rw-r--r--sys/cddl/dev/dtrace/aarch64/dtrace_subr.c5
-rw-r--r--sys/cddl/dev/fbt/aarch64/fbt_isa.c51
3 files changed, 39 insertions, 19 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
index 2bedd01cf3e7..f15a971f12be 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
@@ -2466,6 +2466,8 @@ extern void dtrace_helpers_destroy(proc_t *);
#define B_DATA_MASK 0x00ffffff
#define B_INSTR 0x14000000
+#define NOP_INSTR 0xd503201f
+
#define RET_INSTR 0xd65f03c0
#define SUB_MASK 0xffc00000
diff --git a/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c b/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c
index 9bf9f0798bb5..58d33511560b 100644
--- a/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c
+++ b/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c
@@ -314,6 +314,11 @@ dtrace_invop_start(struct trapframe *frame)
return (0);
}
+ if (invop == NOP_INSTR) {
+ 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 f15bc12291d3..12be95ea2217 100644
--- a/sys/cddl/dev/fbt/aarch64/fbt_isa.c
+++ b/sys/cddl/dev/fbt/aarch64/fbt_isa.c
@@ -110,28 +110,41 @@ fbt_provide_module_function(linker_file_t lf, int symindx,
/* Look for stp (pre-indexed) operation */
found = false;
- for (; instr < limit; instr++) {
- /* Some functions start with "stp xt1, xt2, [xn, <const>]!" */
- if ((*instr & LDP_STP_MASK) == STP_64) {
+ /*
+ * If the first instruction is a nop it's a specially marked
+ * asm function. We only support a nop first as it's not a normal
+ * part of the function prologue.
+ */
+ if (*instr == NOP_INSTR)
+ found = true;
+ if (!found) {
+ for (; instr < limit; instr++) {
/*
- * Assume any other store of this type means we
- * are past the function prolog.
+ * Some functions start with
+ * "stp xt1, xt2, [xn, <const>]!"
*/
- if (((*instr >> ADDR_SHIFT) & ADDR_MASK) == 31)
- found = true;
- break;
- }
+ if ((*instr & LDP_STP_MASK) == STP_64) {
+ /*
+ * Assume any other store of this type means we
+ * are past the function prolog.
+ */
+ if (((*instr >> ADDR_SHIFT) & ADDR_MASK) == 31)
+ 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;
+ /*
+ * 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;
+ }
}
}