aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/kprobes-arm.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel/kprobes-arm.c')
-rw-r--r--arch/arm/kernel/kprobes-arm.c58
1 files changed, 7 insertions, 51 deletions
diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index a1143e86a09a..c6f2c693b1b6 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -437,54 +437,6 @@ static void __kprobes simulate_mrs(struct kprobe *p, struct pt_regs *regs)
437 regs->uregs[rd] = regs->ARM_cpsr & mask; 437 regs->uregs[rd] = regs->ARM_cpsr & mask;
438} 438}
439 439
440static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs)
441{
442 kprobe_opcode_t insn = p->opcode;
443 int rn = (insn >> 16) & 0xf;
444 int lbit = insn & (1 << 20);
445 int wbit = insn & (1 << 21);
446 int ubit = insn & (1 << 23);
447 int pbit = insn & (1 << 24);
448 long *addr = (long *)regs->uregs[rn];
449 int reg_bit_vector;
450 int reg_count;
451
452 reg_count = 0;
453 reg_bit_vector = insn & 0xffff;
454 while (reg_bit_vector) {
455 reg_bit_vector &= (reg_bit_vector - 1);
456 ++reg_count;
457 }
458
459 if (!ubit)
460 addr -= reg_count;
461 addr += (!pbit == !ubit);
462
463 reg_bit_vector = insn & 0xffff;
464 while (reg_bit_vector) {
465 int reg = __ffs(reg_bit_vector);
466 reg_bit_vector &= (reg_bit_vector - 1);
467 if (lbit)
468 regs->uregs[reg] = *addr++;
469 else
470 *addr++ = regs->uregs[reg];
471 }
472
473 if (wbit) {
474 if (!ubit)
475 addr -= reg_count;
476 addr -= (!pbit == !ubit);
477 regs->uregs[rn] = (long)addr;
478 }
479}
480
481static void __kprobes simulate_stm1_pc(struct kprobe *p, struct pt_regs *regs)
482{
483 regs->ARM_pc = (long)p->addr + str_pc_offset;
484 simulate_ldm1stm1(p, regs);
485 regs->ARM_pc = (long)p->addr + 4;
486}
487
488static void __kprobes simulate_mov_ipsp(struct kprobe *p, struct pt_regs *regs) 440static void __kprobes simulate_mov_ipsp(struct kprobe *p, struct pt_regs *regs)
489{ 441{
490 regs->uregs[12] = regs->uregs[13]; 442 regs->uregs[12] = regs->uregs[13];
@@ -1463,9 +1415,13 @@ space_cccc_100x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1463 1415
1464 /* LDM(1) : cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */ 1416 /* LDM(1) : cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
1465 /* STM(1) : cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */ 1417 /* STM(1) : cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */
1466 asi->insn_handler = ((insn & 0x108000) == 0x008000) ? /* STM & R15 */ 1418
1467 simulate_stm1_pc : simulate_ldm1stm1; 1419 /*
1468 return INSN_GOOD_NO_SLOT; 1420 * Make the instruction unconditional because the new emulation
1421 * functions don't bother to setup the PSR context.
1422 */
1423 insn = (insn | 0xe0000000) & ~0x10000000;
1424 return kprobe_decode_ldmstm(insn, asi);
1469} 1425}
1470 1426
1471static enum kprobe_insn __kprobes 1427static enum kprobe_insn __kprobes