aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Ostapenko <pm@igoro.pro>2023-10-03 16:48:00 +0000
committerMark Johnston <markj@FreeBSD.org>2023-10-03 17:07:41 +0000
commitb4db386f9fa7be9668aa09d14b0bbd048a7a7e89 (patch)
tree26b048a365461f4d7082e3f34cd49b1ba897e6c6
parent4862e8ac0223d7b19c8b3e070af1e2b38b18f333 (diff)
dtrace: fix fbt regression for aarch64
fbt computes incorrect instruction position for AArch64 kernel module symbol. The issue is with the for loop, it does an extra increment of instr pointer after the required instruction is found. Hence, a wrong instruction is targeted for patching. Signed-off-by: Igor Ostapenko <pm@igoro.pro> Fixes: 980746e5cb26 ("fbt: simplify arm64 function-prologue parsing") Reviewed by: markj Pull Request: https://github.com/freebsd/freebsd-src/pull/855 MFC after: 1 week
-rw-r--r--sys/cddl/dev/fbt/aarch64/fbt_isa.c17
1 files changed, 8 insertions, 9 deletions
diff --git a/sys/cddl/dev/fbt/aarch64/fbt_isa.c b/sys/cddl/dev/fbt/aarch64/fbt_isa.c
index 4094ea43a9fe..44690b97f77a 100644
--- a/sys/cddl/dev/fbt/aarch64/fbt_isa.c
+++ b/sys/cddl/dev/fbt/aarch64/fbt_isa.c
@@ -90,7 +90,6 @@ fbt_provide_module_function(linker_file_t lf, int symindx,
uint32_t *instr, *limit;
const char *name;
char *modname;
- bool found;
int offs;
modname = opaque;
@@ -119,16 +118,16 @@ fbt_provide_module_function(linker_file_t lf, int symindx,
if ((*instr & BTI_MASK) == BTI_INSTR)
instr++;
- /* Look for stp (pre-indexed) operation */
- found = false;
/*
* 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;
- for (; !found && instr < limit; instr++) {
+ goto found;
+
+ /* Look for stp (pre-indexed) or sub operation */
+ for (; instr < limit; instr++) {
/*
* Functions start with "stp xt1, xt2, [xn, <const>]!" or
* "sub sp, sp, <const>".
@@ -142,14 +141,14 @@ fbt_provide_module_function(linker_file_t lf, int symindx,
* past the function prologue.
*/
if (((*instr >> ADDR_SHIFT) & ADDR_MASK) == 31)
- found = true;
+ break;
} else 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;
}
-
- if (!found)
+found:
+ if (instr >= limit)
return (0);
fbt = malloc(sizeof (fbt_probe_t), M_FBT, M_WAITOK | M_ZERO);