procfs.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /*
  2. * Server-side /proc support for Solaris
  3. *
  4. * Copyright (C) 2007 Alexandre Julliard
  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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  19. */
  20. #include "config.h"
  21. #include <assert.h>
  22. #include <errno.h>
  23. #include <fcntl.h>
  24. #include <stdio.h>
  25. #include <signal.h>
  26. #include <stdarg.h>
  27. #include <sys/types.h>
  28. #include <unistd.h>
  29. #include "ntstatus.h"
  30. #define WIN32_NO_STATUS
  31. #include "winternl.h"
  32. #include "file.h"
  33. #include "process.h"
  34. #include "thread.h"
  35. #ifdef USE_PROCFS
  36. /* procfs doesn't support large files */
  37. # undef _FILE_OFFSET_BITS
  38. # define _FILE_OFFSET_BITS 32
  39. #include <procfs.h>
  40. static int open_proc_as( struct process *process, int flags )
  41. {
  42. char buffer[32];
  43. int fd;
  44. if (process->unix_pid == -1)
  45. {
  46. set_error( STATUS_ACCESS_DENIED );
  47. return -1;
  48. }
  49. sprintf( buffer, "/proc/%u/as", process->unix_pid );
  50. if ((fd = open( buffer, flags )) == -1)
  51. {
  52. if (errno == ENOENT) /* probably got killed */
  53. {
  54. process->unix_pid = -1;
  55. set_error( STATUS_ACCESS_DENIED );
  56. }
  57. else file_set_error();
  58. }
  59. return fd;
  60. }
  61. static int open_proc_lwpctl( struct thread *thread )
  62. {
  63. char buffer[48];
  64. int fd;
  65. if (thread->unix_pid == -1) return -1;
  66. sprintf( buffer, "/proc/%u/lwp/%u/lwpctl", thread->unix_pid, thread->unix_tid );
  67. if ((fd = open( buffer, O_WRONLY )) == -1)
  68. {
  69. if (errno == ENOENT) /* probably got killed */
  70. thread->unix_pid = thread->unix_tid = -1;
  71. else
  72. file_set_error();
  73. }
  74. return fd;
  75. }
  76. /* handle a SIGCHLD signal */
  77. void sigchld_callback(void)
  78. {
  79. assert( 0 ); /* should only be called when using ptrace */
  80. }
  81. /* initialize the process tracing mechanism */
  82. void init_tracing_mechanism(void)
  83. {
  84. /* no initialization needed */
  85. }
  86. /* initialize the per-process tracing mechanism */
  87. void init_process_tracing( struct process *process )
  88. {
  89. /* setup is done on-demand */
  90. }
  91. /* terminate the per-process tracing mechanism */
  92. void finish_process_tracing( struct process *process )
  93. {
  94. }
  95. /* send a Unix signal to a specific thread */
  96. int send_thread_signal( struct thread *thread, int sig )
  97. {
  98. int fd = open_proc_lwpctl( thread );
  99. long kill[2];
  100. ssize_t ret;
  101. if (fd == -1) return 0;
  102. kill[0] = PCKILL;
  103. kill[1] = sig;
  104. ret = write( fd, kill, sizeof(kill) );
  105. close( fd );
  106. return (ret == sizeof(kill));
  107. }
  108. /* read data from a process memory space */
  109. int read_process_memory( struct process *process, client_ptr_t ptr, size_t size, char *dest )
  110. {
  111. ssize_t ret;
  112. int fd;
  113. if ((off_t)ptr != ptr)
  114. {
  115. set_error( STATUS_ACCESS_DENIED );
  116. return 0;
  117. }
  118. if ((fd = open_proc_as( process, O_RDONLY )) == -1) return 0;
  119. ret = pread( fd, dest, size, (off_t)ptr );
  120. close( fd );
  121. if (ret == size) return 1;
  122. if (ret == -1) file_set_error();
  123. else set_error( STATUS_ACCESS_VIOLATION );
  124. return 0;
  125. }
  126. /* write data to a process memory space */
  127. int write_process_memory( struct process *process, client_ptr_t ptr, size_t size, const char *src )
  128. {
  129. ssize_t ret;
  130. int fd;
  131. if ((off_t)ptr != ptr)
  132. {
  133. set_error( STATUS_ACCESS_DENIED );
  134. return 0;
  135. }
  136. if ((fd = open_proc_as( process, O_WRONLY )) == -1) return 0;
  137. ret = pwrite( fd, src, size, (off_t)ptr );
  138. close( fd );
  139. if (ret == size) return 1;
  140. if (ret == -1) file_set_error();
  141. else set_error( STATUS_ACCESS_VIOLATION );
  142. return 0;
  143. }
  144. /* retrieve an LDT selector entry */
  145. void get_selector_entry( struct thread *thread, int entry, unsigned int *base,
  146. unsigned int *limit, unsigned char *flags )
  147. {
  148. ssize_t ret;
  149. off_t pos = thread->process->ldt_copy;
  150. int fd;
  151. if (!pos)
  152. {
  153. set_error( STATUS_ACCESS_DENIED );
  154. return;
  155. }
  156. if ((fd = open_proc_as( thread->process, O_RDONLY )) == -1) return;
  157. ret = pread( fd, base, sizeof(*base), pos + entry*sizeof(int) );
  158. if (ret != sizeof(*base)) goto error;
  159. ret = pread( fd, limit, sizeof(*limit), pos + (8192 + entry)*sizeof(int) );
  160. if (ret != sizeof(*limit)) goto error;
  161. ret = pread( fd, flags, sizeof(*flags), pos + 2*8192*sizeof(int) + entry );
  162. if (ret != sizeof(*flags)) goto error;
  163. close( fd );
  164. return;
  165. error:
  166. if (ret == -1) file_set_error();
  167. else set_error( STATUS_ACCESS_VIOLATION );
  168. close( fd );
  169. }
  170. /* initialize registers in new thread if necessary */
  171. void init_thread_context( struct thread *thread )
  172. {
  173. }
  174. /* retrieve the thread registers */
  175. void get_thread_context( struct thread *thread, context_t *context, unsigned int flags )
  176. {
  177. /* FIXME: get debug registers */
  178. }
  179. /* set the thread registers */
  180. void set_thread_context( struct thread *thread, const context_t *context, unsigned int flags )
  181. {
  182. /* FIXME: set debug registers */
  183. }
  184. #endif /* USE_PROCFS */