[RFC PATCH 6/6] uprobes/x86: Emulate rip-relative conditional "near" jmp's

From: Oleg Nesterov
Date: Sun Apr 06 2014 - 16:17:43 EST


It seems that 16bit conditional jmp is just
0x0f + short_jump_opcode_incremented by 0x10.

But I'll try to cleanup this patch...

Signed-off-by: Oleg Nesterov <oleg@xxxxxxxxxx>
---
arch/x86/kernel/uprobes.c | 18 +++++++++++++++---
1 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
index 797b8a4..8f92cbf 100644
--- a/arch/x86/kernel/uprobes.c
+++ b/arch/x86/kernel/uprobes.c
@@ -564,6 +564,19 @@ static int ttt_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn)
if (WARN_ON_ONCE(!insn_complete(insn)))
return -ENOEXEC;

+#define CASE(op_y, op_n, cond) \
+ case 0x ## op_y: case 0x ## op_n:
+
+ if (insn->opcode.nbytes == 2 && opc1 == 0x0f) {
+ opc1 = OPCODE2(insn) - 0x10;
+
+ switch (opc1) {
+ X86_COND_OPCODES
+ default:
+ return -ENOSYS;
+ }
+ }
+
switch (opc1) {
case 0xeb: /* jmp 8 */
case 0xe9: /* jmp 32 */
@@ -573,10 +586,7 @@ static int ttt_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn)
case 0xe8: /* call relative */
ttt_clear_displacement(auprobe, insn);
/* fall through */
- #define CASE(op_y, op_n, cond) \
- case 0x ## op_y: case 0x ## op_n:
X86_COND_OPCODES
- #undef CASE
auprobe->ttt.opc1 = opc1;
break;

@@ -584,6 +594,8 @@ static int ttt_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn)
return -ENOSYS;
}

+#undef CASE
+
auprobe->ttt.ilen = insn->length;
auprobe->ttt.disp = insn->moffset1.value;
/* so far we assume that it fits into ->moffset1 */
--
1.5.5.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/