diff options
author | Jon Medhurst <tixy@yxit.co.uk> | 2011-07-02 11:05:53 -0400 |
---|---|---|
committer | Tixy <tixy@medhuaa1.miniserver.com> | 2011-07-13 13:32:44 -0400 |
commit | 2f335829040cb16d0640e87121bef208894d4934 (patch) | |
tree | d4377f53bbbc4a6983716c305bccee697fa1c269 /arch/arm/kernel/kprobes-thumb.c | |
parent | f8695142820f3cb3bc97444a240eec5375a2b107 (diff) |
ARM: kprobes: Decode 16-bit Thumb PC- and SP-relative address 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 | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/arch/arm/kernel/kprobes-thumb.c b/arch/arm/kernel/kprobes-thumb.c index 632a5e8f5977..2b30828d5f0c 100644 --- a/arch/arm/kernel/kprobes-thumb.c +++ b/arch/arm/kernel/kprobes-thumb.c | |||
@@ -74,6 +74,28 @@ t16_simulate_ldrstr_sp_relative(struct kprobe *p, struct pt_regs *regs) | |||
74 | base[index] = regs->uregs[rt]; | 74 | base[index] = regs->uregs[rt]; |
75 | } | 75 | } |
76 | 76 | ||
77 | static void __kprobes | ||
78 | t16_simulate_reladr(struct kprobe *p, struct pt_regs *regs) | ||
79 | { | ||
80 | kprobe_opcode_t insn = p->opcode; | ||
81 | unsigned long base = (insn & 0x800) ? regs->ARM_sp | ||
82 | : (thumb_probe_pc(p) & ~3); | ||
83 | long offset = insn & 0xff; | ||
84 | int rt = (insn >> 8) & 0x7; | ||
85 | regs->uregs[rt] = base + offset * 4; | ||
86 | } | ||
87 | |||
88 | static void __kprobes | ||
89 | t16_simulate_add_sp_imm(struct kprobe *p, struct pt_regs *regs) | ||
90 | { | ||
91 | kprobe_opcode_t insn = p->opcode; | ||
92 | long imm = insn & 0x7f; | ||
93 | if (insn & 0x80) /* SUB */ | ||
94 | regs->ARM_sp -= imm * 4; | ||
95 | else /* ADD */ | ||
96 | regs->ARM_sp += imm * 4; | ||
97 | } | ||
98 | |||
77 | static unsigned long __kprobes | 99 | static unsigned long __kprobes |
78 | t16_emulate_loregs(struct kprobe *p, struct pt_regs *regs) | 100 | t16_emulate_loregs(struct kprobe *p, struct pt_regs *regs) |
79 | { | 101 | { |
@@ -154,6 +176,10 @@ t16_decode_hiregs(kprobe_opcode_t insn, struct arch_specific_insn *asi) | |||
154 | static const union decode_item t16_table_1011[] = { | 176 | static const union decode_item t16_table_1011[] = { |
155 | /* Miscellaneous 16-bit instructions */ | 177 | /* Miscellaneous 16-bit instructions */ |
156 | 178 | ||
179 | /* ADD (SP plus immediate) 1011 0000 0xxx xxxx */ | ||
180 | /* SUB (SP minus immediate) 1011 0000 1xxx xxxx */ | ||
181 | DECODE_SIMULATE (0xff00, 0xb000, t16_simulate_add_sp_imm), | ||
182 | |||
157 | /* | 183 | /* |
158 | * If-Then, and hints | 184 | * If-Then, and hints |
159 | * 1011 1111 xxxx xxxx | 185 | * 1011 1111 xxxx xxxx |
@@ -274,6 +300,13 @@ const union decode_item kprobe_decode_thumb16_table[] = { | |||
274 | DECODE_SIMULATE (0xf000, 0x9000, t16_simulate_ldrstr_sp_relative), | 300 | DECODE_SIMULATE (0xf000, 0x9000, t16_simulate_ldrstr_sp_relative), |
275 | 301 | ||
276 | /* | 302 | /* |
303 | * Generate PC-/SP-relative address | ||
304 | * ADR (literal) 1010 0xxx xxxx xxxx | ||
305 | * ADD (SP plus immediate) 1010 1xxx xxxx xxxx | ||
306 | */ | ||
307 | DECODE_SIMULATE (0xf000, 0xa000, t16_simulate_reladr), | ||
308 | |||
309 | /* | ||
277 | * Miscellaneous 16-bit instructions | 310 | * Miscellaneous 16-bit instructions |
278 | * 1011 xxxx xxxx xxxx | 311 | * 1011 xxxx xxxx xxxx |
279 | */ | 312 | */ |