ptrace.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  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. long arch_ptrace(struct task_struct *child, long request,
  43. unsigned long addr, unsigned long data)
  44. {
  45. unsigned long __user *datap = (long __user __force *)data;
  46. unsigned long tmp;
  47. long ret = -EIO;
  48. char *childreg;
  49. struct pt_regs copyregs;
  50. int ex1_offset;
  51. switch (request) {
  52. case PTRACE_PEEKUSR: /* Read register from pt_regs. */
  53. if (addr >= PTREGS_SIZE)
  54. break;
  55. childreg = (char *)task_pt_regs(child) + addr;
  56. #ifdef CONFIG_COMPAT
  57. if (is_compat_task()) {
  58. if (addr & (sizeof(compat_long_t)-1))
  59. break;
  60. ret = put_user(*(compat_long_t *)childreg,
  61. (compat_long_t __user *)datap);
  62. } else
  63. #endif
  64. {
  65. if (addr & (sizeof(long)-1))
  66. break;
  67. ret = put_user(*(long *)childreg, datap);
  68. }
  69. break;
  70. case PTRACE_POKEUSR: /* Write register in pt_regs. */
  71. if (addr >= PTREGS_SIZE)
  72. break;
  73. childreg = (char *)task_pt_regs(child) + addr;
  74. /* Guard against overwrites of the privilege level. */
  75. ex1_offset = PTREGS_OFFSET_EX1;
  76. #if defined(CONFIG_COMPAT) && defined(__BIG_ENDIAN)
  77. if (is_compat_task()) /* point at low word */
  78. ex1_offset += sizeof(compat_long_t);
  79. #endif
  80. if (addr == ex1_offset)
  81. data = PL_ICS_EX1(USER_PL, EX1_ICS(data));
  82. #ifdef CONFIG_COMPAT
  83. if (is_compat_task()) {
  84. if (addr & (sizeof(compat_long_t)-1))
  85. break;
  86. *(compat_long_t *)childreg = data;
  87. } else
  88. #endif
  89. {
  90. if (addr & (sizeof(long)-1))
  91. break;
  92. *(long *)childreg = data;
  93. }
  94. ret = 0;
  95. break;
  96. case PTRACE_GETREGS: /* Get all registers from the child. */
  97. if (copy_to_user(datap, task_pt_regs(child),
  98. sizeof(struct pt_regs)) == 0) {
  99. ret = 0;
  100. }
  101. break;
  102. case PTRACE_SETREGS: /* Set all registers in the child. */
  103. if (copy_from_user(&copyregs, datap,
  104. sizeof(struct pt_regs)) == 0) {
  105. copyregs.ex1 =
  106. PL_ICS_EX1(USER_PL, EX1_ICS(copyregs.ex1));
  107. *task_pt_regs(child) = copyregs;
  108. ret = 0;
  109. }
  110. break;
  111. case PTRACE_GETFPREGS: /* Get the child FPU state. */
  112. case PTRACE_SETFPREGS: /* Set the child FPU state. */
  113. break;
  114. case PTRACE_SETOPTIONS:
  115. /* Support TILE-specific ptrace options. */
  116. child->ptrace &= ~PT_TRACE_MASK_TILE;
  117. tmp = data & PTRACE_O_MASK_TILE;
  118. data &= ~PTRACE_O_MASK_TILE;
  119. ret = ptrace_request(child, request, addr, data);
  120. if (tmp & PTRACE_O_TRACEMIGRATE)
  121. child->ptrace |= PT_TRACE_MIGRATE;
  122. break;
  123. default:
  124. #ifdef CONFIG_COMPAT
  125. if (task_thread_info(current)->status & TS_COMPAT) {
  126. ret = compat_ptrace_request(child, request,
  127. addr, data);
  128. break;
  129. }
  130. #endif
  131. ret = ptrace_request(child, request, addr, data);
  132. break;
  133. }
  134. return ret;
  135. }
  136. #ifdef CONFIG_COMPAT
  137. /* Not used; we handle compat issues in arch_ptrace() directly. */
  138. long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
  139. compat_ulong_t addr, compat_ulong_t data)
  140. {
  141. BUG();
  142. }
  143. #endif
  144. void do_syscall_trace(void)
  145. {
  146. if (!test_thread_flag(TIF_SYSCALL_TRACE))
  147. return;
  148. if (!(current->ptrace & PT_PTRACED))
  149. return;
  150. /*
  151. * The 0x80 provides a way for the tracing parent to distinguish
  152. * between a syscall stop and SIGTRAP delivery
  153. */
  154. ptrace_notify(SIGTRAP|((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0));
  155. /*
  156. * this isn't the same as continuing with a signal, but it will do
  157. * for normal use. strace only continues with a signal if the
  158. * stopping signal is not SIGTRAP. -brl
  159. */
  160. if (current->exit_code) {
  161. send_sig(current->exit_code, current, 1);
  162. current->exit_code = 0;
  163. }
  164. }
  165. void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
  166. {
  167. struct siginfo info;
  168. memset(&info, 0, sizeof(info));
  169. info.si_signo = SIGTRAP;
  170. info.si_code = TRAP_BRKPT;
  171. info.si_addr = (void __user *) regs->pc;
  172. /* Send us the fakey SIGTRAP */
  173. force_sig_info(SIGTRAP, &info, tsk);
  174. }
  175. /* Handle synthetic interrupt delivered only by the simulator. */
  176. void __kprobes do_breakpoint(struct pt_regs* regs, int fault_num)
  177. {
  178. send_sigtrap(current, regs, fault_num);
  179. }