kprobes-arm.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. /*
  2. * arch/arm/kernel/kprobes-decode.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 "kprobes.h"
  63. #include "probes-arm.h"
  64. #if __LINUX_ARM_ARCH__ >= 6
  65. #define BLX(reg) "blx "reg" \n\t"
  66. #else
  67. #define BLX(reg) "mov lr, pc \n\t" \
  68. "mov pc, "reg" \n\t"
  69. #endif
  70. static void __kprobes
  71. emulate_ldrdstrd(probes_opcode_t insn,
  72. struct arch_probes_insn *asi, struct pt_regs *regs)
  73. {
  74. unsigned long pc = regs->ARM_pc + 4;
  75. int rt = (insn >> 12) & 0xf;
  76. int rn = (insn >> 16) & 0xf;
  77. int rm = insn & 0xf;
  78. register unsigned long rtv asm("r0") = regs->uregs[rt];
  79. register unsigned long rt2v asm("r1") = regs->uregs[rt+1];
  80. register unsigned long rnv asm("r2") = (rn == 15) ? pc
  81. : regs->uregs[rn];
  82. register unsigned long rmv asm("r3") = regs->uregs[rm];
  83. __asm__ __volatile__ (
  84. BLX("%[fn]")
  85. : "=r" (rtv), "=r" (rt2v), "=r" (rnv)
  86. : "0" (rtv), "1" (rt2v), "2" (rnv), "r" (rmv),
  87. [fn] "r" (asi->insn_fn)
  88. : "lr", "memory", "cc"
  89. );
  90. regs->uregs[rt] = rtv;
  91. regs->uregs[rt+1] = rt2v;
  92. if (is_writeback(insn))
  93. regs->uregs[rn] = rnv;
  94. }
  95. static void __kprobes
  96. emulate_ldr(probes_opcode_t insn,
  97. struct arch_probes_insn *asi, struct pt_regs *regs)
  98. {
  99. unsigned long pc = regs->ARM_pc + 4;
  100. int rt = (insn >> 12) & 0xf;
  101. int rn = (insn >> 16) & 0xf;
  102. int rm = insn & 0xf;
  103. register unsigned long rtv asm("r0");
  104. register unsigned long rnv asm("r2") = (rn == 15) ? pc
  105. : regs->uregs[rn];
  106. register unsigned long rmv asm("r3") = regs->uregs[rm];
  107. __asm__ __volatile__ (
  108. BLX("%[fn]")
  109. : "=r" (rtv), "=r" (rnv)
  110. : "1" (rnv), "r" (rmv), [fn] "r" (asi->insn_fn)
  111. : "lr", "memory", "cc"
  112. );
  113. if (rt == 15)
  114. load_write_pc(rtv, regs);
  115. else
  116. regs->uregs[rt] = rtv;
  117. if (is_writeback(insn))
  118. regs->uregs[rn] = rnv;
  119. }
  120. static void __kprobes
  121. emulate_str(probes_opcode_t insn,
  122. struct arch_probes_insn *asi, struct pt_regs *regs)
  123. {
  124. unsigned long rtpc = regs->ARM_pc - 4 + str_pc_offset;
  125. unsigned long rnpc = regs->ARM_pc + 4;
  126. int rt = (insn >> 12) & 0xf;
  127. int rn = (insn >> 16) & 0xf;
  128. int rm = insn & 0xf;
  129. register unsigned long rtv asm("r0") = (rt == 15) ? rtpc
  130. : regs->uregs[rt];
  131. register unsigned long rnv asm("r2") = (rn == 15) ? rnpc
  132. : regs->uregs[rn];
  133. register unsigned long rmv asm("r3") = regs->uregs[rm];
  134. __asm__ __volatile__ (
  135. BLX("%[fn]")
  136. : "=r" (rnv)
  137. : "r" (rtv), "0" (rnv), "r" (rmv), [fn] "r" (asi->insn_fn)
  138. : "lr", "memory", "cc"
  139. );
  140. if (is_writeback(insn))
  141. regs->uregs[rn] = rnv;
  142. }
  143. static void __kprobes
  144. emulate_rd12rn16rm0rs8_rwflags(probes_opcode_t insn,
  145. struct arch_probes_insn *asi, struct pt_regs *regs)
  146. {
  147. unsigned long pc = regs->ARM_pc + 4;
  148. int rd = (insn >> 12) & 0xf;
  149. int rn = (insn >> 16) & 0xf;
  150. int rm = insn & 0xf;
  151. int rs = (insn >> 8) & 0xf;
  152. register unsigned long rdv asm("r0") = regs->uregs[rd];
  153. register unsigned long rnv asm("r2") = (rn == 15) ? pc
  154. : regs->uregs[rn];
  155. register unsigned long rmv asm("r3") = (rm == 15) ? pc
  156. : regs->uregs[rm];
  157. register unsigned long rsv asm("r1") = regs->uregs[rs];
  158. unsigned long cpsr = regs->ARM_cpsr;
  159. __asm__ __volatile__ (
  160. "msr cpsr_fs, %[cpsr] \n\t"
  161. BLX("%[fn]")
  162. "mrs %[cpsr], cpsr \n\t"
  163. : "=r" (rdv), [cpsr] "=r" (cpsr)
  164. : "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv),
  165. "1" (cpsr), [fn] "r" (asi->insn_fn)
  166. : "lr", "memory", "cc"
  167. );
  168. if (rd == 15)
  169. alu_write_pc(rdv, regs);
  170. else
  171. regs->uregs[rd] = rdv;
  172. regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
  173. }
  174. static void __kprobes
  175. emulate_rd12rn16rm0_rwflags_nopc(probes_opcode_t insn,
  176. struct arch_probes_insn *asi, struct pt_regs *regs)
  177. {
  178. int rd = (insn >> 12) & 0xf;
  179. int rn = (insn >> 16) & 0xf;
  180. int rm = insn & 0xf;
  181. register unsigned long rdv asm("r0") = regs->uregs[rd];
  182. register unsigned long rnv asm("r2") = regs->uregs[rn];
  183. register unsigned long rmv asm("r3") = regs->uregs[rm];
  184. unsigned long cpsr = regs->ARM_cpsr;
  185. __asm__ __volatile__ (
  186. "msr cpsr_fs, %[cpsr] \n\t"
  187. BLX("%[fn]")
  188. "mrs %[cpsr], cpsr \n\t"
  189. : "=r" (rdv), [cpsr] "=r" (cpsr)
  190. : "0" (rdv), "r" (rnv), "r" (rmv),
  191. "1" (cpsr), [fn] "r" (asi->insn_fn)
  192. : "lr", "memory", "cc"
  193. );
  194. regs->uregs[rd] = rdv;
  195. regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
  196. }
  197. static void __kprobes
  198. emulate_rd16rn12rm0rs8_rwflags_nopc(probes_opcode_t insn,
  199. struct arch_probes_insn *asi,
  200. struct pt_regs *regs)
  201. {
  202. int rd = (insn >> 16) & 0xf;
  203. int rn = (insn >> 12) & 0xf;
  204. int rm = insn & 0xf;
  205. int rs = (insn >> 8) & 0xf;
  206. register unsigned long rdv asm("r2") = regs->uregs[rd];
  207. register unsigned long rnv asm("r0") = regs->uregs[rn];
  208. register unsigned long rmv asm("r3") = regs->uregs[rm];
  209. register unsigned long rsv asm("r1") = regs->uregs[rs];
  210. unsigned long cpsr = regs->ARM_cpsr;
  211. __asm__ __volatile__ (
  212. "msr cpsr_fs, %[cpsr] \n\t"
  213. BLX("%[fn]")
  214. "mrs %[cpsr], cpsr \n\t"
  215. : "=r" (rdv), [cpsr] "=r" (cpsr)
  216. : "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv),
  217. "1" (cpsr), [fn] "r" (asi->insn_fn)
  218. : "lr", "memory", "cc"
  219. );
  220. regs->uregs[rd] = rdv;
  221. regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
  222. }
  223. static void __kprobes
  224. emulate_rd12rm0_noflags_nopc(probes_opcode_t insn,
  225. struct arch_probes_insn *asi, struct pt_regs *regs)
  226. {
  227. int rd = (insn >> 12) & 0xf;
  228. int rm = insn & 0xf;
  229. register unsigned long rdv asm("r0") = regs->uregs[rd];
  230. register unsigned long rmv asm("r3") = regs->uregs[rm];
  231. __asm__ __volatile__ (
  232. BLX("%[fn]")
  233. : "=r" (rdv)
  234. : "0" (rdv), "r" (rmv), [fn] "r" (asi->insn_fn)
  235. : "lr", "memory", "cc"
  236. );
  237. regs->uregs[rd] = rdv;
  238. }
  239. static void __kprobes
  240. emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(probes_opcode_t insn,
  241. struct arch_probes_insn *asi,
  242. struct pt_regs *regs)
  243. {
  244. int rdlo = (insn >> 12) & 0xf;
  245. int rdhi = (insn >> 16) & 0xf;
  246. int rn = insn & 0xf;
  247. int rm = (insn >> 8) & 0xf;
  248. register unsigned long rdlov asm("r0") = regs->uregs[rdlo];
  249. register unsigned long rdhiv asm("r2") = regs->uregs[rdhi];
  250. register unsigned long rnv asm("r3") = regs->uregs[rn];
  251. register unsigned long rmv asm("r1") = regs->uregs[rm];
  252. unsigned long cpsr = regs->ARM_cpsr;
  253. __asm__ __volatile__ (
  254. "msr cpsr_fs, %[cpsr] \n\t"
  255. BLX("%[fn]")
  256. "mrs %[cpsr], cpsr \n\t"
  257. : "=r" (rdlov), "=r" (rdhiv), [cpsr] "=r" (cpsr)
  258. : "0" (rdlov), "1" (rdhiv), "r" (rnv), "r" (rmv),
  259. "2" (cpsr), [fn] "r" (asi->insn_fn)
  260. : "lr", "memory", "cc"
  261. );
  262. regs->uregs[rdlo] = rdlov;
  263. regs->uregs[rdhi] = rdhiv;
  264. regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
  265. }
  266. const union decode_action kprobes_arm_actions[NUM_PROBES_ARM_ACTIONS] = {
  267. [PROBES_EMULATE_NONE] = {.handler = probes_emulate_none},
  268. [PROBES_SIMULATE_NOP] = {.handler = probes_simulate_nop},
  269. [PROBES_PRELOAD_IMM] = {.handler = probes_simulate_nop},
  270. [PROBES_PRELOAD_REG] = {.handler = probes_simulate_nop},
  271. [PROBES_BRANCH_IMM] = {.handler = simulate_blx1},
  272. [PROBES_MRS] = {.handler = simulate_mrs},
  273. [PROBES_BRANCH_REG] = {.handler = simulate_blx2bx},
  274. [PROBES_CLZ] = {.handler = emulate_rd12rm0_noflags_nopc},
  275. [PROBES_SATURATING_ARITHMETIC] = {
  276. .handler = emulate_rd12rn16rm0_rwflags_nopc},
  277. [PROBES_MUL1] = {.handler = emulate_rdlo12rdhi16rn0rm8_rwflags_nopc},
  278. [PROBES_MUL2] = {.handler = emulate_rd16rn12rm0rs8_rwflags_nopc},
  279. [PROBES_SWP] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
  280. [PROBES_LDRSTRD] = {.handler = emulate_ldrdstrd},
  281. [PROBES_LOAD_EXTRA] = {.handler = emulate_ldr},
  282. [PROBES_LOAD] = {.handler = emulate_ldr},
  283. [PROBES_STORE_EXTRA] = {.handler = emulate_str},
  284. [PROBES_STORE] = {.handler = emulate_str},
  285. [PROBES_MOV_IP_SP] = {.handler = simulate_mov_ipsp},
  286. [PROBES_DATA_PROCESSING_REG] = {
  287. .handler = emulate_rd12rn16rm0rs8_rwflags},
  288. [PROBES_DATA_PROCESSING_IMM] = {
  289. .handler = emulate_rd12rn16rm0rs8_rwflags},
  290. [PROBES_MOV_HALFWORD] = {.handler = emulate_rd12rm0_noflags_nopc},
  291. [PROBES_SEV] = {.handler = probes_emulate_none},
  292. [PROBES_WFE] = {.handler = probes_simulate_nop},
  293. [PROBES_SATURATE] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
  294. [PROBES_REV] = {.handler = emulate_rd12rm0_noflags_nopc},
  295. [PROBES_MMI] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
  296. [PROBES_PACK] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
  297. [PROBES_EXTEND] = {.handler = emulate_rd12rm0_noflags_nopc},
  298. [PROBES_EXTEND_ADD] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
  299. [PROBES_MUL_ADD_LONG] = {
  300. .handler = emulate_rdlo12rdhi16rn0rm8_rwflags_nopc},
  301. [PROBES_MUL_ADD] = {.handler = emulate_rd16rn12rm0rs8_rwflags_nopc},
  302. [PROBES_BITFIELD] = {.handler = emulate_rd12rm0_noflags_nopc},
  303. [PROBES_BRANCH] = {.handler = simulate_bbl},
  304. [PROBES_LDMSTM] = {.decoder = kprobe_decode_ldmstm}
  305. };