diff options
author | Jon Medhurst <tixy@yxit.co.uk> | 2011-07-03 09:40:26 -0400 |
---|---|---|
committer | Tixy <tixy@medhuaa1.miniserver.com> | 2011-07-13 13:32:46 -0400 |
commit | 7848786a7a198dd5e097330ad0cbfdf155a25499 (patch) | |
tree | 5c0b0418fb32dfe41e9e16255074acfe27071195 /arch/arm/kernel/kprobes-thumb.c | |
parent | 2fcaf7e75804dbb75862a230a5a19d0508153324 (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/arm/kernel/kprobes-thumb.c')
-rw-r--r-- | arch/arm/kernel/kprobes-thumb.c | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/arch/arm/kernel/kprobes-thumb.c b/arch/arm/kernel/kprobes-thumb.c index cf834484fb58..1fbeba8093f1 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 | ||
127 | static void __kprobes | ||
128 | t32_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 | |||
147 | static void __kprobes | ||
148 | t32_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 | |||
127 | static const union decode_item t32_table_1110_100x_x0xx[] = { | 167 | static 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 | ||
336 | static 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 | |||
296 | static const union decode_item t32_table_1111_0xxx___1[] = { | 385 | static 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 | */ |