linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] ARM: kprobes: Fixes for ARM instruction emulation
@ 2011-04-04 20:33 Tixy
  2011-04-04 20:33 ` [PATCH 1/4] ARM: kprobes: Fix probing of conditionally executed instructions Tixy
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Tixy @ 2011-04-04 20:33 UTC (permalink / raw)
  To: linux-arm-kernel

When kprobes are inserted into code an ARM instruction is replaced
by a breakpoint. When this is hit, the original instruction must be
emulated out-of-line. This patchset fixes some bugs in this emulation.

[PATCH 1/4] ARM: kprobes: Fix probing of conditionally executed instructions
[PATCH 2/4] ARM: kprobes: Remove redundant condition checks from simulation routines
[PATCH 3/4] ARM: kprobes: Fix emulation of CMP, CMN, TST and TEQ instructions.
[PATCH 4/4] ARM: kprobes: Fix emulation of data processing (immediate) instructions

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/4] ARM: kprobes: Fix probing of conditionally executed instructions
  2011-04-04 20:33 [PATCH 0/4] ARM: kprobes: Fixes for ARM instruction emulation Tixy
@ 2011-04-04 20:33 ` Tixy
  2011-04-04 21:00   ` Nicolas Pitre
  2011-04-04 20:33 ` [PATCH 2/4] ARM: kprobes: Remove redundant condition checks from simulation routines Tixy
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Tixy @ 2011-04-04 20:33 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jon Medhurst <tixy@yxit.co.uk>

When a kprobe is placed onto conditionally executed ARM instructions,
many of the emulation routines used to single step them produce corrupt
register results. Rather than fix all of these cases we modify the
framework which calls them to test the relevant condition flags and, if
the test fails, step the PC onto the next instruction without calling
any emulation code.

Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
---
 arch/arm/include/asm/kprobes.h   |    3 +
 arch/arm/kernel/kprobes-decode.c |    9 ++++
 arch/arm/kernel/kprobes-decode.h |   98 ++++++++++++++++++++++++++++++++++++++
 arch/arm/kernel/kprobes.c        |    3 +-
 4 files changed, 112 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/kernel/kprobes-decode.h

diff --git a/arch/arm/include/asm/kprobes.h b/arch/arm/include/asm/kprobes.h
index bb8a19b..e46bdd0 100644
--- a/arch/arm/include/asm/kprobes.h
+++ b/arch/arm/include/asm/kprobes.h
@@ -39,10 +39,13 @@ typedef u32 kprobe_opcode_t;
 struct kprobe;
 typedef void (kprobe_insn_handler_t)(struct kprobe *, struct pt_regs *);
 
+typedef unsigned long (kprobe_check_cc)(unsigned long);
+
 /* Architecture specific copy of original instruction. */
 struct arch_specific_insn {
 	kprobe_opcode_t		*insn;
 	kprobe_insn_handler_t	*insn_handler;
+	kprobe_check_cc		*insn_check_cc;
 };
 
 struct prev_kprobe {
diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c
index 8f6ed43..c88c8d2 100644
--- a/arch/arm/kernel/kprobes-decode.c
+++ b/arch/arm/kernel/kprobes-decode.c
@@ -63,6 +63,7 @@
 
 #include <linux/kernel.h>
 #include <linux/kprobes.h>
+#include "kprobes-decode.h"
 
 #define sign_extend(x, signbit) ((x) | (0 - ((x) & (1 << (signbit)))))
 
@@ -1384,6 +1385,13 @@ space_cccc_111x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 	return INSN_GOOD;
 }
 
