diff options
author | Christos Margiolis <christos@FreeBSD.org> | 2023-07-19 14:53:08 +0000 |
---|---|---|
committer | Christos Margiolis <christos@FreeBSD.org> | 2023-07-19 14:53:08 +0000 |
commit | ea89133dbc5f29cbb8db48ecc09a47ea22d8aa9e (patch) | |
tree | ecf9eb5494b54cefe62646ee134166021c533456 | |
parent | 8ada3f78e68fe8827d6c84e9fd5f808f93984ca7 (diff) | |
download | src-ea89133dbc5f29cbb8db48ecc09a47ea22d8aa9e.tar.gz src-ea89133dbc5f29cbb8db48ecc09a47ea22d8aa9e.zip |
kinst: check for 'push %rbp' anywhere in the function
Currently kinst checks if only the first instruction is 'push %rbp',
essentially excluding functions that do push RBP, but not in the first
instruction. This patch modifies kinst to check for 'push %rbp', as
well, as a following 'pop %rbp', anywhere in the function. This behavior
also matches that of FBT.
Reviewed by: markj
Approved by: markj (mentor)
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D40283
-rw-r--r-- | sys/cddl/dev/kinst/amd64/kinst_isa.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/sys/cddl/dev/kinst/amd64/kinst_isa.c b/sys/cddl/dev/kinst/amd64/kinst_isa.c index 908dc79e9247..398f30a281c0 100644 --- a/sys/cddl/dev/kinst/amd64/kinst_isa.c +++ b/sys/cddl/dev/kinst/amd64/kinst_isa.c @@ -22,6 +22,7 @@ #include "kinst.h" #define KINST_PUSHL_RBP 0x55 +#define KINST_POPL_RBP 0x5d #define KINST_STI 0xfb #define KINST_POPF 0x9d @@ -500,7 +501,8 @@ kinst_make_probe(linker_file_t lf, int symindx, linker_symval_t *symval, dtrace_kinst_probedesc_t *pd; const char *func; int error, instrsize, n, off; - uint8_t *instr, *limit; + uint8_t *instr, *limit, *tmp; + bool push_found, pop_found; pd = opaque; func = symval->name; @@ -515,12 +517,21 @@ kinst_make_probe(linker_file_t lf, int symindx, linker_symval_t *symval, 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(). + * Refuse to instrument functions lacking the usual frame pointer + * manipulations since they might correspond to exception handlers. */ - if (*instr != KINST_PUSHL_RBP) + tmp = instr; + push_found = pop_found = false; + while (tmp < limit) { + if (*tmp == KINST_PUSHL_RBP) + push_found = true; + else if (*tmp == KINST_POPL_RBP) + pop_found = true; + if (push_found && pop_found) + break; + tmp += dtrace_instr_size(tmp); + } + if (!push_found || !pop_found) return (0); n = 0; |