OSDN Git Service

2002-11-19 Michael Snyder <msnyder@redhat.com>
[pf3gnuchains/pf3gnuchains3x.git] / rda / unix / ptrace-target.c
1 /* ptrace-target.c
2
3    Copyright 2000, 2001, 2002 Red Hat, Inc.
4
5    This file is part of RDA, the Red Hat Debug Agent (and library).
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330,
20    Boston, MA 02111-1307, USA.
21    
22    Alternative licenses for RDA may be arranged by contacting Red Hat,
23    Inc.  */
24
25 #include "config.h"
26
27 #include <stdio.h>
28 #include <assert.h>
29 #include <stdlib.h>
30
31 #include "server.h"
32 #include "ptrace-target.h"
33
34 #include <sys/wait.h>
35 #include <string.h>
36 #include <errno.h>
37 #include <signal.h>
38 #include <unistd.h>
39
40 #include "gdbserv.h" 
41 #include "gdbserv-target.h" 
42 #include "gdbserv-utils.h"
43 #include "gdb_proc_service.h"
44 #include "gdbserv-thread-db.h"
45
46 /* This is unix ptrace gdbserv target that uses the RDA library to implement
47    a remote gdbserver on a unix ptrace host.  It controls the process
48    to be debugged on the linux host, allowing GDB to pull the strings
49    from any host on the network (or on a serial port).  */
50
51 /* Track sole connection to a remote gdb client. */
52 /* FIXME: needed? */
53 static struct gdbserv* ptrace_connect_lock = NULL;
54
55 /* Close all open file descriptors except for stdin, stdout, and
56    stderr.  */
57
58 static void
59 close_open_files (void)
60 {
61   long max_open_files = sysconf (_SC_OPEN_MAX);
62   int fd;
63
64   for (fd = 3; fd < max_open_files; fd++)
65     {
66       close (fd);
67     }
68 }
69
70 /* ptrace_create_child:
71
72    Fork the child process and capture it via ptrace.
73    
74    Args: char *exec_path;       \* path to executable file *\
75          char **all_args;       \* argv array for child.   *\
76 */
77
78 /* Local Functions: */
79
80 static int
81 ptrace_create_child (struct child_process *process)
82 {
83   int pid;
84
85   pid = fork ();
86   if (pid < 0)
87     {
88       /*perror_with_name ("fork");*/
89       fprintf (stderr, "PTRACE: fork failed!\n");
90       return 0;
91     }
92
93   if (pid == 0)
94     {
95       close_open_files ();
96       if (process->debug_backend)
97         fprintf (stderr, "PTRACE_TRACEME\n");
98       errno = 0;
99       ptrace (PTRACE_TRACEME, 0L, 0L, 0L);
100       if (errno != 0)
101         {
102           fprintf (stderr, "PTRACE: child cannot be traced!\n");
103           goto fail;
104         }
105       if (process->executable != NULL && process->argv != NULL)
106         execv (process->executable, process->argv);
107       else
108         sleep (-1);     /* FIXME ??? */
109
110       fprintf (stderr, "Cannot exec %s: %s.\n", process->executable,
111                errno > 0 && errno < sys_nerr ? 
112                strerror (errno) : "unknown error");
113     fail:
114       fflush (stderr);
115       _exit (0177);
116     }
117
118   return pid;
119 }
120
121 /* Decode the waitstatus returned by waitpid, and return the appropriate
122    stop status and stop_signal to gdb.  FIXME: this is not specific to 
123    ptrace, but there's no better place to put it (server.c?) */
124
125 extern int
126 handle_waitstatus (struct child_process *process, union wait w)
127 {
128   if (WIFEXITED (w))
129     {
130       if (process->debug_informational)
131         fprintf (stderr, "\nChild %d exited with retcode = %d\n", 
132                  process->pid, WEXITSTATUS (w));
133       process->stop_status = 'W';
134       return (process->stop_signal = WEXITSTATUS (w));
135     }
136   else if (!WIFSTOPPED (w))
137     {
138       if (process->debug_informational)
139         fprintf (stderr, "\nChild %d terminated with signal = %d\n", 
140                  process->pid, WTERMSIG (w));
141       process->stop_status = 'X';
142       return (process->stop_signal = WTERMSIG (w));
143     }
144
145 #if defined(_MIPSEL) || defined(_MIPSEB)
146   /*
147    * If we were single_stepping, restore the opcodes hoisted
148    * for the breakpoint[s].
149    */
150   if (process->is_ss)
151     {
152       ptrace (PTRACE_POKETEXT, process->pid, process->ss_info[0].ss_addr, process->ss_info[0].ss_val);
153       process->ss_info[0].ss_addr = 0;
154       
155       if (process->ss_info[1].ss_addr) {
156         ptrace (PTRACE_POKETEXT, process->pid, process->ss_info[1].ss_addr, process->ss_info[1].ss_val);
157         process->ss_info[1].ss_addr = 0;
158       }
159       process->is_ss = 0;
160     }
161 #endif /* _MIPSEL */
162
163   process->stop_status = 'T';
164   process->stop_signal = WSTOPSIG (w);
165   return process->stop_signal;
166 }
167
168 static void
169 ptrace_kill_program (struct child_process *process, int signum)
170 {
171   if (process->debug_backend)
172     fprintf (stderr, "KILL %d, %d\n", process->pid, signum);
173   kill (process->pid, signum);
174 }
175
176 /*
177  * Exported functions
178  */
179
180 /* Read user memory
181  *
182  * Returns 0 for success, errno for failure
183  */
184
185 extern int
186 ptrace_read_user (int pid, 
187                   ptrace_arg3_type addr, 
188                   int len, 
189                   void *buff)
190 {
191   int i;
192
193   /* Require: addr is on the proper boundary, and 
194      len is a proper multiple of PTRACE_XFER_SIZE.  
195      Caller's responsibility.  */
196
197   for (i = 0; i < len; i+= PTRACE_XFER_SIZE)
198     {
199       errno = 0;
200       *(ptrace_xfer_type *) &((char *)buff)[i] =
201         ptrace (PTRACE_PEEKUSER, pid, addr + i, 0);
202       if (errno != 0)
203         return errno;
204     }
205   return 0;
206 }
207
208 /* Write user memory
209  *
210  * Returns 0 for success, errno for failure
211  */
212
213 extern int
214 ptrace_write_user (int pid, 
215                    ptrace_arg3_type addr, 
216                    int len, 
217                    const void *buff)
218 {
219   int i;
220
221   /* Require: addr is on the proper boundary, and 
222      len is a proper multiple of PTRACE_XFER_SIZE.  
223      Caller's responsibility.  */
224
225   for (i = 0; i < len; i+= PTRACE_XFER_SIZE)
226     {
227 #ifdef X86_LINUX_TARGET
228       if (addr + i == 44)
229         continue;       /* Forbidden address/register, not writable. */
230 #endif
231       errno = 0;
232       ptrace (PTRACE_POKEUSER, pid, addr + i, 
233               * (ptrace_xfer_type *) &((char *)buff)[i]);
234 #if defined(_MIPSEL) || defined(MIPS_LINUX_TARGET)
235       /* mips linux kernel 2.4 has a bug where PTRACE_POKEUSER
236         returns -ESRCH even when it succeeds */
237       if (errno == ESRCH)
238         errno = 0;
239 #endif
240       if (errno != 0)
241         return errno;
242     }
243   return 0;
244 }
245
246 #if defined (PTRACE_GETREGS) || defined (PT_GETREGS)
247
248 /* get general regs */
249
250 int
251 ptrace_get_gregs (struct gdbserv *serv, int alt_pid, void *buff)
252 {
253   struct child_process *process = gdbserv_target_data (serv);
254   int pid = alt_pid == 0 ? process->pid : alt_pid;
255
256   /* Require: buff is of the appropriate size for the target arch. */
257
258   errno = 0;
259   ptrace (PTRACE_GETREGS, pid, 0, (ptrace_arg4_type) buff);
260   return errno;
261 }
262 #endif
263
264 #if defined (PTRACE_SETREGS) || defined (PT_SETREGS)
265 /* set general regs */
266
267 int
268 ptrace_set_gregs (struct gdbserv *serv, int alt_pid, const void *buff)
269 {
270   struct child_process *process = gdbserv_target_data (serv);
271   int pid = alt_pid == 0 ? process->pid : alt_pid;
272
273   /* Require: buff is of the appropriate size for the target arch. */
274
275   errno = 0;
276   ptrace (PTRACE_SETREGS, pid, 0, (ptrace_arg4_type) buff);
277   return errno;
278 }
279 #endif
280
281
282 /* get floating point regs */
283
284 extern int
285 ptrace_get_fpregs (struct gdbserv *serv, int alt_pid, void *buff)
286 {
287 #if defined (PTRACE_GETFPREGS) || defined (PT_GETFPREGS)
288   struct child_process *process = gdbserv_target_data (serv);
289   int pid = alt_pid == 0 ? process->pid : alt_pid;
290
291   /* Require: buff is of the appropriate size for the target arch. */
292
293   errno = 0;
294   ptrace (PTRACE_GETFPREGS, pid, 0, (ptrace_arg4_type) buff);
295   return errno;
296 #else
297   return -1;
298 #endif
299 }
300
301
302 /* set floating point regs */
303
304 extern int
305 ptrace_set_fpregs (struct gdbserv *serv, int alt_pid, const void *buff)
306 {
307 #if defined (PTRACE_SETFPREGS) || defined (PT_SETFPREGS)
308   struct child_process *process = gdbserv_target_data (serv);
309   int pid = alt_pid == 0 ? process->pid : alt_pid;
310
311   /* Require: buff is of the appropriate size for the target arch. */
312
313   errno = 0;
314   ptrace (PTRACE_SETFPREGS, pid, 0, (ptrace_arg4_type) buff);
315   return errno;
316 #else
317   return -1;
318 #endif
319 }
320
321
322 /* get extended floating point regs */
323
324 int
325 ptrace_get_fpxregs (struct gdbserv *serv, int alt_pid, void *buff)
326 {
327 #if defined (PTRACE_GETFPXREGS) || defined (PT_GETFPXREGS)
328   struct child_process *process = gdbserv_target_data (serv);
329   int pid = alt_pid == 0 ? process->pid : alt_pid;
330
331   /* Require: buff is of the appropriate size for the target arch. */
332
333   errno = 0;
334   ptrace (PTRACE_GETFPXREGS, pid, 0, (ptrace_arg4_type) buff);
335   return errno;
336 #else
337   return -1;
338 #endif
339 }
340
341
342 /* set extended floating point regs */
343
344 int
345 ptrace_set_fpxregs (struct gdbserv *serv, int alt_pid, const void *buff)
346 {
347 #if defined (PTRACE_SETFPXREGS) || defined (PT_SETFPXREGS)
348   struct child_process *process = gdbserv_target_data (serv);
349   int pid = alt_pid == 0 ? process->pid : alt_pid;
350
351   /* Require: buff is of the appropriate size for the target arch. */
352
353   errno = 0;
354   ptrace (PTRACE_SETFPXREGS, pid, 0, (ptrace_arg4_type) buff);
355   return errno;
356 #else
357   return -1;
358 #endif
359 }
360
361 /* target vector: */
362
363 static void
364 ptrace_flush_i_cache (struct gdbserv *serv)
365 {
366   /* Calls to ptrace() take care of this for us automatically when
367      needed.  I.e, nothing to do...  */
368   return;
369 }
370
371 /* sigkill vector
372  */
373
374 static void
375 ptrace_sigkill_program (struct gdbserv *serv)
376 {
377   struct child_process *process = gdbserv_target_data (serv);
378
379   ptrace_kill_program (process, SIGKILL);
380 }
381
382 /* exit program vector
383  */
384 static void
385 ptrace_exit_program (struct gdbserv *serv)
386 {
387   ptrace_sigkill_program (serv);
388   gdbserv_fromtarget_exit (serv, GDBSERV_SIGQUIT);
389 }
390
391 /* break program vector
392  */
393
394 static void
395 ptrace_break_program (struct gdbserv *serv)
396 {
397   struct child_process *process = gdbserv_target_data (serv);
398
399   if (process->debug_backend)
400     fprintf (stderr, " -- send SIGINT to child %d\n", process->pid);
401   kill (process->pid, SIGINT);
402 }
403
404 /* get_trap_number vector
405  */
406
407 static unsigned long
408 ptrace_get_trap_number (struct gdbserv *serv)
409 {
410   struct child_process *process = gdbserv_target_data (serv);
411
412   return process->stop_signal;
413 }
414
415 /* compute signal vector
416  * No translation necessary -- using unix native signals .
417  */
418
419 static unsigned long
420 ptrace_compute_signal (struct gdbserv *serv, unsigned long tgtsig)
421 {
422   if (tgtsig == 0)
423     return GDBSERV_SIGNONE;
424 #ifdef SIGHUP
425   if (tgtsig == SIGHUP)
426     return GDBSERV_SIGHUP;
427 #endif
428 #ifdef SIGINT
429   if (tgtsig == SIGINT)
430     return GDBSERV_SIGINT;
431 #endif
432 #ifdef SIGQUIT
433   if (tgtsig == SIGQUIT)
434     return GDBSERV_SIGQUIT;
435 #endif
436 #ifdef SIGILL
437   if (tgtsig == SIGILL)
438     return GDBSERV_SIGILL;
439 #endif
440 #ifdef SIGTRAP
441   if (tgtsig == SIGTRAP)
442     return GDBSERV_SIGTRAP;
443 #endif
444 #ifdef SIGABRT
445   if (tgtsig == SIGABRT)
446     return GDBSERV_SIGABRT;
447 #endif
448 #ifdef SIGIOT
449   if (tgtsig == SIGIOT)
450     return GDBSERV_SIGABRT;
451 #endif
452 #ifdef SIGEMT
453   if (tgtsig == SIGEMT)
454     return GDBSERV_SIGEMT;
455 #endif
456 #ifdef SIGFPE
457   if (tgtsig == SIGFPE)
458     return GDBSERV_SIGFPE;
459 #endif
460 #ifdef SIGKILL
461   if (tgtsig == SIGKILL)
462     return GDBSERV_SIGKILL;
463 #endif
464 #ifdef SIGBUS
465   if (tgtsig == SIGBUS)
466     return GDBSERV_SIGBUS;
467 #endif
468 #ifdef SIGSEGV
469   if (tgtsig == SIGSEGV)
470     return GDBSERV_SIGSEGV;
471 #endif
472 #ifdef SIGSYS
473   if (tgtsig == SIGSYS)
474     return GDBSERV_SIGSYS;
475 #endif
476 #ifdef SIGPIPE
477   if (tgtsig == SIGPIPE)
478     return GDBSERV_SIGPIPE;
479 #endif
480 #ifdef SIGALRM
481   if (tgtsig == SIGALRM)
482     return GDBSERV_SIGALRM;
483 #endif
484 #ifdef SIGTERM
485   if (tgtsig == SIGTERM)
486     return GDBSERV_SIGTERM;
487 #endif
488 #ifdef SIGURG
489   if (tgtsig == SIGURG)
490     return GDBSERV_SIGURG;
491 #endif
492 #ifdef SIGSTOP
493   if (tgtsig == SIGSTOP)
494     return GDBSERV_SIGSTOP;
495 #endif
496 #ifdef SIGTSTP
497   if (tgtsig == SIGTSTP)
498     return GDBSERV_SIGTSTP;
499 #endif
500 #ifdef SIGCONT
501   if (tgtsig == SIGCONT)
502     return GDBSERV_SIGCONT;
503 #endif
504 #ifdef SIGCHLD
505   if (tgtsig == SIGCHLD)
506     return GDBSERV_SIGCHLD;
507 #endif
508 #ifdef SIGCLD
509   if (tgtsig == SIGCLD)
510     return GDBSERV_SIGCHLD;
511 #endif
512 #ifdef SIGTTIN
513   if (tgtsig == SIGTTIN)
514     return GDBSERV_SIGTTIN;
515 #endif
516 #ifdef SIGTTOU
517   if (tgtsig == SIGTTOU)
518     return GDBSERV_SIGTTOU;
519 #endif
520 #ifdef SIGIO
521   if (tgtsig == SIGIO)
522     return GDBSERV_SIGIO;
523 #endif
524 #ifdef SIGXCPU
525   if (tgtsig == SIGXCPU)
526     return GDBSERV_SIGXCPU;
527 #endif
528 #ifdef SIGXFSZ
529   if (tgtsig == SIGXFSZ)
530     return GDBSERV_SIGXFSZ;
531 #endif
532 #ifdef SIGVTALRM
533   if (tgtsig == SIGVTALRM)
534     return GDBSERV_SIGVTALRM;
535 #endif
536 #ifdef SIGPROF
537   if (tgtsig == SIGPROF)
538     return GDBSERV_SIGPROF;
539 #endif
540 #ifdef SIGWINCH
541   if (tgtsig == SIGWINCH)
542     return GDBSERV_SIGWINCH;
543 #endif
544 #ifdef SIGLOST
545   if (tgtsig == SIGLOST)
546     return GDBSERV_SIGLOST;
547 #endif
548 #ifdef SIGUSR1
549   if (tgtsig == SIGUSR1)
550     return GDBSERV_SIGUSR1;
551 #endif
552 #ifdef SIGUSR2
553   if (tgtsig == SIGUSR2)
554     return GDBSERV_SIGUSR2;
555 #endif
556 #ifdef SIGPWR
557   if (tgtsig == SIGPWR)
558     return GDBSERV_SIGPWR;
559 #endif
560 #ifdef SIGPOLL
561   if (tgtsig == SIGPOLL)
562     return GDBSERV_SIGPOLL;
563 #endif
564 #ifdef SIGWIND
565   if (tgtsig == SIGWIND)
566     return GDBSERV_SIGWIND;
567 #endif
568 #ifdef SIGPHONE
569   if (tgtsig == SIGPHONE)
570     return GDBSERV_SIGPHONE;
571 #endif
572 #ifdef SIGWAITING
573   if (tgtsig == SIGWAITING)
574     return GDBSERV_SIGWAITING;
575 #endif
576 #ifdef SIGLWP
577   if (tgtsig == SIGLWP)
578     return GDBSERV_SIGLWP;
579 #endif
580 #ifdef SIGDANGER
581   if (tgtsig == SIGDANGER)
582     return GDBSERV_SIGDANGER;
583 #endif
584 #ifdef SIGGRANT
585   if (tgtsig == SIGGRANT)
586     return GDBSERV_SIGGRANT;
587 #endif
588 #ifdef SIGRETRACT
589   if (tgtsig == SIGRETRACT)
590     return GDBSERV_SIGRETRACT;
591 #endif
592 #ifdef SIGMSG
593   if (tgtsig == SIGMSG)
594     return GDBSERV_SIGMSG;
595 #endif
596 #ifdef SIGSOUND
597   if (tgtsig == SIGSOUND)
598     return GDBSERV_SIGSOUND;
599 #endif
600 #ifdef SIGSAC
601   if (tgtsig == SIGSAC)
602     return GDBSERV_SIGSAC;
603 #endif
604 #ifdef SIGPRIO
605   if (tgtsig == SIGPRIO)
606     return GDBSERV_SIGPRIO;
607 #endif
608 #ifdef SIGSTKFLT
609   if (tgtsig == SIGSTKFLT)
610     return GDBSERV_SIGSEGV;     /* ? */
611 #endif
612 #ifdef SIGPWR
613   if (tgtsig == SIGPWR)
614     return GDBSERV_SIGPWR;
615 #endif
616 #if defined (SIGRTMIN) && defined (SIGRTMAX)
617     if (tgtsig == SIGRTMIN)
618       return GDBSERV_SIGRT32;
619     if (tgtsig == SIGRTMIN + 32)
620       return GDBSERV_SIGRT64;
621     if (tgtsig > SIGRTMIN && tgtsig <  SIGRTMAX)
622       return GDBSERV_SIGRT33 + tgtsig - 1;
623     return GDBSERV_SIGNONE;     /* ? */
624 #endif
625 }
626
627 /* singlestep vector
628  */
629
630 static void
631 ptrace_singlestep_program (struct gdbserv *serv)
632 {
633   struct child_process *process = gdbserv_target_data (serv);
634
635   /* FIXME: handle signals! */
636   if (process->debug_backend)
637     fprintf (stderr, "PTRACE_SINGLESTEP %d signal %d\n", 
638              process->pid, process->signal_to_send);
639   process->stop_signal = 0;
640   process->stop_status = 0;
641
642   errno = 0;
643   ptrace (PTRACE_SINGLESTEP, process->pid, 1L, process->signal_to_send);
644   if (errno)
645     fprintf (stderr, "singlestep: ptrace error %s in %d\n",
646              strerror (errno), process->pid);
647   process->signal_to_send = 0;
648 }
649
650 /*
651  * Continue vector
652  */
653
654 static void 
655 ptrace_continue_program (struct gdbserv *serv)
656 {
657   struct child_process *process = gdbserv_target_data (serv);
658
659   /* FIXME: handle signals! */
660   if (process->debug_backend)
661     fprintf (stderr, "PTRACE_CONT %d signal %d\n", 
662              process->pid, process->signal_to_send);
663   process->stop_signal = 0;
664   process->stop_status = 0;
665
666   errno = 0;
667   ptrace (PTRACE_CONT, process->pid, 1L, process->signal_to_send);
668   if (errno)
669     fprintf (stderr, "continue: ptrace error %s in %d\n", 
670              strerror (errno), process->pid);
671   process->signal_to_send = 0;
672 }
673
674 /* Set continue-signal vector 
675  */
676
677 static int
678 ptrace_process_signal (struct gdbserv *serv, int sig)
679 {
680   struct child_process *process = gdbserv_target_data (serv);
681
682   /* Save the signal value for later use by continue/singlestep.  */
683   switch (sig) {
684   case GDBSERV_SIGNONE:
685     process->signal_to_send = 0;                break;
686 #ifdef SIGHUP
687   case GDBSERV_SIGHUP:
688     process->signal_to_send = SIGHUP;           break;
689 #endif
690 #ifdef SIGINT
691   case GDBSERV_SIGINT:
692     process->signal_to_send = SIGINT;           break;
693 #endif
694 #ifdef SIGQUIT
695   case GDBSERV_SIGQUIT:
696     process->signal_to_send = SIGQUIT;          break;
697 #endif
698 #ifdef SIGILL
699   case GDBSERV_SIGILL:
700     process->signal_to_send = SIGILL;           break;
701 #endif
702 #ifdef SIGTRAP
703   case GDBSERV_SIGTRAP:
704     process->signal_to_send = SIGTRAP;          break;
705 #endif
706 #ifdef SIGABRT
707   case GDBSERV_SIGABRT:
708     process->signal_to_send = SIGABRT;          break;
709 #endif
710 #ifdef SIGEMT
711   case GDBSERV_SIGEMT:
712     process->signal_to_send = SIGEMT;           break;
713 #endif
714 #ifdef SIGFPE
715   case GDBSERV_SIGFPE:
716     process->signal_to_send = SIGFPE;           break;
717 #endif
718 #ifdef SIGKILL
719   case GDBSERV_SIGKILL:
720     process->signal_to_send = SIGKILL;          break;
721 #endif
722 #ifdef SIGBUS
723   case GDBSERV_SIGBUS:
724     process->signal_to_send = SIGBUS;           break;
725 #endif
726 #ifdef SIGSEGV
727   case GDBSERV_SIGSEGV:
728     process->signal_to_send = SIGSEGV;          break;
729 #endif
730 #ifdef SIGSYS
731   case GDBSERV_SIGSYS:
732     process->signal_to_send = SIGSYS;           break;
733 #endif
734 #ifdef SIGPIPE
735   case GDBSERV_SIGPIPE:
736     process->signal_to_send = SIGPIPE;          break;
737 #endif
738 #ifdef SIGALRM
739   case GDBSERV_SIGALRM:
740     process->signal_to_send = SIGALRM;          break;
741 #endif
742 #ifdef SIGTERM
743   case GDBSERV_SIGTERM:
744     process->signal_to_send = SIGTERM;          break;
745 #endif
746 #ifdef SIGURG
747   case GDBSERV_SIGURG:
748     process->signal_to_send = SIGURG;           break;
749 #endif
750 #ifdef SIGSTOP
751   case GDBSERV_SIGSTOP:
752     process->signal_to_send = SIGSTOP;          break;
753 #endif
754 #ifdef SIGTSTP
755   case GDBSERV_SIGTSTP:
756     process->signal_to_send = SIGTSTP;          break;
757 #endif
758 #ifdef SIGCONT
759   case GDBSERV_SIGCONT:
760     process->signal_to_send = SIGCONT;          break;
761 #endif
762 #ifdef SIGCHLD
763   case GDBSERV_SIGCHLD:
764     process->signal_to_send = SIGCHLD;          break;
765 #endif
766 #if defined (SIGCLD) && !defined (SIGCHLD)
767   case GDBSERV_SIGCHLD:
768     process->signal_to_send = SIGCLD;           break;
769 #endif
770 #ifdef SIGTTIN
771   case GDBSERV_SIGTTIN:
772     process->signal_to_send = SIGTTIN;          break;
773 #endif
774 #ifdef SIGTTOU
775   case GDBSERV_SIGTTOU:
776     process->signal_to_send = SIGTTOU;          break;
777 #endif
778 #ifdef SIGIO
779   case GDBSERV_SIGIO:
780     process->signal_to_send = SIGIO;            break;
781 #endif
782 #ifdef SIGXCPU
783   case GDBSERV_SIGXCPU:
784     process->signal_to_send = SIGXCPU;          break;
785 #endif
786 #ifdef SIGXFSZ
787   case GDBSERV_SIGXFSZ:
788     process->signal_to_send = SIGXFSZ;          break;
789 #endif
790 #ifdef SIGVTALRM
791   case GDBSERV_SIGVTALRM:
792     process->signal_to_send = SIGVTALRM;        break;
793 #endif
794 #ifdef SIGPROF
795   case GDBSERV_SIGPROF:
796     process->signal_to_send = SIGPROF;          break;
797 #endif
798 #ifdef SIGWINCH
799   case GDBSERV_SIGWINCH:
800     process->signal_to_send = SIGWINCH;         break;
801 #endif
802 #ifdef SIGLOST
803   case GDBSERV_SIGLOST:
804     process->signal_to_send = SIGLOST;          break;
805 #endif
806 #ifdef SIGUSR1
807   case GDBSERV_SIGUSR1:
808     process->signal_to_send = SIGUSR1;          break;
809 #endif
810 #ifdef SIGUSR2
811   case GDBSERV_SIGUSR2:
812     process->signal_to_send = SIGUSR2;          break;
813 #endif
814 #ifdef SIGPWR
815   case GDBSERV_SIGPWR:
816     process->signal_to_send = SIGPWR;           break;
817 #endif
818 #ifdef SIGPOLL
819   case GDBSERV_SIGPOLL:
820     process->signal_to_send = SIGPOLL;          break;
821 #endif
822 #ifdef SIGWIND
823   case GDBSERV_SIGWIND:
824     process->signal_to_send = SIGWIND;          break;
825 #endif
826 #ifdef SIGPHONE
827   case GDBSERV_SIGPHONE:
828     process->signal_to_send = SIGPHONE;         break;
829 #endif
830 #ifdef SIGWAITING
831   case GDBSERV_SIGWAITING:
832     process->signal_to_send = SIGWAITING;       break;
833 #endif
834 #ifdef SIGLWP
835   case GDBSERV_SIGLWP:
836     process->signal_to_send = SIGLWP;           break;
837 #endif
838 #ifdef SIGDANGER
839   case GDBSERV_SIGDANGER:
840     process->signal_to_send = SIGDANGER;        break;
841 #endif
842 #ifdef SIGGRANT
843   case GDBSERV_SIGGRANT:
844     process->signal_to_send = SIGGRANT;         break;
845 #endif
846 #ifdef SIGRETRACT
847   case GDBSERV_SIGRETRACT:
848     process->signal_to_send = SIGRETRACT;       break;
849 #endif
850 #ifdef SIGMSG
851   case GDBSERV_SIGMSG:
852     process->signal_to_send = SIGMSG;           break;
853 #endif
854 #ifdef SIGSOUND
855   case GDBSERV_SIGSOUND:
856     process->signal_to_send = SIGSOUND;         break;
857 #endif
858 #ifdef SIGSAK
859   case GDBSERV_SIGSAK:
860     process->signal_to_send = SIGSAK;           break;
861 #endif
862 #ifdef SIGPRIO
863   case GDBSERV_SIGPRIO:
864     process->signal_to_send = SIGPRIO;          break;
865 #endif
866 #if defined (SIGRTMIN) && defined (SIGRTMAX)
867   case GDBSERV_SIGRT32:
868     process->signal_to_send = SIGRTMIN;         break;
869   case GDBSERV_SIGRT33:
870     process->signal_to_send = SIGRTMIN+1;       break;
871   case GDBSERV_SIGRT34:
872     process->signal_to_send = SIGRTMIN+2;       break;
873   case GDBSERV_SIGRT35:
874     process->signal_to_send = SIGRTMIN+3;       break;
875   case GDBSERV_SIGRT36:
876     process->signal_to_send = SIGRTMIN+4;       break;
877   case GDBSERV_SIGRT37:
878     process->signal_to_send = SIGRTMIN+5;       break;
879   case GDBSERV_SIGRT38:
880     process->signal_to_send = SIGRTMIN+6;       break;
881   case GDBSERV_SIGRT39:
882     process->signal_to_send = SIGRTMIN+7;       break;
883   case GDBSERV_SIGRT40:
884     process->signal_to_send = SIGRTMIN+8;       break;
885   case GDBSERV_SIGRT41:
886     process->signal_to_send = SIGRTMIN+9;       break;
887   case GDBSERV_SIGRT42:
888     process->signal_to_send = SIGRTMIN+10;      break;
889   case GDBSERV_SIGRT43:
890     process->signal_to_send = SIGRTMIN+11;      break;
891   case GDBSERV_SIGRT44:
892     process->signal_to_send = SIGRTMIN+12;      break;
893   case GDBSERV_SIGRT45:
894     process->signal_to_send = SIGRTMIN+13;      break;
895   case GDBSERV_SIGRT46:
896     process->signal_to_send = SIGRTMIN+14;      break;
897   case GDBSERV_SIGRT47:
898     process->signal_to_send = SIGRTMIN+15;      break;
899   case GDBSERV_SIGRT48:
900     process->signal_to_send = SIGRTMIN+16;      break;
901   case GDBSERV_SIGRT49:
902     process->signal_to_send = SIGRTMIN+17;      break;
903   case GDBSERV_SIGRT50:
904     process->signal_to_send = SIGRTMIN+18;      break;
905   case GDBSERV_SIGRT51:
906     process->signal_to_send = SIGRTMIN+19;      break;
907   case GDBSERV_SIGRT52:
908     process->signal_to_send = SIGRTMIN+20;      break;
909   case GDBSERV_SIGRT53:
910     process->signal_to_send = SIGRTMIN+21;      break;
911   case GDBSERV_SIGRT54:
912     process->signal_to_send = SIGRTMIN+22;      break;
913   case GDBSERV_SIGRT55:
914     process->signal_to_send = SIGRTMIN+23;      break;
915   case GDBSERV_SIGRT56:
916     process->signal_to_send = SIGRTMIN+24;      break;
917   case GDBSERV_SIGRT57:
918     process->signal_to_send = SIGRTMIN+25;      break;
919   case GDBSERV_SIGRT58:
920     process->signal_to_send = SIGRTMIN+26;      break;
921   case GDBSERV_SIGRT59:
922     process->signal_to_send = SIGRTMIN+27;      break;
923   case GDBSERV_SIGRT60:
924     process->signal_to_send = SIGRTMIN+28;      break;
925   case GDBSERV_SIGRT61:
926     process->signal_to_send = SIGRTMIN+29;      break;
927   case GDBSERV_SIGRT62:
928     process->signal_to_send = SIGRTMIN+30;      break;
929   case GDBSERV_SIGRT63:
930     process->signal_to_send = SIGRTMIN+31;      break;
931   case GDBSERV_SIGRT64:
932     process->signal_to_send = SIGRTMIN+32;      break;
933 #endif
934   }
935   /* Since we will handle the signal, we don't want gdbserv
936      to handle it by calling kill!  Return zero.  */
937   return 0;
938 }
939
940 /* Read memory vector
941  */
942
943 static long
944 ptrace_xfer_mem (struct gdbserv *serv, 
945                  struct gdbserv_reg *addr, 
946                  void *data, 
947                  long len, 
948                  int read)
949 {
950   struct child_process *process = gdbserv_target_data (serv);
951   ptrace_arg3_type request_base;
952   ptrace_arg3_type xfer_base;
953   ptrace_arg3_type temp_addr;
954   ptrace_xfer_type *buf;
955   long xfer_count;
956   int i;
957
958   /* Get request address.  */
959   gdbserv_reg_to_ulong (serv, addr, &request_base);
960   /* Round down to a PTRACE word boundary. */
961   xfer_base = request_base & - PTRACE_XFER_SIZE;
962   /* Round length up to a PTRACE word boundary. */
963   xfer_count = (((request_base + len) - xfer_base) + PTRACE_XFER_SIZE - 1)
964     / PTRACE_XFER_SIZE;
965   /* Allocate space for xfer.  */
966   buf = (ptrace_xfer_type *) alloca (xfer_count * PTRACE_XFER_SIZE);
967
968   /* Perform memory xfer.  */
969   if (read)
970     {
971       for (i = 0; i < xfer_count; i++)
972         {
973           temp_addr = xfer_base + i * PTRACE_XFER_SIZE;
974
975           errno = 0;
976           buf[i] = ptrace (PTRACE_PEEKTEXT, process->pid, temp_addr, 0L);
977
978           if (process->debug_backend)
979             fprintf (stderr, "PTRACE_PEEKTEXT-1 0x%08lx in %d, 0x%08lx\n", 
980                      (long) temp_addr, process->pid, (long) buf[i]);
981           if (errno)
982             {
983               if (errno != EIO)
984                 fprintf (stderr, 
985                          "xfer_mem(1): ptrace error at 0x%08lx in %d: %s\n", 
986                          (long) temp_addr, process->pid, strerror (errno));
987               return -1;
988             }
989         }
990   
991       /* Copy results to caller's buffer space.  */
992       memcpy (data, (char *) buf + (request_base - xfer_base), len);
993     }
994   else /* write */
995     {
996       /* If the xfer buffer overlaps the write-request buffer, 
997          we must first read the values that are there before 
998          replacing with the desired values (otherwise these bytes
999          would be uninitialized).  */
1000       if ((unsigned long long) xfer_base < 
1001           (unsigned long long) request_base)
1002         {
1003           errno = 0;
1004           buf[0] = ptrace (PTRACE_PEEKTEXT, 
1005                            process->pid, xfer_base, 0L);
1006           if (process->debug_backend)
1007             fprintf (stderr, "PTRACE_PEEKTEXT-2 0x%08lx in %d, 0x%08lx\n", 
1008                      (long) xfer_base, process->pid, (long) buf[0]);
1009
1010           if (errno)
1011             {
1012               if (errno != EIO)
1013                 fprintf (stderr, 
1014                          "xfer_mem(2): ptrace error at 0x%08lx in %d: %s\n", 
1015                          (long) xfer_base, process->pid, strerror (errno));
1016               return -1;
1017             }
1018         }
1019       if ((xfer_count > 0) &&
1020           ((unsigned long long) (xfer_base + xfer_count * PTRACE_XFER_SIZE) > 
1021            (unsigned long long) (request_base + len)))
1022         {
1023           temp_addr = xfer_base + (xfer_count - 1) * PTRACE_XFER_SIZE;
1024           errno = 0;
1025           buf[xfer_count - 1] =
1026             ptrace (PTRACE_PEEKTEXT, process->pid, temp_addr, 0L);
1027           if (process->debug_backend)
1028             fprintf (stderr, "PTRACE_PEEKTEXT-3 0x%08lx in %d, 0x%08lx\n", 
1029                      (long) temp_addr, process->pid, 
1030                      (long) buf[xfer_count - 1]);
1031
1032           if (errno)
1033             {
1034               if (errno != EIO)
1035                 fprintf (stderr, 
1036                          "xfer_mem(3): ptrace error at 0x%08lx in %d: %s\n", 
1037                          (long) temp_addr, process->pid, strerror (errno));
1038               return -1;
1039             }
1040         }
1041
1042       /* Now copy user buffer to xfer buffer.  */
1043       memcpy ((char *) buf + (request_base - xfer_base), data, len);
1044       /* Now write out the data.  */
1045       for (i = 0; i < xfer_count; i++)
1046         {
1047           temp_addr = xfer_base + i * PTRACE_XFER_SIZE;
1048
1049           errno = 0;
1050           ptrace (PTRACE_POKETEXT, process->pid, temp_addr, buf[i]);
1051
1052           if (process->debug_backend)
1053             fprintf (stderr, "PTRACE_POKETEXT 0x%08lx in %d, 0x%08lx\n", 
1054                      (long) temp_addr, process->pid, (long) buf[i]);
1055
1056           if (errno)
1057             {
1058               if (errno != EIO)
1059                 fprintf (stderr, 
1060                          "xfer_mem(4): ptrace error at 0x%08lx in %d: %s\n", 
1061                          (long) temp_addr, process->pid, strerror (errno));
1062               return -1;
1063             }
1064         }
1065     }
1066
1067   return len;
1068 }
1069
1070 static long
1071 ptrace_set_mem (struct gdbserv *serv, 
1072                 struct gdbserv_reg *addr, 
1073                 void *data, 
1074                 long len)
1075 {
1076   return ptrace_xfer_mem (serv, addr, data, len, 0);
1077 }
1078
1079 static long
1080 ptrace_get_mem (struct gdbserv *serv, 
1081                 struct gdbserv_reg *addr, 
1082                 void *data, 
1083                 long len)
1084 {
1085   return ptrace_xfer_mem (serv, addr, data, len, 1);
1086 }
1087
1088
1089
1090
1091 /* Detach vector -- shut down this target connection.
1092  */
1093
1094 static void
1095 ptrace_detach (struct gdbserv *serv, struct gdbserv_target *target)
1096 {
1097   struct child_process *process = gdbserv_target_data (serv);
1098
1099   assert (ptrace_connect_lock == serv);
1100
1101   if (process->debug_informational)
1102     fprintf (stderr, "ptrace - detached.\n");
1103   ptrace_connect_lock = NULL;
1104
1105   /* Quit out of main loop for this demo.  In general, this is not
1106      necessary, as the next incoming connection could again be handled
1107      by ptrace_attach() above.  */
1108   server_quit_p = 1;
1109 }
1110
1111 /* This function is called from gdbloop_poll when a new incoming
1112    connection is attempted.  It may return NULL if the new connection
1113    is to be refused, or a gdbserv_target vector if the connection is
1114    accepted.  */
1115
1116 struct gdbserv_target* 
1117 ptrace_attach (struct gdbserv *serv, void *data)
1118 {
1119   struct gdbserv_target *ptrace_target;
1120   struct child_process *process = data;
1121   union wait w;
1122   int pid;
1123
1124
1125   /* Enable server tracing. */
1126   /*  gdbserv_state_trace = stderr;*/
1127
1128   if (ptrace_connect_lock != NULL)
1129     {
1130       fprintf (stderr, "ptrace: rejected duplicate connection.\n");
1131       return NULL;
1132     }
1133
1134   if (process->debug_informational)
1135     fprintf (stderr, "ptrace: accepted gdb connection.\n");
1136   ptrace_connect_lock = serv;
1137
1138   process->pid = ptrace_create_child (process);
1139
1140   do {
1141     pid = wait (&w);
1142   } while (pid != process->pid);
1143
1144   handle_waitstatus (process, w);
1145
1146   if (process->pid > 0)
1147     {
1148       if (process->debug_informational)
1149         fprintf (stderr, "ptrace: created child process %d, %s\n", 
1150                  process->pid, process->executable);
1151     }
1152   else
1153     {
1154       fprintf (stderr, "PTRACE: failed to create child process %s!\n",
1155                process->executable);
1156       return NULL;
1157     }
1158
1159   ptrace_target = malloc (sizeof (struct gdbserv_target));
1160   memset (ptrace_target, 0, sizeof (*ptrace_target));
1161
1162   /* Callback structure for function pointers that handle processed
1163      control packets.  See gdbserv-target.h for docs on the individual
1164      functions. */
1165
1166   ptrace_target->process_get_gen       = NULL;
1167   ptrace_target->process_set_gen       = NULL;
1168   ptrace_target->process_rcmd          = NULL;
1169   ptrace_target->process_set_args      = NULL;
1170   ptrace_target->process_set_reg       = NULL;
1171   ptrace_target->process_get_reg       = NULL;
1172   ptrace_target->process_set_regs      = NULL;
1173   ptrace_target->process_get_regs      = NULL;
1174   ptrace_target->input_reg             = NULL;
1175   ptrace_target->output_reg            = NULL;
1176   ptrace_target->gg_reg_nr             = NULL;
1177   ptrace_target->expedited_reg_nr      = NULL;
1178   ptrace_target->sizeof_reg            = NULL;
1179   ptrace_target->set_reg               = NULL;
1180   ptrace_target->get_reg               = NULL;
1181   ptrace_target->get_mem               = ptrace_get_mem;
1182   ptrace_target->set_mem               = ptrace_set_mem;
1183   ptrace_target->process_set_pc        = NULL;
1184   ptrace_target->flush_i_cache         = ptrace_flush_i_cache;
1185   ptrace_target->process_signal        = ptrace_process_signal;
1186   ptrace_target->compute_signal        = ptrace_compute_signal;
1187   ptrace_target->get_trap_number       = ptrace_get_trap_number;
1188   ptrace_target->exit_program          = ptrace_exit_program;
1189   ptrace_target->break_program         = ptrace_break_program;
1190   ptrace_target->reset_program         = NULL;
1191   ptrace_target->restart_program       = NULL;
1192   ptrace_target->singlestep_program    = ptrace_singlestep_program;
1193   ptrace_target->cyclestep_program     = NULL;
1194   ptrace_target->sigkill_program       = ptrace_sigkill_program;
1195   ptrace_target->continue_program      = ptrace_continue_program;
1196   ptrace_target->remove_breakpoint     = NULL;
1197   ptrace_target->set_breakpoint        = NULL;
1198   ptrace_target->process_target_packet = NULL;
1199   ptrace_target->detach                = ptrace_detach;
1200
1201   ptrace_target->data = data;   /* Save ptr to child_process struct.  */
1202
1203 #if defined(_MIPSEL) || defined(_MIPSEB)
1204   process->is_ss = 0;
1205 #endif
1206
1207   return ptrace_target;
1208 }
1209
1210 /* This function is called from the main loop, and waits for an event
1211    (such as a signal or exception) from the running child process. */
1212
1213 int
1214 ptrace_check_child_state (struct child_process *process)
1215 {
1216   struct gdbserv *serv = process->serv;
1217   int ret;
1218   union wait w;
1219
1220   ret = waitpid (process->pid, (int *) &w, WNOHANG);
1221
1222   if (ret > 0)  /* found an event */
1223     {
1224       ret = handle_waitstatus (process, w);
1225       if (process->debug_backend)
1226         fprintf (stderr, "wait returned %d\n", ret);
1227       return 1;
1228     }
1229   return 0;
1230 }
1231
1232 /* Exported service functions */
1233
1234 /* Function: continue_lwp
1235    Send PTRACE_CONT to an lwp. 
1236    Returns -1 for failure, zero for success. */
1237
1238 extern int
1239 continue_lwp (lwpid_t lwpid, int signal)
1240 {
1241   if (thread_db_noisy)
1242     fprintf (stderr, "<ptrace (PTRACE_CONT, %d, 0, %d)>\n", lwpid, signal);
1243
1244   if (ptrace (PTRACE_CONT, lwpid, 0, signal) < 0)
1245     {
1246       fprintf (stderr, "<<< ERROR: PTRACE_CONT %d failed >>>\n", lwpid);
1247       return -1;
1248     }
1249   return 0;
1250 }
1251
1252 /* Function: singlestep_lwp
1253    Send PTRACE_SINGLESTEP to an lwp.
1254    Returns -1 for failure, zero for success. */
1255
1256 extern int
1257 singlestep_lwp (lwpid_t lwpid, int signal)
1258 {
1259   if (thread_db_noisy)
1260     fprintf (stderr, "<ptrace (PTRACE_SINGLESTEP, %d, 0, %d)>\n", lwpid, signal);
1261
1262   if (ptrace (PTRACE_SINGLESTEP, lwpid, 0, signal) < 0)
1263     {
1264       fprintf (stderr, "<<< ERROR: PTRACE_SINGLESTEP %d failed >>>\n", lwpid);
1265       return -1;
1266     }
1267   return 0;
1268 }
1269
1270 /* Function: attach_lwp
1271    Send PTRACE_ATTACH to an lwp.
1272    Returns -1 for failure, zero for success. */
1273
1274 extern int
1275 attach_lwp (lwpid_t lwpid)
1276 {
1277   errno = 0;
1278   if (ptrace (PTRACE_ATTACH, lwpid, 0, 0) == 0)
1279     {
1280       if (thread_db_noisy)
1281         fprintf (stderr, "<ptrace (PTRACE_ATTACH, %d, 0, 0)>\n", lwpid);
1282       return 0;
1283     }
1284   else
1285     {
1286       fprintf (stderr, "<<< ERROR ptrace attach %d failed, %s >>>\n",
1287                lwpid, strerror (errno));
1288       return -1;
1289     }
1290 }
1291
1292 /* Function: stop_lwp
1293    Use SIGSTOP to force an lwp to stop. 
1294    Returns -1 for failure, zero for success. */
1295
1296 extern int
1297 stop_lwp (lwpid_t lwpid)
1298 {
1299   if (kill (lwpid, SIGSTOP) == 0)
1300     {
1301 #if 0 /* Too noisy! */
1302       if (thread_db_noisy)
1303         fprintf (stderr, "<kill (%d, SIGSTOP)>\n", lwpid);
1304 #endif
1305       return 0;
1306     }
1307   else
1308     {
1309       fprintf (stderr, "<<< ERROR -- kill (%d, SIGSTOP) failed >>>\n", lwpid);
1310       return -1;
1311     }
1312 }
1313
1314 /* proc_service callback functions */
1315
1316 ps_err_e
1317 ps_pstop (gdb_ps_prochandle_t ph)               /* Process stop */
1318 {
1319   fprintf (stderr, "<ps_pstop [UN-IMPLEMENTED]>\n");
1320   return PS_ERR; /* unimplemented. */
1321 }
1322
1323 ps_err_e
1324 ps_pcontinue (gdb_ps_prochandle_t ph)           /* Process continue */
1325 {
1326   fprintf (stderr, "<ps_pcontinue [UN-IMPLEMENTED]>\n");
1327   return PS_ERR; /* unimplemented. */
1328 }
1329
1330 ps_err_e
1331 ps_lstop (gdb_ps_prochandle_t ph,               /* LWP stop */
1332           lwpid_t lwpid)
1333 {
1334   fprintf (stderr, "<ps_lstop [UN-IMPLEMENTED]>\n");
1335   return PS_ERR; /* unimplemented. */
1336 }
1337
1338 ps_err_e
1339 ps_lcontinue (gdb_ps_prochandle_t ph,           /* LWP continue */
1340               lwpid_t lwpid)
1341 {
1342   if (continue_lwp (lwpid, 0) < 0)
1343     return PS_OK;
1344   else
1345     return PS_ERR;
1346 }
1347
1348 ps_err_e
1349 ps_pdread (gdb_ps_prochandle_t ph,      /* read from data segment */
1350            paddr_t             addr,
1351            gdb_ps_read_buf_t   buf,
1352            gdb_ps_size_t       size)
1353 {
1354   long bytes_read;
1355   struct gdbserv_reg addr_reg;
1356
1357   /* Use unsigned long long for maximum portability. */
1358   gdbserv_ulonglong_to_reg (ph->serv, (unsigned long long) addr, &addr_reg);
1359
1360   bytes_read = ptrace_get_mem (ph->serv, &addr_reg, buf, (long) size);
1361
1362   if (bytes_read == (long) size)
1363     return PS_OK;
1364   else
1365     return PS_ERR;
1366 }
1367
1368 ps_err_e
1369 ps_pdwrite (gdb_ps_prochandle_t ph,     /* write to data segment */
1370             paddr_t             addr,
1371             gdb_ps_write_buf_t  buf,
1372             gdb_ps_size_t       size)
1373 {
1374   long bytes_written;
1375   struct gdbserv_reg addr_reg;
1376
1377   /* Use unsigned long long for maximum portability. */
1378   gdbserv_ulonglong_to_reg (ph->serv, (unsigned long long) addr, &addr_reg);
1379
1380   bytes_written = ptrace_set_mem (ph->serv, &addr_reg, buf, (long) size);
1381
1382   if (bytes_written == (long) size)
1383     return PS_OK;
1384   else
1385     return PS_ERR;
1386 }
1387
1388 ps_err_e
1389 ps_ptread (gdb_ps_prochandle_t ph,      /* read from text segment */
1390            paddr_t             addr,
1391            gdb_ps_read_buf_t   buf,
1392            gdb_ps_size_t       size)
1393 {
1394   long bytes_read;
1395   struct gdbserv_reg addr_reg;
1396
1397   /* Use unsigned long long for maximum portability. */
1398   gdbserv_ulonglong_to_reg (ph->serv, (unsigned long long) addr, &addr_reg);
1399
1400   bytes_read = ptrace_get_mem (ph->serv, &addr_reg, buf, (long) size);
1401
1402   if (bytes_read == (long) size)
1403     return PS_OK;
1404   else
1405     return PS_ERR;
1406 }
1407
1408 ps_err_e
1409 ps_ptwrite (gdb_ps_prochandle_t ph,     /* write to text segment */
1410             paddr_t             addr,
1411             gdb_ps_write_buf_t  buf,
1412             gdb_ps_size_t       size)
1413 {
1414   long bytes_written;
1415   struct gdbserv_reg addr_reg;
1416
1417   /* Use unsigned long long for maximum portability. */
1418   gdbserv_ulonglong_to_reg (ph->serv, (unsigned long long) addr, &addr_reg);
1419
1420   bytes_written = ptrace_set_mem (ph->serv, &addr_reg, buf, (long) size);
1421
1422   if (bytes_written == (long) size)
1423     return PS_OK;
1424   else
1425     return PS_ERR;
1426 }
1427