Commit 263e368a authored by Jon Medhurst's avatar Jon Medhurst Committed by Tixy
Browse files

ARM: kprobes: Add load_write_pc()



This writes a value to PC which was obtained as the result of a
LDR or LDM instruction. For ARMv5T and later this must perform
interworking.

Signed-off-by: default avatarJon Medhurst <tixy@yxit.co.uk>
Acked-by: default avatarNicolas Pitre <nicolas.pitre@linaro.org>
parent f39ca8b4
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -45,9 +45,24 @@ void __init find_str_pc_offset(void)
#endif /* !find_str_pc_offset */


#ifndef test_load_write_pc_interworking

bool load_write_pc_interworks;

void __init test_load_write_pc_interworking(void)
{
	int arch = cpu_architecture();
	BUG_ON(arch == CPU_ARCH_UNKNOWN);
	load_write_pc_interworks = arch >= CPU_ARCH_ARMv5T;
}

#endif /* !test_load_write_pc_interworking */


void __init arm_kprobe_decode_init(void)
{
	find_str_pc_offset();
	test_load_write_pc_interworking();
}


+24 −0
Original line number Diff line number Diff line
@@ -109,6 +109,30 @@ static inline void __kprobes bx_write_pc(long pcv, struct pt_regs *regs)
	regs->ARM_pc = pcv;
}


#if __LINUX_ARM_ARCH__ >= 6

/* Kernels built for >= ARMv6 should never run on <= ARMv5 hardware, so... */
#define load_write_pc_interworks true
#define test_load_write_pc_interworking()

#else /* __LINUX_ARM_ARCH__ < 6 */

/* We need run-time testing to determine if load_write_pc() should interwork. */
extern bool load_write_pc_interworks;
void __init test_load_write_pc_interworking(void);

#endif

static inline void __kprobes load_write_pc(long pcv, struct pt_regs *regs)
{
	if (load_write_pc_interworks)
		bx_write_pc(pcv, regs);
	else
		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);