context_sparc.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /*
  2. * Sparc register context support
  3. *
  4. * Copyright (C) 2000 Ulrich Weigand
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. */
  20. #include "config.h"
  21. #ifdef __sparc__
  22. #include <assert.h>
  23. #include <errno.h>
  24. #include <sys/types.h>
  25. #ifdef HAVE_SYS_REG_H
  26. # include <sys/reg.h>
  27. #endif
  28. #include <stdarg.h>
  29. #include <unistd.h>
  30. #ifdef HAVE_SYS_PTRACE_H
  31. # include <sys/ptrace.h>
  32. #endif
  33. #include "windef.h"
  34. #include "winbase.h"
  35. #include "file.h"
  36. #include "thread.h"
  37. #include "request.h"
  38. #if defined(__sun) || defined(__sun__)
  39. /* retrieve a thread context */
  40. static void get_thread_context( struct thread *thread, unsigned int flags, CONTEXT *context )
  41. {
  42. int pid = get_ptrace_pid(thread);
  43. if (flags & CONTEXT_FULL)
  44. {
  45. struct regs regs;
  46. if (ptrace( PTRACE_GETREGS, pid, 0, (int) &regs ) == -1) goto error;
  47. if (flags & CONTEXT_INTEGER)
  48. {
  49. context->g0 = 0;
  50. context->g1 = regs.r_g1;
  51. context->g2 = regs.r_g2;
  52. context->g3 = regs.r_g3;
  53. context->g4 = regs.r_g4;
  54. context->g5 = regs.r_g5;
  55. context->g6 = regs.r_g6;
  56. context->g7 = regs.r_g7;
  57. context->o0 = regs.r_o0;
  58. context->o1 = regs.r_o1;
  59. context->o2 = regs.r_o2;
  60. context->o3 = regs.r_o3;
  61. context->o4 = regs.r_o4;
  62. context->o5 = regs.r_o5;
  63. context->o6 = regs.r_o6;
  64. context->o7 = regs.r_o7;
  65. /* FIXME: local and in registers */
  66. }
  67. if (flags & CONTEXT_CONTROL)
  68. {
  69. context->psr = regs.r_psr;
  70. context->pc = regs.r_pc;
  71. context->npc = regs.r_npc;
  72. context->y = regs.r_y;
  73. context->wim = 0; /* FIXME */
  74. context->tbr = 0; /* FIXME */
  75. }
  76. }
  77. if (flags & CONTEXT_FLOATING_POINT)
  78. {
  79. /* FIXME */
  80. }
  81. return;
  82. error:
  83. file_set_error();
  84. }
  85. /* set a thread context */
  86. static void set_thread_context( struct thread *thread, unsigned int flags, const CONTEXT *context )
  87. {
  88. /* FIXME */
  89. }
  90. #else /* __sun__ */
  91. #error You must implement get/set_thread_context for your platform
  92. #endif /* __sun__ */
  93. /* copy a context structure according to the flags */
  94. static void copy_context( CONTEXT *to, const CONTEXT *from, int flags )
  95. {
  96. if (flags & CONTEXT_CONTROL)
  97. {
  98. to->psr = from->psr;
  99. to->pc = from->pc;
  100. to->npc = from->npc;
  101. to->y = from->y;
  102. to->wim = from->wim;
  103. to->tbr = from->tbr;
  104. }
  105. if (flags & CONTEXT_INTEGER)
  106. {
  107. to->g0 = from->g0;
  108. to->g1 = from->g1;
  109. to->g2 = from->g2;
  110. to->g3 = from->g3;
  111. to->g4 = from->g4;
  112. to->g5 = from->g5;
  113. to->g6 = from->g6;
  114. to->g7 = from->g7;
  115. to->o0 = from->o0;
  116. to->o1 = from->o1;
  117. to->o2 = from->o2;
  118. to->o3 = from->o3;
  119. to->o4 = from->o4;
  120. to->o5 = from->o5;
  121. to->o6 = from->o6;
  122. to->o7 = from->o7;
  123. to->l0 = from->l0;
  124. to->l1 = from->l1;
  125. to->l2 = from->l2;
  126. to->l3 = from->l3;
  127. to->l4 = from->l4;
  128. to->l5 = from->l5;
  129. to->l6 = from->l6;
  130. to->l7 = from->l7;
  131. to->i0 = from->i0;
  132. to->i1 = from->i1;
  133. to->i2 = from->i2;
  134. to->i3 = from->i3;
  135. to->i4 = from->i4;
  136. to->i5 = from->i5;
  137. to->i6 = from->i6;
  138. to->i7 = from->i7;
  139. }
  140. if (flags & CONTEXT_FLOATING_POINT)
  141. {
  142. /* FIXME */
  143. }
  144. }
  145. /* retrieve the current instruction pointer of a thread */
  146. void *get_thread_ip( struct thread *thread )
  147. {
  148. CONTEXT context;
  149. context.pc = 0;
  150. if (suspend_for_ptrace( thread ))
  151. {
  152. get_thread_context( thread, CONTEXT_CONTROL, &context );
  153. resume_after_ptrace( thread );
  154. }
  155. return (void *)context.pc;
  156. }
  157. /* determine if we should continue the thread in single-step mode */
  158. int get_thread_single_step( struct thread *thread )
  159. {
  160. return 0; /* FIXME */
  161. }
  162. /* send a signal to a specific thread */
  163. int tkill( int pid, int sig )
  164. {
  165. /* FIXME: should do something here */
  166. errno = ENOSYS;
  167. return -1;
  168. }
  169. /* retrieve the current context of a thread */
  170. DECL_HANDLER(get_thread_context)
  171. {
  172. struct thread *thread;
  173. void *data;
  174. int flags = req->flags & ~CONTEXT_SPARC; /* get rid of CPU id */
  175. if (get_reply_max_size() < sizeof(CONTEXT))
  176. {
  177. set_error( STATUS_INVALID_PARAMETER );
  178. return;
  179. }
  180. if (!(thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT ))) return;
  181. if ((data = set_reply_data_size( sizeof(CONTEXT) )))
  182. {
  183. if (thread->context) /* thread is inside an exception event */
  184. {
  185. copy_context( data, thread->context, flags );
  186. flags = 0;
  187. }
  188. if (flags && suspend_for_ptrace( thread ))
  189. {
  190. get_thread_context( thread, flags, data );
  191. resume_after_ptrace( thread );
  192. }
  193. }
  194. release_object( thread );
  195. }
  196. /* set the current context of a thread */
  197. DECL_HANDLER(set_thread_context)
  198. {
  199. struct thread *thread;
  200. int flags = req->flags & ~CONTEXT_SPARC; /* get rid of CPU id */
  201. if (get_req_data_size() < sizeof(CONTEXT))
  202. {
  203. set_error( STATUS_INVALID_PARAMETER );
  204. return;
  205. }
  206. if ((thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT )))
  207. {
  208. if (thread->context) /* thread is inside an exception event */
  209. {
  210. copy_context( thread->context, get_req_data(), flags );
  211. flags = 0;
  212. }
  213. if (flags && suspend_for_ptrace( thread ))
  214. {
  215. set_thread_context( thread, flags, get_req_data() );
  216. resume_after_ptrace( thread );
  217. }
  218. release_object( thread );
  219. }
  220. }
  221. #endif /* __sparc__ */