diff options
author | Jon Medhurst <tixy@yxit.co.uk> | 2011-07-02 10:51:03 -0400 |
---|---|---|
committer | Tixy <tixy@medhuaa1.miniserver.com> | 2011-07-13 13:32:43 -0400 |
commit | a9c3c29e72cc459be0ecd597f0af11a67713175b (patch) | |
tree | e167451c8ebfef40c75f0c52fc3c14bc97dadaea /arch/arm/kernel/kprobes-thumb.c | |
parent | 059987ffa7f8905fada25c8af1734e254209c55d (diff) |
ARM: kprobes: Decode 16-bit Thumb BX and BLX 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 | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/arch/arm/kernel/kprobes-thumb.c b/arch/arm/kernel/kprobes-thumb.c index e1cef8273126..b457da0e7397 100644 --- a/arch/arm/kernel/kprobes-thumb.c +++ b/arch/arm/kernel/kprobes-thumb.c | |||
@@ -26,6 +26,31 @@ | |||
26 | */ | 26 | */ |
27 | #define current_cond(cpsr) ((cpsr >> 12) & 0xf) | 27 | #define current_cond(cpsr) ((cpsr >> 12) & 0xf) |
28 | 28 | ||
29 | /* | ||
30 | * Return the PC value for a probe in thumb code. | ||
31 | * This is the address of the probed instruction plus 4. | ||
32 | * We subtract one because the address will have bit zero set to indicate | ||
33 | * a pointer to thumb code. | ||
34 | */ | ||
35 | static inline unsigned long __kprobes thumb_probe_pc(struct kprobe *p) | ||
36 | { | ||
37 | return (unsigned long)p->addr - 1 + 4; | ||
38 | } | ||
39 | |||
40 | static void __kprobes | ||
41 | t16_simulate_bxblx(struct kprobe *p, struct pt_regs *regs) | ||
42 | { | ||
43 | kprobe_opcode_t insn = p->opcode; | ||
44 | unsigned long pc = thumb_probe_pc(p); | ||
45 | int rm = (insn >> 3) & 0xf; | ||
46 | unsigned long rmv = (rm == 15) ? pc : regs->uregs[rm]; | ||
47 | |||
48 | if (insn & (1 << 7)) /* BLX ? */ | ||
49 | regs->ARM_lr = (unsigned long)p->addr + 2; | ||
50 | |||
51 | bx_write_pc(rmv, regs); | ||
52 | } | ||
53 | |||
29 | static unsigned long __kprobes | 54 | static unsigned long __kprobes |
30 | t16_emulate_loregs(struct kprobe *p, struct pt_regs *regs) | 55 | t16_emulate_loregs(struct kprobe *p, struct pt_regs *regs) |
31 | { | 56 | { |
@@ -132,6 +157,18 @@ const union decode_item kprobe_decode_thumb16_table[] = { | |||
132 | DECODE_EMULATE (0xfc00, 0x4000, t16_emulate_loregs_noitrwflags), | 157 | DECODE_EMULATE (0xfc00, 0x4000, t16_emulate_loregs_noitrwflags), |
133 | 158 | ||
134 | /* | 159 | /* |
160 | * Special data instructions and branch and exchange | ||
161 | * 0100 01xx xxxx xxxx | ||
162 | */ | ||
163 | |||
164 | /* BLX pc 0100 0111 1111 1xxx */ | ||
165 | DECODE_REJECT (0xfff8, 0x47f8), | ||
166 | |||
167 | /* BX (register) 0100 0111 0xxx xxxx */ | ||
168 | /* BLX (register) 0100 0111 1xxx xxxx */ | ||
169 | DECODE_SIMULATE (0xff00, 0x4700, t16_simulate_bxblx), | ||
170 | |||
171 | /* | ||
135 | * Miscellaneous 16-bit instructions | 172 | * Miscellaneous 16-bit instructions |
136 | * 1011 xxxx xxxx xxxx | 173 | * 1011 xxxx xxxx xxxx |
137 | */ | 174 | */ |