aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorJon Medhurst <tixy@yxit.co.uk>2011-07-02 11:16:05 -0400
committerTixy <tixy@medhuaa1.miniserver.com>2011-07-13 13:32:44 -0400
commit5b94faf8d76be2116223c2591b31ddae5eecac2b (patch)
tree41671fb7b3002447399c6df74da93d729cf3543c /arch/arm
parentfd0c8d8a48c57cb8a3f1fbbe46a2b208b57ff477 (diff)
ARM: kprobes: Decode 16-bit Thumb IT instruction
The normal Thumb singlestepping routine updates the IT state after calling the instruction handler. We don't what this to happen after the IT instruction simulation sets the IT state, therefore we need to provide a custom singlestep routine. Signed-off-by: Jon Medhurst <tixy@yxit.co.uk> Acked-by: Nicolas Pitre <nicolas.pitre@linaro.org>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/kernel/kprobes-thumb.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/arch/arm/kernel/kprobes-thumb.c b/arch/arm/kernel/kprobes-thumb.c
index e0289493b4c6..e496948fefac 100644
--- a/arch/arm/kernel/kprobes-thumb.c
+++ b/arch/arm/kernel/kprobes-thumb.c
@@ -110,6 +110,37 @@ t16_simulate_cbz(struct kprobe *p, struct pt_regs *regs)
110 } 110 }
111} 111}
112 112
113static void __kprobes
114t16_simulate_it(struct kprobe *p, struct pt_regs *regs)
115{
116 /*
117 * The 8 IT state bits are split into two parts in CPSR:
118 * ITSTATE<1:0> are in CPSR<26:25>
119 * ITSTATE<7:2> are in CPSR<15:10>
120 * The new IT state is in the lower byte of insn.
121 */
122 kprobe_opcode_t insn = p->opcode;
123 unsigned long cpsr = regs->ARM_cpsr;
124 cpsr &= ~PSR_IT_MASK;
125 cpsr |= (insn & 0xfc) << 8;
126 cpsr |= (insn & 0x03) << 25;
127 regs->ARM_cpsr = cpsr;
128}
129
130static void __kprobes
131t16_singlestep_it(struct kprobe *p, struct pt_regs *regs)
132{
133 regs->ARM_pc += 2;
134 t16_simulate_it(p, regs);
135}
136
137static enum kprobe_insn __kprobes
138t16_decode_it(kprobe_opcode_t insn, struct arch_specific_insn *asi)
139{
140 asi->insn_singlestep = t16_singlestep_it;
141 return INSN_GOOD_NO_SLOT;
142}
143
113static unsigned long __kprobes 144static unsigned long __kprobes
114t16_emulate_loregs(struct kprobe *p, struct pt_regs *regs) 145t16_emulate_loregs(struct kprobe *p, struct pt_regs *regs)
115{ 146{
@@ -310,6 +341,8 @@ static const union decode_item t16_table_1011[] = {
310 DECODE_SIMULATE (0xffcf, 0xbf00, kprobe_simulate_nop), 341 DECODE_SIMULATE (0xffcf, 0xbf00, kprobe_simulate_nop),
311 /* Unassigned hints 1011 1111 xxxx 0000 */ 342 /* Unassigned hints 1011 1111 xxxx 0000 */
312 DECODE_REJECT (0xff0f, 0xbf00), 343 DECODE_REJECT (0xff0f, 0xbf00),
344 /* IT 1011 1111 xxxx xxxx */
345 DECODE_CUSTOM (0xff00, 0xbf00, t16_decode_it),
313 346
314 DECODE_END 347 DECODE_END
315}; 348};