Commit f8695142 authored by Jon Medhurst's avatar Jon Medhurst Committed by Tixy

ARM: kprobes: Decode 16-bit Thumb load and store instructions

Most of these instructions only operate on the low registers R0-R7
so they can make use of t16_emulate_loregs_rwflags.

The instructions which use SP or PC for addressing have their own
simulation functions.
Signed-off-by: default avatarJon Medhurst <tixy@yxit.co.uk>
Acked-by: default avatarNicolas Pitre <nicolas.pitre@linaro.org>
parent 3b5940e8
...@@ -51,6 +51,29 @@ t16_simulate_bxblx(struct kprobe *p, struct pt_regs *regs) ...@@ -51,6 +51,29 @@ t16_simulate_bxblx(struct kprobe *p, struct pt_regs *regs)
bx_write_pc(rmv, regs); bx_write_pc(rmv, regs);
} }
static void __kprobes
t16_simulate_ldr_literal(struct kprobe *p, struct pt_regs *regs)
{
kprobe_opcode_t insn = p->opcode;
unsigned long* base = (unsigned long *)(thumb_probe_pc(p) & ~3);
long index = insn & 0xff;
int rt = (insn >> 8) & 0x7;
regs->uregs[rt] = base[index];
}
static void __kprobes
t16_simulate_ldrstr_sp_relative(struct kprobe *p, struct pt_regs *regs)
{
kprobe_opcode_t insn = p->opcode;
unsigned long* base = (unsigned long *)regs->ARM_sp;
long index = insn & 0xff;
int rt = (insn >> 8) & 0x7;
if (insn & 0x800) /* LDR */
regs->uregs[rt] = base[index];
else /* STR */
base[index] = regs->uregs[rt];
}
static unsigned long __kprobes static unsigned long __kprobes
t16_emulate_loregs(struct kprobe *p, struct pt_regs *regs) t16_emulate_loregs(struct kprobe *p, struct pt_regs *regs)
{ {
...@@ -217,12 +240,49 @@ const union decode_item kprobe_decode_thumb16_table[] = { ...@@ -217,12 +240,49 @@ const union decode_item kprobe_decode_thumb16_table[] = {
/* MOV (register) 0100 0110 xxxx xxxx */ /* MOV (register) 0100 0110 xxxx xxxx */
DECODE_CUSTOM (0xfc00, 0x4400, t16_decode_hiregs), DECODE_CUSTOM (0xfc00, 0x4400, t16_decode_hiregs),
/*
* Load from Literal Pool
* LDR (literal) 0100 1xxx xxxx xxxx
*/
DECODE_SIMULATE (0xf800, 0x4800, t16_simulate_ldr_literal),
/*
* 16-bit Thumb Load/store instructions
* 0101 xxxx xxxx xxxx
* 011x xxxx xxxx xxxx
* 100x xxxx xxxx xxxx
*/
/* STR (register) 0101 000x xxxx xxxx */
/* STRH (register) 0101 001x xxxx xxxx */
/* STRB (register) 0101 010x xxxx xxxx */
/* LDRSB (register) 0101 011x xxxx xxxx */
/* LDR (register) 0101 100x xxxx xxxx */
/* LDRH (register) 0101 101x xxxx xxxx */
/* LDRB (register) 0101 110x xxxx xxxx */
/* LDRSH (register) 0101 111x xxxx xxxx */
/* STR (immediate, Thumb) 0110 0xxx xxxx xxxx */
/* LDR (immediate, Thumb) 0110 1xxx xxxx xxxx */
/* STRB (immediate, Thumb) 0111 0xxx xxxx xxxx */
/* LDRB (immediate, Thumb) 0111 1xxx xxxx xxxx */
DECODE_EMULATE (0xc000, 0x4000, t16_emulate_loregs_rwflags),
/* STRH (immediate, Thumb) 1000 0xxx xxxx xxxx */
/* LDRH (immediate, Thumb) 1000 1xxx xxxx xxxx */
DECODE_EMULATE (0xf000, 0x8000, t16_emulate_loregs_rwflags),
/* STR (immediate, Thumb) 1001 0xxx xxxx xxxx */
/* LDR (immediate, Thumb) 1001 1xxx xxxx xxxx */
DECODE_SIMULATE (0xf000, 0x9000, t16_simulate_ldrstr_sp_relative),
/* /*
* Miscellaneous 16-bit instructions * Miscellaneous 16-bit instructions
* 1011 xxxx xxxx xxxx * 1011 xxxx xxxx xxxx
*/ */
DECODE_TABLE (0xf000, 0xb000, t16_table_1011), DECODE_TABLE (0xf000, 0xb000, t16_table_1011),
/* STM 1100 0xxx xxxx xxxx */
/* LDM 1100 1xxx xxxx xxxx */
DECODE_EMULATE (0xf000, 0xc000, t16_emulate_loregs_rwflags),
DECODE_END DECODE_END
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment