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

Commit 080e0013 authored by Jon Medhurst's avatar Jon Medhurst Committed by Tixy
Browse files

ARM: kprobes: Decode 32-bit Thumb data-processing (shifted register) instructions

parent dd212bd3
Loading
Loading
Loading
Loading
+93 −0
Original line number Diff line number Diff line
@@ -97,6 +97,33 @@ t32_emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs)
	regs->uregs[rt2] = rt2v;
}

static void __kprobes
t32_emulate_rd8rn16rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
{
	kprobe_opcode_t insn = p->opcode;
	int rd = (insn >> 8) & 0xf;
	int rn = (insn >> 16) & 0xf;
	int rm = insn & 0xf;

	register unsigned long rdv asm("r1") = regs->uregs[rd];
	register unsigned long rnv asm("r2") = regs->uregs[rn];
	register unsigned long rmv asm("r3") = regs->uregs[rm];
	unsigned long cpsr = regs->ARM_cpsr;

	__asm__ __volatile__ (
		"msr	cpsr_fs, %[cpsr]	\n\t"
		"blx    %[fn]			\n\t"
		"mrs	%[cpsr], cpsr		\n\t"
		: "=r" (rdv), [cpsr] "=r" (cpsr)
		: "0" (rdv), "r" (rnv), "r" (rmv),
		  "1" (cpsr), [fn] "r" (p->ainsn.insn_fn)
		: "lr", "memory", "cc"
	);

	regs->uregs[rd] = rdv;
	regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
}

static const union decode_item t32_table_1110_100x_x0xx[] = {
	/* Load/store multiple instructions */

@@ -154,6 +181,66 @@ static const union decode_item t32_table_1110_100x_x1xx[] = {
	DECODE_END
};

static const union decode_item t32_table_1110_101x[] = {
	/* Data-processing (shifted register)				*/

	/* TST			1110 1010 0001 xxxx xxxx 1111 xxxx xxxx */
	/* TEQ			1110 1010 1001 xxxx xxxx 1111 xxxx xxxx */
	DECODE_EMULATEX	(0xff700f00, 0xea100f00, t32_emulate_rd8rn16rm0_rwflags,
						 REGS(NOSPPC, 0, 0, 0, NOSPPC)),

	/* CMN			1110 1011 0001 xxxx xxxx 1111 xxxx xxxx */
	DECODE_OR	(0xfff00f00, 0xeb100f00),
	/* CMP			1110 1011 1011 xxxx xxxx 1111 xxxx xxxx */
	DECODE_EMULATEX	(0xfff00f00, 0xebb00f00, t32_emulate_rd8rn16rm0_rwflags,
						 REGS(NOPC, 0, 0, 0, NOSPPC)),

	/* MOV			1110 1010 010x 1111 xxxx xxxx xxxx xxxx */
	/* MVN			1110 1010 011x 1111 xxxx xxxx xxxx xxxx */
	DECODE_EMULATEX	(0xffcf0000, 0xea4f0000, t32_emulate_rd8rn16rm0_rwflags,
						 REGS(0, 0, NOSPPC, 0, NOSPPC)),

	/* ???			1110 1010 101x xxxx xxxx xxxx xxxx xxxx */
	/* ???			1110 1010 111x xxxx xxxx xxxx xxxx xxxx */
	DECODE_REJECT	(0xffa00000, 0xeaa00000),
	/* ???			1110 1011 001x xxxx xxxx xxxx xxxx xxxx */
	DECODE_REJECT	(0xffe00000, 0xeb200000),
	/* ???			1110 1011 100x xxxx xxxx xxxx xxxx xxxx */
	DECODE_REJECT	(0xffe00000, 0xeb800000),
	/* ???			1110 1011 111x xxxx xxxx xxxx xxxx xxxx */
	DECODE_REJECT	(0xffe00000, 0xebe00000),

	/* ADD/SUB SP, SP, Rm, LSL #0..3				*/
	/*			1110 1011 x0xx 1101 x000 1101 xx00 xxxx */
	DECODE_EMULATEX	(0xff4f7f30, 0xeb0d0d00, t32_emulate_rd8rn16rm0_rwflags,
						 REGS(SP, 0, SP, 0, NOSPPC)),

	/* ADD/SUB SP, SP, Rm, shift					*/
	/*			1110 1011 x0xx 1101 xxxx 1101 xxxx xxxx */
	DECODE_REJECT	(0xff4f0f00, 0xeb0d0d00),

	/* ADD/SUB Rd, SP, Rm, shift					*/
	/*			1110 1011 x0xx 1101 xxxx xxxx xxxx xxxx */
	DECODE_EMULATEX	(0xff4f0000, 0xeb0d0000, t32_emulate_rd8rn16rm0_rwflags,
						 REGS(SP, 0, NOPC, 0, NOSPPC)),

	/* AND			1110 1010 000x xxxx xxxx xxxx xxxx xxxx */
	/* BIC			1110 1010 001x xxxx xxxx xxxx xxxx xxxx */
	/* ORR			1110 1010 010x xxxx xxxx xxxx xxxx xxxx */
	/* ORN			1110 1010 011x xxxx xxxx xxxx xxxx xxxx */
	/* EOR			1110 1010 100x xxxx xxxx xxxx xxxx xxxx */
	/* PKH			1110 1010 110x xxxx xxxx xxxx xxxx xxxx */
	/* ADD			1110 1011 000x xxxx xxxx xxxx xxxx xxxx */
	/* ADC			1110 1011 010x xxxx xxxx xxxx xxxx xxxx */
	/* SBC			1110 1011 011x xxxx xxxx xxxx xxxx xxxx */
	/* SUB			1110 1011 101x xxxx xxxx xxxx xxxx xxxx */
	/* RSB			1110 1011 110x xxxx xxxx xxxx xxxx xxxx */
	DECODE_EMULATEX	(0xfe000000, 0xea000000, t32_emulate_rd8rn16rm0_rwflags,
						 REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)),

	DECODE_END
};

static const union decode_item t32_table_1111_0xxx___1[] = {
	/* Branches and miscellaneous control				*/

@@ -183,6 +270,12 @@ const union decode_item kprobe_decode_thumb32_table[] = {
	 */
	DECODE_TABLE	(0xfe400000, 0xe8400000, t32_table_1110_100x_x1xx),

	/*
	 * Data-processing (shifted register)
	 *			1110 101x xxxx xxxx xxxx xxxx xxxx xxxx
	 */
	DECODE_TABLE	(0xfe000000, 0xea000000, t32_table_1110_101x),

	/*
	 * Branches and miscellaneous control
	 *			1111 0xxx xxxx xxxx 1xxx xxxx xxxx xxxx