2 * Server-side /proc support for Solaris
4 * Copyright (C) 2007 Alexandre Julliard
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.
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.
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
29 #include <sys/types.h>
33 #define WIN32_NO_STATUS
42 /* procfs doesn't support large files */
43 # undef _FILE_OFFSET_BITS
44 # define _FILE_OFFSET_BITS 32
47 static int open_proc_as( struct process
*process
, int flags
)
52 if (process
->unix_pid
== -1)
54 set_error( STATUS_ACCESS_DENIED
);
58 sprintf( buffer
, "/proc/%u/as", process
->unix_pid
);
59 if ((fd
= open( buffer
, flags
)) == -1)
61 if (errno
== ENOENT
) /* probably got killed */
63 process
->unix_pid
= -1;
64 set_error( STATUS_ACCESS_DENIED
);
66 else file_set_error();
71 static int open_proc_lwpctl( struct thread
*thread
)
76 if (thread
->unix_pid
== -1) return -1;
78 sprintf( buffer
, "/proc/%u/lwp/%u/lwpctl", thread
->unix_pid
, thread
->unix_tid
);
79 if ((fd
= open( buffer
, O_WRONLY
)) == -1)
81 if (errno
== ENOENT
) /* probably got killed */
82 thread
->unix_pid
= thread
->unix_tid
= -1;
90 /* handle a SIGCHLD signal */
91 void sigchld_callback(void)
93 assert( 0 ); /* should only be called when using ptrace */
96 /* initialize the process tracing mechanism */
97 void init_tracing_mechanism(void)
99 /* no initialization needed */
102 /* initialize the per-process tracing mechanism */
103 void init_process_tracing( struct process
*process
)
105 /* setup is done on-demand */
108 /* terminate the per-process tracing mechanism */
109 void finish_process_tracing( struct process
*process
)
113 /* send a Unix signal to a specific thread */
114 int send_thread_signal( struct thread
*thread
, int sig
)
116 int fd
= open_proc_lwpctl( thread
);
120 if (fd
== -1) return 0;
124 ret
= write( fd
, kill
, sizeof(kill
) );
126 return (ret
== sizeof(kill
));
129 /* read data from a process memory space */
130 int read_process_memory( struct process
*process
, client_ptr_t ptr
, size_t size
, char *dest
)
135 if ((off_t
)ptr
!= ptr
)
137 set_error( STATUS_ACCESS_DENIED
);
141 if ((fd
= open_proc_as( process
, O_RDONLY
)) == -1) return 0;
143 ret
= pread( fd
, dest
, size
, (off_t
)ptr
);
145 if (ret
== size
) return 1;
147 if (ret
== -1) file_set_error();
148 else set_error( STATUS_ACCESS_VIOLATION
);
152 /* write data to a process memory space */
153 int write_process_memory( struct process
*process
, client_ptr_t ptr
, size_t size
, const char *src
)
158 if ((off_t
)ptr
!= ptr
)
160 set_error( STATUS_ACCESS_DENIED
);
164 if ((fd
= open_proc_as( process
, O_WRONLY
)) == -1) return 0;
166 ret
= pwrite( fd
, src
, size
, (off_t
)ptr
);
168 if (ret
== size
) return 1;
170 if (ret
== -1) file_set_error();
171 else set_error( STATUS_ACCESS_VIOLATION
);
175 /* retrieve an LDT selector entry */
176 void get_selector_entry( struct thread
*thread
, int entry
, unsigned int *base
,
177 unsigned int *limit
, unsigned char *flags
)
180 off_t pos
= thread
->process
->ldt_copy
;
185 set_error( STATUS_ACCESS_DENIED
);
188 if ((fd
= open_proc_as( thread
->process
, O_RDONLY
)) == -1) return;
190 ret
= pread( fd
, base
, sizeof(*base
), pos
+ entry
*sizeof(int) );
191 if (ret
!= sizeof(*base
)) goto error
;
192 ret
= pread( fd
, limit
, sizeof(*limit
), pos
+ (8192 + entry
)*sizeof(int) );
193 if (ret
!= sizeof(*limit
)) goto error
;
194 ret
= pread( fd
, flags
, sizeof(*flags
), pos
+ 2*8192*sizeof(int) + entry
);
195 if (ret
!= sizeof(*flags
)) goto error
;
200 if (ret
== -1) file_set_error();
201 else set_error( STATUS_ACCESS_VIOLATION
);
205 /* initialize registers in new thread if necessary */
206 void init_thread_context( struct thread
*thread
)
210 /* retrieve the thread registers */
211 void get_thread_context( struct thread
*thread
, context_t
*context
, unsigned int flags
)
213 /* FIXME: get debug registers */
216 /* set the thread registers */
217 void set_thread_context( struct thread
*thread
, const context_t
*context
, unsigned int flags
)
219 /* FIXME: set debug registers */
222 #endif /* USE_PROCFS */