+static kprobe_check_cc* const condition_checks[16] = {
+	&__check_eq, &__check_ne, &__check_cs, &__check_cc,
+	&__check_mi, &__check_pl, &__check_vs, &__check_vc,
+	&__check_hi, &__check_ls, &__check_ge, &__check_lt,
+	&__check_gt, &__check_le, &__check_al, &__check_al
+};
+
 /* Return:
  *   INSN_REJECTED     If instruction is one not allowed to kprobe,
  *   INSN_GOOD         If instruction is supported and uses instruction slot,
@@ -1399,6 +1407,7 @@ space_cccc_111x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 enum kprobe_insn __kprobes
 arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 {
+	asi->insn_check_cc = condition_checks[insn>>28];
 	asi->insn[1] = KPROBE_RETURN_INSTRUCTION;
 
 	if ((insn & 0xf0000000) == 0xf0000000) {
diff --git a/arch/arm/kernel/kprobes-decode.h b/arch/arm/kernel/kprobes-decode.h
new file mode 100644
index 0000000..d6b4337
--- /dev/null
+++ b/arch/arm/kernel/kprobes-decode.h
@@ -0,0 +1,98 @@
+/*
+ * arch/arm/kernel/kprobes-decode.h
+ *
+ * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+static inline unsigned long __kprobes __check_eq(unsigned long cpsr)
+{
+	return cpsr & PSR_Z_BIT;
+}
+
+static inline unsigned long __kprobes __check_ne(unsigned long cpsr)
+{
+	return (~cpsr) & PSR_Z_BIT;
+}
+
+static inline unsigned long __kprobes __check_cs(unsigned long cpsr)
+{
+	return cpsr & PSR_C_BIT;
+}
+
+static inline unsigned long __kprobes __check_cc(unsigned long cpsr)
+{
+	return (~cpsr) & PSR_C_BIT;
+}
+
+static inline unsigned long __kprobes __check_mi(unsigned long cpsr)
+{
+	return cpsr & PSR_N_BIT;
+}
+
+static inline unsigned long __kprobes __check_pl(unsigned long cpsr)
+{
+	return (~cpsr) & PSR_N_BIT;
+}
+
+static inline unsigned long __kprobes __check_vs(unsigned long cpsr)
+{
+	return cpsr & PSR_V_BIT;
+}
+
+static inline unsigned long __kprobes __check_vc(unsigned long cpsr)
+{
+	return (~cpsr) & PSR_V_BIT;
+}
+
+static inline unsigned long __kprobes __check_hi(unsigned long cpsr)
+{
+	cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
+	return cpsr & PSR_C_BIT;
+}
+
+static inline unsigned long __kprobes __check_ls(unsigned long cpsr)
+{
+	cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
+	return (~cpsr) & PSR_C_BIT;
+}
+
+static inline unsigned long __kprobes __check_ge(unsigned long cpsr)
+{
+	cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
+	return (~cpsr) & PSR_N_BIT;
+}
+
+static inline unsigned long __kprobes __check_lt(unsigned long cpsr)
+{
+	cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
+	return cpsr & PSR_N_BIT;
+}
+
+static inline unsigned long __kprobes __check_gt(unsigned long cpsr)
+{
+	cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
+	cpsr |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */
+	return (~cpsr) & PSR_N_BIT;
+}
+
+static inline unsigned long __kprobes __check_le(unsigned long cpsr)
+{
+	cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
+	cpsr |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */
+	return cpsr & PSR_N_BIT;
+}
+
+static inline unsigned long __kprobes __check_al(unsigned long cpsr)
+{
+	return true;
+}
+
+static inline unsigned long __kprobes __check_nv(unsigned long cpsr)
+{
+	return false;
+}
+
diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c
index 2ba7deb..1656c87 100644
--- a/arch/arm/kernel/kprobes.c
+++ b/arch/arm/kernel/kprobes.c
@@ -134,7 +134,8 @@ static void __kprobes singlestep(struct kprobe *p, struct pt_regs *regs,
 				 struct kprobe_ctlblk *kcb)
 {
 	regs->ARM_pc += 4;
-	p->ainsn.insn_handler(p, regs);
+	if (p->ainsn.insn_check_cc(regs->ARM_cpsr))
+		p->ainsn.insn_handler(p, regs);
 }
 
 /*
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/4] ARM: kprobes: Remove redundant condition checks from simulation routines
  2011-04-04 20:33 [PATCH 0/4] ARM: kprobes: Fixes for ARM instruction emulation Tixy
  2011-04-04 20:33 ` [PATCH 1/4] ARM: kprobes: Fix probing of conditionally executed instructions Tixy
@ 2011-04-04 20:33 ` Tixy
  2011-04-04 20:33 ` [PATCH 3/4] ARM: kprobes: Fix emulation of CMP, CMN, TST and TEQ instructions Tixy
  2011-04-04 20:33 ` [PATCH 4/4] ARM: kprobes: Fix emulation of data processing (immediate) instructions Tixy
  3 siblings, 0 replies; 7+ messages in thread
From: Tixy @ 2011-04-04 20:33 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jon Medhurst <tixy@yxit.co.uk>

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

Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
---
 arch/arm/kernel/kprobes-decode.c |   30 +++---------------------------
 1 files changed, 3 insertions(+), 27 deletions(-)

diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c
index c88c8d2..9161fdc 100644
--- a/arch/arm/kernel/kprobes-decode.c
+++ b/arch/arm/kernel/kprobes-decode.c
@@ -72,10 +72,6 @@
 #define PSR_fs	(PSR_f|PSR_s)
 
 #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_1arg_fn_t)(long);
@@ -420,14 +416,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)
 {
-	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
 	kprobe_opcode_t insn = p->opcode;
 	long iaddr = (long)p->addr;
 	int disp  = branch_displacement(insn);
 
-	if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
-		return;
-
 	if (insn & (1 << 24))
 		regs->ARM_lr = iaddr + 4;
 
@@ -447,14 +439,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)
 {
-	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
 	kprobe_opcode_t insn = p->opcode;
 	int rm = insn & 0xf;
 	long rmv = regs->uregs[rm];
 
-	if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
-		return;
-
 	if (insn & (1 << 5))
 		regs->ARM_lr = (long)p->addr + 4;
 
@@ -466,7 +454,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)
 {
-	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
 	kprobe_opcode_t insn = p->opcode;
 	int rn = (insn >> 16) & 0xf;
 	int lbit = insn & (1 << 20);
@@ -477,9 +464,6 @@ static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs)
 	int reg_bit_vector;
 	int reg_count;
 
-	if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
-		return;
-
 	reg_count = 0;
 	reg_bit_vector = insn & 0xffff;
 	while (reg_bit_vector) {
@@ -511,11 +495,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)
 {
-	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;
 	simulate_ldm1stm1(p, regs);
 	regs->ARM_pc = (long)p->addr + 4;
@@ -1045,9 +1024,8 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 		/* BLX(2) : cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */
 		/* BX     : cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */
 		if ((insn & 0x0ff000d0) == 0x01200010) {
-			asi->insn[0] = truecc_insn(insn);
 			asi->insn_handler = simulate_blx2bx;
-			return INSN_GOOD;
+			return INSN_GOOD_NO_SLOT;
 		}
 
 		/* CLZ : cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */
@@ -1322,10 +1300,9 @@ space_cccc_100x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 
 	/* LDM(1) : cccc 100x x0x1 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 */
 				simulate_stm1_pc : simulate_ldm1stm1;
-	return INSN_GOOD;
+	return INSN_GOOD_NO_SLOT;
 }
 
 static enum kprobe_insn __kprobes
@@ -1333,9 +1310,8 @@ space_cccc_101x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 {
 	/* B  : cccc 1010 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;
-	return INSN_GOOD;
+	return INSN_GOOD_NO_SLOT;
 }
 
 static enum kprobe_insn __kprobes
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/4] ARM: kprobes: Fix emulation of CMP, CMN, TST and TEQ instructions.
  2011-04-04 20:33 [PATCH 0/4] ARM: kprobes: Fixes for ARM instruction emulation Tixy
  2011-04-04 20:33 ` [PATCH 1/4] ARM: kprobes: Fix probing of conditionally executed instructions Tixy
  2011-04-04 20:33 ` [PATCH 2/4] ARM: kprobes: Remove redundant condition checks from simulation routines Tixy
@ 2011-04-04 20:33 ` Tixy
  2011-04-04 20:33 ` [PATCH 4/4] ARM: kprobes: Fix emulation of data processing (immediate) instructions Tixy
  3 siblings, 0 replies; 7+ messages in thread
From: Tixy @ 2011-04-04 20:33 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jon Medhurst <tixy@yxit.co.uk>

Probing these instructions was corrupting R0 because the emulation code
didn't account for the fact that they don't write a result to a
register.

Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
---
 arch/arm/kernel/kprobes-decode.c |   55 ++++++++++++++++++++++++++++++++++++-
 1 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c
index 9161fdc..0b8757e 100644
--- a/arch/arm/kernel/kprobes-decode.c
+++ b/arch/arm/kernel/kprobes-decode.c
@@ -797,6 +797,17 @@ emulate_alu_imm_rwflags(struct kprobe *p, struct pt_regs *regs)
 }
 
 static void __kprobes
+emulate_alu_tests_imm(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;
+	int rn = (insn >> 16) & 0xf;
+	long rnv = (rn == 15) ? (long)p->addr + 8 : regs->uregs[rn];
+
+	insnslot_1arg_rwflags(rnv, &regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes
 emulate_alu_rflags(struct kprobe *p, struct pt_regs *regs)
 {
 	insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
@@ -832,6 +843,22 @@ emulate_alu_rwflags(struct kprobe *p, struct pt_regs *regs)
 		insnslot_3arg_rwflags(rnv, rmv, rsv, &regs->ARM_cpsr, i_fn);
 }
 
+static void __kprobes
+emulate_alu_tests(struct kprobe *p, struct pt_regs *regs)
+{
+	insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
+	kprobe_opcode_t insn = p->opcode;
+	long ppc = (long)p->addr + 8;
+	int rn = (insn >> 16) & 0xf;
+	int rs = (insn >> 8) & 0xf;	/* rs/rsv may be invalid, don't care. */
+	int rm = insn & 0xf;
+	long rnv = (rn == 15) ? ppc : regs->uregs[rn];
+	long rmv = (rm == 15) ? ppc : regs->uregs[rm];
+	long rsv = regs->uregs[rs];
+
+	insnslot_3arg_rwflags(rnv, rmv, rsv, &regs->ARM_cpsr, i_fn);
+}
+
 static enum kprobe_insn __kprobes
 prep_emulate_ldr_str(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 {
@@ -1131,8 +1158,20 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 		insn |= 0x00000200;     /* Rs = r2 */
 	}
 	asi->insn[0] = insn;
-	asi->insn_handler = (insn & (1 << 20)) ?  /* S-bit */
+
+	if ((insn & 0x0f900000) == 0x01100000) {
+		/*
+		 * TST : cccc 0001 0001 xxxx xxxx xxxx xxxx xxxx
+		 * TEQ : cccc 0001 0011 xxxx xxxx xxxx xxxx xxxx
+		 * CMP : cccc 0001 0101 xxxx xxxx xxxx xxxx xxxx
+		 * CMN : cccc 0001 0111 xxxx xxxx xxxx xxxx xxxx
+		 */
+		asi->insn_handler = emulate_alu_tests;
+	} else {
+		/* ALU ops which write to Rd */
+		asi->insn_handler = (insn & (1 << 20)) ?  /* S-bit */
 				emulate_alu_rwflags : emulate_alu_rflags;
+	}
 	return INSN_GOOD;
 }
 
