aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorJon Medhurst <tixy@yxit.co.uk>2011-04-06 06:17:10 -0400
committerNicolas Pitre <nicolas.pitre@linaro.org>2011-04-28 23:40:54 -0400
commita539f5d46c868cb1f37b92e62e040b400571aed4 (patch)
treedad675c6706c9e5562c6f98e554ad51a1dfa1889 /arch/arm
parent073090cb701148396b1130be81f8ac84a41f196d (diff)
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: Jon Medhurst <tixy@yxit.co.uk> Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/kernel/kprobes-decode.c30
1 files changed, 3 insertions, 27 deletions
diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c
index 2e84169b9e91..f52fac0c59f0 100644
--- a/arch/arm/kernel/kprobes-decode.c
+++ b/arch/arm/kernel/kprobes-decode.c
@@ -71,10 +71,6 @@
71#define PSR_fs (PSR_f|PSR_s) 71#define PSR_fs (PSR_f|PSR_s)
72 72
73#define KPROBE_RETURN_INSTRUCTION 0xe1a0f00e /* mov pc, lr */ 73#define KPROBE_RETURN_INSTRUCTION 0xe1a0f00e /* mov pc, lr */
74#define SET_R0_TRUE_INSTRUCTION 0xe3a00001 /* mov r0, #1 */
75
76#define truecc_insn(insn) (((insn) & 0xf0000000) | \
77 (SET_R0_TRUE_INSTRUCTION & 0x0fffffff))
78 74
79typedef long (insn_0arg_fn_t)(void); 75typedef long (insn_0arg_fn_t)(void);
80typedef long (insn_1arg_fn_t)(long); 76typedef long (insn_1arg_fn_t)(long);
@@ -419,14 +415,10 @@ insnslot_llret_4arg_rwflags(long r0, long r1, long r2, long r3, long *cpsr,
419 415
420static void __kprobes simulate_bbl(struct kprobe *p, struct pt_regs *regs) 416static void __kprobes simulate_bbl(struct kprobe *p, struct pt_regs *regs)
421{ 417{
422 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
423 kprobe_opcode_t insn = p->opcode; 418 kprobe_opcode_t insn = p->opcode;
424 long iaddr = (long)p->addr; 419 long iaddr = (long)p->addr;
425 int disp = branch_displacement(insn); 420 int disp = branch_displacement(insn);
426 421
427 if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
428 return;
429
430 if (insn & (1 << 24)) 422 if (insn & (1 << 24))
431 regs->ARM_lr = iaddr + 4; 423 regs->ARM_lr = iaddr + 4;
432 424
@@ -446,14 +438,10 @@ static void __kprobes simulate_blx1(struct kprobe *p, struct pt_regs *regs)
446 438
447static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs) 439static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs)
448{ 440{
449 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
450 kprobe_opcode_t insn = p->opcode; 441 kprobe_opcode_t insn = p->opcode;
451 int rm = insn & 0xf; 442 int rm = insn & 0xf;
452 long rmv = regs->uregs[rm]; 443 long rmv = regs->uregs[rm];
453 444
454 if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
455 return;
456
457 if (insn & (1 << 5)) 445 if (insn & (1 << 5))
458 regs->ARM_lr = (long)p->addr + 4; 446 regs->ARM_lr = (long)p->addr + 4;
459 447
@@ -465,7 +453,6 @@ static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs)
465 453
466static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs) 454static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs)
467{ 455{
468 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
469 kprobe_opcode_t insn = p->opcode; 456 kprobe_opcode_t insn = p->opcode;
470 int rn = (insn >> 16) & 0xf; 457 int rn = (insn >> 16) & 0xf;
471 int lbit = insn & (1 << 20); 458 int lbit = insn & (1 << 20);
@@ -476,9 +463,6 @@ static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs)
476 int reg_bit_vector; 463 int reg_bit_vector;
477 int reg_count; 464 int reg_count;
478 465
479 if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
480 return;
481
482 reg_count = 0; 466 reg_count = 0;
483 reg_bit_vector = insn & 0xffff; 467 reg_bit_vector = insn & 0xffff;
484 while (reg_bit_vector) { 468 while (reg_bit_vector) {
@@ -510,11 +494,6 @@ static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs)
510 494
511static void __kprobes simulate_stm1_pc(struct kprobe *p, struct pt_regs *regs) 495static void __kprobes simulate_stm1_pc(struct kprobe *p, struct pt_regs *regs)
512{ 496{
513 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
514
515 if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
516 return;
517
518 regs->ARM_pc = (long)p->addr + str_pc_offset; 497 regs->ARM_pc = (long)p->addr + str_pc_offset;
519 simulate_ldm1stm1(p, regs); 498 simulate_ldm1stm1(p, regs);
520 regs->ARM_pc = (long)p->addr + 4; 499 regs->ARM_pc = (long)p->addr + 4;
@@ -1056,9 +1035,8 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1056 /* BLX(2) : cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */ 1035 /* BLX(2) : cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */
1057 /* BX : cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */ 1036 /* BX : cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */
1058 if ((insn & 0x0ff000d0) == 0x01200010) { 1037 if ((insn & 0x0ff000d0) == 0x01200010) {
1059 asi->insn[0] = truecc_insn(insn);
1060 asi->insn_handler = simulate_blx2bx; 1038 asi->insn_handler = simulate_blx2bx;
1061 return INSN_GOOD; 1039 return INSN_GOOD_NO_SLOT;
1062 } 1040 }
1063 1041
1064 /* CLZ : cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */ 1042 /* 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)
1333 1311
1334 /* LDM(1) : cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */ 1312 /* LDM(1) : cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
1335 /* STM(1) : cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */ 1313 /* STM(1) : cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */
1336 asi->insn[0] = truecc_insn(insn);
1337 asi->insn_handler = ((insn & 0x108000) == 0x008000) ? /* STM & R15 */ 1314 asi->insn_handler = ((insn & 0x108000) == 0x008000) ? /* STM & R15 */
1338 simulate_stm1_pc : simulate_ldm1stm1; 1315 simulate_stm1_pc : simulate_ldm1stm1;
1339 return INSN_GOOD; 1316 return INSN_GOOD_NO_SLOT;
1340} 1317}
1341 1318
1342static enum kprobe_insn __kprobes 1319static enum kprobe_insn __kprobes
@@ -1344,9 +1321,8 @@ space_cccc_101x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1344{ 1321{
1345 /* B : cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */ 1322 /* B : cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */
1346 /* BL : cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */ 1323 /* BL : cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */
1347 asi->insn[0] = truecc_insn(insn);
1348 asi->insn_handler = simulate_bbl; 1324 asi->insn_handler = simulate_bbl;
1349 return INSN_GOOD; 1325 return INSN_GOOD_NO_SLOT;
1350} 1326}
1351 1327
1352static enum kprobe_insn __kprobes 1328static enum kprobe_insn __kprobes