Loading arch/arm/kernel/kprobes-arm.c +90 −80 Original line number Diff line number Diff line Loading @@ -1209,27 +1209,6 @@ static const union decode_item arm_cccc_000x_table[] = { DECODE_END }; static enum kprobe_insn __kprobes space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi) { if ((insn & 0x0f900080) == 0x01000000) return kprobe_decode_insn(insn, asi, arm_cccc_0001_0xx0____0xxx_table, false); if ((insn & 0x0f900090) == 0x01000080) return kprobe_decode_insn(insn, asi, arm_cccc_0001_0xx0____1xx0_table, false); if ((insn & 0x0f0000f0) == 0x00000090) return kprobe_decode_insn(insn, asi, arm_cccc_0000_____1001_table, false); if ((insn & 0x0f0000f0) == 0x01000090) return kprobe_decode_insn(insn, asi, arm_cccc_0001_____1001_table, false); if ((insn & 0x0e000090) == 0x00000090) return kprobe_decode_insn(insn, asi, arm_cccc_000x_____1xx1_table, false); return kprobe_decode_insn(insn, asi, arm_cccc_000x_table, false); } static const union decode_item arm_cccc_001x_table[] = { /* Data-processing (immediate) */ Loading Loading @@ -1447,31 +1426,96 @@ static const union decode_item arm_cccc_100x_table[] = { DECODE_END }; static enum kprobe_insn __kprobes 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_handler = simulate_bbl; return INSN_GOOD_NO_SLOT; } const union decode_item kprobe_decode_arm_table[] = { /* * Unconditional instructions * 1111 xxxx xxxx xxxx xxxx xxxx xxxx xxxx */ DECODE_TABLE (0xf0000000, 0xf0000000, arm_1111_table), static enum kprobe_insn __kprobes space_cccc_11xx(kprobe_opcode_t insn, struct arch_specific_insn *asi) { /* Coprocessor instructions... */ /* MCRR : cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */ /* MRRC : cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */ /* LDC : cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */ /* STC : cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */ /* CDP : cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */ /* MCR : cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */ /* MRC : cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */ /* * Miscellaneous instructions * cccc 0001 0xx0 xxxx xxxx xxxx 0xxx xxxx */ DECODE_TABLE (0x0f900080, 0x01000000, arm_cccc_0001_0xx0____0xxx_table), /* SVC : cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */ /* * Halfword multiply and multiply-accumulate * cccc 0001 0xx0 xxxx xxxx xxxx 1xx0 xxxx */ DECODE_TABLE (0x0f900090, 0x01000080, arm_cccc_0001_0xx0____1xx0_table), return INSN_REJECTED; } /* * Multiply and multiply-accumulate * cccc 0000 xxxx xxxx xxxx xxxx 1001 xxxx */ DECODE_TABLE (0x0f0000f0, 0x00000090, arm_cccc_0000_____1001_table), /* * Synchronization primitives * cccc 0001 xxxx xxxx xxxx xxxx 1001 xxxx */ DECODE_TABLE (0x0f0000f0, 0x01000090, arm_cccc_0001_____1001_table), /* * Extra load/store instructions * cccc 000x xxxx xxxx xxxx xxxx 1xx1 xxxx */ DECODE_TABLE (0x0e000090, 0x00000090, arm_cccc_000x_____1xx1_table), /* * Data-processing (register) * cccc 000x xxxx xxxx xxxx xxxx xxx0 xxxx * Data-processing (register-shifted register) * cccc 000x xxxx xxxx xxxx xxxx 0xx1 xxxx */ DECODE_TABLE (0x0e000000, 0x00000000, arm_cccc_000x_table), /* * Data-processing (immediate) * cccc 001x xxxx xxxx xxxx xxxx xxxx xxxx */ DECODE_TABLE (0x0e000000, 0x02000000, arm_cccc_001x_table), /* * Media instructions * cccc 011x xxxx xxxx xxxx xxxx xxx1 xxxx */ DECODE_TABLE (0x0f000010, 0x06000010, arm_cccc_0110_____xxx1_table), DECODE_TABLE (0x0f000010, 0x07000010, arm_cccc_0111_____xxx1_table), /* * Load/store word and unsigned byte * cccc 01xx xxxx xxxx xxxx xxxx xxxx xxxx */ DECODE_TABLE (0x0c000000, 0x04000000, arm_cccc_01xx_table), /* * Block data transfer instructions * cccc 100x xxxx xxxx xxxx xxxx xxxx xxxx */ DECODE_TABLE (0x0e000000, 0x08000000, arm_cccc_100x_table), /* B cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */ /* BL cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */ DECODE_SIMULATE (0x0e000000, 0x0a000000, simulate_bbl), /* * Supervisor Call, and coprocessor instructions */ /* MCRR cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx */ /* MRRC cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx */ /* LDC cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */ /* STC cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */ /* CDP cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */ /* MCR cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */ /* MRC cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */ /* SVC cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */ DECODE_REJECT (0x0c000000, 0x0c000000), DECODE_END }; static void __kprobes arm_singlestep(struct kprobe *p, struct pt_regs *regs) { Loading @@ -1496,39 +1540,5 @@ arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi) { asi->insn_singlestep = arm_singlestep; asi->insn_check_cc = kprobe_condition_checks[insn>>28]; asi->insn[1] = KPROBE_RETURN_INSTRUCTION; if ((insn & 0xf0000000) == 0xf0000000) return kprobe_decode_insn(insn, asi, arm_1111_table, false); else if ((insn & 0x0e000000) == 0x00000000) return space_cccc_000x(insn, asi); else if ((insn & 0x0e000000) == 0x02000000) return kprobe_decode_insn(insn, asi, arm_cccc_001x_table, false); else if ((insn & 0x0f000010) == 0x06000010) return kprobe_decode_insn(insn, asi, arm_cccc_0110_____xxx1_table, false); else if ((insn & 0x0f000010) == 0x07000010) return kprobe_decode_insn(insn, asi, arm_cccc_0111_____xxx1_table, false); else if ((insn & 0x0c000000) == 0x04000000) return kprobe_decode_insn(insn, asi, arm_cccc_01xx_table, false); else if ((insn & 0x0e000000) == 0x08000000) return kprobe_decode_insn(insn, asi, arm_cccc_100x_table, false); else if ((insn & 0x0e000000) == 0x0a000000) return space_cccc_101x(insn, asi); return space_cccc_11xx(insn, asi); return kprobe_decode_insn(insn, asi, kprobe_decode_arm_table, false); } Loading
arch/arm/kernel/kprobes-arm.c +90 −80 Original line number Diff line number Diff line Loading @@ -1209,27 +1209,6 @@ static const union decode_item arm_cccc_000x_table[] = { DECODE_END }; static enum kprobe_insn __kprobes space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi) { if ((insn & 0x0f900080) == 0x01000000) return kprobe_decode_insn(insn, asi, arm_cccc_0001_0xx0____0xxx_table, false); if ((insn & 0x0f900090) == 0x01000080) return kprobe_decode_insn(insn, asi, arm_cccc_0001_0xx0____1xx0_table, false); if ((insn & 0x0f0000f0) == 0x00000090) return kprobe_decode_insn(insn, asi, arm_cccc_0000_____1001_table, false); if ((insn & 0x0f0000f0) == 0x01000090) return kprobe_decode_insn(insn, asi, arm_cccc_0001_____1001_table, false); if ((insn & 0x0e000090) == 0x00000090) return kprobe_decode_insn(insn, asi, arm_cccc_000x_____1xx1_table, false); return kprobe_decode_insn(insn, asi, arm_cccc_000x_table, false); } static const union decode_item arm_cccc_001x_table[] = { /* Data-processing (immediate) */ Loading Loading @@ -1447,31 +1426,96 @@ static const union decode_item arm_cccc_100x_table[] = { DECODE_END }; static enum kprobe_insn __kprobes 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_handler = simulate_bbl; return INSN_GOOD_NO_SLOT; } const union decode_item kprobe_decode_arm_table[] = { /* * Unconditional instructions * 1111 xxxx xxxx xxxx xxxx xxxx xxxx xxxx */ DECODE_TABLE (0xf0000000, 0xf0000000, arm_1111_table), static enum kprobe_insn __kprobes space_cccc_11xx(kprobe_opcode_t insn, struct arch_specific_insn *asi) { /* Coprocessor instructions... */ /* MCRR : cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */ /* MRRC : cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */ /* LDC : cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */ /* STC : cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */ /* CDP : cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */ /* MCR : cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */ /* MRC : cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */ /* * Miscellaneous instructions * cccc 0001 0xx0 xxxx xxxx xxxx 0xxx xxxx */ DECODE_TABLE (0x0f900080, 0x01000000, arm_cccc_0001_0xx0____0xxx_table), /* SVC : cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */ /* * Halfword multiply and multiply-accumulate * cccc 0001 0xx0 xxxx xxxx xxxx 1xx0 xxxx */ DECODE_TABLE (0x0f900090, 0x01000080, arm_cccc_0001_0xx0____1xx0_table), return INSN_REJECTED; } /* * Multiply and multiply-accumulate * cccc 0000 xxxx xxxx xxxx xxxx 1001 xxxx */ DECODE_TABLE (0x0f0000f0, 0x00000090, arm_cccc_0000_____1001_table), /* * Synchronization primitives * cccc 0001 xxxx xxxx xxxx xxxx 1001 xxxx */ DECODE_TABLE (0x0f0000f0, 0x01000090, arm_cccc_0001_____1001_table), /* * Extra load/store instructions * cccc 000x xxxx xxxx xxxx xxxx 1xx1 xxxx */ DECODE_TABLE (0x0e000090, 0x00000090, arm_cccc_000x_____1xx1_table), /* * Data-processing (register) * cccc 000x xxxx xxxx xxxx xxxx xxx0 xxxx * Data-processing (register-shifted register) * cccc 000x xxxx xxxx xxxx xxxx 0xx1 xxxx */ DECODE_TABLE (0x0e000000, 0x00000000, arm_cccc_000x_table), /* * Data-processing (immediate) * cccc 001x xxxx xxxx xxxx xxxx xxxx xxxx */ DECODE_TABLE (0x0e000000, 0x02000000, arm_cccc_001x_table), /* * Media instructions * cccc 011x xxxx xxxx xxxx xxxx xxx1 xxxx */ DECODE_TABLE (0x0f000010, 0x06000010, arm_cccc_0110_____xxx1_table), DECODE_TABLE (0x0f000010, 0x07000010, arm_cccc_0111_____xxx1_table), /* * Load/store word and unsigned byte * cccc 01xx xxxx xxxx xxxx xxxx xxxx xxxx */ DECODE_TABLE (0x0c000000, 0x04000000, arm_cccc_01xx_table), /* * Block data transfer instructions * cccc 100x xxxx xxxx xxxx xxxx xxxx xxxx */ DECODE_TABLE (0x0e000000, 0x08000000, arm_cccc_100x_table), /* B cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */ /* BL cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */ DECODE_SIMULATE (0x0e000000, 0x0a000000, simulate_bbl), /* * Supervisor Call, and coprocessor instructions */ /* MCRR cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx */ /* MRRC cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx */ /* LDC cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */ /* STC cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */ /* CDP cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */ /* MCR cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */ /* MRC cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */ /* SVC cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */ DECODE_REJECT (0x0c000000, 0x0c000000), DECODE_END }; static void __kprobes arm_singlestep(struct kprobe *p, struct pt_regs *regs) { Loading @@ -1496,39 +1540,5 @@ arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi) { asi->insn_singlestep = arm_singlestep; asi->insn_check_cc = kprobe_condition_checks[insn>>28]; asi->insn[1] = KPROBE_RETURN_INSTRUCTION; if ((insn & 0xf0000000) == 0xf0000000) return kprobe_decode_insn(insn, asi, arm_1111_table, false); else if ((insn & 0x0e000000) == 0x00000000) return space_cccc_000x(insn, asi); else if ((insn & 0x0e000000) == 0x02000000) return kprobe_decode_insn(insn, asi, arm_cccc_001x_table, false); else if ((insn & 0x0f000010) == 0x06000010) return kprobe_decode_insn(insn, asi, arm_cccc_0110_____xxx1_table, false); else if ((insn & 0x0f000010) == 0x07000010) return kprobe_decode_insn(insn, asi, arm_cccc_0111_____xxx1_table, false); else if ((insn & 0x0c000000) == 0x04000000) return kprobe_decode_insn(insn, asi, arm_cccc_01xx_table, false); else if ((insn & 0x0e000000) == 0x08000000) return kprobe_decode_insn(insn, asi, arm_cccc_100x_table, false); else if ((insn & 0x0e000000) == 0x0a000000) return space_cccc_101x(insn, asi); return space_cccc_11xx(insn, asi); return kprobe_decode_insn(insn, asi, kprobe_decode_arm_table, false); }