Module Name:src
Committed By: riastradh
Date: Mon May 22 15:12:54 UTC 2023
Modified Files:
src/external/cddl/osnet/dev/fbt/arm: fbt_isa.c
Log Message:
dtrace_fbt: Read and write instructions appropriately-endian on arm.
arm is a little more complicated because it has three cases:
- big-endian data, big-endian instructions
- big-endian data, little-endian instructions
- little-endian data, little-endian instructions
To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/external/cddl/osnet/dev/fbt/arm/fbt_isa.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/external/cddl/osnet/dev/fbt/arm/fbt_isa.c
diff -u src/external/cddl/osnet/dev/fbt/arm/fbt_isa.c:1.1 src/external/cddl/osnet/dev/fbt/arm/fbt_isa.c:1.2
--- src/external/cddl/osnet/dev/fbt/arm/fbt_isa.c:1.1 Mon May 28 23:47:39 2018
+++ src/external/cddl/osnet/dev/fbt/arm/fbt_isa.c Mon May 22 15:12:54 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: fbt_isa.c,v 1.1 2018/05/28 23:47:39 chs Exp $ */
+/* $NetBSD: fbt_isa.c,v 1.2 2023/05/22 15:12:54 riastradh Exp $ */
/*
* CDDL HEADER START
@@ -56,6 +56,26 @@
#define FBT_ENTRY "entry"
#define FBT_RETURN "return"
+static uint32_t
+ldinstr(const uint32_t *instr)
+{
+#ifdef _ARM_ARCH_BE8 /* big-endian data, big-endian instructions */
+ return *instr;
+#else/* little-endian instructions */
+ return le32toh(*instr);
+#endif
+}
+
+static void
+stinstr(uint32_t *instr, uint32_t val)
+{
+
+#ifdef _ARM_ARCH_BE8 /* big-endian data, big-endian instructions */
+ val = bswap32(val);
+#endif
+ ktext_write(instr, , sizeof(val)); /* write little-endian */
+}
+
int
fbt_invop(uintptr_t addr, struct trapframe *frame, uintptr_t rval)
{
@@ -98,9 +118,7 @@ fbt_patch_tracepoint(fbt_probe_t *fbt, f
dtrace_icookie_t c;
c = dtrace_interrupt_disable();
-
- ktext_write(fbt->fbtp_patchpoint, , sizeof (val));
-
+ stinstr(fbt->fbtp_patchpoint, val);
dtrace_interrupt_enable(c);
}
@@ -126,14 +144,14 @@ fbt_provide_module_function(linker_file_
* va_arg functions has first instruction of
* sub sp, sp, #?
*/
- if ((*instr & 0xf000) == FBT_SUBSP)
+ if ((ldinstr(instr) & 0xf000) == FBT_SUBSP)
instr++;
/*
* check if insn is a pushm with LR
*/
- if ((*instr & 0x) != FBT_PUSHM ||
- (*instr & (1 << LR)) == 0)
+ if ((ldinstr(instr) & 0x) != FBT_PUSHM ||
+ (ldinstr(instr) & (1 << LR)) == 0)
return (0);
fbt = kmem_zalloc(sizeof (fbt_probe_t), KM_SLEEP);
@@ -143,7 +161,7 @@ fbt_provide_module_function(linker_file_
fbt->fbtp_patchpoint = instr;
fbt->fbtp_ctl = lf;
fbt->fbtp_loadcnt = lf->loadcnt;
- fbt->fbtp_savedval = *instr;
+ fbt->fbtp_savedval = ldinstr(instr);
fbt->fbtp_patchval = FBT_BREAKPOINT;
fbt->fbtp_rval = DTRACE_INVOP_PUSHM;
fbt->fbtp_symindx = symindx;
@@ -153,18 +171,18 @@ fbt_provide_module_function(linker_file_
lf->fbt_nentries++;
- popm = FBT_POPM | ((*instr) & 0x3FFF) | 0x8000;
+ popm = FBT_POPM | (ldinstr(instr) & 0x3FFF) | 0x8000;
retfbt = NULL;
again:
for (; instr < limit; instr++) {
- if (*instr == popm)
+ if (ldinstr(instr) == popm)
break;
- else if ((*instr & 0xff00) == FBT_JUMP) {
+ else if ((ldinstr(instr) & 0xff00) == FBT_JUMP) {
uint32_t *target, *start;
int offset;
- offset = (*instr & 0xff);
+ offset = (ldinstr(instr) & 0xff);
offset <<= 8;
offset /= 64;
target = instr + (2 + offset);
@@ -195,11 +213,11 @@ again:
fbt->fbtp_ctl = lf;
fbt->fbtp_loadcnt = lf->loadcnt;
fbt->fbtp_symindx = symindx;
- if ((*instr & 0xff00) == FBT_JUMP)
+ if ((ldinstr(instr) & 0xff00) == FBT_JUMP)
fbt->fbtp_rval = DTRACE_INVOP_B;
else
fbt->fbtp_rval = DTRACE_INVOP_POPM;
- fbt->fbtp_savedval = *instr;
+ fbt->fbtp_savedval = ldinstr(instr);
fbt->fbtp_patchval = FBT_BREAKPOINT;
fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];
fbt_probetab[FBT_ADDR2NDX(instr)] = fbt;
@@ -279,14 +297,14 @@ fbt_provide_module_cb(const char *name,
instr = (uint32_t *) value;
limit = (uint32_t *)((uintptr_t)value + symsize);
- if (!FBT_MOV_IP_SP_P(*instr)
- && !FBT_BX_LR_P(*instr)
- && !FBT_MOVW_P(*instr)
- && !FBT_MOV_IMM_P(*instr)
- && !FBT_B_LABEL_P(*instr)
- && !FBT_LDR_IMM_P(*instr)
- && !FBT_CMP_IMM_P(*instr)
- && !FBT_PUSH_P(*instr)
+ if (!FBT_MOV_IP_SP_P(ldinstr(instr))
+ && !FBT_BX_LR_P(ldinstr(instr))
+ && !FBT_MOVW_P(ldinstr(instr))
+ && !FBT_MOV_IMM_P(ldinstr(instr))
+ && !FBT_B_LABEL_P(ldinstr(instr))
+ && !FBT_LDR_IMM_P(ldinstr(instr))
+ && !FBT_CMP_IMM_P(ldinstr(instr))
+ && !FBT_PUSH_P(ldinstr(instr))
) {
return 0;
}
@@ -298,31 +316,39 @@ fbt_provide_module_cb(const char *name,
fbt->fbtp_patchpoint = instr;
fbt->fbtp_ctl = mod;
/* fbt->fbtp_loadcnt = lf->loadcnt; */
- if (FBT_MOV_IP_SP_P(*instr))
- fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_MOV_IP_SP);
- else if