diff options
author | Dmitry Kovalenko <d.kovalenko@samsung.com> | 2015-04-30 15:46:48 +0300 |
---|---|---|
committer | Dmitry Kovalenko <d.kovalenko@samsung.com> | 2015-04-30 15:46:48 +0300 |
commit | 72c3a043112cba706e3681a065ac1dcde1782c9e (patch) | |
tree | 0efde0eae141bfeae201ea304a006178341ae549 /uprobe | |
parent | 483630ae22b25b202c69d868592daf059f45ad10 (diff) | |
parent | fa9e1004f58dfde4a3a114b6c57bed3a584710e2 (diff) | |
download | swap-modules-72c3a043112cba706e3681a065ac1dcde1782c9e.tar.gz swap-modules-72c3a043112cba706e3681a065ac1dcde1782c9e.tar.bz2 swap-modules-72c3a043112cba706e3681a065ac1dcde1782c9e.zip |
Merge branch 'tizen_2.4' into tizen_2.4_dev
Signed-off-by: Dmitry Kovalenko <d.kovalenko@samsung.com>
Conflicts:
uprobe/swap_uprobes.c
us_manager/img/img_ip.c
us_manager/img/img_proc.h
us_manager/sspt/sspt.h
us_manager/sspt/sspt_debug.h
us_manager/sspt/sspt_file.c
Change-Id: Ic7e1d03f57ebf988cae51b004498460ba08aee45
Diffstat (limited to 'uprobe')
-rw-r--r-- | uprobe/arch/arm/swap-asm/swap_uprobes.c | 478 | ||||
-rw-r--r-- | uprobe/arch/arm/swap-asm/swap_uprobes.h | 9 | ||||
-rw-r--r-- | uprobe/arch/x86/swap-asm/swap_uprobes.c | 200 | ||||
-rw-r--r-- | uprobe/arch/x86/swap-asm/swap_uprobes.h | 11 | ||||
-rw-r--r-- | uprobe/swap_uprobes.c | 151 | ||||
-rw-r--r-- | uprobe/swap_uprobes.h | 18 |
6 files changed, 488 insertions, 379 deletions
diff --git a/uprobe/arch/arm/swap-asm/swap_uprobes.c b/uprobe/arch/arm/swap-asm/swap_uprobes.c index cb6ae3d7..6585ef7b 100644 --- a/uprobe/arch/arm/swap-asm/swap_uprobes.c +++ b/uprobe/arch/arm/swap-asm/swap_uprobes.c @@ -61,14 +61,15 @@ static inline long branch_t16_dest(kprobe_opcode_t insn, unsigned int insn_addr) { long offset = insn & 0x3ff; offset -= insn & 0x400; - return (insn_addr + 4 + offset * 2); + return insn_addr + 4 + offset * 2; } -static inline long branch_cond_t16_dest(kprobe_opcode_t insn, unsigned int insn_addr) +static inline long branch_cond_t16_dest(kprobe_opcode_t insn, + unsigned int insn_addr) { long offset = insn & 0x7f; offset -= insn & 0x80; - return (insn_addr + 4 + offset * 2); + return insn_addr + 4 + offset * 2; } static inline long branch_t32_dest(kprobe_opcode_t insn, unsigned int insn_addr) @@ -79,9 +80,9 @@ static inline long branch_t32_dest(kprobe_opcode_t insn, unsigned int insn_addr) poff -= (insn & 0x400); if (insn & (1 << 12)) - return ((insn_addr + 4 + (poff << 12) + offset * 4)); + return insn_addr + 4 + (poff << 12) + offset * 4; else - return ((insn_addr + 4 + (poff << 12) + offset * 4) & ~3); + return (insn_addr + 4 + (poff << 12) + offset * 4) & ~3; } static inline long cbz_t16_dest(kprobe_opcode_t insn, unsigned int insn_addr) @@ -124,40 +125,57 @@ static int arch_check_insn_thumb(unsigned long insn) THUMB2_INSN_MATCH(B1, insn) || THUMB2_INSN_MATCH(B2, insn) || THUMB2_INSN_MATCH(BXJ, insn) || - (THUMB2_INSN_MATCH(ADR, insn) && THUMB2_INSN_REG_RD(insn) == 15) || + (THUMB2_INSN_MATCH(ADR, insn) && + THUMB2_INSN_REG_RD(insn) == 15) || (THUMB2_INSN_MATCH(LDRW, insn) && THUMB2_INSN_REG_RT(insn) == 15) || - (THUMB2_INSN_MATCH(LDRW1, insn) && THUMB2_INSN_REG_RT(insn) == 15) || - (THUMB2_INSN_MATCH(LDRHW, insn) && THUMB2_INSN_REG_RT(insn) == 15) || - (THUMB2_INSN_MATCH(LDRHW1, insn) && THUMB2_INSN_REG_RT(insn) == 15) || - (THUMB2_INSN_MATCH(LDRWL, insn) && THUMB2_INSN_REG_RT(insn) == 15) || + (THUMB2_INSN_MATCH(LDRW1, insn) && + THUMB2_INSN_REG_RT(insn) == 15) || + (THUMB2_INSN_MATCH(LDRHW, insn) && + THUMB2_INSN_REG_RT(insn) == 15) || + (THUMB2_INSN_MATCH(LDRHW1, insn) && + THUMB2_INSN_REG_RT(insn) == 15) || + (THUMB2_INSN_MATCH(LDRWL, insn) && + THUMB2_INSN_REG_RT(insn) == 15) || THUMB2_INSN_MATCH(LDMIA, insn) || THUMB2_INSN_MATCH(LDMDB, insn) || (THUMB2_INSN_MATCH(DP, insn) && THUMB2_INSN_REG_RD(insn) == 15) || (THUMB2_INSN_MATCH(RSBW, insn) && THUMB2_INSN_REG_RD(insn) == 15) || (THUMB2_INSN_MATCH(RORW, insn) && THUMB2_INSN_REG_RD(insn) == 15) || (THUMB2_INSN_MATCH(ROR, insn) && THUMB2_INSN_REG_RD(insn) == 15) || - (THUMB2_INSN_MATCH(LSLW1, insn) && THUMB2_INSN_REG_RD(insn) == 15) || - (THUMB2_INSN_MATCH(LSLW2, insn) && THUMB2_INSN_REG_RD(insn) == 15) || - (THUMB2_INSN_MATCH(LSRW1, insn) && THUMB2_INSN_REG_RD(insn) == 15) || - (THUMB2_INSN_MATCH(LSRW2, insn) && THUMB2_INSN_REG_RD(insn) == 15) || + (THUMB2_INSN_MATCH(LSLW1, insn) && + THUMB2_INSN_REG_RD(insn) == 15) || + (THUMB2_INSN_MATCH(LSLW2, insn) && + THUMB2_INSN_REG_RD(insn) == 15) || + (THUMB2_INSN_MATCH(LSRW1, insn) && + THUMB2_INSN_REG_RD(insn) == 15) || + (THUMB2_INSN_MATCH(LSRW2, insn) && + THUMB2_INSN_REG_RD(insn) == 15) || /* skip PC, #-imm12 -> SP, #-imm8 and Tegra-hanging instructions */ - (THUMB2_INSN_MATCH(STRW1, insn) && THUMB2_INSN_REG_RN(insn) == 15) || - (THUMB2_INSN_MATCH(STRBW1, insn) && THUMB2_INSN_REG_RN(insn) == 15) || - (THUMB2_INSN_MATCH(STRHW1, insn) && THUMB2_INSN_REG_RN(insn) == 15) || + (THUMB2_INSN_MATCH(STRW1, insn) && + THUMB2_INSN_REG_RN(insn) == 15) || + (THUMB2_INSN_MATCH(STRBW1, insn) && + THUMB2_INSN_REG_RN(insn) == 15) || + (THUMB2_INSN_MATCH(STRHW1, insn) && + THUMB2_INSN_REG_RN(insn) == 15) || (THUMB2_INSN_MATCH(STRW, insn) && THUMB2_INSN_REG_RN(insn) == 15) || - (THUMB2_INSN_MATCH(STRHW, insn) && THUMB2_INSN_REG_RN(insn) == 15) || + (THUMB2_INSN_MATCH(STRHW, insn) && + THUMB2_INSN_REG_RN(insn) == 15) || (THUMB2_INSN_MATCH(LDRW, insn) && THUMB2_INSN_REG_RN(insn) == 15) || - (THUMB2_INSN_MATCH(LDRBW, insn) && THUMB2_INSN_REG_RN(insn) == 15) || - (THUMB2_INSN_MATCH(LDRHW, insn) && THUMB2_INSN_REG_RN(insn) == 15) || + (THUMB2_INSN_MATCH(LDRBW, insn) && + THUMB2_INSN_REG_RN(insn) == 15) || + (THUMB2_INSN_MATCH(LDRHW, insn) && + THUMB2_INSN_REG_RN(insn) == 15) || /* skip STRDx/LDRDx Rt, Rt2, [Rd, ...] */ - (THUMB2_INSN_MATCH(LDRD, insn) || THUMB2_INSN_MATCH(LDRD1, insn) || THUMB2_INSN_MATCH(STRD, insn))) { + (THUMB2_INSN_MATCH(LDRD, insn) || THUMB2_INSN_MATCH(LDRD1, insn) || + THUMB2_INSN_MATCH(STRD, insn))) { ret = -EFAULT; } return ret; } -static int prep_pc_dep_insn_execbuf_thumb(kprobe_opcode_t * insns, kprobe_opcode_t insn, int uregs) +static int prep_pc_dep_insn_execbuf_thumb(kprobe_opcode_t *insns, + kprobe_opcode_t insn, int uregs) { unsigned char mreg = 0; unsigned char reg = 0; @@ -166,63 +184,60 @@ static int prep_pc_dep_insn_execbuf_thumb(kprobe_opcode_t * insns, kprobe_opcode reg = ((insn & 0xffff) & uregs) >> 8; } else { if (THUMB_INSN_MATCH(MOV3, insn)) { - if (((((unsigned char) insn) & 0xff) >> 3) == 15) { + if (((((unsigned char)insn) & 0xff) >> 3) == 15) reg = (insn & 0xffff) & uregs; - } else { + else return 0; - } } else { if (THUMB2_INSN_MATCH(ADR, insn)) { reg = ((insn >> 16) & uregs) >> 8; - if (reg == 15) { + if (reg == 15) return 0; - } } else { - if (THUMB2_INSN_MATCH(LDRW, insn) || THUMB2_INSN_MATCH(LDRW1, insn) || - THUMB2_INSN_MATCH(LDRHW, insn) || THUMB2_INSN_MATCH(LDRHW1, insn) || + if (THUMB2_INSN_MATCH(LDRW, insn) || + THUMB2_INSN_MATCH(LDRW1, insn) || + THUMB2_INSN_MATCH(LDRHW, insn) || + THUMB2_INSN_MATCH(LDRHW1, insn) || THUMB2_INSN_MATCH(LDRWL, insn)) { reg = ((insn >> 16) & uregs) >> 12; - if (reg == 15) { + if (reg == 15) return 0; - } } else { - // LDRB.W PC, [PC, #immed] => PLD [PC, #immed], so Rt == PC is skipped - if (THUMB2_INSN_MATCH(LDRBW, insn) || THUMB2_INSN_MATCH(LDRBW1, insn) || + /* LDRB.W PC, [PC, #immed] => + PLD [PC, #immed], + so Rt == PC is skipped */ + if (THUMB2_INSN_MATCH(LDRBW, insn) || + THUMB2_INSN_MATCH(LDRBW1, insn) || THUMB2_INSN_MATCH(LDREX, insn)) { reg = ((insn >> 16) & uregs) >> 12; } else { if (THUMB2_INSN_MATCH(DP, insn)) { reg = ((insn >> 16) & uregs) >> 12; - if (reg == 15) { + if (reg == 15) return 0; - } } else { if (THUMB2_INSN_MATCH(RSBW, insn)) { reg = ((insn >> 12) & uregs) >> 8; - if (reg == 15){ + if (reg == 15) return 0; - } } else { if (THUMB2_INSN_MATCH(RORW, insn)) { reg = ((insn >> 12) & uregs) >> 8; - if (reg == 15) { + if (reg == 15) return 0; - } } else { if (THUMB2_INSN_MATCH(ROR, insn) || THUMB2_INSN_MATCH(LSLW1, insn) || THUMB2_INSN_MATCH(LSLW2, insn) || THUMB2_INSN_MATCH(LSRW1, insn) || THUMB2_INSN_MATCH(LSRW2, insn)) { reg = ((insn >> 12) & uregs) >> 8; - if (reg == 15) { + if (reg == 15) return 0; - } } else { if (THUMB2_INSN_MATCH(TEQ1, insn) || THUMB2_INSN_MATCH(TST1, insn)) { reg = 15; } else { - if (THUMB2_INSN_MATCH(TEQ2, insn) || THUMB2_INSN_MATCH(TST2, insn)) { + if (THUMB2_INSN_MATCH(TEQ2, insn) || THUMB2_INSN_MATCH(TST2, insn)) reg = THUMB2_INSN_REG_RM(insn); - } } } } @@ -234,83 +249,107 @@ static int prep_pc_dep_insn_execbuf_thumb(kprobe_opcode_t * insns, kprobe_opcode } } - if ((THUMB2_INSN_MATCH(STRW, insn) || THUMB2_INSN_MATCH(STRBW, insn) || - THUMB2_INSN_MATCH(STRD, insn) || THUMB2_INSN_MATCH(STRHT, insn) || - THUMB2_INSN_MATCH(STRT, insn) || THUMB2_INSN_MATCH(STRHW1, insn) || - THUMB2_INSN_MATCH(STRHW, insn)) && THUMB2_INSN_REG_RT(insn) == 15) { + if ((THUMB2_INSN_MATCH(STRW, insn) || + THUMB2_INSN_MATCH(STRBW, insn) || + THUMB2_INSN_MATCH(STRD, insn) || + THUMB2_INSN_MATCH(STRHT, insn) || + THUMB2_INSN_MATCH(STRT, insn) || + THUMB2_INSN_MATCH(STRHW1, insn) || + THUMB2_INSN_MATCH(STRHW, insn)) && + THUMB2_INSN_REG_RT(insn) == 15) { reg = THUMB2_INSN_REG_RT(insn); } if (reg == 6 || reg == 7) { - *((unsigned short*)insns + 0) = (*((unsigned short*)insns + 0) & 0x00ff) | ((1 << mreg) | (1 << (mreg + 1))); - *((unsigned short*)insns + 1) = (*((unsigned short*)insns + 1) & 0xf8ff) | (mreg << 8); - *((unsigned short*)insns + 2) = (*((unsigned short*)insns + 2) & 0xfff8) | (mreg + 1); - *((unsigned short*)insns + 3) = (*((unsigned short*)insns + 3) & 0xffc7) | (mreg << 3); - *((unsigned short*)insns + 7) = (*((unsigned short*)insns + 7) & 0xf8ff) | (mreg << 8); - *((unsigned short*)insns + 8) = (*((unsigned short*)insns + 8) & 0xffc7) | (mreg << 3); - *((unsigned short*)insns + 9) = (*((unsigned short*)insns + 9) & 0xffc7) | ((mreg + 1) << 3); - *((unsigned short*)insns + 10) = (*((unsigned short*)insns + 10) & 0x00ff) | (( 1 << mreg) | (1 << (mreg + 1))); + *((unsigned short *)insns + 0) = + (*((unsigned short *)insns + 0) & 0x00ff) | + ((1 << mreg) | (1 << (mreg + 1))); + *((unsigned short *)insns + 1) = + (*((unsigned short *)insns + 1) & 0xf8ff) | (mreg << 8); + *((unsigned short *)insns + 2) = + (*((unsigned short *)insns + 2) & 0xfff8) | (mreg + 1); + *((unsigned short *)insns + 3) = + (*((unsigned short *)insns + 3) & 0xffc7) | (mreg << 3); + *((unsigned short *)insns + 7) = + (*((unsigned short *)insns + 7) & 0xf8ff) | (mreg << 8); + *((unsigned short *)insns + 8) = + (*((unsigned short *)insns + 8) & 0xffc7) | (mreg << 3); + *((unsigned short *)insns + 9) = + (*((unsigned short *)insns + 9) & 0xffc7) | + ((mreg + 1) << 3); + *((unsigned short *)insns + 10) = + (*((unsigned short *)insns + 10) & 0x00ff) | + ((1 << mreg) | (1 << (mreg + 1))); } if (THUMB_INSN_MATCH(APC, insn)) { - // ADD Rd, PC, #immed_8*4 -> ADD Rd, SP, #immed_8*4 - *((unsigned short*)insns + 4) = ((insn & 0xffff) | 0x800); // ADD Rd, SP, #immed_8*4 + /* ADD Rd, PC, #immed_8*4 -> ADD Rd, SP, #immed_8*4 */ + *((unsigned short *)insns + 4) = ((insn & 0xffff) | 0x800); } else { if (THUMB_INSN_MATCH(LRO3, insn)) { - // LDR Rd, [PC, #immed_8*4] -> LDR Rd, [SP, #immed_8*4] - *((unsigned short*)insns + 4) = ((insn & 0xffff) + 0x5000); // LDR Rd, [SP, #immed_8*4] + /* LDR Rd, [PC, #immed_8*4] -> + * LDR Rd, [SP, #immed_8*4] */ + *((unsigned short *)insns + 4) = + ((insn & 0xffff) + 0x5000); } else { if (THUMB_INSN_MATCH(MOV3, insn)) { - // MOV Rd, PC -> MOV Rd, SP - *((unsigned short*)insns + 4) = ((insn & 0xffff) ^ 0x10); // MOV Rd, SP + /* MOV Rd, PC -> MOV Rd, SP */ + *((unsigned short *)insns + 4) = + ((insn & 0xffff) ^ 0x10); } else { if (THUMB2_INSN_MATCH(ADR, insn)) { - // ADDW Rd, PC, #imm -> ADDW Rd, SP, #imm - insns[2] = (insn & 0xfffffff0) | 0x0d; // ADDW Rd, SP, #imm + /* ADDW Rd,PC,#imm -> ADDW Rd,SP,#imm */ + insns[2] = (insn & 0xfffffff0) | 0x0d; } else { - if (THUMB2_INSN_MATCH(LDRW, insn) || THUMB2_INSN_MATCH(LDRBW, insn) || + if (THUMB2_INSN_MATCH(LDRW, insn) || + THUMB2_INSN_MATCH(LDRBW, insn) || THUMB2_INSN_MATCH(LDRHW, insn)) { - // LDR.W Rt, [PC, #-<imm_12>] -> LDR.W Rt, [SP, #-<imm_8>] - // !!!!!!!!!!!!!!!!!!!!!!!! - // !!! imm_12 vs. imm_8 !!! - // !!!!!!!!!!!!!!!!!!!!!!!! - insns[2] = (insn & 0xf0fffff0) | 0x0c00000d; // LDR.W Rt, [SP, #-<imm_8>] + /* LDR.W Rt, [PC, #-<imm_12>] -> + * LDR.W Rt, [SP, #-<imm_8>] + * !!!!!!!!!!!!!!!!!!!!!!!! + * !!! imm_12 vs. imm_8 !!! + * !!!!!!!!!!!!!!!!!!!!!!!! */ + insns[2] = (insn & 0xf0fffff0) | 0x0c00000d; } else { - if (THUMB2_INSN_MATCH(LDRW1, insn) || THUMB2_INSN_MATCH(LDRBW1, insn) || - THUMB2_INSN_MATCH(LDRHW1, insn) || THUMB2_INSN_MATCH(LDRD, insn) || - THUMB2_INSN_MATCH(LDRD1, insn) || THUMB2_INSN_MATCH(LDREX, insn)) { - // LDRx.W Rt, [PC, #+<imm_12>] -> LDRx.W Rt, [SP, #+<imm_12>] (+/-imm_8 for LDRD Rt, Rt2, [PC, #<imm_8>] - insns[2] = (insn & 0xfffffff0) | 0xd; // LDRx.W Rt, [SP, #+<imm_12>] + if (THUMB2_INSN_MATCH(LDRW1, insn) || + THUMB2_INSN_MATCH(LDRBW1, insn) || + THUMB2_INSN_MATCH(LDRHW1, insn) || + THUMB2_INSN_MATCH(LDRD, insn) || + THUMB2_INSN_MATCH(LDRD1, insn) || + THUMB2_INSN_MATCH(LDREX, insn)) { + /* LDRx.W Rt, [PC, #+<imm_12>] -> + * LDRx.W Rt, [SP, #+<imm_12>] + (+/-imm_8 for LDRD Rt, Rt2, [PC, #<imm_8>] */ + insns[2] = (insn & 0xfffffff0) | 0xd; } else { if (THUMB2_INSN_MATCH(MUL, insn)) { - insns[2] = (insn & 0xfff0ffff) | 0x000d0000; // MUL Rd, Rn, SP + insns[2] = (insn & 0xfff0ffff) | 0x000d0000; /* MUL Rd, Rn, SP */ } else { if (THUMB2_INSN_MATCH(DP, insn)) { - if (THUMB2_INSN_REG_RM(insn) == 15) { - insns[2] = (insn & 0xfff0ffff) | 0x000d0000; // DP Rd, Rn, PC - } else if (THUMB2_INSN_REG_RN(insn) == 15) { - insns[2] = (insn & 0xfffffff0) | 0xd; // DP Rd, PC, Rm - } + if (THUMB2_INSN_REG_RM(insn) == 15) + insns[2] = (insn & 0xfff0ffff) | 0x000d0000; /* DP Rd, Rn, PC */ + else if (THUMB2_INSN_REG_RN(insn) == 15) + insns[2] = (insn & 0xfffffff0) | 0xd; /* DP Rd, PC, Rm */ } else { if (THUMB2_INSN_MATCH(LDRWL, insn)) { - // LDRx.W Rt, [PC, #<imm_12>] -> LDRx.W Rt, [SP, #+<imm_12>] (+/-imm_8 for LDRD Rt, Rt2, [PC, #<imm_8>] - insns[2] = (insn & 0xfffffff0) | 0xd; // LDRx.W Rt, [SP, #+<imm_12>] + /* LDRx.W Rt, [PC, #<imm_12>] -> + * LDRx.W Rt, [SP, #+<imm_12>] + * (+/-imm_8 for LDRD Rt, Rt2, [PC, #<imm_8>] */ + insns[2] = (insn & 0xfffffff0) | 0xd; } else { if (THUMB2_INSN_MATCH(RSBW, insn)) { - insns[2] = (insn & 0xfffffff0) | 0xd; // RSB{S}.W Rd, PC, #<const> -> RSB{S}.W Rd, SP, #<const> + insns[2] = (insn & 0xfffffff0) | 0xd; /* RSB{S}.W Rd, PC, #<const> -> RSB{S}.W Rd, SP, #<const> */ } else { if (THUMB2_INSN_MATCH(RORW, insn) || THUMB2_INSN_MATCH(LSLW1, insn) || THUMB2_INSN_MATCH(LSRW1, insn)) { - if ((THUMB2_INSN_REG_RM(insn) == 15) && (THUMB2_INSN_REG_RN(insn) == 15)) { - insns[2] = (insn & 0xfffdfffd); // ROR.W Rd, PC, PC - } else if (THUMB2_INSN_REG_RM(insn) == 15) { - insns[2] = (insn & 0xfff0ffff) | 0xd0000; // ROR.W Rd, Rn, PC - } else if (THUMB2_INSN_REG_RN(insn) == 15) { - insns[2] = (insn & 0xfffffff0) | 0xd; // ROR.W Rd, PC, Rm - } + if ((THUMB2_INSN_REG_RM(insn) == 15) && (THUMB2_INSN_REG_RN(insn) == 15)) + insns[2] = (insn & 0xfffdfffd); /* ROR.W Rd, PC, PC */ + else if (THUMB2_INSN_REG_RM(insn) == 15) + insns[2] = (insn & 0xfff0ffff) | 0xd0000; /* ROR.W Rd, Rn, PC */ + else if (THUMB2_INSN_REG_RN(insn) == 15) + insns[2] = (insn & 0xfffffff0) | 0xd; /* ROR.W Rd, PC, Rm */ } else { - if (THUMB2_INSN_MATCH(ROR, insn) || THUMB2_INSN_MATCH(LSLW2, insn) || THUMB2_INSN_MATCH(LSRW2, insn)) { - insns[2] = (insn & 0xfff0ffff) | 0xd0000; // ROR{S} Rd, PC, #<const> -> ROR{S} Rd, SP, #<const> - } + if (THUMB2_INSN_MATCH(ROR, insn) || THUMB2_INSN_MATCH(LSLW2, insn) || THUMB2_INSN_MATCH(LSRW2, insn)) + insns[2] = (insn & 0xfff0ffff) | 0xd0000; /* ROR{S} Rd, PC, #<const> -> ROR{S} Rd, SP, #<const> */ } } } @@ -324,48 +363,47 @@ static int prep_pc_dep_insn_execbuf_thumb(kprobe_opcode_t * insns, kprobe_opcode } if (THUMB2_INSN_MATCH(STRW, insn) || THUMB2_INSN_MATCH(STRBW, insn)) { - insns[2] = (insn & 0xfff0ffff) | 0x000d0000; // STRx.W Rt, [Rn, SP] + insns[2] = (insn & 0xfff0ffff) | 0x000d0000; /* STRx.W Rt, [Rn, SP] */ } else { if (THUMB2_INSN_MATCH(STRD, insn) || THUMB2_INSN_MATCH(STRHT, insn) || THUMB2_INSN_MATCH(STRT, insn) || THUMB2_INSN_MATCH(STRHW1, insn)) { - if (THUMB2_INSN_REG_RN(insn) == 15) { - insns[2] = (insn & 0xfffffff0) | 0xd; // STRD/T/HT{.W} Rt, [SP, ...] - } else { + if (THUMB2_INSN_REG_RN(insn) == 15) + insns[2] = (insn & 0xfffffff0) | 0xd; /* STRD/T/HT{.W} Rt, [SP, ...] */ + else insns[2] = insn; - } } else { if (THUMB2_INSN_MATCH(STRHW, insn) && (THUMB2_INSN_REG_RN(insn) == 15)) { - if (THUMB2_INSN_REG_RN(insn) == 15) { - insns[2] = (insn & 0xf0fffff0) | 0x0c00000d; // STRH.W Rt, [SP, #-<imm_8>] - } else { + if (THUMB2_INSN_REG_RN(insn) == 15) + insns[2] = (insn & 0xf0fffff0) | 0x0c00000d; /* STRH.W Rt, [SP, #-<imm_8>] */ + else insns[2] = insn; - } } } } - // STRx PC, xxx + /* STRx PC, xxx */ if ((reg == 15) && (THUMB2_INSN_MATCH(STRW, insn) || THUMB2_INSN_MATCH(STRBW, insn) || THUMB2_INSN_MATCH(STRD, insn) || THUMB2_INSN_MATCH(STRHT, insn) || THUMB2_INSN_MATCH(STRT, insn) || THUMB2_INSN_MATCH(STRHW1, insn) || - THUMB2_INSN_MATCH(STRHW, insn) )) { + THUMB2_INSN_MATCH(STRHW, insn))) { insns[2] = (insns[2] & 0x0fffffff) | 0xd0000000; } if (THUMB2_INSN_MATCH(TEQ1, insn) || THUMB2_INSN_MATCH(TST1, insn)) { - insns[2] = (insn & 0xfffffff0) | 0xd; // TEQ SP, #<const> + insns[2] = (insn & 0xfffffff0) | 0xd; /* TEQ SP, #<const> */ } else { - if (THUMB2_INSN_MATCH(TEQ2, insn) || THUMB2_INSN_MATCH(TST2, insn)) { - if ((THUMB2_INSN_REG_RN(insn) == 15) && (THUMB2_INSN_REG_RM(insn) == 15)) { - insns[2] = (insn & 0xfffdfffd); // TEQ/TST PC, PC - } else if (THUMB2_INSN_REG_RM(insn) == 15) { - insns[2] = (insn & 0xfff0ffff) | 0xd0000; // TEQ/TST Rn, PC - } else if (THUMB2_INSN_REG_RN(insn) == 15) { - insns[2] = (insn & 0xfffffff0) | 0xd; // TEQ/TST PC, Rm - } + if (THUMB2_INSN_MATCH(TEQ2, insn) || + THUMB2_INSN_MATCH(TST2, insn)) { + if ((THUMB2_INSN_REG_RN(insn) == 15) && + (THUMB2_INSN_REG_RM(insn) == 15)) + insns[2] = (insn & 0xfffdfffd); /* TEQ/TST PC, PC */ + else if (THUMB2_INSN_REG_RM(insn) == 15) + insns[2] = (insn & 0xfff0ffff) | 0xd0000; /* TEQ/TST Rn, PC */ + else if (THUMB2_INSN_REG_RN(insn) == 15) + insns[2] = (insn & 0xfffffff0) | 0xd; /* TEQ/TST PC, Rm */ } } @@ -384,13 +422,13 @@ static int arch_copy_trampoline_thumb_uprobe(struct uprobe *up) p->safe_thumb = 1; if (vaddr & 0x01) { - printk("Error in %s at %d: attempt to register kprobe at an unaligned address\n", __FILE__, __LINE__); + printk(KERN_INFO "Error in %s at %d: attempt to register " + "kprobe at an unaligned address\n", __FILE__, __LINE__); return -EINVAL; } - if (!arch_check_insn_thumb(insn)) { + if (!arch_check_insn_thumb(insn)) p->safe_thumb = 0; - } uregs = 0; pc_dep = 0; @@ -398,54 +436,85 @@ static int arch_copy_trampoline_thumb_uprobe(struct uprobe *up) if (THUMB_INSN_MATCH(APC, insn) || THUMB_INSN_MATCH(LRO3, insn)) { uregs = 0x0700; /* 8-10 */ pc_dep = 1; - } else if (THUMB_INSN_MATCH(MOV3, insn) && (((((unsigned char)insn) & 0xff) >> 3) == 15)) { + } else if (THUMB_INSN_MATCH(MOV3, insn) && + (((((unsigned char)insn) & 0xff) >> 3) == 15)) { /* MOV Rd, PC */ uregs = 0x07; pc_dep = 1; } else if THUMB2_INSN_MATCH(ADR, insn) { uregs = 0x0f00; /* Rd 8-11 */ pc_dep = 1; - } else if (((THUMB2_INSN_MATCH(LDRW, insn) || THUMB2_INSN_MATCH(LDRW1, insn) || - THUMB2_INSN_MATCH(LDRBW, insn) || THUMB2_INSN_MATCH(LDRBW1, insn) || - THUMB2_INSN_MATCH(LDRHW, insn) || THUMB2_INSN_MATCH(LDRHW1, insn) || - THUMB2_INSN_MATCH(LDRWL, insn)) && THUMB2_INSN_REG_RN(insn) == 15) || + } else if (((THUMB2_INSN_MATCH(LDRW, insn) || + THUMB2_INSN_MATCH(LDRW1, insn) || + THUMB2_INSN_MATCH(LDRBW, insn) || + THUMB2_INSN_MATCH(LDRBW1, insn) || + THUMB2_INSN_MATCH(LDRHW, insn) || + THUMB2_INSN_MATCH(LDRHW1, insn) || + THUMB2_INSN_MATCH(LDRWL, insn)) && + THUMB2_INSN_REG_RN(insn) == 15) || THUMB2_INSN_MATCH(LDREX, insn) || - ((THUMB2_INSN_MATCH(STRW, insn) || THUMB2_INSN_MATCH(STRBW, insn) || - THUMB2_INSN_MATCH(STRHW, insn) || THUMB2_INSN_MATCH(STRHW1, insn)) && - (THUMB2_INSN_REG_RN(insn) == 15 || THUMB2_INSN_REG_RT(insn) == 15)) || - ((THUMB2_INSN_MATCH(STRT, insn) || THUMB2_INSN_MATCH(STRHT, insn)) && - (THUMB2_INSN_REG_RN(insn) == 15 || THUMB2_INSN_REG_RT(insn) == 15))) { + ((THUMB2_INSN_MATCH(STRW, insn) || + THUMB2_INSN_MATCH(STRBW, insn) || + THUMB2_INSN_MATCH(STRHW, insn) || + THUMB2_INSN_MATCH(STRHW1, insn)) && + (THUMB2_INSN_REG_RN(insn) == 15 || + THUMB2_INSN_REG_RT(insn) == 15)) || + ((THUMB2_INSN_MATCH(STRT, insn) || + THUMB2_INSN_MATCH(STRHT, insn)) && + (THUMB2_INSN_REG_RN(insn) == 15 || + THUMB2_INSN_REG_RT(insn) == 15))) { uregs = 0xf000; /* Rt 12-15 */ pc_dep = 1; - } else if ((THUMB2_INSN_MATCH(LDRD, insn) || THUMB2_INSN_MATCH(LDRD1, insn)) && (THUMB2_INSN_REG_RN(insn) == 15)) { + } else if ((THUMB2_INSN_MATCH(LDRD, insn) || + THUMB2_INSN_MATCH(LDRD1, insn)) && + (THUMB2_INSN_REG_RN(insn) == 15)) { uregs = 0xff00; /* Rt 12-15, Rt2 8-11 */ pc_dep = 1; - } else if (THUMB2_INSN_MATCH(MUL, insn) && THUMB2_INSN_REG_RM(insn) == 15) { + } else if (THUMB2_INSN_MATCH(MUL, insn) && + THUMB2_INSN_REG_RM(insn) == 15) { uregs = 0xf; pc_dep = 1; - } else if (THUMB2_INSN_MATCH(DP, insn) && (THUMB2_INSN_REG_RN(insn) == 15 || THUMB2_INSN_REG_RM(insn) == 15)) { + } else if (THUMB2_INSN_MATCH(DP, insn) && + (THUMB2_INSN_REG_RN(insn) == 15 || + THUMB2_INSN_REG_RM(insn) == 15)) { uregs = 0xf000; /* Rd 12-15 */ pc_dep = 1; - } else if (THUMB2_INSN_MATCH(STRD, insn) && ((THUMB2_INSN_REG_RN(insn) == 15) || (THUMB2_INSN_REG_RT(insn) == 15) || THUMB2_INSN_REG_RT2(insn) == 15)) { + } else if (THUMB2_INSN_MATCH(STRD, insn) && + ((THUMB2_INSN_REG_RN(insn) == 15) || + (THUMB2_INSN_REG_RT(insn) == 15) || + THUMB2_INSN_REG_RT2(insn) == 15)) { uregs = 0xff00; /* Rt 12-15, Rt2 8-11 */ pc_dep = 1; - } else if (THUMB2_INSN_MATCH(RSBW, insn) && THUMB2_INSN_REG_RN(insn) == 15) { + } else if (THUMB2_INSN_MATCH(RSBW, insn) && + THUMB2_INSN_REG_RN(insn) == 15) { uregs = 0x0f00; /* Rd 8-11 */ pc_dep = 1; - } else if (THUMB2_INSN_MATCH (RORW, insn) && (THUMB2_INSN_REG_RN(insn) == 15 || THUMB2_INSN_REG_RM(insn) == 15)) { + } else if (THUMB2_INSN_MATCH(RORW, insn) && + (THUMB2_INSN_REG_RN(insn) == 15 || + THUMB2_INSN_REG_RM(insn) == 15)) { uregs = 0x0f00; pc_dep = 1; - } else if ((THUMB2_INSN_MATCH(ROR, insn) || THUMB2_INSN_MATCH(LSLW2, insn) || THUMB2_INSN_MATCH(LSRW2, insn)) && THUMB2_INSN_REG_RM(insn) == 15) { + } else if ((THUMB2_INSN_MATCH(ROR, insn) || + THUMB2_INSN_MATCH(LSLW2, insn) || + THUMB2_INSN_MATCH(LSRW2, insn)) && + THUMB2_INSN_REG_RM(insn) == 15) { uregs = 0x0f00; /* Rd 8-11 */ pc_dep = 1; - } else if ((THUMB2_INSN_MATCH(LSLW1, insn) || THUMB2_INSN_MATCH(LSRW1, insn)) && (THUMB2_INSN_REG_RN(insn) == 15 || THUMB2_INSN_REG_RM(insn) == 15)) { + } else if ((THUMB2_INSN_MATCH(LSLW1, insn) || + THUMB2_INSN_MATCH(LSRW1, insn)) && + (THUMB2_INSN_REG_RN(insn) == 15 || + THUMB2_INSN_REG_RM(insn) == 15)) { uregs = 0x0f00; /* Rd 8-11 */ pc_dep = 1; - } else if ((THUMB2_INSN_MATCH(TEQ1, insn) || THUMB2_INSN_MATCH(TST1, insn)) && THUMB2_INSN_REG_RN(insn) == 15) { + } else if ((THUMB2_INSN_MATCH(TEQ1, insn) || + THUMB2_INSN_MATCH(TST1, insn)) && + THUMB2_INSN_REG_RN(insn) == 15) { uregs = 0xf0000; /* Rn 0-3 (16-19) */ pc_dep = 1; - } else if ((THUMB2_INSN_MATCH(TEQ2, insn) || THUMB2_INSN_MATCH(TST2, insn)) && - (THUMB2_INSN_REG_RN(insn) == 15 || THUMB2_INSN_REG_RM(insn) == 15)) { + } else if ((THUMB2_INSN_MATCH(TEQ2, insn) || + THUMB2_INSN_MATCH(TST2, insn)) && + (THUMB2_INSN_REG_RN(insn) == 15 || + THUMB2_INSN_REG_RM(insn) == 15)) { uregs = 0xf0000; /* Rn 0-3 (16-19) */ pc_dep = 1; } @@ -453,93 +522,98 @@ static int arch_copy_trampoline_thumb_uprobe(struct uprobe *up) if (unlikely(uregs && pc_dep)) { memcpy(tramp, pc_dep_insn_execbuf_thumb, tramp_len); if (prep_pc_dep_insn_execbuf_thumb(tramp, insn, uregs) != 0) { - printk("Error in %s at %d: failed to prepare exec buffer for insn %lx!", + printk(KERN_INFO "Error in %s at %d: failed to " + "prepare exec buffer for insn %lx!", __FILE__, __LINE__, insn); p->safe_thumb = 1; } addr = vaddr + 4; - *((unsigned short*)tramp + 13) = 0xdeff; - *((unsigned short*)tramp + 14) = addr & 0x0000ffff; - *((unsigned short*)tramp + 15) = addr >> 16; + *((unsigned short *)tramp + 13) = 0xdeff; + *((unsigned short *)tramp + 14) = addr & 0x0000ffff; + *((unsigned short *)tramp + 15) = addr >> 16; if (!is_thumb2(insn)) { addr = vaddr + 2; - *((unsigned short*)tramp + 16) = (addr & 0x0000ffff) | 0x1; - *((unsigned short*)tramp + 17) = addr >> 16; + *((unsigned short *)tramp + 16) = + (addr & 0x0000ffff) | 0x1; + *((unsigned short *)tramp + 17) = addr >> 16; } else { addr = vaddr + 4; - *((unsigned short*)tramp + 16) = (addr & 0x0000ffff) | 0x1; - *((unsigned short*)tramp + 17) = addr >> 16; + *((unsigned short *)tramp + 16) = + (addr & 0x0000ffff) | 0x1; + *((unsigned short *)tramp + 17) = addr >> 16; } } else { memcpy(tramp, gen_insn_execbuf_thumb, tramp_len); - *((unsigned short*)tramp + 13) = 0xdeff; + *((unsigned short *)tramp + 13) = 0xdeff; if (!is_thumb2(insn)) { addr = vaddr + 2; - *((unsigned short*)tramp + 2) = insn; - *((unsigned short*)tramp + 16) = (addr & 0x0000ffff) | 0x1; - *((unsigned short*)tramp + 17) = addr >> 16; + *((unsigned short *)tramp + 2) = insn; + *((unsigned short *)tramp + 16) = + (addr & 0x0000ffff) | 0x1; + *((unsigned short *)tramp + 17) = addr >> 16; } else { addr = vaddr + 4; tramp[1] = insn; - *((unsigned short*)tramp + 16) = (addr & 0x0000ffff) | 0x1; - *((unsigned short*)tramp + 17) = addr >> 16; + *((unsigned short *)tramp + 16) = + (addr & 0x0000ffff) | 0x1; + *((unsigned short *)tramp + 17) = addr >> 16; } } if (THUMB_INSN_MATCH(B2, insn)) { memcpy(tramp, b_off_insn_execbuf_thumb, tramp_len); - *((unsigned short*)tramp + 13) = 0xdeff; + *((unsigned short *)tramp + 13) = 0xdeff; addr = branch_t16_dest(insn, vaddr); - *((unsigned short*)tramp + 14) = (addr & 0x0000ffff) | 0x1; - *((unsigned short*)tramp + 15) = addr >> 16; - *((unsigned short*)tramp + 16) = 0; - *((unsigned short*)tramp + 17) = 0; + *((unsigned short *)tramp + 14) = (addr & 0x0000ffff) | 0x1; + *((unsigned short *)tramp + 15) = addr >> 16; + *((unsigned short *)tramp + 16) = 0; + *((unsigned short *)tramp + 17) = 0; } else if (THUMB_INSN_MATCH(B1, insn)) { memcpy(tramp, b_cond_insn_execbuf_thumb, tramp_len); - *((unsigned short*)tramp + 13) = 0xdeff; - *((unsigned short*)tramp + 0) |= (insn & 0xf00); + *((unsigned short *)tramp + 13) = 0xdeff; + *((unsigned short *)tramp + 0) |= (insn & 0xf00); addr = branch_cond_t16_dest(insn, vaddr); - *((unsigned short*)tramp + 14) = (addr & 0x0000ffff) | 0x1; - *((unsigned short*)tramp + 15) = addr >> 16; + *((unsigned short *)tramp + 14) = (addr & 0x0000ffff) | 0x1; + *((unsigned short *)tramp + 15) = addr >> 16; addr = vaddr + 2; - *((unsigned short*)tramp + 16) = (addr & 0x0000ffff) | 0x1; - *((unsigned short*)tramp + 17) = addr >> 16; + *((unsigned short *)tramp + 16) = (addr & 0x0000ffff) | 0x1; + *((unsigned short *)tramp + 17) = addr >> 16; } else if (THUMB_INSN_MATCH(BLX2, insn) || THUMB_INSN_MATCH(BX, insn)) { memcpy(tramp, b_r_insn_execbuf_thumb, tramp_len); - *((unsigned short*)tramp + 13) = 0xdeff; - *((unsigned short*)tramp + 4) = insn; + *((unsigned short *)tramp + 13) = 0xdeff; + *((unsigned short *)tramp + 4) = insn; addr = vaddr + 2; - *((unsigned short*)tramp + 16) = (addr & 0x0000ffff) | 0x1; - *((unsigned short*)tramp + 17) = addr >> 16; + *((unsigned short *)tramp + 16) = (addr & 0x0000ffff) | 0x1; + *((unsigned short *)tramp + 17) = addr >> 16; } else if (THUMB2_INSN_MATCH(BLX1, insn) || THUMB2_INSN_MATCH(BL, insn)) { memcpy(tramp, blx_off_insn_execbuf_thumb, tramp_len); - *((unsigned short*)tramp + 13) = 0xdeff; + *((unsigned short *)tramp + 13) = 0xdeff; addr = branch_t32_dest(insn, vaddr); - *((unsigned short*)tramp + 14) = (addr & 0x0000ffff); - *((unsigned short*)tramp + 15) = addr >> 16; + *((unsigned short *)tramp + 14) = (addr & 0x0000ffff); + *((unsigned short *)tramp + 15) = addr >> 16; addr = vaddr + 4; - *((unsigned short*)tramp + 16) = (addr & 0x0000ffff) | 0x1; - *((unsigned short*)tramp + 17) = addr >> 16; + *((unsigned short *)tramp + 16) = (addr & 0x0000ffff) | 0x1; + *((unsigned short *)tramp + 17) = addr >> 16; } else if (THUMB_INSN_MATCH(CBZ, insn)) { memcpy(tramp, cbz_insn_execbuf_thumb, tramp_len); - *((unsigned short*)tramp + 13) = 0xdeff; + *((unsigned short *)tramp + 13) = 0xdeff; /* zero out original branch displacement (imm5 = 0; i = 0) */ - *((unsigned short*)tramp + 0) = insn & (~0x2f8); + *((unsigned short *)tramp + 0) = insn & (~0x2f8); /* replace it with 8 bytes offset in execbuf (imm5 = 0b00010) */ - *((unsigned short*)tramp + 0) |= 0x20; + *((unsigned short *)tramp + 0) |= 0x20; addr = cbz_t16_dest(insn, vaddr); - *((unsigned short*)tramp + 14) = (addr & 0x0000ffff) | 0x1; - *((unsigned short*)tramp + 15) = addr >> 16; + *((unsigned short *)tramp + 14) = (addr & 0x0000ffff) | 0x1; + *((unsigned short *)tramp + 15) = addr >> 16; addr = vaddr + 2; - *((unsigned short*)tramp + 16) = (addr & 0x0000ffff) | 0x1; - *((unsigned short*)tramp + 17) = addr >> 16; + *((unsigned short *)tramp + 16) = (addr & 0x0000ffff) | 0x1; + *((unsigned short *)tramp + 17) = addr >> 16; } return 0; @@ -560,8 +634,9 @@ int arch_prepare_uprobe(struct uprobe *up) unsigned long insn; if (vaddr & 0x01) { - printk("Error in %s at %d: attempt to register uprobe " - "at an unaligned address\n", __FILE__, __LINE__); + printk(KERN_INFO "Error in %s at %d: attempt " + "to register uprobe at an unaligned address\n", + __FILE__, __LINE__); return -EINVAL; } @@ -574,7 +649,7 @@ int arch_prepare_uprobe(struct uprobe *up) arch_copy_trampoline_thumb_uprobe(up); if ((p->safe_arm) && (p->safe_thumb)) { - printk("Error in %s at %d: failed " + printk(KERN_INFO "Error in %s at %d: failed " "arch_copy_trampoline_*_uprobe() (both) " "[tgid=%u, addr=%lx, data=%lx]\n", __FILE__, __LINE__, task->tgid, vaddr, insn); @@ -583,7 +658,8 @@ int arch_prepare_uprobe(struct uprobe *up) up->atramp.utramp = swap_slot_alloc(up->sm); if (up->atramp.utramp == NULL) { - printk("Error: swap_slot_alloc failed (%08lx)\n", vaddr); + printk(KERN_INFO "Error: swap_slot_alloc failed (%08lx)\n", + vaddr); return -ENOMEM; } @@ -624,11 +700,11 @@ void arch_prepare_uretprobe(struct uretprobe_instance *ri, /* Set flag of current mode */ ri->sp = (kprobe_opcode_t *)((long)ri->sp | !!thumb_mode(regs)); - if (thumb_mode(regs)) { + if (thumb_mode(regs)) regs->ARM_lr = (unsigned long)(ri->rp->up.kp.ainsn.insn) + 0x1b; - } else { - regs->ARM_lr = (unsigned long)(ri->rp->up.kp.ainsn.insn + UPROBES_TRAMP_RET_BREAK_IDX); - } + else + regs->ARM_lr = (unsigned long)(ri->rp->up.kp.ainsn.insn + + UPROBES_TRAMP_RET_BREAK_IDX); } /** @@ -664,8 +740,8 @@ int arch_disarm_urp_inst(struct uretprobe_instance *ri, retval = read_proc_vm_atomic(task, (unsigned long)stack, buf, sizeof(buf)); if (retval != sizeof(buf)) { - printk("---> %s (%d/%d): failed to read stack from %08lx\n", - task->comm, task->tgid, task->pid, + printk(KERN_INFO "---> %s (%d/%d): failed to read " + "stack from %08lx\n", task->comm, task->tgid, task->pid, (unsigned long)stack); retval = -EFAULT; goto check_lr; @@ -684,7 +760,7 @@ int arch_disarm_urp_inst(struct uretprobe_instance *ri, goto check_lr; } - printk("---> %s (%d/%d): trampoline found at " + printk(KERN_INFO "---> %s (%d/%d): trampoline found at " "%08lx (%08lx /%+d) - %p\n", task->comm, task->tgid, task->pid, (unsigned long)found, (unsigned long)sp, @@ -693,7 +769,8 @@ int arch_disarm_urp_inst(struct uretprobe_instance *ri, &ri->ret_addr, sizeof(ri->ret_addr)); if (retval != sizeof(ri->ret_addr)) { - printk("---> %s (%d/%d): failed to write value to %08lx", + printk(KERN_INFO "---> %s (%d/%d): " + "failed to write value to %08lx", task->comm, task->tgid, task->pid, (unsigned long)found); retval = -EFAULT; } else { @@ -702,14 +779,14 @@ int arch_disarm_urp_inst(struct uretprobe_instance *ri, check_lr: /* check lr anyway */ if (ra == (unsigned long)tramp) { - printk("---> %s (%d/%d): trampoline found at " + printk(KERN_INFO "---> %s (%d/%d): trampoline found at " "lr = %08lx - %p\n", task->comm, task->tgid, task->pid, ra, ri->rp->up.kp.addr); swap_set_ret_addr(uregs, (unsigned long)ri->ret_addr); retval = 0; } else if (retval) { - printk("---> %s (%d/%d): trampoline NOT found at " + printk(KERN_INFO "---> %s (%d/%d): trampoline NOT found at " "sp = %08lx, lr = %08lx - %p\n", task->comm, task->tgid, task->pid, (unsigned long)sp, ra, ri->rp->up.kp.addr); @@ -730,7 +807,8 @@ int setjmp_upre_handler(struct kprobe *p, struct pt_regs *regs) struct uprobe *up = container_of(p, struct uprobe, kp); struct ujprobe *jp = container_of(up, struct ujprobe, up); - kprobe_pre_entry_handler_t pre_entry = (kprobe_pre_entry_handler_t)jp->pre_entry; + kprobe_pre_entry_handler_t pre_entry = + (kprobe_pre_entry_handler_t)jp->pre_entry; entry_point_t entry = (entry_point_t)jp->entry; if (pre_entry) { @@ -759,7 +837,8 @@ unsigned long arch_get_trampoline_addr(struct kprobe *p, struct pt_regs *regs) { return thumb_mode(regs) ? (unsigned long)(p->ainsn.insn) + 0x1b : - (unsigned long)(p->ainsn.insn + UPROBES_TRAMP_RET_BREAK_IDX); + (unsigned long)(p->ainsn.insn + + UPROBES_TRAMP_RET_BREAK_IDX); } /** @@ -796,7 +875,7 @@ static void restore_opcode_for_thumb(struct kprobe *p, struct pt_regs *regs) if (thumb_mode(regs) && !is_thumb2(p->opcode)) { u16 tmp = p->opcode >> 16; write_proc_vm_atomic(current, - (unsigned long)((u16*)p->addr + 1), &tmp, 2); + (unsigned long)((u16 *)p->addr + 1), &tmp, 2); flush_insns(p->addr, 4); } } @@ -829,7 +908,7 @@ static int make_trampoline(struct uprobe *up, struct pt_regs *regs) tramp = up->atramp.tramp_thumb; break; default: - printk("Error in %s at %d: we are in arm mode " + printk(KERN_INFO "Error in %s at %d: we are in arm mode " "(!) and check instruction was fail " "(%0lX instruction at %p address)!\n", __FILE__, __LINE__, p->opcode, p->addr); @@ -867,7 +946,7 @@ static int uprobe_handler(struct pt_regs *regs) p = get_ukprobe_by_insn_slot(tramp_addr, tgid, regs); if (p == NULL) { - printk("no_uprobe: Not one of ours: let " + printk(KERN_INFO "no_uprobe: Not one of ours: let " "kernel handle it %p\n", addr); return 1; } @@ -878,7 +957,7 @@ static int uprobe_handler(struct pt_regs *regs) struct uprobe *up = kp2up(p); if (make_trampoline(up, regs)) { - printk("no_uprobe live\n"); + printk(KERN_INFO "no_uprobe live\n"); return 0; } @@ -886,9 +965,8 @@ static int uprobe_handler(struct pt_regs *regs) add_uprobe_table(p); } - if (!p->pre_handler || !p->pre_handler(p, regs)) { + if (!p->pre_handler || !p->pre_handler(p, regs)) prepare_singlestep(p, regs); - } } return 0; diff --git a/uprobe/arch/arm/swap-asm/swap_uprobes.h b/uprobe/arch/arm/swap-asm/swap_uprobes.h index c519d129..3a1a12cf 100644 --- a/uprobe/arch/arm/swap-asm/swap_uprobes.h +++ b/uprobe/arch/arm/swap-asm/swap_uprobes.h @@ -79,7 +79,8 @@ static inline int longjmp_break_uhandler(struct kprobe *p, struct pt_regs *regs) } void arch_opcode_analysis_uretprobe(struct uretprobe *rp); -void arch_prepare_uretprobe(struct uretprobe_instance *ri, struct pt_regs *regs); +void arch_prepare_uretprobe(struct uretprobe_instance *ri, + struct pt_regs *regs); int arch_disarm_urp_inst(struct uretprobe_instance *ri, struct task_struct *task); @@ -104,7 +105,8 @@ static inline unsigned long swap_get_uarg(struct pt_regs *regs, unsigned long n) ptr = (u32 *)regs->ARM_sp + n - 4; if (get_user(addr, ptr)) - printk("failed to dereference a pointer, ptr=%p\n", ptr); + printk(KERN_INFO "failed to dereference a pointer, ptr=%p\n", + ptr); return addr; } @@ -127,7 +129,8 @@ static inline void swap_put_uarg(struct pt_regs *regs, unsigned long n, ptr = (u32 *)regs->ARM_sp + n - 4; if (put_user(val, ptr)) - printk("failed to dereference a pointer, ptr=%p\n", ptr); + printk(KERN_INFO "failed to dereference a pointer, ptr=%p\n", + ptr); } int swap_arch_init_uprobes(void); diff --git a/uprobe/arch/x86/swap-asm/swap_uprobes.c b/uprobe/arch/x86/swap-asm/swap_uprobes.c index 1d4ed5db..2527824b 100644 --- a/uprobe/arch/x86/swap-asm/swap_uprobes.c +++ b/uprobe/arch/x86/swap-asm/swap_uprobes.c @@ -44,8 +44,8 @@ * @brief Uprobe control block */ struct uprobe_ctlblk { - unsigned long flags; /**< Flags */ - struct kprobe *p; /**< Pointer to the uprobe's kprobe */ + unsigned long flags; /**< Flags */ + struct kprobe *p; /**< Pointer to the uprobe's kprobe */ }; static unsigned long trampoline_addr(struct uprobe *up) @@ -102,7 +102,7 @@ int arch_prepare_uprobe(struct uprobe *up) panic("failed to read memory %p!\n", p->addr); /* TODO: this is a workaround */ if (tramp[0] == call_relative_opcode) { - printk("cannot install probe: 1st instruction is call\n"); + printk(KERN_INFO "cannot install probe: 1st instruction is call\n"); return -1; } @@ -127,19 +127,22 @@ int setjmp_upre_handler(struct kprobe *p, struct pt_regs *regs) { struct uprobe *up = container_of(p, struct uprobe, kp); struct ujprobe *jp = container_of(up, struct ujprobe, up); - kprobe_pre_entry_handler_t pre_entry = (kprobe_pre_entry_handler_t)jp->pre_entry; + kprobe_pre_entry_handler_t pre_entry = + (kprobe_pre_entry_handler_t)jp->pre_entry; entry_point_t entry = (entry_point_t)jp->entry; unsigned long args[6]; /* FIXME some user space apps crash if we clean interrupt bit */ - //regs->EREG(flags) &= ~IF_MASK; + /* regs->EREG(flags) &= ~IF_MASK; */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) trace_hardirqs_off(); #endif /* read first 6 args from stack */ - if (!read_proc_vm_atomic(current, regs->EREG(sp) + 4, args, sizeof(args))) - panic("failed to read user space func arguments %lx!\n", regs->EREG(sp) + 4); + if (!read_proc_vm_atomic(current, regs->EREG(sp) + 4, + args, sizeof(args))) + panic("failed to read user space func arguments %lx!\n", + regs->EREG(sp) + 4); if (pre_entry) p->ss_addr[smp_processor_id()] = (kprobe_opcode_t *) @@ -166,11 +169,14 @@ void arch_prepare_uretprobe(struct uretprobe_instance *ri, struct pt_regs *regs) unsigned long ra = trampoline_addr(&ri->rp->up); ri->sp = (kprobe_opcode_t *)regs->sp; - if (!read_proc_vm_atomic(current, regs->EREG(sp), &(ri->ret_addr), sizeof(ri->ret_addr))) - panic("failed to read user space func ra %lx!\n", regs->EREG(sp)); + if (!read_proc_vm_atomic(current, regs->EREG(sp), &(ri->ret_addr), + sizeof(ri->ret_addr))) + panic("failed to read user space func ra %lx!\n", + regs->EREG(sp)); if (!write_proc_vm_atomic(current, regs->EREG(sp), &ra, sizeof(ra))) - panic("failed to write user space func ra %lx!\n", regs->EREG(sp)); + panic("failed to write user space func ra %lx!\n", + regs->EREG(sp)); } /** @@ -190,7 +196,7 @@ int arch_disarm_urp_inst(struct uretprobe_instance *ri, unsigned long tramp_addr = trampoline_addr(&ri->rp->up); len = read_proc_vm_atomic(task, sp, &ret_addr, sizeof(ret_addr)); if (len != sizeof(ret_addr)) { - printk("---> %s (%d/%d): failed to read stack from %08lx\n", + printk(KERN_INFO "---> %s (%d/%d): failed to read stack from %08lx\n", task->comm, task->tgid, task->pid, sp); return -EFAULT; } @@ -199,13 +205,13 @@ int arch_disarm_urp_inst(struct uretprobe_instance *ri, len = write_proc_vm_atomic(task, sp, &ri->ret_addr, sizeof(ri->ret_addr)); if (len != sizeof(ri->ret_addr)) { - printk("---> %s (%d/%d): failed to write " + printk(KERN_INFO "---> %s (%d/%d): failed to write " "orig_ret_addr to %08lx", task->comm, task->tgid, task->pid, sp); return -EFAULT; } } else { - printk("---> %s (%d/%d): trampoline NOT found at sp = %08lx\n", + printk(KERN_INFO "---> %s (%d/%d): trampoline NOT found at sp = %08lx\n", task->comm, task->tgid, task->pid, sp); return -ENOENT; } @@ -252,20 +258,22 @@ void arch_remove_uprobe(struct uprobe *up) static void set_user_jmp_op(void *from, void *to) { - struct __arch_jmp_op - { + struct __arch_jmp_op { char op; long raddr; - } __attribute__ ((packed)) jop; + } __packed jop; jop.raddr = (long)(to) - ((long)(from) + 5); jop.op = RELATIVEJUMP_INSTRUCTION; - if (!write_proc_vm_atomic(current, (unsigned long)from, &jop, sizeof(jop))) + if (!write_proc_vm_atomic(current, (unsigned long)from, &jop, + sizeof(jop))) panic("failed to write jump opcode to user space %p!\n", from); } -static void resume_execution(struct kprobe *p, struct pt_regs *regs, unsigned long flags) +static void resume_execution(struct kprobe *p, + struct pt_regs *regs, + unsigned long flags) { unsigned long *tos, tos_dword = 0; unsigned long copy_eip = (unsigned long)p->ainsn.insn; @@ -275,75 +283,94 @@ static void resume_execution(struct kprobe *p, struct pt_regs *regs, unsigned lo regs->EREG(flags) &= ~TF_MASK; tos = (unsigned long *)&tos_dword; - if (!read_proc_vm_atomic(current, regs->EREG(sp), &tos_dword, sizeof(tos_dword))) - panic("failed to read dword from top of the user space stack %lx!\n", regs->EREG(sp)); + if (!read_proc_vm_atomic(current, regs->EREG(sp), &tos_dword, + sizeof(tos_dword))) + panic("failed to read dword from top of the user space stack " + "%lx!\n", regs->EREG(sp)); - if (!read_proc_vm_atomic(current, (unsigned long)p->ainsn.insn, insns, 2 * sizeof(kprobe_opcode_t))) - panic("failed to read first 2 opcodes of instruction copy from user space %p!\n", p->ainsn.insn); + if (!read_proc_vm_atomic(current, (unsigned long)p->ainsn.insn, insns, + 2 * sizeof(kprobe_opcode_t))) + panic("failed to read first 2 opcodes of instruction copy " + "from user space %p!\n", p->ainsn.insn); switch (insns[0]) { - case 0x9c: /* pushfl */ - *tos &= ~(TF_MASK | IF_MASK); - *tos |= flags & (TF_MASK | IF_MASK); - break; - case 0xc2: /* iret/ret/lret */ - case 0xc3: - case 0xca: - case 0xcb: - case 0xcf: - case 0xea: /* jmp absolute -- eip is correct */ - /* eip is already adjusted, no more changes required */ - p->ainsn.boostable = 1; - goto no_change; - case 0xe8: /* call relative - Fix return addr */ - *tos = orig_eip + (*tos - copy_eip); - break; - case 0x9a: /* call absolute -- same as call absolute, indirect */ + case 0x9c: /* pushfl */ + *tos &= ~(TF_MASK | IF_MASK); + *tos |= flags & (TF_MASK | IF_MASK); + break; + case 0xc2: /* iret/ret/lret */ + case 0xc3: + case 0xca: + case 0xcb: + case 0xcf: + case 0xea: /* jmp absolute -- eip is correct */ + /* eip is already adjusted, no more changes required */ + p->ainsn.boostable = 1; + goto no_change; + case 0xe8: /* call relative - Fix return addr */ + *tos = orig_eip + (*tos - copy_eip); + break; + case 0x9a: /* call absolute -- same as call absolute, indirect */ + *tos = orig_eip + (*tos - copy_eip); + + if (!write_proc_vm_atomic(current, + regs->EREG(sp), + &tos_dword, + sizeof(tos_dword))) + panic("failed to write dword to top of the" + " user space stack %lx!\n", + regs->EREG(sp)); + + goto no_change; + case 0xff: + if ((insns[1] & 0x30) == 0x10) { + /* + * call absolute, indirect + * Fix return addr; eip is correct. + * But this is not boostable + */ *tos = orig_eip + (*tos - copy_eip); - if (!write_proc_vm_atomic(current, regs->EREG (sp), &tos_dword, sizeof(tos_dword))) - panic("failed to write dword to top of the user space stack %lx!\n", regs->EREG (sp)); + if (!write_proc_vm_atomic(current, regs->EREG(sp), + &tos_dword, + sizeof(tos_dword))) + panic("failed to write dword to top of the " + "user space stack %lx!\n", + regs->EREG(sp)); goto no_change; - case 0xff: - if ((insns[1] & 0x30) == 0x10) { - /* - * call absolute, indirect - * Fix return addr; eip is correct. - * But this is not boostable - */ - *tos = orig_eip + (*tos - copy_eip); - - if (!write_proc_vm_atomic(current, regs->EREG(sp), &tos_dword, sizeof(tos_dword))) - panic("failed to write dword to top of the user space stack %lx!\n", regs->EREG(sp)); - - goto no_change; - } else if (((insns[1] & 0x31) == 0x20) || /* jmp near, absolute indirect */ - ((insns[1] & 0x31) == 0x21)) { - /* jmp far, absolute indirect */ - /* eip is correct. And this is boostable */ - p->ainsn.boostable = 1; - goto no_change; - } - case 0xf3: - if (insns[1] == 0xc3) - /* repz ret special handling: no more changes */ - goto no_change; - break; - default: - break; + } else if (((insns[1] & 0x31) == 0x20) || /* jmp near, absolute + * indirect */ + ((insns[1] & 0x31) == 0x21)) { + /* jmp far, absolute indirect */ + /* eip is correct. And this is boostable */ + p->ainsn.boostable = 1; + goto no_change; + } + case 0xf3: + if (insns[1] == 0xc3) + /* repz ret special handling: no more changes */ + goto no_change; + break; + default: + break; } - if (!write_proc_vm_atomic(current, regs->EREG(sp), &tos_dword, sizeof(tos_dword))) - panic("failed to write dword to top of the user space stack %lx!\n", regs->EREG(sp)); + if (!write_proc_vm_atomic(current, regs->EREG(sp), &tos_dword, + sizeof(tos_dword))) + panic("failed to write dword to top of the user space stack " + "%lx!\n", regs->EREG(sp)); if (p->ainsn.boostable == 0) { - if ((regs->EREG(ip) > copy_eip) && (regs->EREG(ip) - copy_eip) + 5 < MAX_INSN_SIZE) { + if ((regs->EREG(ip) > copy_eip) && (regs->EREG(ip) - copy_eip) + + 5 < MAX_INSN_SIZE) { /* * These instructions can be executed directly if it * jumps back to correct address. */ - set_user_jmp_op((void *) regs->EREG(ip), (void *)orig_eip + (regs->EREG(ip) - copy_eip)); + set_user_jmp_op((void *) regs->EREG(ip), + (void *)orig_eip + + (regs->EREG(ip) - copy_eip)); p->ainsn.boostable = 1; } else { p->ainsn.boostable = -1; @@ -364,7 +391,7 @@ static int make_trampoline(struct uprobe *up) tramp = swap_slot_alloc(up->sm); if (tramp == 0) { - printk("trampoline out of memory\n"); + printk(KERN_INFO "trampoline out of memory\n"); return -ENOMEM; } @@ -398,7 +425,7 @@ static int uprobe_handler(struct pt_regs *regs) p = get_ukprobe_by_insn_slot(tramp_addr, tgid, regs); if (p == NULL) { - printk("no_uprobe\n"); + printk(KERN_INFO "no_uprobe\n"); return 0; } @@ -451,7 +478,8 @@ static int post_uprobe_handler(struct pt_regs *regs) return 1; } -static int uprobe_exceptions_notify(struct notifier_block *self, unsigned long val, void *data) +static int uprobe_exceptions_notify(struct notifier_block *self, + unsigned long val, void *data) { struct die_args *args = (struct die_args *)data; int ret = NOTIFY_DONE; @@ -461,19 +489,19 @@ static int uprobe_exceptions_notify(struct notifier_block *self, unsigned long v switch (val) { #ifdef CONFIG_KPROBES - case DIE_INT3: + case DIE_INT3: #else - case DIE_TRAP: + case DIE_TRAP: #endif - if (uprobe_handler(args->regs)) - ret = NOTIFY_STOP; - break; - case DIE_DEBUG: - if (post_uprobe_handler(args->regs)) - ret = NOTIFY_STOP; - break; - default: - break; + if (uprobe_handler(args->regs)) + ret = NOTIFY_STOP; + break; + case DIE_DEBUG: + if (post_uprobe_handler(args->regs)) + ret = NOTIFY_STOP; + break; + default: + break; } return ret; diff --git a/uprobe/arch/x86/swap-asm/swap_uprobes.h b/uprobe/arch/x86/swap-asm/swap_uprobes.h index 360c0330..40345dff 100644 --- a/uprobe/arch/x86/swap-asm/swap_uprobes.h +++ b/uprobe/arch/x86/swap-asm/swap_uprobes.h @@ -84,7 +84,8 @@ static inline int arch_opcode_analysis_uretprobe(struct uretprobe *rp) return 0; } -void arch_prepare_uretprobe(struct uretprobe_instance *ri, struct pt_regs *regs); +void arch_prepare_uretprobe(struct uretprobe_instance *ri, + struct pt_regs *regs); int arch_disarm_urp_inst(struct uretprobe_instance *ri, struct task_struct *task); unsigned long arch_get_trampoline_addr(struct kprobe *p, struct pt_regs *regs); @@ -98,20 +99,22 @@ static inline unsigned long swap_get_uarg(struct pt_regs *regs, unsigned long n) /* 1 - return address saved on top of the stack */ ptr = (u32 *)regs->sp + n + 1; if (get_user(addr, ptr)) - printk("failed to dereference a pointer, ptr=%p\n", ptr); + printk(KERN_INFO "failed to dereference a pointer, ptr=%p\n", + ptr); return addr; } static inline void swap_put_uarg(struct pt_regs *regs, unsigned long n, - unsigned long val) + unsigned long val) { u32 *ptr; /* 1 - return address saved on top of the stack */ ptr = (u32 *)regs->sp + n + 1; if (put_user(val, ptr)) - printk("failed to dereference a pointer, ptr=%p\n", ptr); + printk(KERN_INFO "failed to dereference a pointer, ptr=%p\n", + ptr); } int swap_arch_init_uprobes(void); diff --git a/uprobe/swap_uprobes.c b/uprobe/swap_uprobes.c index dff5be8f..7f078c0e 100644 --- a/uprobe/swap_uprobes.c +++ b/uprobe/swap_uprobes.c @@ -66,11 +66,11 @@ void print_uprobe_hash_table(void) struct kprobe *p; DECLARE_NODE_PTR_FOR_HLIST(node); - // print uprobe table + /* print uprobe table */ for (i = 0; i < UPROBE_TABLE_SIZE; ++i) { head = &uprobe_insn_slot_table[i]; swap_hlist_for_each_entry_rcu(p, node, head, is_hlist_arm) { - printk("####### find U tgid=%u, addr=%x\n", + printk(KERN_INFO "####### find U tgid=%u, addr=%x\n", p->tgid, p->addr); } } @@ -102,27 +102,28 @@ static int aggr_pre_uhandler(struct kprobe *p, struct pt_regs *regs) list_for_each_entry_rcu(kp, &p->list, list) { if (kp->pre_handler) { ret = kp->pre_handler(kp, regs); - if (ret) { + if (ret) return ret; - } } } return 0; } -static void aggr_post_uhandler(struct kprobe *p, struct pt_regs *regs, unsigned long flags) +static void aggr_post_uhandler(struct kprobe *p, struct pt_regs *regs, + unsigned long flags) { struct kprobe *kp; list_for_each_entry_rcu(kp, &p->list, list) { - if (kp->post_handler) { + if (kp->post_handler) kp->post_handler(kp, regs, flags); - } } } -static int aggr_fault_uhandler(struct kprobe *p, struct pt_regs *regs, int trapnr) +static int aggr_fault_uhandler(struct kprobe *p, + struct pt_regs *regs, + int trapnr) { return 0; } @@ -139,19 +140,17 @@ static int aggr_break_uhandler(struct kprobe *p, struct pt_regs *regs) static int add_new_uprobe(struct kprobe *old_p, struct kprobe *p) { if (p->break_handler) { - if (old_p->break_handler) { + if (old_p->break_handler) return -EEXIST; - } list_add_tail_rcu(&p->list, &old_p->list); old_p->break_handler = aggr_break_uhandler; } else { - list_add_rcu (&p->list, &old_p->list); + list_add_rcu(&p->list, &old_p->list); } - if (p->post_handler && !old_p->post_handler) { + if (p->post_handler && !old_p->post_handler) old_p->post_handler = aggr_post_uhandler; - } return 0; } @@ -168,13 +167,11 @@ static inline void add_aggr_uprobe(struct kprobe *ap, struct kprobe *p) ap->pre_handler = aggr_pre_uhandler; ap->fault_handler = aggr_fault_uhandler; - if (p->post_handler) { + if (p->post_handler) ap->post_handler = aggr_post_uhandler; - } - if (p->break_handler) { + if (p->break_handler) ap->break_handler = aggr_break_uhandler; - } INIT_LIST_HEAD(&ap->list); list_add_rcu(&p->list, &ap->list); @@ -196,9 +193,8 @@ static int register_aggr_uprobe(struct kprobe *old_p, struct kprobe *p) ret = add_new_uprobe(old_p, p); } else { struct uprobe *uap = kzalloc(sizeof(*uap), GFP_KERNEL); - if (!uap) { + if (!uap) return -ENOMEM; - } uap->task = kp2up(p)->task; ap = up2kp(uap); @@ -231,7 +227,7 @@ static void arm_uprobe(struct uprobe *p) void disarm_uprobe(struct kprobe *p, struct task_struct *task) { int ret = write_proc_vm_atomic(task, (unsigned long)p->addr, - &p->opcode, sizeof(p->opcode)); + &p->opcode, sizeof(p->opcode)); if (!ret) { panic("disarm_uprobe: failed to write memory " "tgid=%u, addr=%p!\n", task->tgid, p->addr); @@ -242,25 +238,22 @@ EXPORT_SYMBOL_GPL(disarm_uprobe); static void init_uprobes_insn_slots(void) { int i; - for (i = 0; i < UPROBE_TABLE_SIZE; ++i) { + for (i = 0; i < UPROBE_TABLE_SIZE; ++i) INIT_HLIST_HEAD(&uprobe_insn_slot_table[i]); - } } static void init_uprobe_table(void) { int i; - for (i = 0; i < UPROBE_TABLE_SIZE; ++i) { + for (i = 0; i < UPROBE_TABLE_SIZE; ++i) INIT_HLIST_HEAD(&uprobe_table[i]); - } } static void init_uretprobe_inst_table(void) { int i; - for (i = 0; i < UPROBE_TABLE_SIZE; ++i) { - INIT_HLIST_HEAD (&uretprobe_inst_table[i]); - } + for (i = 0; i < UPROBE_TABLE_SIZE; ++i) + INIT_HLIST_HEAD(&uretprobe_inst_table[i]); } /** @@ -279,9 +272,8 @@ struct kprobe *get_ukprobe(void *addr, pid_t tgid) head = &uprobe_table[hash_ptr(addr, UPROBE_HASH_BITS)]; swap_hlist_for_each_entry_rcu(p, node, head, hlist) { - if (p->addr == addr && kp2up(p)->task->tgid == tgid) { + if (p->addr == addr && kp2up(p)->task->tgid == tgid) return p; - } } return NULL; @@ -295,7 +287,9 @@ struct kprobe *get_ukprobe(void *addr, pid_t tgid) */ void add_uprobe_table(struct kprobe *p) { - hlist_add_head_rcu(&p->is_hlist, &uprobe_insn_slot_table[hash_ptr(p->ainsn.insn, UPROBE_HASH_BITS)]); + hlist_add_head_rcu(&p->is_hlist, + &uprobe_insn_slot_table[hash_ptr(p->ainsn.insn, + UPROBE_HASH_BITS)]); } /** @@ -307,7 +301,9 @@ void add_uprobe_table(struct kprobe *p) * @return Pointer to the kprobe on success,\n * NULL otherwise. */ -struct kprobe *get_ukprobe_by_insn_slot(void *addr, pid_t tgid, struct pt_regs *regs) +struct kprobe *get_ukprobe_by_insn_slot(void *addr, + pid_t tgid, + struct pt_regs *regs) { struct hlist_head *head; struct kprobe *p; @@ -316,9 +312,8 @@ struct kprobe *get_ukprobe_by_insn_slot(void *addr, pid_t tgid, struct pt_regs * /* TODO: test - two processes invokes instrumented function */ head = &uprobe_insn_slot_table[hash_ptr(addr, UPROBE_HASH_BITS)]; swap_hlist_for_each_entry_rcu(p, node, head, is_hlist) { - if (p->ainsn.insn == addr && kp2up(p)->task->tgid == tgid) { + if (p->ainsn.insn == addr && kp2up(p)->task->tgid == tgid) return p; - } } return NULL; @@ -332,7 +327,7 @@ static void remove_uprobe(struct uprobe *up) static struct hlist_head *uretprobe_inst_table_head(void *hash_key) { - return &uretprobe_inst_table[hash_ptr (hash_key, UPROBE_HASH_BITS)]; + return &uretprobe_inst_table[hash_ptr(hash_key, UPROBE_HASH_BITS)]; } /* Called with uretprobe_lock held */ @@ -417,7 +412,7 @@ static int alloc_nodes_uretprobe(struct uretprobe *rp) struct uretprobe_instance *inst; int i; -#if 1//def CONFIG_PREEMPT +#if 1 /* def CONFIG_PREEMPT */ rp->maxactive += max(COMMON_URP_NR, 2 * NR_CPUS); #else rp->maxacpptive += NR_CPUS; @@ -448,14 +443,15 @@ static struct uretprobe_instance *get_free_urp_inst(struct uretprobe *rp) } if (!alloc_nodes_uretprobe(rp)) { - swap_hlist_for_each_entry(ri, node, &rp->free_instances, uflist) { + swap_hlist_for_each_entry(ri, node, + &rp->free_instances, uflist) { return ri; } } return NULL; } -// =================================================================== +/* =================================================================== */ /** * @brief Registers uprobe. @@ -470,18 +466,17 @@ int swap_register_uprobe(struct uprobe *up) struct kprobe *p, *old_p; p = &up->kp; - if (!p->addr) { + if (!p->addr) return -EINVAL; - } DBPRINTF("p->addr = 0x%p p = 0x%p\n", p->addr, p); -// thumb address = address-1; +/* thumb address = address-1; */ #if defined(CONFIG_ARM) - // TODO: must be corrected in 'bundle' - if ((unsigned long) p->addr & 0x01) { - p->addr = (kprobe_opcode_t *)((unsigned long)p->addr & 0xfffffffe); - } + /* TODO: must be corrected in 'bundle' */ + if ((unsigned long) p->addr & 0x01) + p->addr = (kprobe_opcode_t *)((unsigned long)p->addr & + 0xfffffffe); #endif p->ainsn.insn = NULL; @@ -494,13 +489,13 @@ int swap_register_uprobe(struct uprobe *up) p->count = 0; #endif - // get the first item + /* get the first item */ old_p = get_ukprobe(p->addr, kp2up(p)->task->tgid); if (old_p) { struct task_struct *task = up->task; /* TODO: add support many uprobes on address */ - printk("uprobe on task[%u %u %s] vaddr=%p is there\n", + printk(KERN_INFO "uprobe on task[%u %u %s] vaddr=%p is there\n", task->tgid, task->pid, task->comm, p->addr); ret = -EINVAL; goto out; @@ -521,11 +516,12 @@ int swap_register_uprobe(struct uprobe *up) goto out; } - DBPRINTF ("before out ret = 0x%x\n", ret); + DBPRINTF("before out ret = 0x%x\n", ret); - // TODO: add uprobe (must be in function) + /* TODO: add uprobe (must be in function) */ INIT_HLIST_NODE(&p->hlist); - hlist_add_head_rcu(&p->hlist, &uprobe_table[hash_ptr(p->addr, UPROBE_HASH_BITS)]); + hlist_add_head_rcu(&p->hlist, + &uprobe_table[hash_ptr(p->addr, UPROBE_HASH_BITS)]); arm_uprobe(up); out: @@ -548,9 +544,8 @@ void __swap_unregister_uprobe(struct uprobe *up, int disarm) p = &up->kp; old_p = get_ukprobe(p->addr, kp2up(p)->task->tgid); - if (unlikely(!old_p)) { + if (unlikely(!old_p)) return; - } if (p != old_p) { list_for_each_entry_rcu(list_p, &old_p->list, list) { @@ -583,27 +578,24 @@ valid_p: kfree(old_p); } - if (!in_atomic()) { + if (!in_atomic()) synchronize_sched(); - } remove_uprobe(up); } else { - if (p->break_handler) { + if (p->break_handler) old_p->break_handler = NULL; - } if (p->post_handler) { - list_for_each_entry_rcu (list_p, &old_p->list, list) { + list_for_each_entry_rcu(list_p, &old_p->list, list) { if (list_p->post_handler) { cleanup_p = 2; break; } } - if (cleanup_p == 0) { + if (cleanup_p == 0) old_p->post_handler = NULL; - } } } } @@ -659,10 +651,8 @@ void __swap_unregister_ujprobe(struct ujprobe *jp, int disarm) * dereference error. That is why we check whether this node * really belongs to the hlist. */ - - if (!(hlist_unhashed(&jp->up.kp.is_hlist))) { + if (!(hlist_unhashed(&jp->up.kp.is_hlist))) hlist_del_rcu(&jp->up.kp.is_hlist); - } } EXPORT_SYMBOL_GPL(__swap_unregister_ujprobe); @@ -764,11 +754,13 @@ static int pre_handler_uretprobe(struct kprobe *p, struct pt_regs *regs) return 0; #endif - /* TODO: consider to only swap the RA after the last pre_handler fired */ + /* TODO: consider to only swap the + * RA after the last pre_handler fired */ spin_lock_irqsave(&uretprobe_lock, flags); /* TODO: test - remove retprobe after func entry but before its exit */ - if ((ri = get_free_urp_inst(rp)) != NULL) { + ri = get_free_urp_inst(rp); + if (ri != NULL) { ri->rp = rp; ri->task = current; @@ -799,7 +791,7 @@ int swap_register_uretprobe(struct uretprobe *rp) int i, ret = 0; struct uretprobe_instance *inst; - DBPRINTF ("START\n"); + DBPRINTF("START\n"); rp->up.kp.pre_handler = pre_handler_uretprobe; rp->up.kp.post_handler = NULL; @@ -808,7 +800,7 @@ int swap_register_uretprobe(struct uretprobe *rp) /* Pre-allocate memory for max kretprobe instances */ if (rp->maxactive <= 0) { -#if 1//def CONFIG_PREEMPT +#if 1 /* def CONFIG_PREEMPT */ rp->maxactive = max(10, 2 * NR_CPUS); #else rp->maxactive = NR_CPUS; @@ -849,7 +841,8 @@ EXPORT_SYMBOL_GPL(swap_register_uretprobe); * @param task Pointer to the child task struct. * @return 0 */ -int swap_disarm_urp_inst_for_task(struct task_struct *parent, struct task_struct *task) +int swap_disarm_urp_inst_for_task(struct task_struct *parent, + struct task_struct *task) { unsigned long flags; struct uretprobe_instance *ri; @@ -861,9 +854,8 @@ int swap_disarm_urp_inst_for_task(struct task_struct *parent, struct task_struct head = uretprobe_inst_table_head(parent->mm); swap_hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { - if (parent == ri->task) { + if (parent == ri->task) arch_disarm_urp_inst(ri, task); - } } spin_unlock_irqrestore(&uretprobe_lock, flags); @@ -891,7 +883,7 @@ void swap_discard_pending_uretprobes(struct task_struct *task) head = uretprobe_inst_table_head(task->mm); swap_hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { if (ri->task == task) { - printk("%s (%d/%d): pending urp inst: %08lx\n", + printk(KERN_INFO "%s (%d/%d): pending urp inst: %08lx\n", task->comm, task->tgid, task->pid, (unsigned long)ri->rp->up.kp.addr); arch_disarm_urp_inst(ri, task); @@ -916,22 +908,22 @@ void __swap_unregister_uretprobe(struct uretprobe *rp, int disarm) struct uretprobe_instance *ri; __swap_unregister_uprobe(&rp->up, disarm); - spin_lock_irqsave (&uretprobe_lock, flags); + spin_lock_irqsave(&uretprobe_lock, flags); while ((ri = get_used_urp_inst(rp)) != NULL) { if (arch_disarm_urp_inst(ri, ri->task) != 0) - printk("%s (%d/%d): cannot disarm urp instance (%08lx)\n", - ri->task->comm, ri->task->tgid, ri->task->pid, - (unsigned long)rp->up.kp.addr); + printk(KERN_INFO "%s (%d/%d): " + "cannot disarm urp instance (%08lx)\n", + ri->task->comm, ri->task->tgid, ri->task->pid, + (unsigned long)rp->up.kp.addr); recycle_urp_inst(ri); } if (hlist_empty(&rp->used_instances)) { struct kprobe *p = &rp->up.kp; - if (!(hlist_unhashed(&p->is_hlist))) { + if (!(hlist_unhashed(&p->is_hlist))) hlist_del_rcu(&p->is_hlist); - } } while ((ri = get_used_urp_inst(rp)) != NULL) { @@ -975,9 +967,10 @@ void swap_unregister_all_uprobes(struct task_struct *task) head = &uprobe_table[i]; swap_hlist_for_each_entry_safe(p, node, tnode, head, hlist) { if (kp2up(p)->task->tgid == task->tgid) { - struct uprobe *up = container_of(p, struct uprobe, kp); - printk("%s: delete uprobe at %p[%lx] for " - "%s/%d\n", __func__, p->addr, + struct uprobe *up = + container_of(p, struct uprobe, kp); + printk(KERN_INFO "%s: delete uprobe at %p[%lx]" + " for %s/%d\n", __func__, p->addr, (unsigned long)p->opcode, task->comm, task->pid); swap_unregister_uprobe(up); @@ -1010,4 +1003,4 @@ static int once(void) SWAP_LIGHT_INIT_MODULE(once, swap_arch_init_uprobes, swap_arch_exit_uprobes, NULL, NULL); -MODULE_LICENSE ("GPL"); +MODULE_LICENSE("GPL"); diff --git a/uprobe/swap_uprobes.h b/uprobe/swap_uprobes.h index e2a417fa..89ce3725 100644 --- a/uprobe/swap_uprobes.h +++ b/uprobe/swap_uprobes.h @@ -53,19 +53,20 @@ struct uprobe { /** * @brief Uprobe pre-entry handler. */ -typedef unsigned long (*uprobe_pre_entry_handler_t)(void *priv_arg, struct pt_regs * regs); +typedef unsigned long (*uprobe_pre_entry_handler_t)(void *priv_arg, + struct pt_regs *regs); /** * @struct ujprobe * @brief Stores ujprobe data, based on uprobe. */ struct ujprobe { - struct uprobe up; /**< Uprobe for this ujprobe */ - void *entry; /**< Probe handling code to jump to */ + struct uprobe up; /**< Uprobe for this ujprobe */ + void *entry; /**< Probe handling code to jump to */ /** Handler which will be called before 'entry' */ uprobe_pre_entry_handler_t pre_entry; - void *priv_arg; /**< Private args for handler */ - char *args; /**< Function args format string */ + void *priv_arg; /**< Private args for handler */ + char *args; /**< Function args format string */ }; struct uretprobe_instance; @@ -73,7 +74,8 @@ struct uretprobe_instance; /** * @brief Uretprobe handler. */ -typedef int (*uretprobe_handler_t)(struct uretprobe_instance *, struct pt_regs *); +typedef int (*uretprobe_handler_t)(struct uretprobe_instance *, + struct pt_regs *); /** * @strict uretprobe @@ -134,7 +136,9 @@ void swap_discard_pending_uretprobes(struct task_struct *task); void swap_ujprobe_return(void); struct kprobe *get_ukprobe(void *addr, pid_t tgid); -struct kprobe *get_ukprobe_by_insn_slot(void *addr, pid_t tgid, struct pt_regs *regs); +struct kprobe *get_ukprobe_by_insn_slot(void *addr, + pid_t tgid, + struct pt_regs *regs); static inline struct uprobe *kp2up(struct kprobe *p) { |