123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- /*
- * Server-side /proc support for Solaris
- *
- * Copyright (C) 2007 Alexandre Julliard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
- #include "config.h"
- #include <assert.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <stdio.h>
- #include <signal.h>
- #include <stdarg.h>
- #include <sys/types.h>
- #include <unistd.h>
- #include "ntstatus.h"
- #define WIN32_NO_STATUS
- #include "winternl.h"
- #include "file.h"
- #include "process.h"
- #include "thread.h"
- #ifdef USE_PROCFS
- /* procfs doesn't support large files */
- # undef _FILE_OFFSET_BITS
- # define _FILE_OFFSET_BITS 32
- #include <procfs.h>
- static int open_proc_as( struct process *process, int flags )
- {
- char buffer[32];
- int fd;
- if (process->unix_pid == -1)
- {
- set_error( STATUS_ACCESS_DENIED );
- return -1;
- }
- sprintf( buffer, "/proc/%u/as", process->unix_pid );
- if ((fd = open( buffer, flags )) == -1)
- {
- if (errno == ENOENT) /* probably got killed */
- {
- process->unix_pid = -1;
- set_error( STATUS_ACCESS_DENIED );
- }
- else file_set_error();
- }
- return fd;
- }
- static int open_proc_lwpctl( struct thread *thread )
- {
- char buffer[48];
- int fd;
- if (thread->unix_pid == -1) return -1;
- sprintf( buffer, "/proc/%u/lwp/%u/lwpctl", thread->unix_pid, thread->unix_tid );
- if ((fd = open( buffer, O_WRONLY )) == -1)
- {
- if (errno == ENOENT) /* probably got killed */
- thread->unix_pid = thread->unix_tid = -1;
- else
- file_set_error();
- }
- return fd;
- }
- /* handle a SIGCHLD signal */
- void sigchld_callback(void)
- {
- assert( 0 ); /* should only be called when using ptrace */
- }
- /* initialize the process tracing mechanism */
- void init_tracing_mechanism(void)
- {
- /* no initialization needed */
- }
- /* initialize the per-process tracing mechanism */
- void init_process_tracing( struct process *process )
- {
- /* setup is done on-demand */
- }
- /* terminate the per-process tracing mechanism */
- void finish_process_tracing( struct process *process )
- {
- }
- /* send a Unix signal to a specific thread */
- int send_thread_signal( struct thread *thread, int sig )
- {
- int fd = open_proc_lwpctl( thread );
- long kill[2];
- ssize_t ret;
- if (fd == -1) return 0;
- kill[0] = PCKILL;
- kill[1] = sig;
- ret = write( fd, kill, sizeof(kill) );
- close( fd );
- return (ret == sizeof(kill));
- }
- /* read data from a process memory space */
- int read_process_memory( struct process *process, client_ptr_t ptr, size_t size, char *dest )
- {
- ssize_t ret;
- int fd;
- if ((off_t)ptr != ptr)
- {
- set_error( STATUS_ACCESS_DENIED );
- return 0;
- }
- if ((fd = open_proc_as( process, O_RDONLY )) == -1) return 0;
- ret = pread( fd, dest, size, (off_t)ptr );
- close( fd );
- if (ret == size) return 1;
- if (ret == -1) file_set_error();
- else set_error( STATUS_ACCESS_VIOLATION );
- return 0;
- }
- /* write data to a process memory space */
- int write_process_memory( struct process *process, client_ptr_t ptr, size_t size, const char *src )
- {
- ssize_t ret;
- int fd;
- if ((off_t)ptr != ptr)
- {
- set_error( STATUS_ACCESS_DENIED );
- return 0;
- }
- if ((fd = open_proc_as( process, O_WRONLY )) == -1) return 0;
- ret = pwrite( fd, src, size, (off_t)ptr );
- close( fd );
- if (ret == size) return 1;
- if (ret == -1) file_set_error();
- else set_error( STATUS_ACCESS_VIOLATION );
- return 0;
- }
- /* retrieve an LDT selector entry */
- void get_selector_entry( struct thread *thread, int entry, unsigned int *base,
- unsigned int *limit, unsigned char *flags )
- {
- ssize_t ret;
- off_t pos = thread->process->ldt_copy;
- int fd;
- if (!pos)
- {
- set_error( STATUS_ACCESS_DENIED );
- return;
- }
- if ((fd = open_proc_as( thread->process, O_RDONLY )) == -1) return;
- ret = pread( fd, base, sizeof(*base), pos + entry*sizeof(int) );
- if (ret != sizeof(*base)) goto error;
- ret = pread( fd, limit, sizeof(*limit), pos + (8192 + entry)*sizeof(int) );
- if (ret != sizeof(*limit)) goto error;
- ret = pread( fd, flags, sizeof(*flags), pos + 2*8192*sizeof(int) + entry );
- if (ret != sizeof(*flags)) goto error;
- close( fd );
- return;
- error:
- if (ret == -1) file_set_error();
- else set_error( STATUS_ACCESS_VIOLATION );
- close( fd );
- }
- /* initialize registers in new thread if necessary */
- void init_thread_context( struct thread *thread )
- {
- }
- /* retrieve the thread registers */
- void get_thread_context( struct thread *thread, context_t *context, unsigned int flags )
- {
- /* FIXME: get debug registers */
- }
- /* set the thread registers */
- void set_thread_context( struct thread *thread, const context_t *context, unsigned int flags )
- {
- /* FIXME: set debug registers */
- }
- #endif /* USE_PROCFS */
|