diff options
author | Jon Medhurst <tixy@yxit.co.uk> | 2011-06-09 06:01:54 -0400 |
---|---|---|
committer | Tixy <tixy@medhuaa1.miniserver.com> | 2011-07-13 13:32:43 -0400 |
commit | 059987ffa7f8905fada25c8af1734e254209c55d (patch) | |
tree | 81b04303f15f9046bd59e54e70e1dda3103cd75a | |
parent | 02d194f64772aee91e7319ca033905b0bafee04c (diff) |
ARM: kprobes: Add bx_write_pc()
This writes a value to PC, with interworking. I.e. switches to Thumb or
ARM mode depending on the state of the least significant bit.
Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
Acked-by: Nicolas Pitre <nicolas.pitre@linaro.org>
-rw-r--r-- | arch/arm/kernel/kprobes.h | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/arch/arm/kernel/kprobes.h b/arch/arm/kernel/kprobes.h index 36e07684fe08..12627a376bf6 100644 --- a/arch/arm/kernel/kprobes.h +++ b/arch/arm/kernel/kprobes.h | |||
@@ -95,6 +95,20 @@ static inline unsigned long it_advance(unsigned long cpsr) | |||
95 | return cpsr; | 95 | return cpsr; |
96 | } | 96 | } |
97 | 97 | ||
98 | static inline void __kprobes bx_write_pc(long pcv, struct pt_regs *regs) | ||
99 | { | ||
100 | long cpsr = regs->ARM_cpsr; | ||
101 | if (pcv & 0x1) { | ||
102 | cpsr |= PSR_T_BIT; | ||
103 | pcv &= ~0x1; | ||
104 | } else { | ||
105 | cpsr &= ~PSR_T_BIT; | ||
106 | pcv &= ~0x2; /* Avoid UNPREDICTABLE address allignment */ | ||
107 | } | ||
108 | regs->ARM_cpsr = cpsr; | ||
109 | regs->ARM_pc = pcv; | ||
110 | } | ||
111 | |||
98 | void __kprobes kprobe_simulate_nop(struct kprobe *p, struct pt_regs *regs); | 112 | void __kprobes kprobe_simulate_nop(struct kprobe *p, struct pt_regs *regs); |
99 | void __kprobes kprobe_emulate_none(struct kprobe *p, struct pt_regs *regs); | 113 | void __kprobes kprobe_emulate_none(struct kprobe *p, struct pt_regs *regs); |
100 | 114 | ||