uprobes/x86: Emulate nop's using ops->emulate()
Finally we can kill the ugly (and very limited) code in __skip_sstep(). Just change branch_setup_xol_ops() to treat "nop" as jmp to the next insn. Thanks to lib/insn.c, it is clever enough. OPCODE1() == 0x90 includes "(rep;)+ nop;" at least, and (afaics) much more. Signed-off-by: Oleg Nesterov <oleg@redhat.com> Reviewed-by: Jim Keniston <jkenisto@us.ibm.com>
This commit is contained in:
Родитель
7ba6db2d68
Коммит
d241006354
|
@ -478,6 +478,7 @@ static int branch_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn)
|
|||
switch (OPCODE1(insn)) {
|
||||
case 0xeb: /* jmp 8 */
|
||||
case 0xe9: /* jmp 32 */
|
||||
case 0x90: /* prefix* + nop; same as jmp with .offs = 0 */
|
||||
break;
|
||||
default:
|
||||
return -ENOSYS;
|
||||
|
@ -710,29 +711,10 @@ void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
|
|||
regs->flags &= ~X86_EFLAGS_TF;
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip these instructions as per the currently known x86 ISA.
|
||||
* rep=0x66*; nop=0x90
|
||||
*/
|
||||
static bool __skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (auprobe->ops->emulate)
|
||||
return auprobe->ops->emulate(auprobe, regs);
|
||||
|
||||
/* TODO: move this code into ->emulate() hook */
|
||||
for (i = 0; i < MAX_UINSN_BYTES; i++) {
|
||||
if (auprobe->insn[i] == 0x66)
|
||||
continue;
|
||||
|
||||
if (auprobe->insn[i] == 0x90) {
|
||||
regs->ip += i + 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче