Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 19 Jul 2023 14:59:49 GMT
From:      Christos Margiolis <christos@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: ea89133dbc5f - main - kinst: check for 'push %rbp' anywhere in the function
Message-ID:  <202307191459.36JExn2c067547@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by christos:

URL: https://cgit.FreeBSD.org/src/commit/?id=ea89133dbc5f29cbb8db48ecc09a47ea22d8aa9e

commit ea89133dbc5f29cbb8db48ecc09a47ea22d8aa9e
Author:     Christos Margiolis <christos@FreeBSD.org>
AuthorDate: 2023-07-19 14:53:08 +0000
Commit:     Christos Margiolis <christos@FreeBSD.org>
CommitDate: 2023-07-19 14:53:08 +0000

    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
---
 sys/cddl/dev/kinst/amd64/kinst_isa.c | 23 +++++++++++++++++------
 1 file 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;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202307191459.36JExn2c067547>