aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorJon Medhurst <tixy@yxit.co.uk>2011-04-12 02:45:24 -0400
committerNicolas Pitre <nicolas.pitre@linaro.org>2011-04-28 23:40:58 -0400
commit8dd7cfbed83c74b1fb991fae264944e041e22e62 (patch)
tree97eac596f52e2244a2fc96020ef666d01504e637 /arch
parent780b5c1162286cc75ef2dcc0f14215d9f9f06230 (diff)
ARM: kprobes: Fix emulation of SXTB16, SXTB, SXTH, UXTB16, UXTB and UXTH instructions
These sign extension instructions are encoded as extend-and-add instructions where the register to add is specified as r15. The decoding routines weren't checking for this and were using the incorrect emulation code, giving incorrect results. Signed-off-by: Jon Medhurst <tixy@yxit.co.uk> Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/kernel/kprobes-decode.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c
index f0ca7f4bc4cb..1e413a9c17ef 100644
--- a/arch/arm/kernel/kprobes-decode.c
+++ b/arch/arm/kernel/kprobes-decode.c
@@ -1390,18 +1390,28 @@ space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1390 return prep_emulate_rd12rn16rm0_wflags(insn, asi); 1390 return prep_emulate_rd12rn16rm0_wflags(insn, asi);
1391 1391
1392 /* SXTAB16 : cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx : */ 1392 /* SXTAB16 : cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx : */
1393 /* SXTB : cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx : */ 1393 /* SXTB16 : cccc 0110 1000 1111 xxxx xxxx 0111 xxxx : */
1394 /* ??? : cccc 0110 1001 xxxx xxxx xxxx 0111 xxxx : */ 1394 /* ??? : cccc 0110 1001 xxxx xxxx xxxx 0111 xxxx : */
1395 /* SXTAB : cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx : */ 1395 /* SXTAB : cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx : */
1396 /* SXTB : cccc 0110 1010 1111 xxxx xxxx 0111 xxxx : */
1396 /* SXTAH : cccc 0110 1011 xxxx xxxx xxxx 0111 xxxx : */ 1397 /* SXTAH : cccc 0110 1011 xxxx xxxx xxxx 0111 xxxx : */
1398 /* SXTH : cccc 0110 1011 1111 xxxx xxxx 0111 xxxx : */
1397 /* UXTAB16 : cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx : */ 1399 /* UXTAB16 : cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx : */
1400 /* UXTB16 : cccc 0110 1100 1111 xxxx xxxx 0111 xxxx : */
1398 /* ??? : cccc 0110 1101 xxxx xxxx xxxx 0111 xxxx : */ 1401 /* ??? : cccc 0110 1101 xxxx xxxx xxxx 0111 xxxx : */
1399 /* UXTAB : cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx : */ 1402 /* UXTAB : cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx : */
1403 /* UXTB : cccc 0110 1110 1111 xxxx xxxx 0111 xxxx : */
1400 /* UXTAH : cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx : */ 1404 /* UXTAH : cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx : */
1405 /* UXTH : cccc 0110 1111 1111 xxxx xxxx 0111 xxxx : */
1401 if ((insn & 0x0f8000f0) == 0x06800070) { 1406 if ((insn & 0x0f8000f0) == 0x06800070) {
1402 if ((insn & 0x00300000) == 0x00100000) 1407 if ((insn & 0x00300000) == 0x00100000)
1403 return INSN_REJECTED; /* Unallocated space */ 1408 return INSN_REJECTED; /* Unallocated space */
1404 return prep_emulate_rd12rn16rm0_wflags(insn, asi); 1409
1410 if ((insn & 0x000f0000) == 0x000f0000) {
1411 return prep_emulate_rd12rm0(insn, asi);
1412 } else {
1413 return prep_emulate_rd12rn16rm0_wflags(insn, asi);
1414 }
1405 } 1415 }
1406 1416
1407 /* Other instruction encodings aren't yet defined */ 1417 /* Other instruction encodings aren't yet defined */