diff --git a/sys/cddl/dev/kinst/amd64/kinst_isa.c b/sys/cddl/dev/kinst/amd64/kinst_isa.c --- a/sys/cddl/dev/kinst/amd64/kinst_isa.c +++ b/sys/cddl/dev/kinst/amd64/kinst_isa.c @@ -500,6 +500,29 @@ return (0); } + +/* + * Instead of ignoring functions that do not `push %rbp` in their first + * instruction right away, we check if there's a `push %rbp` anywhere in the + * function. Functions that do not push the frame pointer might correspond to + * exception handlers with which we should not meddle. + * + * FIXME: This does however exclude functions which can be safely traced, such + * as cpu_switch() and leaf functions compiled without + * `-mno-omit-leaf-frame-pointer`. + */ +static bool +kinst_can_trace_func(uint8_t *instr, uint8_t *limit) +{ + uint8_t *p; + + for (p = instr; p < limit; p += dtrace_instr_size(p)) + if (*p == KINST_PUSHL_RBP) + return (true); + + return (false); +} + int kinst_make_probe(linker_file_t lf, int symindx, linker_symval_t *symval, void *opaque) @@ -520,13 +543,7 @@ if (instr >= limit) return (0); - /* - * Ignore functions not beginning with the usual function prologue. - * These might correspond to exception handlers with which we should not - * meddle. This does however exclude functions which can be safely - * traced, such as cpu_switch(). - */ - if (*instr != KINST_PUSHL_RBP) + if (!kinst_can_trace_func(instr, limit)) return (0); n = 0;