diff options
author | Jon Medhurst <tixy@yxit.co.uk> | 2011-06-09 11:01:54 +0100 |
---|---|---|
committer | Tixy <tixy@medhuaa1.miniserver.com> | 2011-07-13 17:32:43 +0000 |
commit | 059987ffa7f8905fada25c8af1734e254209c55d (patch) | |
tree | 81b04303f15f9046bd59e54e70e1dda3103cd75a /arch/arm/kernel/kprobes.h | |
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>
Diffstat (limited to 'arch/arm/kernel/kprobes.h')
-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 36e07684fe0..12627a376bf 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) return cpsr; } +static inline void __kprobes bx_write_pc(long pcv, struct pt_regs *regs) +{ + long cpsr = regs->ARM_cpsr; + if (pcv & 0x1) { + cpsr |= PSR_T_BIT; + pcv &= ~0x1; + } else { + cpsr &= ~PSR_T_BIT; + pcv &= ~0x2; /* Avoid UNPREDICTABLE address allignment */ + } + regs->ARM_cpsr = cpsr; + regs->ARM_pc = pcv; +} + void __kprobes kprobe_simulate_nop(struct kprobe *p, struct pt_regs *regs); void __kprobes kprobe_emulate_none(struct kprobe *p, struct pt_regs *regs); |