ptrace.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /*
  2. * arch/v850/kernel/ptrace.c -- `ptrace' system call
  3. *
  4. * Copyright (C) 2002,03,04 NEC Electronics Corporation
  5. * Copyright (C) 2002,03,04 Miles Bader <miles@gnu.org>
  6. *
  7. * Derived from arch/mips/kernel/ptrace.c:
  8. *
  9. * Copyright (C) 1992 Ross Biro
  10. * Copyright (C) Linus Torvalds
  11. * Copyright (C) 1994, 95, 96, 97, 98, 2000 Ralf Baechle
  12. * Copyright (C) 1996 David S. Miller
  13. * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
  14. * Copyright (C) 1999 MIPS Technologies, Inc.
  15. *
  16. * This file is subject to the terms and conditions of the GNU General
  17. * Public License. See the file COPYING in the main directory of this
  18. * archive for more details.
  19. */
  20. #include <linux/kernel.h>
  21. #include <linux/mm.h>
  22. #include <linux/sched.h>
  23. #include <linux/smp_lock.h>
  24. #include <linux/ptrace.h>
  25. #include <linux/signal.h>
  26. #include <asm/errno.h>
  27. #include <asm/ptrace.h>
  28. #include <asm/processor.h>
  29. #include <asm/uaccess.h>
  30. /* Returns the address where the register at REG_OFFS in P is stashed away. */
  31. static v850_reg_t *reg_save_addr (unsigned reg_offs, struct task_struct *t)
  32. {
  33. struct pt_regs *regs;
  34. /* Three basic cases:
  35. (1) A register normally saved before calling the scheduler, is
  36. available in the kernel entry pt_regs structure at the top
  37. of the kernel stack. The kernel trap/irq exit path takes
  38. care to save/restore almost all registers for ptrace'd
  39. processes.
  40. (2) A call-clobbered register, where the process P entered the
  41. kernel via [syscall] trap, is not stored anywhere; that's
  42. OK, because such registers are not expected to be preserved
  43. when the trap returns anyway (so we don't actually bother to
  44. test for this case).
  45. (3) A few registers not used at all by the kernel, and so
  46. normally never saved except by context-switches, are in the
  47. context switch state. */
  48. if (reg_offs == PT_CTPC || reg_offs == PT_CTPSW || reg_offs == PT_CTBP)
  49. /* Register saved during context switch. */
  50. regs = thread_saved_regs (t);
  51. else
  52. /* Register saved during kernel entry (or not available). */
  53. regs = task_pt_regs (t);
  54. return (v850_reg_t *)((char *)regs + reg_offs);
  55. }
  56. /* Set the bits SET and clear the bits CLEAR in the v850e DIR
  57. (`debug information register'). Returns the new value of DIR. */
  58. static inline v850_reg_t set_dir (v850_reg_t set, v850_reg_t clear)
  59. {
  60. register v850_reg_t rval asm ("r10");
  61. register v850_reg_t arg0 asm ("r6") = set;
  62. register v850_reg_t arg1 asm ("r7") = clear;
  63. /* The dbtrap handler has exactly this functionality when called
  64. from kernel mode. 0xf840 is a `dbtrap' insn. */
  65. asm (".short 0xf840" : "=r" (rval) : "r" (arg0), "r" (arg1));
  66. return rval;
  67. }
  68. /* Makes sure hardware single-stepping is (globally) enabled.
  69. Returns true if successful. */
  70. static inline int enable_single_stepping (void)
  71. {
  72. static int enabled = 0; /* Remember whether we already did it. */
  73. if (! enabled) {
  74. /* Turn on the SE (`single-step enable') bit, 0x100, in the
  75. DIR (`debug information register'). This may fail if a
  76. processor doesn't support it or something. We also try
  77. to clear bit 0x40 (`INI'), which is necessary to use the
  78. debug stuff on the v850e2; on the v850e, clearing 0x40
  79. shouldn't cause any problem. */
  80. v850_reg_t dir = set_dir (0x100, 0x40);
  81. /* Make sure it really got set. */
  82. if (dir & 0x100)
  83. enabled = 1;
  84. }
  85. return enabled;
  86. }
  87. /* Try to set CHILD's single-step flag to VAL. Returns true if successful. */
  88. static int set_single_step (struct task_struct *t, int val)
  89. {
  90. v850_reg_t *psw_addr = reg_save_addr(PT_PSW, t);
  91. if (val) {
  92. /* Make sure single-stepping is enabled. */
  93. if (! enable_single_stepping ())
  94. return 0;
  95. /* Set T's single-step flag. */
  96. *psw_addr |= 0x800;
  97. } else
  98. *psw_addr &= ~0x800;
  99. return 1;
  100. }
  101. long arch_ptrace(struct task_struct *child, long request, long addr, long data)
  102. {
  103. int rval;
  104. switch (request) {
  105. unsigned long val, copied;
  106. case PTRACE_PEEKTEXT: /* read word at location addr. */
  107. case PTRACE_PEEKDATA:
  108. copied = access_process_vm(child, addr, &val, sizeof(val), 0);
  109. rval = -EIO;
  110. if (copied != sizeof(val))
  111. break;
  112. rval = put_user(val, (unsigned long *)data);
  113. goto out;
  114. case PTRACE_POKETEXT: /* write the word at location addr. */
  115. case PTRACE_POKEDATA:
  116. rval = 0;
  117. if (access_process_vm(child, addr, &data, sizeof(data), 1)
  118. == sizeof(data))
  119. break;
  120. rval = -EIO;
  121. goto out;
  122. /* Read/write the word at location ADDR in the registers. */
  123. case PTRACE_PEEKUSR:
  124. case PTRACE_POKEUSR:
  125. rval = 0;
  126. if (addr >= PT_SIZE && request == PTRACE_PEEKUSR) {
  127. /* Special requests that don't actually correspond
  128. to offsets in struct pt_regs. */
  129. if (addr == PT_TEXT_ADDR)
  130. val = child->mm->start_code;
  131. else if (addr == PT_DATA_ADDR)
  132. val = child->mm->start_data;
  133. else if (addr == PT_TEXT_LEN)
  134. val = child->mm->end_code
  135. - child->mm->start_code;
  136. else
  137. rval = -EIO;
  138. } else if (addr >= 0 && addr < PT_SIZE && (addr & 0x3) == 0) {
  139. v850_reg_t *reg_addr = reg_save_addr(addr, child);
  140. if (request == PTRACE_PEEKUSR)
  141. val = *reg_addr;
  142. else
  143. *reg_addr = data;
  144. } else
  145. rval = -EIO;
  146. if (rval == 0 && request == PTRACE_PEEKUSR)
  147. rval = put_user (val, (unsigned long *)data);
  148. goto out;
  149. /* Continue and stop at next (return from) syscall */
  150. case PTRACE_SYSCALL:
  151. /* Restart after a signal. */
  152. case PTRACE_CONT:
  153. /* Execute a single instruction. */
  154. case PTRACE_SINGLESTEP:
  155. rval = -EIO;
  156. if (!valid_signal(data))
  157. break;
  158. /* Turn CHILD's single-step flag on or off. */
  159. if (! set_single_step (child, request == PTRACE_SINGLESTEP))
  160. break;
  161. if (request == PTRACE_SYSCALL)
  162. set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
  163. else
  164. clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
  165. child->exit_code = data;
  166. wake_up_process(child);
  167. rval = 0;
  168. break;
  169. /*
  170. * make the child exit. Best I can do is send it a sigkill.
  171. * perhaps it should be put in the status that it wants to
  172. * exit.
  173. */
  174. case PTRACE_KILL:
  175. rval = 0;
  176. if (child->exit_state == EXIT_ZOMBIE) /* already dead */
  177. break;
  178. child->exit_code = SIGKILL;
  179. wake_up_process(child);
  180. break;
  181. case PTRACE_DETACH: /* detach a process that was attached. */
  182. set_single_step (child, 0); /* Clear single-step flag */
  183. rval = ptrace_detach(child, data);
  184. break;
  185. default:
  186. rval = -EIO;
  187. goto out;
  188. }
  189. out:
  190. return rval;
  191. }
  192. asmlinkage void syscall_trace(void)
  193. {
  194. if (!test_thread_flag(TIF_SYSCALL_TRACE))
  195. return;
  196. if (!(current->ptrace & PT_PTRACED))
  197. return;
  198. /* The 0x80 provides a way for the tracing parent to distinguish
  199. between a syscall stop and SIGTRAP delivery */
  200. ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
  201. ? 0x80 : 0));
  202. /*
  203. * this isn't the same as continuing with a signal, but it will do
  204. * for normal use. strace only continues with a signal if the
  205. * stopping signal is not SIGTRAP. -brl
  206. */
  207. if (current->exit_code) {
  208. send_sig(current->exit_code, current, 1);
  209. current->exit_code = 0;
  210. }
  211. }
  212. void ptrace_disable (struct task_struct *child)
  213. {
  214. /* nothing to do */
  215. }