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, &val, 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, &val, 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 & 0xfffff000) == FBT_SUBSP) + if ((ldinstr(instr) & 0xfffff000) == FBT_SUBSP) instr++; /* * check if insn is a pushm with LR */ - if ((*instr & 0xffff0000) != FBT_PUSHM || - (*instr & (1 << LR)) == 0) + if ((ldinstr(instr) & 0xffff0000) != 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 & 0xff000000) == FBT_JUMP) { + else if ((ldinstr(instr) & 0xff000000) == FBT_JUMP) { uint32_t *target, *start; int offset; - offset = (*instr & 0xffffff); + offset = (ldinstr(instr) & 0xffffff); 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 & 0xff000000) == FBT_JUMP) + if ((ldinstr(instr) & 0xff000000) == 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 (FBT_LDR_IMM_P(*instr)) - fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_LDR_IMM); - else if (FBT_MOVW_P(*instr)) - fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_MOVW); - else if (FBT_MOV_IMM_P(*instr)) - fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_MOV_IMM); - else if (FBT_CMP_IMM_P(*instr)) - fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_CMP_IMM); - else if (FBT_BX_LR_P(*instr)) - fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_BX_LR); - else if (FBT_PUSH_P(*instr)) - fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_PUSHM); - else if (FBT_B_LABEL_P(*instr)) - fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_B); - else + if (FBT_MOV_IP_SP_P(ldinstr(instr))) { + fbt->fbtp_rval = BUILD_RVAL(ldinstr(instr), + DTRACE_INVOP_MOV_IP_SP); + } else if (FBT_LDR_IMM_P(ldinstr(instr))) { + fbt->fbtp_rval = BUILD_RVAL(ldinstr(instr), + DTRACE_INVOP_LDR_IMM); + } else if (FBT_MOVW_P(ldinstr(instr))) { + fbt->fbtp_rval = BUILD_RVAL(ldinstr(instr), DTRACE_INVOP_MOVW); + } else if (FBT_MOV_IMM_P(ldinstr(instr))) { + fbt->fbtp_rval = BUILD_RVAL(ldinstr(instr), + DTRACE_INVOP_MOV_IMM); + } else if (FBT_CMP_IMM_P(ldinstr(instr))) { + fbt->fbtp_rval = BUILD_RVAL(ldinstr(instr), + DTRACE_INVOP_CMP_IMM); + } else if (FBT_BX_LR_P(ldinstr(instr))) { + fbt->fbtp_rval = BUILD_RVAL(ldinstr(instr), + DTRACE_INVOP_BX_LR); + } else if (FBT_PUSH_P(ldinstr(instr))) { + fbt->fbtp_rval = BUILD_RVAL(ldinstr(instr), + DTRACE_INVOP_PUSHM); + } else if (FBT_B_LABEL_P(ldinstr(instr))) { + fbt->fbtp_rval = BUILD_RVAL(ldinstr(instr), + DTRACE_INVOP_B); + } else { KASSERT(0); + } KASSERTMSG((fbt->fbtp_rval >> 28) != 0, "fbt %p insn 0x%x name %s rval 0x%08x", - fbt, *instr, name, fbt->fbtp_rval); + fbt, ldinstr(instr), name, fbt->fbtp_rval); - fbt->fbtp_patchval = PATCHVAL_ENCODE_COND(*instr); - fbt->fbtp_savedval = *instr; + fbt->fbtp_patchval = PATCHVAL_ENCODE_COND(ldinstr(instr)); + fbt->fbtp_savedval = ldinstr(instr); fbt->fbtp_symindx = symindx; fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)]; @@ -336,13 +362,14 @@ fbt_provide_module_cb(const char *name, size = 1; - if (!FBT_BX_LR_P(*instr) - && !FBT_MOV_PC_LR_P(*instr) - && !FBT_LDM_P(*instr) - && !FBT_LDMIB_P(*instr) - && !(was_ldm_lr && FBT_B_LABEL_P(*instr)) + if (!FBT_BX_LR_P(ldinstr(instr)) + && !FBT_MOV_PC_LR_P(ldinstr(instr)) + && !FBT_LDM_P(ldinstr(instr)) + && !FBT_LDMIB_P(ldinstr(instr)) + && !(was_ldm_lr && FBT_B_LABEL_P(ldinstr(instr))) ) { - if (FBT_LDM_LR_P(*instr) || FBT_LDMIB_LR_P(*instr)) + if (FBT_LDM_LR_P(ldinstr(instr)) || + FBT_LDMIB_LR_P(ldinstr(instr))) was_ldm_lr = true; else was_ldm_lr = false; @@ -370,26 +397,32 @@ fbt_provide_module_cb(const char *name, /* fbt->fbtp_loadcnt = lf->loadcnt; */ fbt->fbtp_symindx = symindx; - if (FBT_BX_LR_P(*instr)) - fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_BX_LR); - else if (FBT_MOV_PC_LR_P(*instr)) - fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_MOV_PC_LR); - else if (FBT_LDM_P(*instr)) - fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_LDM); - else if (FBT_LDMIB_P(*instr)) - fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_POPM); - else if (FBT_B_LABEL_P(*instr)) - fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_B); - else + if (FBT_BX_LR_P(ldinstr(instr))) { + fbt->fbtp_rval = BUILD_RVAL(ldinstr(instr), + DTRACE_INVOP_BX_LR); + } else if (FBT_MOV_PC_LR_P(ldinstr(instr))) { + fbt->fbtp_rval = BUILD_RVAL(ldinstr(instr), + DTRACE_INVOP_MOV_PC_LR); + } else if (FBT_LDM_P(ldinstr(instr))) { + fbt->fbtp_rval = BUILD_RVAL(ldinstr(instr), + DTRACE_INVOP_LDM); + } else if (FBT_LDMIB_P(ldinstr(instr))) { + fbt->fbtp_rval = BUILD_RVAL(ldinstr(instr), + DTRACE_INVOP_POPM); + } else if (FBT_B_LABEL_P(ldinstr(instr))) { + fbt->fbtp_rval = BUILD_RVAL(ldinstr(instr), + DTRACE_INVOP_B); + } else { KASSERT(0); + } KASSERTMSG((fbt->fbtp_rval >> 28) != 0, "fbt %p name %s rval 0x%08x", fbt, name, fbt->fbtp_rval); fbt->fbtp_roffset = (uintptr_t)(instr - (uint32_t *) value); - fbt->fbtp_patchval = PATCHVAL_ENCODE_COND(*instr); + fbt->fbtp_patchval = PATCHVAL_ENCODE_COND(ldinstr(instr)); - fbt->fbtp_savedval = *instr; + fbt->fbtp_savedval = ldinstr(instr); fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)]; fbt_probetab[FBT_ADDR2NDX(instr)] = fbt;