Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a539f5d4 authored by Jon Medhurst's avatar Jon Medhurst Committed by Nicolas Pitre
Browse files

ARM: kprobes: Remove redundant condition checks from simulation routines



Now we have the framework code handling conditionally executed
instructions we can remove redundant checks in individual simulation
routines.

Signed-off-by: default avatarJon Medhurst <tixy@yxit.co.uk>
Signed-off-by: default avatarNicolas Pitre <nicolas.pitre@linaro.org>
parent 073090cb
Loading
Loading
Loading
Loading
+3 −27
Original line number Original line Diff line number Diff line
@@ -71,10 +71,6 @@
#define PSR_fs	(PSR_f|PSR_s)
#define PSR_fs	(PSR_f|PSR_s)


#define KPROBE_RETURN_INSTRUCTION	0xe1a0f00e	/* mov pc, lr */
#define KPROBE_RETURN_INSTRUCTION	0xe1a0f00e	/* mov pc, lr */
#define SET_R0_TRUE_INSTRUCTION		0xe3a00001	/* mov	r0, #1 */

#define	truecc_insn(insn)	(((insn) & 0xf0000000) | \
				 (SET_R0_TRUE_INSTRUCTION & 0x0fffffff))


typedef long (insn_0arg_fn_t)(void);
typedef long (insn_0arg_fn_t)(void);
typedef long (insn_1arg_fn_t)(long);
typedef long (insn_1arg_fn_t)(long);
@@ -419,14 +415,10 @@ insnslot_llret_4arg_rwflags(long r0, long r1, long r2, long r3, long *cpsr,


static void __kprobes simulate_bbl(struct kprobe *p, struct pt_regs *regs)
static void __kprobes simulate_bbl(struct kprobe *p, struct pt_regs *regs)
{
{
	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
	kprobe_opcode_t insn = p->opcode;
	kprobe_opcode_t insn = p->opcode;
	long iaddr = (long)p->addr;
	long iaddr = (long)p->addr;
	int disp  = branch_displacement(insn);
	int disp  = branch_displacement(insn);


	if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
		return;

	if (insn & (1 << 24))
	if (insn & (1 << 24))
		regs->ARM_lr = iaddr + 4;
		regs->ARM_lr = iaddr + 4;


@@ -446,14 +438,10 @@ static void __kprobes simulate_blx1(struct kprobe *p, struct pt_regs *regs)


static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs)
static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs)
{
{
	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
	kprobe_opcode_t insn = p->opcode;
	kprobe_opcode_t insn = p->opcode;
	int rm = insn & 0xf;
	int rm = insn & 0xf;
	long rmv = regs->uregs[rm];
	long rmv = regs->uregs[rm];


	if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
		return;

	if (insn & (1 << 5))
	if (insn & (1 << 5))
		regs->ARM_lr = (long)p->addr + 4;
		regs->ARM_lr = (long)p->addr + 4;


@@ -465,7 +453,6 @@ static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs)


static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs)
static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs)
{
{
	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
	kprobe_opcode_t insn = p->opcode;
	kprobe_opcode_t insn = p->opcode;
	int rn = (insn >> 16) & 0xf;
	int rn = (insn >> 16) & 0xf;
	int lbit = insn & (1 << 20);
	int lbit = insn & (1 << 20);
@@ -476,9 +463,6 @@ static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs)
	int reg_bit_vector;
	int reg_bit_vector;
	int reg_count;
	int reg_count;


	if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
		return;

	reg_count = 0;
	reg_count = 0;
	reg_bit_vector = insn & 0xffff;
	reg_bit_vector = insn & 0xffff;
	while (reg_bit_vector) {
	while (reg_bit_vector) {
@@ -510,11 +494,6 @@ static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs)


static void __kprobes simulate_stm1_pc(struct kprobe *p, struct pt_regs *regs)
static void __kprobes simulate_stm1_pc(struct kprobe *p, struct pt_regs *regs)
{
{
	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];

	if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
		return;

	regs->ARM_pc = (long)p->addr + str_pc_offset;
	regs->ARM_pc = (long)p->addr + str_pc_offset;
	simulate_ldm1stm1(p, regs);
	simulate_ldm1stm1(p, regs);
	regs->ARM_pc = (long)p->addr + 4;
	regs->ARM_pc = (long)p->addr + 4;
@@ -1056,9 +1035,8 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
		/* BLX(2) : cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */
		/* BLX(2) : cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */
		/* BX     : cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */
		/* BX     : cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */
		if ((insn & 0x0ff000d0) == 0x01200010) {
		if ((insn & 0x0ff000d0) == 0x01200010) {
			asi->insn[0] = truecc_insn(insn);
			asi->insn_handler = simulate_blx2bx;
			asi->insn_handler = simulate_blx2bx;
			return INSN_GOOD;
			return INSN_GOOD_NO_SLOT;
		}
		}


		/* CLZ : cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */
		/* CLZ : cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */
@@ -1333,10 +1311,9 @@ space_cccc_100x(kprobe_opcode_t insn, struct arch_specific_insn *asi)


	/* LDM(1) : cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
	/* LDM(1) : cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
	/* STM(1) : cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */
	/* STM(1) : cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */
	asi->insn[0] = truecc_insn(insn);
	asi->insn_handler = ((insn & 0x108000) == 0x008000) ? /* STM & R15 */
	asi->insn_handler = ((insn & 0x108000) == 0x008000) ? /* STM & R15 */
				simulate_stm1_pc : simulate_ldm1stm1;
				simulate_stm1_pc : simulate_ldm1stm1;
	return INSN_GOOD;
	return INSN_GOOD_NO_SLOT;
}
}


static enum kprobe_insn __kprobes
static enum kprobe_insn __kprobes
@@ -1344,9 +1321,8 @@ space_cccc_101x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
{
{
	/* B  : cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */
	/* B  : cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */
	/* BL : cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */
	/* BL : cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */
	asi->insn[0] = truecc_insn(insn);
	asi->insn_handler = simulate_bbl;
	asi->insn_handler = simulate_bbl;
	return INSN_GOOD;
	return INSN_GOOD_NO_SLOT;
}
}


static enum kprobe_insn __kprobes
static enum kprobe_insn __kprobes