aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/kprobes-thumb.c
diff options
context:
space:
mode:
authorJon Medhurst <tixy@yxit.co.uk>2011-07-03 10:15:11 -0400
committerTixy <tixy@medhuaa1.miniserver.com>2011-07-13 13:32:47 -0400
commit231fb150c6f8a1f226380affc5498dd9abffc9d7 (patch)
tree1ec9a15efb8fa25cc0a7eb5dee8cb76c4cf26181 /arch/arm/kernel/kprobes-thumb.c
parent31656c1a9a9872e2621b2b952294bdea4c23f5bd (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.c55
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
292static void __kprobes
293t32_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
292static const union decode_item t32_table_1110_100x_x0xx[] = { 318static 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
792static 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
766const union decode_item kprobe_decode_thumb32_table[] = { 815const 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 */