0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053 #include <linux/kernel.h>
0054 #include <linux/kprobes.h>
0055 #include <linux/ptrace.h>
0056
0057 #include "../decode-arm.h"
0058 #include "core.h"
0059 #include "checkers.h"
0060
0061 #if __LINUX_ARM_ARCH__ >= 6
0062 #define BLX(reg) "blx "reg" \n\t"
0063 #else
0064 #define BLX(reg) "mov lr, pc \n\t" \
0065 "mov pc, "reg" \n\t"
0066 #endif
0067
0068 static void __kprobes
0069 emulate_ldrdstrd(probes_opcode_t insn,
0070 struct arch_probes_insn *asi, struct pt_regs *regs)
0071 {
0072 unsigned long pc = regs->ARM_pc + 4;
0073 int rt = (insn >> 12) & 0xf;
0074 int rn = (insn >> 16) & 0xf;
0075 int rm = insn & 0xf;
0076
0077 register unsigned long rtv asm("r0") = regs->uregs[rt];
0078 register unsigned long rt2v asm("r1") = regs->uregs[rt+1];
0079 register unsigned long rnv asm("r2") = (rn == 15) ? pc
0080 : regs->uregs[rn];
0081 register unsigned long rmv asm("r3") = regs->uregs[rm];
0082
0083 __asm__ __volatile__ (
0084 BLX("%[fn]")
0085 : "=r" (rtv), "=r" (rt2v), "=r" (rnv)
0086 : "0" (rtv), "1" (rt2v), "2" (rnv), "r" (rmv),
0087 [fn] "r" (asi->insn_fn)
0088 : "lr", "memory", "cc"
0089 );
0090
0091 regs->uregs[rt] = rtv;
0092 regs->uregs[rt+1] = rt2v;
0093 if (is_writeback(insn))
0094 regs->uregs[rn] = rnv;
0095 }
0096
0097 static void __kprobes
0098 emulate_ldr(probes_opcode_t insn,
0099 struct arch_probes_insn *asi, struct pt_regs *regs)
0100 {
0101 unsigned long pc = regs->ARM_pc + 4;
0102 int rt = (insn >> 12) & 0xf;
0103 int rn = (insn >> 16) & 0xf;
0104 int rm = insn & 0xf;
0105
0106 register unsigned long rtv asm("r0");
0107 register unsigned long rnv asm("r2") = (rn == 15) ? pc
0108 : regs->uregs[rn];
0109 register unsigned long rmv asm("r3") = regs->uregs[rm];
0110
0111 __asm__ __volatile__ (
0112 BLX("%[fn]")
0113 : "=r" (rtv), "=r" (rnv)
0114 : "1" (rnv), "r" (rmv), [fn] "r" (asi->insn_fn)
0115 : "lr", "memory", "cc"
0116 );
0117
0118 if (rt == 15)
0119 load_write_pc(rtv, regs);
0120 else
0121 regs->uregs[rt] = rtv;
0122
0123 if (is_writeback(insn))
0124 regs->uregs[rn] = rnv;
0125 }
0126
0127 static void __kprobes
0128 emulate_str(probes_opcode_t insn,
0129 struct arch_probes_insn *asi, struct pt_regs *regs)
0130 {
0131 unsigned long rtpc = regs->ARM_pc - 4 + str_pc_offset;
0132 unsigned long rnpc = regs->ARM_pc + 4;
0133 int rt = (insn >> 12) & 0xf;
0134 int rn = (insn >> 16) & 0xf;
0135 int rm = insn & 0xf;
0136
0137 register unsigned long rtv asm("r0") = (rt == 15) ? rtpc
0138 : regs->uregs[rt];
0139 register unsigned long rnv asm("r2") = (rn == 15) ? rnpc
0140 : regs->uregs[rn];
0141 register unsigned long rmv asm("r3") = regs->uregs[rm];
0142
0143 __asm__ __volatile__ (
0144 BLX("%[fn]")
0145 : "=r" (rnv)
0146 : "r" (rtv), "0" (rnv), "r" (rmv), [fn] "r" (asi->insn_fn)
0147 : "lr", "memory", "cc"
0148 );
0149
0150 if (is_writeback(insn))
0151 regs->uregs[rn] = rnv;
0152 }
0153
0154 static void __kprobes
0155 emulate_rd12rn16rm0rs8_rwflags(probes_opcode_t insn,
0156 struct arch_probes_insn *asi, struct pt_regs *regs)
0157 {
0158 unsigned long pc = regs->ARM_pc + 4;
0159 int rd = (insn >> 12) & 0xf;
0160 int rn = (insn >> 16) & 0xf;
0161 int rm = insn & 0xf;
0162 int rs = (insn >> 8) & 0xf;
0163
0164 register unsigned long rdv asm("r0") = regs->uregs[rd];
0165 register unsigned long rnv asm("r2") = (rn == 15) ? pc
0166 : regs->uregs[rn];
0167 register unsigned long rmv asm("r3") = (rm == 15) ? pc
0168 : regs->uregs[rm];
0169 register unsigned long rsv asm("r1") = regs->uregs[rs];
0170 unsigned long cpsr = regs->ARM_cpsr;
0171
0172 __asm__ __volatile__ (
0173 "msr cpsr_fs, %[cpsr] \n\t"
0174 BLX("%[fn]")
0175 "mrs %[cpsr], cpsr \n\t"
0176 : "=r" (rdv), [cpsr] "=r" (cpsr)
0177 : "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv),
0178 "1" (cpsr), [fn] "r" (asi->insn_fn)
0179 : "lr", "memory", "cc"
0180 );
0181
0182 if (rd == 15)
0183 alu_write_pc(rdv, regs);
0184 else
0185 regs->uregs[rd] = rdv;
0186 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
0187 }
0188
0189 static void __kprobes
0190 emulate_rd12rn16rm0_rwflags_nopc(probes_opcode_t insn,
0191 struct arch_probes_insn *asi, struct pt_regs *regs)
0192 {
0193 int rd = (insn >> 12) & 0xf;
0194 int rn = (insn >> 16) & 0xf;
0195 int rm = insn & 0xf;
0196
0197 register unsigned long rdv asm("r0") = regs->uregs[rd];
0198 register unsigned long rnv asm("r2") = regs->uregs[rn];
0199 register unsigned long rmv asm("r3") = regs->uregs[rm];
0200 unsigned long cpsr = regs->ARM_cpsr;
0201
0202 __asm__ __volatile__ (
0203 "msr cpsr_fs, %[cpsr] \n\t"
0204 BLX("%[fn]")
0205 "mrs %[cpsr], cpsr \n\t"
0206 : "=r" (rdv), [cpsr] "=r" (cpsr)
0207 : "0" (rdv), "r" (rnv), "r" (rmv),
0208 "1" (cpsr), [fn] "r" (asi->insn_fn)
0209 : "lr", "memory", "cc"
0210 );
0211
0212 regs->uregs[rd] = rdv;
0213 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
0214 }
0215
0216 static void __kprobes
0217 emulate_rd16rn12rm0rs8_rwflags_nopc(probes_opcode_t insn,
0218 struct arch_probes_insn *asi,
0219 struct pt_regs *regs)
0220 {
0221 int rd = (insn >> 16) & 0xf;
0222 int rn = (insn >> 12) & 0xf;
0223 int rm = insn & 0xf;
0224 int rs = (insn >> 8) & 0xf;
0225
0226 register unsigned long rdv asm("r2") = regs->uregs[rd];
0227 register unsigned long rnv asm("r0") = regs->uregs[rn];
0228 register unsigned long rmv asm("r3") = regs->uregs[rm];
0229 register unsigned long rsv asm("r1") = regs->uregs[rs];
0230 unsigned long cpsr = regs->ARM_cpsr;
0231
0232 __asm__ __volatile__ (
0233 "msr cpsr_fs, %[cpsr] \n\t"
0234 BLX("%[fn]")
0235 "mrs %[cpsr], cpsr \n\t"
0236 : "=r" (rdv), [cpsr] "=r" (cpsr)
0237 : "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv),
0238 "1" (cpsr), [fn] "r" (asi->insn_fn)
0239 : "lr", "memory", "cc"
0240 );
0241
0242 regs->uregs[rd] = rdv;
0243 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
0244 }
0245
0246 static void __kprobes
0247 emulate_rd12rm0_noflags_nopc(probes_opcode_t insn,
0248 struct arch_probes_insn *asi, struct pt_regs *regs)
0249 {
0250 int rd = (insn >> 12) & 0xf;
0251 int rm = insn & 0xf;
0252
0253 register unsigned long rdv asm("r0") = regs->uregs[rd];
0254 register unsigned long rmv asm("r3") = regs->uregs[rm];
0255
0256 __asm__ __volatile__ (
0257 BLX("%[fn]")
0258 : "=r" (rdv)
0259 : "0" (rdv), "r" (rmv), [fn] "r" (asi->insn_fn)
0260 : "lr", "memory", "cc"
0261 );
0262
0263 regs->uregs[rd] = rdv;
0264 }
0265
0266 static void __kprobes
0267 emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(probes_opcode_t insn,
0268 struct arch_probes_insn *asi,
0269 struct pt_regs *regs)
0270 {
0271 int rdlo = (insn >> 12) & 0xf;
0272 int rdhi = (insn >> 16) & 0xf;
0273 int rn = insn & 0xf;
0274 int rm = (insn >> 8) & 0xf;
0275
0276 register unsigned long rdlov asm("r0") = regs->uregs[rdlo];
0277 register unsigned long rdhiv asm("r2") = regs->uregs[rdhi];
0278 register unsigned long rnv asm("r3") = regs->uregs[rn];
0279 register unsigned long rmv asm("r1") = regs->uregs[rm];
0280 unsigned long cpsr = regs->ARM_cpsr;
0281
0282 __asm__ __volatile__ (
0283 "msr cpsr_fs, %[cpsr] \n\t"
0284 BLX("%[fn]")
0285 "mrs %[cpsr], cpsr \n\t"
0286 : "=r" (rdlov), "=r" (rdhiv), [cpsr] "=r" (cpsr)
0287 : "0" (rdlov), "1" (rdhiv), "r" (rnv), "r" (rmv),
0288 "2" (cpsr), [fn] "r" (asi->insn_fn)
0289 : "lr", "memory", "cc"
0290 );
0291
0292 regs->uregs[rdlo] = rdlov;
0293 regs->uregs[rdhi] = rdhiv;
0294 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
0295 }
0296
0297 const union decode_action kprobes_arm_actions[NUM_PROBES_ARM_ACTIONS] = {
0298 [PROBES_PRELOAD_IMM] = {.handler = probes_simulate_nop},
0299 [PROBES_PRELOAD_REG] = {.handler = probes_simulate_nop},
0300 [PROBES_BRANCH_IMM] = {.handler = simulate_blx1},
0301 [PROBES_MRS] = {.handler = simulate_mrs},
0302 [PROBES_BRANCH_REG] = {.handler = simulate_blx2bx},
0303 [PROBES_CLZ] = {.handler = emulate_rd12rm0_noflags_nopc},
0304 [PROBES_SATURATING_ARITHMETIC] = {
0305 .handler = emulate_rd12rn16rm0_rwflags_nopc},
0306 [PROBES_MUL1] = {.handler = emulate_rdlo12rdhi16rn0rm8_rwflags_nopc},
0307 [PROBES_MUL2] = {.handler = emulate_rd16rn12rm0rs8_rwflags_nopc},
0308 [PROBES_SWP] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
0309 [PROBES_LDRSTRD] = {.handler = emulate_ldrdstrd},
0310 [PROBES_LOAD_EXTRA] = {.handler = emulate_ldr},
0311 [PROBES_LOAD] = {.handler = emulate_ldr},
0312 [PROBES_STORE_EXTRA] = {.handler = emulate_str},
0313 [PROBES_STORE] = {.handler = emulate_str},
0314 [PROBES_MOV_IP_SP] = {.handler = simulate_mov_ipsp},
0315 [PROBES_DATA_PROCESSING_REG] = {
0316 .handler = emulate_rd12rn16rm0rs8_rwflags},
0317 [PROBES_DATA_PROCESSING_IMM] = {
0318 .handler = emulate_rd12rn16rm0rs8_rwflags},
0319 [PROBES_MOV_HALFWORD] = {.handler = emulate_rd12rm0_noflags_nopc},
0320 [PROBES_SEV] = {.handler = probes_emulate_none},
0321 [PROBES_WFE] = {.handler = probes_simulate_nop},
0322 [PROBES_SATURATE] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
0323 [PROBES_REV] = {.handler = emulate_rd12rm0_noflags_nopc},
0324 [PROBES_MMI] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
0325 [PROBES_PACK] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
0326 [PROBES_EXTEND] = {.handler = emulate_rd12rm0_noflags_nopc},
0327 [PROBES_EXTEND_ADD] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
0328 [PROBES_MUL_ADD_LONG] = {
0329 .handler = emulate_rdlo12rdhi16rn0rm8_rwflags_nopc},
0330 [PROBES_MUL_ADD] = {.handler = emulate_rd16rn12rm0rs8_rwflags_nopc},
0331 [PROBES_BITFIELD] = {.handler = emulate_rd12rm0_noflags_nopc},
0332 [PROBES_BRANCH] = {.handler = simulate_bbl},
0333 [PROBES_LDMSTM] = {.decoder = kprobe_decode_ldmstm}
0334 };
0335
0336 const struct decode_checker *kprobes_arm_checkers[] = {arm_stack_checker, arm_regs_checker, NULL};