aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorJon Medhurst <tixy@yxit.co.uk>2011-07-03 09:40:26 -0400
committerTixy <tixy@medhuaa1.miniserver.com>2011-07-13 13:32:46 -0400
commit7848786a7a198dd5e097330ad0cbfdf155a25499 (patch)
tree5c0b0418fb32dfe41e9e16255074acfe27071195 /arch
parent2fcaf7e75804dbb75862a230a5a19d0508153324 (diff)
ARM: kprobes: Decode 32-bit Thumb data-processing (plain binary immediate) instructions
Signed-off-by: Jon Medhurst <tixy@yxit.co.uk> Acked-by: Nicolas Pitre <nicolas.pitre@linaro.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/kernel/kprobes-thumb.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/arch/arm/kernel/kprobes-thumb.c b/arch/arm/kernel/kprobes-thumb.c
index cf834484fb5..1fbeba8093f 100644
--- a/arch/arm/kernel/kprobes-thumb.c
+++ b/arch/arm/kernel/kprobes-thumb.c
@@ -124,6 +124,46 @@ t32_emulate_rd8rn16rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
124 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK); 124 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
125} 125}
126 126
127static void __kprobes
128t32_emulate_rd8pc16_noflags(struct kprobe *p, struct pt_regs *regs)
129{
130 kprobe_opcode_t insn = p->opcode;
131 unsigned long pc = thumb_probe_pc(p);
132 int rd = (insn >> 8) & 0xf;
133
134 register unsigned long rdv asm("r1") = regs->uregs[rd];
135 register unsigned long rnv asm("r2") = pc & ~3;
136
137 __asm__ __volatile__ (
138 "blx %[fn]"
139 : "=r" (rdv)
140 : "0" (rdv), "r" (rnv), [fn] "r" (p->ainsn.insn_fn)
141 : "lr", "memory", "cc"
142 );
143
144 regs->uregs[rd] = rdv;
145}
146
147static void __kprobes
148t32_emulate_rd8rn16_noflags(struct kprobe *p, struct pt_regs *regs)
149{
150 kprobe_opcode_t insn = p->opcode;
151 int rd = (insn >> 8) & 0xf;
152 int rn = (insn >> 16) & 0xf;
153
154 register unsigned long rdv asm("r1") = regs->uregs[rd];
155 register unsigned long rnv asm("r2") = regs->uregs[rn];
156
157 __asm__ __volatile__ (
158 "blx %[fn]"
159 : "=r" (rdv)
160 : "0" (rdv), "r" (rnv), [fn] "r" (p->ainsn.insn_fn)
161 : "lr", "memory", "cc"
162 );
163
164 regs->uregs[rd] = rdv;
165}
166
127static const union decode_item t32_table_1110_100x_x0xx[] = { 167static const union decode_item t32_table_1110_100x_x0xx[] = {
128 /* Load/store multiple instructions */ 168 /* Load/store multiple instructions */
129 169
@@ -293,6 +333,55 @@ static const union decode_item t32_table_1111_0x0x___0[] = {
293 DECODE_END 333 DECODE_END
294}; 334};
295 335
336static const union decode_item t32_table_1111_0x1x___0[] = {
337 /* Data-processing (plain binary immediate) */
338
339 /* ADDW Rd, PC, #imm 1111 0x10 0000 1111 0xxx xxxx xxxx xxxx */
340 DECODE_OR (0xfbff8000, 0xf20f0000),
341 /* SUBW Rd, PC, #imm 1111 0x10 1010 1111 0xxx xxxx xxxx xxxx */
342 DECODE_EMULATEX (0xfbff8000, 0xf2af0000, t32_emulate_rd8pc16_noflags,
343 REGS(PC, 0, NOSPPC, 0, 0)),
344
345 /* ADDW SP, SP, #imm 1111 0x10 0000 1101 0xxx 1101 xxxx xxxx */
346 DECODE_OR (0xfbff8f00, 0xf20d0d00),
347 /* SUBW SP, SP, #imm 1111 0x10 1010 1101 0xxx 1101 xxxx xxxx */
348 DECODE_EMULATEX (0xfbff8f00, 0xf2ad0d00, t32_emulate_rd8rn16_noflags,
349 REGS(SP, 0, SP, 0, 0)),
350
351 /* ADDW 1111 0x10 0000 xxxx 0xxx xxxx xxxx xxxx */
352 DECODE_OR (0xfbf08000, 0xf2000000),
353 /* SUBW 1111 0x10 1010 xxxx 0xxx xxxx xxxx xxxx */
354 DECODE_EMULATEX (0xfbf08000, 0xf2a00000, t32_emulate_rd8rn16_noflags,
355 REGS(NOPCX, 0, NOSPPC, 0, 0)),
356
357 /* MOVW 1111 0x10 0100 xxxx 0xxx xxxx xxxx xxxx */
358 /* MOVT 1111 0x10 1100 xxxx 0xxx xxxx xxxx xxxx */
359 DECODE_EMULATEX (0xfb708000, 0xf2400000, t32_emulate_rd8rn16_noflags,
360 REGS(0, 0, NOSPPC, 0, 0)),
361
362 /* SSAT16 1111 0x11 0010 xxxx 0000 xxxx 00xx xxxx */
363 /* SSAT 1111 0x11 00x0 xxxx 0xxx xxxx xxxx xxxx */
364 /* USAT16 1111 0x11 1010 xxxx 0000 xxxx 00xx xxxx */
365 /* USAT 1111 0x11 10x0 xxxx 0xxx xxxx xxxx xxxx */
366 DECODE_EMULATEX (0xfb508000, 0xf3000000, t32_emulate_rd8rn16rm0_rwflags,
367 REGS(NOSPPC, 0, NOSPPC, 0, 0)),
368
369 /* SFBX 1111 0x11 0100 xxxx 0xxx xxxx xxxx xxxx */
370 /* UFBX 1111 0x11 1100 xxxx 0xxx xxxx xxxx xxxx */
371 DECODE_EMULATEX (0xfb708000, 0xf3400000, t32_emulate_rd8rn16_noflags,
372 REGS(NOSPPC, 0, NOSPPC, 0, 0)),
373
374 /* BFC 1111 0x11 0110 1111 0xxx xxxx xxxx xxxx */
375 DECODE_EMULATEX (0xfbff8000, 0xf36f0000, t32_emulate_rd8rn16_noflags,
376 REGS(0, 0, NOSPPC, 0, 0)),
377
378 /* BFI 1111 0x11 0110 xxxx 0xxx xxxx xxxx xxxx */
379 DECODE_EMULATEX (0xfbf08000, 0xf3600000, t32_emulate_rd8rn16_noflags,
380 REGS(NOSPPCX, 0, NOSPPC, 0, 0)),
381
382 DECODE_END
383};
384
296static const union decode_item t32_table_1111_0xxx___1[] = { 385static const union decode_item t32_table_1111_0xxx___1[] = {
297 /* Branches and miscellaneous control */ 386 /* Branches and miscellaneous control */
298 387
@@ -335,6 +424,12 @@ const union decode_item kprobe_decode_thumb32_table[] = {
335 DECODE_TABLE (0xfa008000, 0xf0000000, t32_table_1111_0x0x___0), 424 DECODE_TABLE (0xfa008000, 0xf0000000, t32_table_1111_0x0x___0),
336 425
337 /* 426 /*
427 * Data-processing (plain binary immediate)
428 * 1111 0x1x xxxx xxxx 0xxx xxxx xxxx xxxx
429 */
430 DECODE_TABLE (0xfa008000, 0xf2000000, t32_table_1111_0x1x___0),
431
432 /*
338 * Branches and miscellaneous control 433 * Branches and miscellaneous control
339 * 1111 0xxx xxxx xxxx 1xxx xxxx xxxx xxxx 434 * 1111 0xxx xxxx xxxx 1xxx xxxx xxxx xxxx
340 */ 435 */