diff --git a/external/cddl/osnet/dev/dtrace/aarch64/dtrace_subr.c b/external/cddl/osnet/dev/dtrace/aarch64/dtrace_subr.c index 7a968c9c2ecc..1f30cab2fb04 100644 --- a/external/cddl/osnet/dev/dtrace/aarch64/dtrace_subr.c +++ b/external/cddl/osnet/dev/dtrace/aarch64/dtrace_subr.c @@ -69,14 +69,19 @@ typedef struct dtrace_invop_hdlr { dtrace_invop_hdlr_t *dtrace_invop_hdlr; int -dtrace_invop(uintptr_t addr, struct trapframe *frame, uintptr_t eax) +dtrace_invop(uintptr_t addr, struct trapframe *frame, uintptr_t r0) { dtrace_invop_hdlr_t *hdlr; int rval; - for (hdlr = dtrace_invop_hdlr; hdlr != NULL; hdlr = hdlr->dtih_next) - if ((rval = hdlr->dtih_func(addr, frame, eax)) != 0) + for (hdlr = dtrace_invop_hdlr; hdlr != NULL; hdlr = hdlr->dtih_next) { + if ((rval = hdlr->dtih_func(addr, frame, r0)) != 0) { + printf("invop %p returned %08x\n", hdlr->dtih_func, + rval); return (rval); + } + printf("invop %p returned 0\n", hdlr->dtih_func); + } return (0); } @@ -263,7 +268,13 @@ dtrace_invop_start(struct trapframe *frame) int tmp; int i; - invop = dtrace_invop(frame->tf_pc, frame, frame->tf_pc); + printf("DTRACE layout: sp@%zd pc@%zd\n", + offsetof(struct trapframe, tf_sp), + offsetof(struct trapframe, tf_pc)); + printf("invop start sp=%p pc=%p\n", + (void *)frame->tf_sp, (void *)frame->tf_pc); + invop = dtrace_invop(frame->tf_pc, frame, frame->tf_regs.r_reg[0]); + printf("invop %08x\n", invop); tmp = (invop & LDP_STP_MASK); if (tmp == STP_64 || tmp == LDP_64) { @@ -276,6 +287,10 @@ dtrace_invop_start(struct trapframe *frame) switch (tmp) { case STP_64: + printf("emulate STP_64 sp=%p r%ld=%p r%ld=%p\n", + sp, + arg1, (void *)frame->tf_regs.r_reg[arg1], + arg2, (void *)frame->tf_regs.r_reg[arg2]); if (offs >> (OFFSET_SIZE - 1)) sp -= (~offs & OFFSET_MASK) + 1; else @@ -284,6 +299,8 @@ dtrace_invop_start(struct trapframe *frame) *(sp + 1) = frame->tf_regs.r_reg[arg2]; break; case LDP_64: + printf("emulate LDP_64 sp=%p r%ld r%ld\n", + sp, arg1, arg2); frame->tf_regs.r_reg[arg1] = *(sp + 0); frame->tf_regs.r_reg[arg2] = *(sp + 1); if (offs >> (OFFSET_SIZE - 1)) @@ -292,12 +309,14 @@ dtrace_invop_start(struct trapframe *frame) sp += (offs); break; default: - break; + __unreachable(); } /* Update the stack pointer and program counter to continue */ frame->tf_sp = (register_t)sp; frame->tf_pc += INSN_SIZE; + printf("emulation successful, sp=%p pc=%p\n", + (void *)frame->tf_sp, (void *)frame->tf_pc); return (0); } @@ -305,15 +324,23 @@ dtrace_invop_start(struct trapframe *frame) data = (invop & B_DATA_MASK); /* The data is the number of 4-byte words to change the pc */ data *= 4; + printf("emulate B %d\n", data); frame->tf_pc += data; + printf("emulation successful, sp=%p pc=%p\n", + (void *)frame->tf_sp, (void *)frame->tf_pc); return (0); } if (invop == RET_INSTR) { + printf("emulate RET to %p\n", (void *)frame->tf_lr); frame->tf_pc = frame->tf_lr; + printf("emulation successful, sp=%p pc=%p\n", + (void *)frame->tf_sp, (void *)frame->tf_pc); return (0); } + printf("%s: emulation failed: %08x sp=%p pc=%p\n", __func__, invop, + (void *)frame->tf_sp, (void *)frame->tf_pc); return (-1); } diff --git a/external/cddl/osnet/dev/fbt/aarch64/fbt_isa.c b/external/cddl/osnet/dev/fbt/aarch64/fbt_isa.c index 123290616ec5..7a31f8822d21 100644 --- a/external/cddl/osnet/dev/fbt/aarch64/fbt_isa.c +++ b/external/cddl/osnet/dev/fbt/aarch64/fbt_isa.c @@ -36,6 +36,9 @@ #include #include #include + +#include + #include #include @@ -62,11 +65,16 @@ fbt_invop(uintptr_t addr, struct trapframe *frame, uintptr_t rval) if ((uintptr_t)fbt->fbtp_patchpoint == addr) { cpu->cpu_dtrace_caller = addr; + printf("fbt probe %p (%08x)\n", (void *)addr, + fbt->fbtp_savedval); dtrace_probe(fbt->fbtp_id, frame->tf_regs.r_reg[0], frame->tf_regs.r_reg[1], frame->tf_regs.r_reg[2], frame->tf_regs.r_reg[3], frame->tf_regs.r_reg[4]); + printf("fbt probe %p (%08x) returned\n", (void *)addr, + fbt->fbtp_savedval); cpu->cpu_dtrace_caller = 0; + KASSERT(fbt->fbtp_savedval != 0); return (fbt->fbtp_savedval); } } @@ -77,9 +85,26 @@ fbt_invop(uintptr_t addr, struct trapframe *frame, uintptr_t rval) void fbt_patch_tracepoint(fbt_probe_t *fbt, fbt_patchval_t val) { +#if 1 + db_write_bytes((db_addr_t)fbt->fbtp_patchpoint, sizeof(val), + (const void *)&val); + cpu_icache_sync_range((vm_offset_t)fbt->fbtp_patchpoint, sizeof(val)); +#else +#if 1 + paddr_t pa; + vaddr_t va; + if (!pmap_extract(pmap_kernel(), (vaddr_t)fbt->fbtp_patchpoint, &pa)) + panic("unmapped fbt patchpoint: %p", fbt->fbtp_patchpoint); + if (!mm_md_direct_mapped_phys(pa, &va)) + panic("no direct map for phys: %"PRIxPADDR, pa); + *(fbt_patchval_t *)va = val; +#else *fbt->fbtp_patchpoint = val; +#endif cpu_icache_sync_range((vm_offset_t)fbt->fbtp_patchpoint, 4); + cpu_idcache_wbinv_range((vm_offset_t)fbt->fbtp_patchpoint, 4); +#endif } #if defined(__FreeBSD__) @@ -138,6 +163,7 @@ fbt_provide_module_cb(const char *name, int symindx, void *value, if (instr >= limit) return (0); + KASSERT(*instr != 0); #ifdef __FreeBSD__ fbt = malloc(sizeof (fbt_probe_t), M_FBT, M_WAITOK | M_ZERO); @@ -157,7 +183,6 @@ fbt_provide_module_cb(const char *name, int symindx, void *value, #endif fbt->fbtp_savedval = *instr; fbt->fbtp_patchval = FBT_PATCHVAL; - fbt->fbtp_rval = DTRACE_INVOP_PUSHM; fbt->fbtp_symindx = symindx; fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)]; @@ -188,6 +213,7 @@ again: if (instr >= limit) return (0); + KASSERT(*instr != 0); /* * We have a winner! @@ -215,13 +241,10 @@ again: #ifdef __NetBSD__ fbt->fbtp_ctl = mod; #endif - fbt->fbtp_symindx = symindx; - if ((*instr & B_MASK) == B_INSTR) - fbt->fbtp_rval = DTRACE_INVOP_B; - else - fbt->fbtp_rval = DTRACE_INVOP_RET; fbt->fbtp_savedval = *instr; fbt->fbtp_patchval = FBT_PATCHVAL; + fbt->fbtp_symindx = symindx; + fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)]; fbt_probetab[FBT_ADDR2NDX(instr)] = fbt; diff --git a/sys/arch/aarch64/aarch64/trap.c b/sys/arch/aarch64/aarch64/trap.c index 63da65ec6282..7f68e9d8489b 100644 --- a/sys/arch/aarch64/aarch64/trap.c +++ b/sys/arch/aarch64/aarch64/trap.c @@ -209,7 +209,12 @@ trap_el1h_sync(struct trapframe *tf) #ifdef KDTRACE_HOOKS if (__SHIFTOUT(esr, ESR_ISS) == 0x40d && dtrace_invop_jump_addr != 0) { + printf("KERNEL layout: sp@%zd pc@%zd\n", + offsetof(struct trapframe, tf_sp), + offsetof(struct trapframe, tf_pc)); (*dtrace_invop_jump_addr)(tf); + printf("dtrace_invop returned sp=%p pc=%p\n", + (void *)tf->tf_sp, (void *)tf->tf_pc); break; } /* FALLTHROUGH */