ptrace.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /*
  2. * Copyright 2010 Tilera Corporation. All Rights Reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation, version 2.
  7. *
  8. * This program is distributed in the hope that it will be useful, but
  9. * WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
  11. * NON INFRINGEMENT. See the GNU General Public License for
  12. * more details.
  13. *
  14. * Copied from i386: Ross Biro 1/23/92
  15. */
  16. #include <linux/kernel.h>
  17. #include <linux/ptrace.h>
  18. #include <linux/kprobes.h>
  19. #include <linux/compat.h>
  20. #include <linux/uaccess.h>
  21. #include <asm/traps.h>
  22. void user_enable_single_step(struct task_struct *child)
  23. {
  24. set_tsk_thread_flag(child, TIF_SINGLESTEP);
  25. }
  26. void user_disable_single_step(struct task_struct *child)
  27. {
  28. clear_tsk_thread_flag(child, TIF_SINGLESTEP);
  29. }
  30. /*
  31. * Called by kernel/ptrace.c when detaching..
  32. */
  33. void ptrace_disable(struct task_struct *child)
  34. {
  35. clear_tsk_thread_flag(child, TIF_SINGLESTEP);
  36. /*
  37. * These two are currently unused, but will be set by arch_ptrace()
  38. * and used in the syscall assembly when we do support them.
  39. */
  40. clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
  41. }
  42. /*
  43. * Get registers from task and ready the result for userspace.
  44. * Note that we localize the API issues to getregs() and putregs() at
  45. * some cost in performance, e.g. we need a full pt_regs copy for
  46. * PEEKUSR, and two copies for POKEUSR. But in general we expect
  47. * GETREGS/PUTREGS to be the API of choice anyway.
  48. */
  49. static char *getregs(struct task_struct *child, struct pt_regs *uregs)
  50. {
  51. *uregs = *task_pt_regs(child);
  52. /* Set up flags ABI bits. */
  53. uregs->flags = 0;
  54. #ifdef CONFIG_COMPAT
  55. if (task_thread_info(child)->status & TS_COMPAT)
  56. uregs->flags |= PT_FLAGS_COMPAT;
  57. #endif
  58. return (char *)uregs;
  59. }
  60. /* Put registers back to task. */
  61. static void putregs(struct task_struct *child, struct pt_regs *uregs)
  62. {
  63. struct pt_regs *regs = task_pt_regs(child);
  64. /* Don't allow overwriting the kernel-internal flags word. */
  65. uregs->flags = regs->flags;
  66. /* Only allow setting the ICS bit in the ex1 word. */
  67. uregs->ex1 = PL_ICS_EX1(USER_PL, EX1_ICS(uregs->ex1));
  68. *regs = *uregs;
  69. }
  70. long arch_ptrace(struct task_struct *child, long request,
  71. unsigned long addr, unsigned long data)
  72. {
  73. unsigned long __user *datap = (long __user __force *)data;
  74. unsigned long tmp;
  75. long ret = -EIO;
  76. char *childreg;
  77. struct pt_regs copyregs;
  78. switch (request) {
  79. case PTRACE_PEEKUSR: /* Read register from pt_regs. */
  80. if (addr >= PTREGS_SIZE)
  81. break;
  82. childreg = getregs(child, &copyregs) + addr;
  83. #ifdef CONFIG_COMPAT
  84. if (is_compat_task()) {
  85. if (addr & (sizeof(compat_long_t)-1))
  86. break;
  87. ret = put_user(*(compat_long_t *)childreg,
  88. (compat_long_t __user *)datap);
  89. } else
  90. #endif
  91. {
  92. if (addr & (sizeof(long)-1))
  93. break;
  94. ret = put_user(*(long *)childreg, datap);
  95. }
  96. break;
  97. case PTRACE_POKEUSR: /* Write register in pt_regs. */
  98. if (addr >= PTREGS_SIZE)
  99. break;
  100. childreg = getregs(child, &copyregs) + addr;
  101. #ifdef CONFIG_COMPAT
  102. if (is_compat_task()) {
  103. if (addr & (sizeof(compat_long_t)-1))
  104. break;
  105. *(compat_long_t *)childreg = data;
  106. } else
  107. #endif
  108. {
  109. if (addr & (sizeof(long)-1))
  110. break;
  111. *(long *)childreg = data;
  112. }
  113. putregs(child, &copyregs);
  114. ret = 0;
  115. break;
  116. case PTRACE_GETREGS: /* Get all registers from the child. */
  117. if (copy_to_user(datap, getregs(child, &copyregs),
  118. sizeof(struct pt_regs)) == 0) {
  119. ret = 0;
  120. }
  121. break;
  122. case PTRACE_SETREGS: /* Set all registers in the child. */
  123. if (copy_from_user(&copyregs, datap,
  124. sizeof(struct pt_regs)) == 0) {
  125. putregs(child, &copyregs);
  126. ret = 0;
  127. }
  128. break;
  129. case PTRACE_GETFPREGS: /* Get the child FPU state. */
  130. case PTRACE_SETFPREGS: /* Set the child FPU state. */
  131. break;
  132. case PTRACE_SETOPTIONS:
  133. /* Support TILE-specific ptrace options. */
  134. child->ptrace &= ~PT_TRACE_MASK_TILE;
  135. tmp = data & PTRACE_O_MASK_TILE;
  136. data &= ~PTRACE_O_MASK_TILE;
  137. ret = ptrace_request(child, request, addr, data);
  138. if (tmp & PTRACE_O_TRACEMIGRATE)
  139. child->ptrace |= PT_TRACE_MIGRATE;
  140. break;
  141. default:
  142. #ifdef CONFIG_COMPAT
  143. if (task_thread_info(current)->status & TS_COMPAT) {
  144. ret = compat_ptrace_request(child, request,
  145. addr, data);
  146. break;
  147. }
  148. #endif
  149. ret = ptrace_request(child, request, addr, data);
  150. break;
  151. }
  152. return ret;
  153. }
  154. #ifdef CONFIG_COMPAT
  155. /* Not used; we handle compat issues in arch_ptrace() directly. */
  156. long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
  157. compat_ulong_t addr, compat_ulong_t data)
  158. {
  159. BUG();
  160. }
  161. #endif
  162. void do_syscall_trace(void)
  163. {
  164. if (!test_thread_flag(TIF_SYSCALL_TRACE))
  165. return;
  166. if (!(current->ptrace & PT_PTRACED))
  167. return;
  168. /*
  169. * The 0x80 provides a way for the tracing parent to distinguish
  170. * between a syscall stop and SIGTRAP delivery
  171. */
  172. ptrace_notify(SIGTRAP|((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0));
  173. /*
  174. * this isn't the same as continuing with a signal, but it will do
  175. * for normal use. strace only continues with a signal if the
  176. * stopping signal is not SIGTRAP. -brl
  177. */
  178. if (current->exit_code) {
  179. send_sig(current->exit_code, current, 1);
  180. current->exit_code = 0;
  181. }
  182. }
  183. void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
  184. {
  185. struct siginfo info;
  186. memset(&info, 0, sizeof(info));
  187. info.si_signo = SIGTRAP;
  188. info.si_code = TRAP_BRKPT;
  189. info.si_addr = (void __user *) regs->pc;
  190. /* Send us the fakey SIGTRAP */
  191. force_sig_info(SIGTRAP, &info, tsk);
  192. }
  193. /* Handle synthetic interrupt delivered only by the simulator. */
  194. void __kprobes do_breakpoint(struct pt_regs* regs, int fault_num)
  195. {
  196. send_sigtrap(current, regs, fault_num);
  197. }