@@ -1159,8 +1198,20 @@ space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 	 */
 	insn &= 0xffff0fff;	/* Rd = r0 */
 	asi->insn[0] = insn;
-	asi->insn_handler = (insn & (1 << 20)) ?  /* S-bit */
+
+	if ((insn & 0x0f900000) == 0x03100000) {
+		/*
+		 * TST : cccc 0011 0001 xxxx xxxx xxxx xxxx xxxx
+		 * TEQ : cccc 0011 0011 xxxx xxxx xxxx xxxx xxxx
+		 * CMP : cccc 0011 0101 xxxx xxxx xxxx xxxx xxxx
+		 * CMN : cccc 0011 0111 xxxx xxxx xxxx xxxx xxxx
+		 */
+		asi->insn_handler = emulate_alu_tests_imm;
+	} else {
+		/* ALU ops which write to Rd */
+		asi->insn_handler = (insn & (1 << 20)) ?  /* S-bit */
 			emulate_alu_imm_rwflags : emulate_alu_imm_rflags;
+	}
 	return INSN_GOOD;
 }
 
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 4/4] ARM: kprobes: Fix emulation of data processing (immediate) instructions
  2011-04-04 20:33 [PATCH 0/4] ARM: kprobes: Fixes for ARM instruction emulation Tixy
                   ` (2 preceding siblings ...)
  2011-04-04 20:33 ` [PATCH 3/4] ARM: kprobes: Fix emulation of CMP, CMN, TST and TEQ instructions Tixy
