diff --git a/sys/arm64/include/asm.h b/sys/arm64/include/asm.h --- a/sys/arm64/include/asm.h +++ b/sys/arm64/include/asm.h @@ -38,9 +38,15 @@ #define _C_LABEL(x) x +#ifdef KDTRACE_HOOKS +#define DTRACE_NOP nop +#else +#define DTRACE_NOP +#endif + #define LENTRY(sym) \ .text; .align 2; .type sym,#function; sym: \ - .cfi_startproc + .cfi_startproc; DTRACE_NOP #define ENTRY(sym) \ .globl sym; LENTRY(sym) #define EENTRY(sym) \ diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h --- a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h @@ -2466,6 +2466,8 @@ #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 --- a/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c +++ b/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c @@ -314,6 +314,11 @@ 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 --- a/sys/cddl/dev/fbt/aarch64/fbt_isa.c +++ b/sys/cddl/dev/fbt/aarch64/fbt_isa.c @@ -110,28 +110,41 @@ /* Look for stp (pre-indexed) operation */ found = false; - for (; instr < limit; instr++) { - /* Some functions start with "stp xt1, xt2, [xn, ]!" */ - 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, ]!" */ - 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, " - * 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, " + * 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; + } } }