diff options
author | Jon Medhurst <tixy@yxit.co.uk> | 2011-07-03 10:15:11 -0400 |
---|---|---|
committer | Tixy <tixy@medhuaa1.miniserver.com> | 2011-07-13 13:32:47 -0400 |
commit | 231fb150c6f8a1f226380affc5498dd9abffc9d7 (patch) | |
tree | 1ec9a15efb8fa25cc0a7eb5dee8cb76c4cf26181 /arch/arm/kernel/kprobes-thumb.c | |
parent | 31656c1a9a9872e2621b2b952294bdea4c23f5bd (diff) |
ARM: kprobes: Decode 32-bit Thumb long multiply and divide 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 | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/arch/arm/kernel/kprobes-thumb.c b/arch/arm/kernel/kprobes-thumb.c index 7c32e5b03cee..4ef12d13c7d0 100644 --- a/arch/arm/kernel/kprobes-thumb.c +++ b/arch/arm/kernel/kprobes-thumb.c | |||
@@ -289,6 +289,32 @@ t32_emulate_rd8rn16_noflags(struct kprobe *p, struct pt_regs *regs) | |||
289 | regs->uregs[rd] = rdv; | 289 | regs->uregs[rd] = rdv; |
290 | } | 290 | } |
291 | 291 | ||
292 | static void __kprobes | ||
293 | t32_emulate_rdlo12rdhi8rn16rm0_noflags(struct kprobe *p, struct pt_regs *regs) | ||
294 | { | ||
295 | kprobe_opcode_t insn = p->opcode; | ||
296 | int rdlo = (insn >> 12) & 0xf; | ||
297 | int rdhi = (insn >> 8) & 0xf; | ||
298 | int rn = (insn >> 16) & 0xf; | ||
299 | int rm = insn & 0xf; | ||
300 | |||
301 | register unsigned long rdlov asm("r0") = regs->uregs[rdlo]; | ||
302 | register unsigned long rdhiv asm("r1") = regs->uregs[rdhi]; | ||
303 | register unsigned long rnv asm("r2") = regs->uregs[rn]; | ||
304 | register unsigned long rmv asm("r3") = regs->uregs[rm]; | ||
305 | |||
306 | __asm__ __volatile__ ( | ||
307 | "blx %[fn]" | ||
308 | : "=r" (rdlov), "=r" (rdhiv) | ||
309 | : "0" (rdlov), "1" (rdhiv), "r" (rnv), "r" (rmv), | ||
310 | [fn] "r" (p->ainsn.insn_fn) | ||
311 | : "lr", "memory", "cc" | ||
312 | ); | ||
313 | |||
314 | regs->uregs[rdlo] = rdlov; | ||
315 | regs->uregs[rdhi] = rdhiv; | ||
316 | } | ||
317 | |||
292 | static const union decode_item t32_table_1110_100x_x0xx[] = { | 318 | static const union decode_item t32_table_1110_100x_x0xx[] = { |
293 | /* Load/store multiple instructions */ | 319 | /* Load/store multiple instructions */ |
294 | 320 | ||
@@ -763,6 +789,29 @@ static const union decode_item t32_table_1111_1010___1111[] = { | |||
763 | DECODE_END | 789 | DECODE_END |
764 | }; | 790 | }; |
765 | 791 | ||
792 | static const union decode_item t32_table_1111_1011_1[] = { | ||
793 | /* Long multiply, long multiply accumulate, and divide */ | ||
794 | |||
795 | /* UMAAL 1111 1011 1110 xxxx xxxx xxxx 0110 xxxx */ | ||
796 | DECODE_OR (0xfff000f0, 0xfbe00060), | ||
797 | /* SMLALxy 1111 1011 1100 xxxx xxxx xxxx 10xx xxxx */ | ||
798 | DECODE_OR (0xfff000c0, 0xfbc00080), | ||
799 | /* SMLALD{X} 1111 1011 1100 xxxx xxxx xxxx 110x xxxx */ | ||
800 | /* SMLSLD{X} 1111 1011 1101 xxxx xxxx xxxx 110x xxxx */ | ||
801 | DECODE_OR (0xffe000e0, 0xfbc000c0), | ||
802 | /* SMULL 1111 1011 1000 xxxx xxxx xxxx 0000 xxxx */ | ||
803 | /* UMULL 1111 1011 1010 xxxx xxxx xxxx 0000 xxxx */ | ||
804 | /* SMLAL 1111 1011 1100 xxxx xxxx xxxx 0000 xxxx */ | ||
805 | /* UMLAL 1111 1011 1110 xxxx xxxx xxxx 0000 xxxx */ | ||
806 | DECODE_EMULATEX (0xff9000f0, 0xfb800000, t32_emulate_rdlo12rdhi8rn16rm0_noflags, | ||
807 | REGS(NOSPPC, NOSPPC, NOSPPC, 0, NOSPPC)), | ||
808 | |||
809 | /* SDIV 1111 1011 1001 xxxx xxxx xxxx 1111 xxxx */ | ||
810 | /* UDIV 1111 1011 1011 xxxx xxxx xxxx 1111 xxxx */ | ||
811 | /* Other unallocated instructions... */ | ||
812 | DECODE_END | ||
813 | }; | ||
814 | |||
766 | const union decode_item kprobe_decode_thumb32_table[] = { | 815 | const union decode_item kprobe_decode_thumb32_table[] = { |
767 | 816 | ||
768 | /* | 817 | /* |
@@ -834,6 +883,12 @@ const union decode_item kprobe_decode_thumb32_table[] = { | |||
834 | DECODE_TABLE (0xff00f000, 0xfa00f000, t32_table_1111_1010___1111), | 883 | DECODE_TABLE (0xff00f000, 0xfa00f000, t32_table_1111_1010___1111), |
835 | 884 | ||
836 | /* | 885 | /* |
886 | * Long multiply, long multiply accumulate, and divide | ||
887 | * 1111 1011 1xxx xxxx xxxx xxxx xxxx xxxx | ||
888 | */ | ||
889 | DECODE_TABLE (0xff800000, 0xfb800000, t32_table_1111_1011_1), | ||
890 | |||
891 | /* | ||
837 | * Coprocessor instructions | 892 | * Coprocessor instructions |
838 | * 1111 11xx xxxx xxxx xxxx xxxx xxxx xxxx | 893 | * 1111 11xx xxxx xxxx xxxx xxxx xxxx xxxx |
839 | */ | 894 | */ |