@ 2011-04-04 20:33 ` Tixy
  3 siblings, 0 replies; 7+ messages in thread
From: Tixy @ 2011-04-04 20:33 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jon Medhurst <tixy@yxit.co.uk>

Emulation of instructions like "ADD rd, rn, #<const>" would result in a
corrupted value for rd.

Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
---
 arch/arm/kernel/kprobes-decode.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c
index 0b8757e..11aedd2 100644
--- a/arch/arm/kernel/kprobes-decode.c
+++ b/arch/arm/kernel/kprobes-decode.c
@@ -1196,7 +1196,7 @@ space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 	 * *S (bit 20) updates condition codes
 	 * ADC/SBC/RSC reads the C flag
 	 */
-	insn &= 0xffff0fff;	/* Rd = r0 */
+	insn &= 0xfff00fff;	/* Rn = r0 and Rd = r0 */
 	asi->insn[0] = insn;
 
 	if ((insn & 0x0f900000) == 0x03100000) {
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 1/4] ARM: kprobes: Fix probing of conditionally executed instructions
  2011-04-04 20:33 ` [PATCH 1/4] ARM: kprobes: Fix probing of conditionally executed instructions Tixy
@ 2011-04-04 21:00   ` Nicolas Pitre
  2011-04-05  6:53     ` Tixy
  0 siblings, 1 reply; 7+ messages in thread
From: Nicolas Pitre @ 2011-04-04 21:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 4 Apr 2011, Tixy wrote:

> diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c
> index 8f6ed43..c88c8d2 100644
> --- a/arch/arm/kernel/kprobes-decode.c
> +++ b/arch/arm/kernel/kprobes-decode.c
> @@ -63,6 +63,7 @@
>  
>  #include <linux/kernel.h>
>  #include <linux/kprobes.h>
> +#include "kprobes-decode.h"
>  
>  #define sign_extend(x, signbit) ((x) | (0 - ((x) & (1 << (signbit)))))
>  
> @@ -1384,6 +1385,13 @@ space_cccc_111x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
>  	return INSN_GOOD;
>  }
>  
> +static kprobe_check_cc* const condition_checks[16] = {
> +	&__check_eq, &__check_ne, &__check_cs, &__check_cc,
> +	&__check_mi, &__check_pl, &__check_vs, &__check_vc,
> +	&__check_hi, &__check_ls, &__check_ge, &__check_lt,
> +	&__check_gt, &__check_le, &__check_al, &__check_al
> +};

Here you create an array of function pointers.

