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
This commit is contained in:
@@ -22,6 +22,7 @@
|
|||||||
#include "kinst.h"
|
#include "kinst.h"
|
||||||
|
|
||||||
#define KINST_PUSHL_RBP 0x55
|
#define KINST_PUSHL_RBP 0x55
|
||||||
|
#define KINST_POPL_RBP 0x5d
|
||||||
#define KINST_STI 0xfb
|
#define KINST_STI 0xfb
|
||||||
#define KINST_POPF 0x9d
|
#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;
|
dtrace_kinst_probedesc_t *pd;
|
||||||
const char *func;
|
const char *func;
|
||||||
int error, instrsize, n, off;
|
int error, instrsize, n, off;
|
||||||
uint8_t *instr, *limit;
|
uint8_t *instr, *limit, *tmp;
|
||||||
|
bool push_found, pop_found;
|
||||||
|
|
||||||
pd = opaque;
|
pd = opaque;
|
||||||
func = symval->name;
|
func = symval->name;
|
||||||
@@ -515,12 +517,21 @@ kinst_make_probe(linker_file_t lf, int symindx, linker_symval_t *symval,
|
|||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ignore functions not beginning with the usual function prologue.
|
* Refuse to instrument functions lacking the usual frame pointer
|
||||||
* These might correspond to exception handlers with which we should not
|
* manipulations since they might correspond to exception handlers.
|
||||||
* meddle. This does however exclude functions which can be safely
|
|
||||||
* traced, such as cpu_switch().
|
|
||||||
*/
|
*/
|
||||||
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);
|
return (0);
|
||||||
|
|
||||||
n = 0;
|
n = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user