diff options
author | Jon Medhurst <tixy@yxit.co.uk> | 2011-04-06 06:17:10 -0400 |
---|---|---|
committer | Nicolas Pitre <nicolas.pitre@linaro.org> | 2011-04-28 23:40:54 -0400 |
commit | a539f5d46c868cb1f37b92e62e040b400571aed4 (patch) | |
tree | dad675c6706c9e5562c6f98e554ad51a1dfa1889 /arch/arm | |
parent | 073090cb701148396b1130be81f8ac84a41f196d (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.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 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 | ||
79 | typedef long (insn_0arg_fn_t)(void); | 75 | typedef long (insn_0arg_fn_t)(void); |
80 | typedef long (insn_1arg_fn_t)(long); | 76 | 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, | |||
419 | 415 | ||
420 | static void __kprobes simulate_bbl(struct kprobe *p, struct pt_regs *regs) | 416 | static 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 | ||
447 | static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs) | 439 | static 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 | ||
466 | static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs) | 454 | static 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 | ||
511 | static void __kprobes simulate_stm1_pc(struct kprobe *p, struct pt_regs *regs) | 495 | static 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 | ||
1342 | static enum kprobe_insn __kprobes | 1319 | static 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 | ||
1352 | static enum kprobe_insn __kprobes | 1328 | static enum kprobe_insn __kprobes |