actions-arm.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. /*
  2. * arch/arm/probes/kprobes/actions-arm.c
  3. *
  4. * Copyright (C) 2006, 2007 Motorola Inc.
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * General Public License for more details.
  14. */
  15. /*
  16. * We do not have hardware single-stepping on ARM, This
  17. * effort is further complicated by the ARM not having a
  18. * "next PC" register. Instructions that change the PC
  19. * can't be safely single-stepped in a MP environment, so
  20. * we have a lot of work to do:
  21. *
  22. * In the prepare phase:
  23. * *) If it is an instruction that does anything
  24. * with the CPU mode, we reject it for a kprobe.
  25. * (This is out of laziness rather than need. The
  26. * instructions could be simulated.)
  27. *
  28. * *) Otherwise, decode the instruction rewriting its
  29. * registers to take fixed, ordered registers and
  30. * setting a handler for it to run the instruction.
  31. *
  32. * In the execution phase by an instruction's handler:
  33. *
  34. * *) If the PC is written to by the instruction, the
  35. * instruction must be fully simulated in software.
  36. *
  37. * *) Otherwise, a modified form of the instruction is
  38. * directly executed. Its handler calls the
  39. * instruction in insn[0]. In insn[1] is a
  40. * "mov pc, lr" to return.
  41. *
  42. * Before calling, load up the reordered registers
  43. * from the original instruction's registers. If one
  44. * of the original input registers is the PC, compute
  45. * and adjust the appropriate input register.
  46. *
  47. * After call completes, copy the output registers to
  48. * the original instruction's original registers.
  49. *
  50. * We don't use a real breakpoint instruction since that
  51. * would have us in the kernel go from SVC mode to SVC
  52. * mode losing the link register. Instead we use an
  53. * undefined instruction. To simplify processing, the
  54. * undefined instruction used for kprobes must be reserved
  55. * exclusively for kprobes use.
  56. *
  57. * TODO: ifdef out some instruction decoding based on architecture.
  58. */
  59. #include <linux/kernel.h>
  60. #include <linux/kprobes.h>
  61. #include <linux/ptrace.h>
  62. #include "../decode-arm.h"
  63. #include "core.h"
  64. #include "checkers.h"
  65. #if __LINUX_ARM_ARCH__ >= 6
  66. #define BLX(reg) "blx "reg" \n\t"
  67. #else
  68. #define BLX(reg) "mov lr, pc \n\t" \
  69. "mov pc, "reg" \n\t"
  70. #endif
  71. static void __kprobes
  72. emulate_ldrdstrd(probes_opcode_t insn,
  73. struct arch_probes_insn *asi, struct pt_regs *regs)
  74. {
  75. unsigned long pc = regs->ARM_pc + 4;
  76. int rt = (insn >> 12) & 0xf;
  77. int rn = (insn >> 16) & 0xf;
  78. int rm = insn & 0xf;
  79. register unsigned long rtv asm("r0") = regs->uregs[rt];
  80. register unsigned long rt2v asm("r1") = regs->uregs[rt+1];
  81. register unsigned long rnv asm("r2") = (rn == 15) ? pc
  82. : regs->uregs[rn];
  83. register unsigned long rmv asm("r3") = regs->uregs[rm];
  84. __asm__ __volatile__ (
  85. BLX("%[fn]")
  86. : "=r" (rtv), "=r" (rt2v), "=r" (rnv)
  87. : "0" (rtv), "1" (rt2v), "2" (rnv), "r" (rmv),
  88. [fn] "r" (asi->insn_fn)
  89. : "lr", "memory", "cc"
  90. );
  91. regs->uregs[rt] = rtv;
  92. regs->uregs[rt+1] = rt2v;
  93. if (is_writeback(insn))
  94. regs->uregs[rn] = rnv;
  95. }
  96. static void __kprobes
  97. emulate_ldr(probes_opcode_t insn,
  98. struct arch_probes_insn *asi, struct pt_regs *regs)
  99. {
  100. unsigned long pc = regs->ARM_pc + 4;
  101. int rt = (insn >> 12) & 0xf;
  102. int rn = (insn >> 16) & 0xf;
  103. int rm = insn & 0xf;
  104. register unsigned long rtv asm("r0");
  105. register unsigned long rnv asm("r2") = (rn == 15) ? pc
  106. : regs->uregs[rn];
  107. register unsigned long rmv asm("r3") = regs->uregs[rm];
  108. __asm__ __volatile__ (
  109. BLX("%[fn]")
  110. : "=r" (rtv), "=r" (rnv)
  111. : "1" (rnv), "r" (rmv), [fn] "r" (asi->insn_fn)
  112. : "lr", "memory", "cc"
  113. );
  114. if (rt == 15)
  115. load_write_pc(rtv, regs);
  116. else
  117. regs->uregs[rt] = rtv;
  118. if (is_writeback(insn))
  119. regs->uregs[rn] = rnv;
  120. }
  121. static void __kprobes
  122. emulate_str(probes_opcode_t insn,
  123. struct arch_probes_insn *asi, struct pt_regs *regs)
  124. {
  125. unsigned long rtpc = regs->ARM_pc - 4 + str_pc_offset;
  126. unsigned long rnpc = regs->ARM_pc + 4;
  127. int rt = (insn >> 12) & 0xf;
  128. int rn = (insn >> 16) & 0xf;
  129. int rm = insn & 0xf;
  130. register unsigned long rtv asm("r0") = (rt == 15) ? rtpc
  131. : regs->uregs[rt];
  132. register unsigned long rnv asm("r2") = (rn == 15) ? rnpc
  133. : regs->uregs[rn];
  134. register unsigned long rmv asm("r3") = regs->uregs[rm];
  135. __asm__ __volatile__ (
  136. BLX("%[fn]")
  137. : "=r" (rnv)
  138. : "r" (rtv), "0" (rnv), "r" (rmv), [fn] "r" (asi->insn_fn)
  139. : "lr", "memory", "cc"
  140. );
  141. if (is_writeback(insn))
  142. regs->uregs[rn] = rnv;
  143. }
  144. static void __kprobes
  145. emulate_rd12rn16rm0rs8_rwflags(probes_opcode_t insn,
  146. struct arch_probes_insn *asi, struct pt_regs *regs)
  147. {
  148. unsigned long pc = regs->ARM_pc + 4;
  149. int rd = (insn >> 12) & 0xf;
  150. int rn = (insn >> 16) & 0xf;
  151. int rm = insn & 0xf;
  152. int rs = (insn >> 8) & 0xf;
  153. register unsigned long rdv asm("r0") = regs->uregs[rd];
  154. register unsigned long rnv asm("r2") = (rn == 15) ? pc
  155. : regs->uregs[rn];
  156. register unsigned long rmv asm("r3") = (rm == 15) ? pc
  157. : regs->uregs[rm];
  158. register unsigned long rsv asm("r1") = regs->uregs[rs];
  159. unsigned long cpsr = regs->ARM_cpsr;
  160. __asm__ __volatile__ (
  161. "msr cpsr_fs, %[cpsr] \n\t"
  162. BLX("%[fn]")
  163. "mrs %[cpsr], cpsr \n\t"
  164. : "=r" (rdv), [cpsr] "=r" (cpsr)
  165. : "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv),
  166. "1" (cpsr), [fn] "r" (asi->insn_fn)
  167. : "lr", "memory", "cc"
  168. );
  169. if (rd == 15)
  170. alu_write_pc(rdv, regs);
  171. else
  172. regs->uregs[rd] = rdv;
  173. regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
  174. }
  175. static void __kprobes
  176. emulate_rd12rn16rm0_rwflags_nopc(probes_opcode_t insn,
  177. struct arch_probes_insn *asi, struct pt_regs *regs)
  178. {
  179. int rd = (insn >> 12) & 0xf;
  180. int rn = (insn >> 16) & 0xf;
  181. int rm = insn & 0xf;
  182. register unsigned long rdv asm("r0") = regs->uregs[rd];
  183. register unsigned long rnv asm("r2") = regs->uregs[rn];
  184. register unsigned long rmv asm("r3") = regs->uregs[rm];
  185. unsigned long cpsr = regs->ARM_cpsr;
  186. __asm__ __volatile__ (
  187. "msr cpsr_fs, %[cpsr] \n\t"
  188. BLX("%[fn]")
  189. "mrs %[cpsr], cpsr \n\t"
  190. : "=r" (rdv), [cpsr] "=r" (cpsr)
  191. : "0" (rdv), "r" (rnv), "r" (rmv),
  192. "1" (cpsr), [fn] "r" (asi->insn_fn)
  193. : "lr", "memory", "cc"
  194. );
  195. regs->uregs[rd] = rdv;
  196. regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
  197. }
  198. static void __kprobes
  199. emulate_rd16rn12rm0rs8_rwflags_nopc(probes_opcode_t insn,
  200. struct arch_probes_insn *asi,
  201. struct pt_regs *regs)
  202. {
  203. int rd = (insn >> 16) & 0xf;
  204. int rn = (insn >> 12) & 0xf;
  205. int rm = insn & 0xf;
  206. int rs = (insn >> 8) & 0xf;
  207. register unsigned long rdv asm("r2") = regs->uregs[rd];
  208. register unsigned long rnv asm("r0") = regs->uregs[rn];
  209. register unsigned long rmv asm("r3") = regs->uregs[rm];
  210. register unsigned long rsv asm("r1") = regs->uregs[rs];
  211. unsigned long cpsr = regs->ARM_cpsr;
  212. __asm__ __volatile__ (
  213. "msr cpsr_fs, %[cpsr] \n\t"
  214. BLX("%[fn]")
  215. "mrs %[cpsr], cpsr \n\t"
  216. : "=r" (rdv), [cpsr] "=r" (cpsr)
  217. : "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv),
  218. "1" (cpsr), [fn] "r" (asi->insn_fn)
  219. : "lr", "memory", "cc"
  220. );
  221. regs->uregs[rd] = rdv;
  222. regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
  223. }
  224. static void __kprobes
  225. emulate_rd12rm0_noflags_nopc(probes_opcode_t insn,
  226. struct arch_probes_insn *asi, struct pt_regs *regs)
  227. {
  228. int rd = (insn >> 12) & 0xf;
  229. int rm = insn & 0xf;
  230. register unsigned long rdv asm("r0") = regs->uregs[rd];
  231. register unsigned long rmv asm("r3") = regs->uregs[rm];
  232. __asm__ __volatile__ (
  233. BLX("%[fn]")
  234. : "=r" (rdv)
  235. : "0" (rdv), "r" (rmv), [fn] "r" (asi->insn_fn)
  236. : "lr", "memory", "cc"
  237. );
  238. regs->uregs[rd] = rdv;
  239. }
  240. static void __kprobes
  241. emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(probes_opcode_t insn,
  242. struct arch_probes_insn *asi,
  243. struct pt_regs *regs)
  244. {
  245. int rdlo = (insn >> 12) & 0xf;
  246. int rdhi = (insn >> 16) & 0xf;
  247. int rn = insn & 0xf;
  248. int rm = (insn >> 8) & 0xf;
  249. register unsigned long rdlov asm("r0") = regs->uregs[rdlo];
  250. register unsigned long rdhiv asm("r2") = regs->uregs[rdhi];
  251. register unsigned long rnv asm("r3") = regs->uregs[rn];
  252. register unsigned long rmv asm("r1") = regs->uregs[rm];
  253. unsigned long cpsr = regs->ARM_cpsr;
  254. __asm__ __volatile__ (
  255. "msr cpsr_fs, %[cpsr] \n\t"
  256. BLX("%[fn]")
  257. "mrs %[cpsr], cpsr \n\t"
  258. : "=r" (rdlov), "=r" (rdhiv), [cpsr] "=r" (cpsr)
  259. : "0" (rdlov), "1" (rdhiv), "r" (rnv), "r" (rmv),
  260. "2" (cpsr), [fn] "r" (asi->insn_fn)
  261. : "lr", "memory", "cc"
  262. );
  263. regs->uregs[rdlo] = rdlov;
  264. regs->uregs[rdhi] = rdhiv;
  265. regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
  266. }
  267. const union decode_action kprobes_arm_actions[NUM_PROBES_ARM_ACTIONS] = {
  268. [PROBES_PRELOAD_IMM] = {.handler = probes_simulate_nop},
  269. [PROBES_PRELOAD_REG] = {.handler = probes_simulate_nop},
  270. [PROBES_BRANCH_IMM] = {.handler = simulate_blx1},
  271. [PROBES_MRS] = {.handler = simulate_mrs},
  272. [PROBES_BRANCH_REG] = {.handler = simulate_blx2bx},
  273. [PROBES_CLZ] = {.handler = emulate_rd12rm0_noflags_nopc},
  274. [PROBES_SATURATING_ARITHMETIC] = {
  275. .handler = emulate_rd12rn16rm0_rwflags_nopc},
  276. [PROBES_MUL1] = {.handler = emulate_rdlo12rdhi16rn0rm8_rwflags_nopc},
  277. [PROBES_MUL2] = {.handler = emulate_rd16rn12rm0rs8_rwflags_nopc},
  278. [PROBES_SWP] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
  279. [PROBES_LDRSTRD] = {.handler = emulate_ldrdstrd},
  280. [PROBES_LOAD_EXTRA] = {.handler = emulate_ldr},
  281. [PROBES_LOAD] = {.handler = emulate_ldr},
  282. [PROBES_STORE_EXTRA] = {.handler = emulate_str},
  283. [PROBES_STORE] = {.handler = emulate_str},
  284. [PROBES_MOV_IP_SP] = {.handler = simulate_mov_ipsp},
  285. [PROBES_DATA_PROCESSING_REG] = {
  286. .handler = emulate_rd12rn16rm0rs8_rwflags},
  287. [PROBES_DATA_PROCESSING_IMM] = {
  288. .handler = emulate_rd12rn16rm0rs8_rwflags},
  289. [PROBES_MOV_HALFWORD] = {.handler = emulate_rd12rm0_noflags_nopc},
  290. [PROBES_SEV] = {.handler = probes_emulate_none},
  291. [PROBES_WFE] = {.handler = probes_simulate_nop},
  292. [PROBES_SATURATE] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
  293. [PROBES_REV] = {.handler = emulate_rd12rm0_noflags_nopc},
  294. [PROBES_MMI] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
  295. [PROBES_PACK] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
  296. [PROBES_EXTEND] = {.handler = emulate_rd12rm0_noflags_nopc},
  297. [PROBES_EXTEND_ADD] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
  298. [PROBES_MUL_ADD_LONG] = {
  299. .handler = emulate_rdlo12rdhi16rn0rm8_rwflags_nopc},
  300. [PROBES_MUL_ADD] = {.handler = emulate_rd16rn12rm0rs8_rwflags_nopc},
  301. [PROBES_BITFIELD] = {.handler = emulate_rd12rm0_noflags_nopc},
  302. [PROBES_BRANCH] = {.handler = simulate_bbl},
  303. [PROBES_LDMSTM] = {.decoder = kprobe_decode_ldmstm}
  304. };
  305. const struct decode_checker *kprobes_arm_checkers[] = {arm_stack_checker, arm_regs_checker, NULL};