diff options
-rw-r--r-- | arch/arm/kernel/kprobes-thumb.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/arch/arm/kernel/kprobes-thumb.c b/arch/arm/kernel/kprobes-thumb.c index 997fc6d59a40..d3133fd2d4e8 100644 --- a/arch/arm/kernel/kprobes-thumb.c +++ b/arch/arm/kernel/kprobes-thumb.c | |||
@@ -141,6 +141,35 @@ t16_decode_it(kprobe_opcode_t insn, struct arch_specific_insn *asi) | |||
141 | return INSN_GOOD_NO_SLOT; | 141 | return INSN_GOOD_NO_SLOT; |
142 | } | 142 | } |
143 | 143 | ||
144 | static void __kprobes | ||
145 | t16_simulate_cond_branch(struct kprobe *p, struct pt_regs *regs) | ||
146 | { | ||
147 | kprobe_opcode_t insn = p->opcode; | ||
148 | unsigned long pc = thumb_probe_pc(p); | ||
149 | long offset = insn & 0x7f; | ||
150 | offset -= insn & 0x80; /* Apply sign bit */ | ||
151 | regs->ARM_pc = pc + (offset * 2); | ||
152 | } | ||
153 | |||
154 | static enum kprobe_insn __kprobes | ||
155 | t16_decode_cond_branch(kprobe_opcode_t insn, struct arch_specific_insn *asi) | ||
156 | { | ||
157 | int cc = (insn >> 8) & 0xf; | ||
158 | asi->insn_check_cc = kprobe_condition_checks[cc]; | ||
159 | asi->insn_handler = t16_simulate_cond_branch; | ||
160 | return INSN_GOOD_NO_SLOT; | ||
161 | } | ||
162 | |||
163 | static void __kprobes | ||
164 | t16_simulate_branch(struct kprobe *p, struct pt_regs *regs) | ||
165 | { | ||
166 | kprobe_opcode_t insn = p->opcode; | ||
167 | unsigned long pc = thumb_probe_pc(p); | ||
168 | long offset = insn & 0x3ff; | ||
169 | offset -= insn & 0x400; /* Apply sign bit */ | ||
170 | regs->ARM_pc = pc + (offset * 2); | ||
171 | } | ||
172 | |||
144 | static unsigned long __kprobes | 173 | static unsigned long __kprobes |
145 | t16_emulate_loregs(struct kprobe *p, struct pt_regs *regs) | 174 | t16_emulate_loregs(struct kprobe *p, struct pt_regs *regs) |
146 | { | 175 | { |
@@ -472,6 +501,15 @@ const union decode_item kprobe_decode_thumb16_table[] = { | |||
472 | /* SVC 1101 1111 xxxx xxxx */ | 501 | /* SVC 1101 1111 xxxx xxxx */ |
473 | DECODE_REJECT (0xfe00, 0xde00), | 502 | DECODE_REJECT (0xfe00, 0xde00), |
474 | 503 | ||
504 | /* Conditional branch 1101 xxxx xxxx xxxx */ | ||
505 | DECODE_CUSTOM (0xf000, 0xd000, t16_decode_cond_branch), | ||
506 | |||
507 | /* | ||
508 | * Unconditional branch | ||
509 | * B 1110 0xxx xxxx xxxx | ||
510 | */ | ||
511 | DECODE_SIMULATE (0xf800, 0xe000, t16_simulate_branch), | ||
512 | |||
475 | DECODE_END | 513 | DECODE_END |
476 | }; | 514 | }; |
477 | 515 | ||