summaryrefslogtreecommitdiff
path: root/uprobe
diff options
context:
space:
mode:
authorDmitry Kovalenko <d.kovalenko@samsung.com>2015-04-30 15:46:48 +0300
committerDmitry Kovalenko <d.kovalenko@samsung.com>2015-04-30 15:46:48 +0300
commit72c3a043112cba706e3681a065ac1dcde1782c9e (patch)
tree0efde0eae141bfeae201ea304a006178341ae549 /uprobe
parent483630ae22b25b202c69d868592daf059f45ad10 (diff)
parentfa9e1004f58dfde4a3a114b6c57bed3a584710e2 (diff)
downloadswap-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.c478
-rw-r--r--uprobe/arch/arm/swap-asm/swap_uprobes.h9
-rw-r--r--uprobe/arch/x86/swap-asm/swap_uprobes.c200
-rw-r--r--uprobe/arch/x86/swap-asm/swap_uprobes.h11
-rw-r--r--uprobe/swap_uprobes.c151
-rw-r--r--uprobe/swap_uprobes.h18
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)
{