/** * arch_uprobe_analyze_insn - instruction analysis including validity and fixups. * @mm: the probed address space. * @arch_uprobe: the probepoint information. * @addr: virtual address at which to install the probepoint * Return 0 on success or a -ve number on error.
*/ int arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsignedlong addr)
{ union mips_instruction inst;
/* * For the time being this also blocks attempts to use uprobes with * MIPS16 and microMIPS.
*/ if (addr & 0x03) return -EINVAL;
inst.word = aup->insn[0];
if (__insn_is_compact_branch(inst)) {
pr_notice("Uprobes for compact branches are not supported\n"); return -EINVAL;
}
/** * is_trap_insn - check if the instruction is a trap variant * @insn: instruction to be checked. * Returns true if @insn is a trap variant. * * This definition overrides the weak definition in kernel/events/uprobes.c. * and is needed for the case where an architecture has multiple trap * instructions (like PowerPC or MIPS). We treat BREAK just like the more * modern conditional trap instructions.
*/ bool is_trap_insn(uprobe_opcode_t *insn)
{ union mips_instruction inst;
inst.word = *insn;
switch (inst.i_format.opcode) { case spec_op: switch (inst.r_format.func) { case break_op: case teq_op: case tge_op: case tgeu_op: case tlt_op: case tltu_op: case tne_op: returntrue;
} break;
case bcond_op: /* Yes, really ... */ switch (inst.u_format.rt) { case teqi_op: case tgei_op: case tgeiu_op: case tlti_op: case tltiu_op: case tnei_op: returntrue;
} break;
}
returnfalse;
}
#define UPROBE_TRAP_NR ULONG_MAX
/* * arch_uprobe_pre_xol - prepare to execute out of line. * @auprobe: the probepoint information. * @regs: reflects the saved user state of current task.
*/ int arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs)
{ struct uprobe_task *utask = current->utask;
/* * Now find the EPC where to resume after the breakpoint has been * dealt with. This may require emulation of a branch.
*/
aup->resume_epc = regs->cp0_epc + 4; if (insn_has_delay_slot((union mips_instruction) aup->insn[0])) {
__compute_return_epc_for_insn(regs,
(union mips_instruction) aup->insn[0]);
aup->resume_epc = regs->cp0_epc;
}
utask->autask.saved_trap_nr = current->thread.trap_nr;
current->thread.trap_nr = UPROBE_TRAP_NR;
regs->cp0_epc = current->utask->xol_vaddr;
/* * If xol insn itself traps and generates a signal(Say, * SIGILL/SIGSEGV/etc), then detect the case where a singlestepped * instruction jumps back to its own address. It is assumed that anything * like do_page_fault/do_trap/etc sets thread.trap_nr != -1. * * arch_uprobe_pre_xol/arch_uprobe_post_xol save/restore thread.trap_nr, * arch_uprobe_xol_was_trapped() simply checks that ->trap_nr is not equal to * UPROBE_TRAP_NR == -1 set by arch_uprobe_pre_xol().
*/ bool arch_uprobe_xol_was_trapped(struct task_struct *tsk)
{ if (tsk->thread.trap_nr != UPROBE_TRAP_NR) returntrue;
/* regs == NULL is a kernel bug */ if (WARN_ON(!regs)) return NOTIFY_DONE;
/* We are only interested in userspace traps */ if (!user_mode(regs)) return NOTIFY_DONE;
switch (val) { case DIE_UPROBE: if (uprobe_pre_sstep_notifier(regs)) return NOTIFY_STOP; break; case DIE_UPROBE_XOL: if (uprobe_post_sstep_notifier(regs)) return NOTIFY_STOP; break; default: break;
}
return 0;
}
/* * This function gets called when XOL instruction either gets trapped or * the thread has a fatal signal. Reset the instruction pointer to its * probed address for the potential restart or for post mortem analysis.
*/ void arch_uprobe_abort_xol(struct arch_uprobe *aup, struct pt_regs *regs)
{ struct uprobe_task *utask = current->utask;
/** * uprobe_get_swbp_addr - compute address of swbp given post-swbp regs * @regs: Reflects the saved state of the task after it has hit a breakpoint * instruction. * Return the address of the breakpoint instruction. * * This overrides the weak version in kernel/events/uprobes.c.
*/ unsignedlong uprobe_get_swbp_addr(struct pt_regs *regs)
{ return instruction_pointer(regs);
}
/* * See if the instruction can be emulated. * Returns true if instruction was emulated, false otherwise. * * For now we always emulate so this function just returns false.
*/ bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
{ returnfalse;
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.22 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.