diff options
author | Jon Medhurst <tixy@yxit.co.uk> | 2011-04-12 02:45:24 -0400 |
---|---|---|
committer | Nicolas Pitre <nicolas.pitre@linaro.org> | 2011-04-28 23:40:58 -0400 |
commit | 8dd7cfbed83c74b1fb991fae264944e041e22e62 (patch) | |
tree | 97eac596f52e2244a2fc96020ef666d01504e637 /arch | |
parent | 780b5c1162286cc75ef2dcc0f14215d9f9f06230 (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.c | 14 |
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 */ |