> diff --git a/arch/arm/kernel/kprobes-decode.h b/arch/arm/kernel/kprobes-decode.h
> new file mode 100644
> index 0000000..d6b4337
> --- /dev/null
> +++ b/arch/arm/kernel/kprobes-decode.h
> @@ -0,0 +1,98 @@
> +/*
> + * arch/arm/kernel/kprobes-decode.h
> + *
> + * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +static inline unsigned long __kprobes __check_eq(unsigned long cpsr)
> +{
> +	return cpsr & PSR_Z_BIT;
> +}

And those functions are declared static inline in a header file.

Because the array needs pointers to those functions, there is no way the 
compiler will be able to make them inline.  Better put them right before 
the array.


Nicolas

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/4] ARM: kprobes: Fix probing of conditionally executed instructions
  2011-04-04 21:00   ` Nicolas Pitre
@ 2011-04-05  6:53     ` Tixy
  0 siblings, 0 replies; 7+ messages in thread
From: Tixy @ 2011-04-05  6:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 2011-04-04 at 17:00 -0400, Nicolas Pitre wrote:
> On Mon, 4 Apr 2011, Tixy wrote:
> 
> > diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c
> > index 8f6ed43..c88c8d2 100644
> > --- a/arch/arm/kernel/kprobes-decode.c
> > +++ b/arch/arm/kernel/kprobes-decode.c
> > @@ -63,6 +63,7 @@
> >  
> >  #include <linux/kernel.h>
> >  #include <linux/kprobes.h>
> > +#include "kprobes-decode.h"
> >  
> >  #define sign_extend(x, signbit) ((x) | (0 - ((x) & (1 << (signbit)))))
> >  
> > @@ -1384,6 +1385,13 @@ space_cccc_111x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
> >  	return INSN_GOOD;
> >  }
> >  
> > +static kprobe_check_cc* const condition_checks[16] = {
> > +	&__check_eq, &__check_ne, &__check_cs, &__check_cc,
> > +	&__check_mi, &__check_pl, &__check_vs, &__check_vc,
> > +	&__check_hi, &__check_ls, &__check_ge, &__check_lt,
> > +	&__check_gt, &__check_le, &__check_al, &__check_al
> > +};
> 
> Here you create an array of function pointers.
> 
> > diff --git a/arch/arm/kernel/kprobes-decode.h b/arch/arm/kernel/kprobes-decode.h
> > new file mode 100644
> > index 0000000..d6b4337
> > --- /dev/null
> > +++ b/arch/arm/kernel/kprobes-decode.h
> > @@ -0,0 +1,98 @@
> > +/*
> > + * arch/arm/kernel/kprobes-decode.h
> > + *
> > + * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + */
> > +
> > +static inline unsigned long __kprobes __check_eq(unsigned long cpsr)
> > +{
> > +	return cpsr & PSR_Z_BIT;
> > +}
> 
> And those functions are declared static inline in a header file.
> 
> Because the array needs pointers to those functions, there is no way the 
> compiler will be able to make them inline.  Better put them right before 
> the array.

Those functions will also be needed in future for use in a switch
statement for thumb handling code. I wanted to avoid cut'n'paste of the
tests.

If you want, I can put them in the C file now, and move them to a header
when the thumb code gets released. I guess I should have done that
anyway, the thumb code could evolve.

I'm still getting use to juggling patches and branches now the ARM fixes
have interrupted the thumb work.

-- 
Tixy 

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2011-04-05  6:53 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-04-04 20:33 [PATCH 0/4] ARM: kprobes: Fixes for ARM instruction emulation Tixy
2011-04-04 20:33 ` [PATCH 1/4] ARM: kprobes: Fix probing of conditionally executed instructions Tixy
2011-04-04 21:00   ` Nicolas Pitre
2011-04-05  6:53     ` Tixy
2011-04-04 20:33 ` [PATCH 2/4] ARM: kprobes: Remove redundant condition checks from simulation routines Tixy
2011-04-04 20:33 ` [PATCH 3/4] ARM: kprobes: Fix emulation of CMP, CMN, TST and TEQ instructions Tixy
2011-04-04 20:33 ` [PATCH 4/4] ARM: kprobes: Fix emulation of data processing (immediate) instructions Tixy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).