xref: /openbsd/gnu/usr.bin/binutils/gdb/inf-ptrace.c (revision 73471bf0)
1 /* Low-level child interface to ptrace.
2 
3    Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
4    1998, 1999, 2000, 2001, 2002, 2004, 2005
5    Free Software Foundation, Inc.
6 
7    This file is part of GDB.
8 
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 59 Temple Place - Suite 330,
22    Boston, MA 02111-1307, USA.  */
23 
24 #include "defs.h"
25 #include "command.h"
26 #include "inferior.h"
27 #include "inflow.h"
28 #include "gdbcore.h"
29 #include "observer.h"
30 #include "regcache.h"
31 
32 #include "gdb_assert.h"
33 #include "gdb_string.h"
34 #include "gdb_ptrace.h"
35 #include "gdb_wait.h"
36 #include <signal.h>
37 
38 #include "inf-child.h"
39 
40 /* HACK: Save the ptrace ops returned by inf_ptrace_target.  */
41 static struct target_ops *ptrace_ops_hack;
42 
43 
44 #ifdef PT_GET_PROCESS_STATE
45 
46 static int
47 inf_ptrace_follow_fork (int follow_child)
48 {
49   pid_t pid, fpid;
50   ptrace_state_t pe;
51 
52   /* FIXME: kettenis/20050720: This stuff should really be passed as
53      an argument by our caller.  */
54   {
55     ptid_t ptid;
56     struct target_waitstatus status;
57 
58     get_last_target_status (&ptid, &status);
59     gdb_assert (status.kind == TARGET_WAITKIND_FORKED);
60 
61     pid = ptid_get_pid (ptid);
62   }
63 
64   if (ptrace (PT_GET_PROCESS_STATE, pid,
65 	       (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1)
66     perror_with_name (("ptrace"));
67 
68   gdb_assert (pe.pe_report_event == PTRACE_FORK);
69   fpid = pe.pe_other_pid;
70 
71   if (follow_child)
72     {
73       inferior_ptid = pid_to_ptid (fpid);
74       detach_breakpoints (pid);
75 
76       /* Reset breakpoints in the child as appropriate.  */
77       follow_inferior_reset_breakpoints ();
78 
79       if (ptrace (PT_DETACH, pid, (PTRACE_TYPE_ARG3)1, 0) == -1)
80 	perror_with_name (("ptrace"));
81     }
82   else
83     {
84       inferior_ptid = pid_to_ptid (pid);
85       detach_breakpoints (fpid);
86 
87       if (ptrace (PT_DETACH, fpid, (PTRACE_TYPE_ARG3)1, 0) == -1)
88 	perror_with_name (("ptrace"));
89     }
90 
91   return 0;
92 }
93 
94 #endif /* PT_GET_PROCESS_STATE */
95 
96 
97 /* Prepare to be traced.  */
98 
99 static void
100 inf_ptrace_me (void)
101 {
102   /* "Trace me, Dr. Memory!"  */
103   ptrace (PT_TRACE_ME, 0, (PTRACE_TYPE_ARG3)0, 0);
104 }
105 
106 /* Start tracing PID.  */
107 
108 static void
109 inf_ptrace_him (int pid)
110 {
111   push_target (ptrace_ops_hack);
112 
113   /* On some targets, there must be some explicit synchronization
114      between the parent and child processes after the debugger
115      forks, and before the child execs the debuggee program.  This
116      call basically gives permission for the child to exec.  */
117 
118   target_acknowledge_created_inferior (pid);
119 
120   /* START_INFERIOR_TRAPS_EXPECTED is defined in inferior.h, and will
121      be 1 or 2 depending on whether we're starting without or with a
122      shell.  */
123   startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
124 
125   /* On some targets, there must be some explicit actions taken after
126      the inferior has been started up.  */
127   target_post_startup_inferior (pid_to_ptid (pid));
128 }
129 
130 /* Start a new inferior Unix child process.  EXEC_FILE is the file to
131    run, ALLARGS is a string containing the arguments to the program.
132    ENV is the environment vector to pass.  If FROM_TTY is non-zero, be
133    chatty about it.  */
134 
135 static void
136 inf_ptrace_create_inferior (char *exec_file, char *allargs, char **env,
137 			    int from_tty)
138 {
139   fork_inferior (exec_file, allargs, env, inf_ptrace_me, inf_ptrace_him,
140 		 NULL, NULL);
141 
142   /* We are at the first instruction we care about.  */
143   observer_notify_inferior_created (&current_target, from_tty);
144 
145   /* Pedal to the metal...  */
146   proceed (read_pc (), TARGET_SIGNAL_0, 0);
147 }
148 
149 #ifdef PT_GET_PROCESS_STATE
150 
151 static void
152 inf_ptrace_post_startup_inferior (ptid_t pid)
153 {
154   ptrace_event_t pe;
155 
156   /* Set the initial event mask.  */
157   memset (&pe, 0, sizeof pe);
158   pe.pe_set_event |= PTRACE_FORK;
159   if (ptrace (PT_SET_EVENT_MASK, ptid_get_pid (pid),
160 	      (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1)
161     perror_with_name (("ptrace"));
162 }
163 
164 #endif
165 
166 /* Clean up a rotting corpse of an inferior after it died.  */
167 
168 static void
169 inf_ptrace_mourn_inferior (void)
170 {
171   int status;
172 
173   /* Wait just one more time to collect the inferior's exit status.
174      Don not check whether this succeeds though, since we may be
175      dealing with a process that we attached to.  Such a process will
176      only report its exit status to its origional parent.  */
177   waitpid (ptid_get_pid (inferior_ptid), &status, 0);
178 
179   unpush_target (ptrace_ops_hack);
180   generic_mourn_inferior ();
181 }
182 
183 /* Attach to the process specified by ARGS.  If FROM_TTY is non-zero,
184    be chatty about it.  */
185 
186 static void
187 inf_ptrace_attach (char *args, int from_tty)
188 {
189   char *exec_file;
190   pid_t pid;
191   char *dummy;
192 
193   if (!args)
194     error_no_arg (_("process-id to attach"));
195 
196   dummy = args;
197   pid = strtol (args, &dummy, 0);
198   /* Some targets don't set errno on errors, grrr!  */
199   if (pid == 0 && args == dummy)
200     error (_("Illegal process-id: %s."), args);
201 
202   if (pid == getpid ())		/* Trying to masturbate?  */
203     error (_("I refuse to debug myself!"));
204 
205   if (from_tty)
206     {
207       exec_file = get_exec_file (0);
208 
209       if (exec_file)
210 	printf_unfiltered (_("Attaching to program: %s, %s\n"), exec_file,
211 			   target_pid_to_str (pid_to_ptid (pid)));
212       else
213 	printf_unfiltered (_("Attaching to %s\n"),
214 			   target_pid_to_str (pid_to_ptid (pid)));
215 
216       gdb_flush (gdb_stdout);
217     }
218 
219 #ifdef PT_ATTACH
220   errno = 0;
221   ptrace (PT_ATTACH, pid, (PTRACE_TYPE_ARG3)0, 0);
222   if (errno != 0)
223     perror_with_name (("ptrace"));
224   attach_flag = 1;
225 #else
226   error (_("This system does not support attaching to a process"));
227 #endif
228 
229   inferior_ptid = pid_to_ptid (pid);
230   push_target (ptrace_ops_hack);
231 
232   /* Do this first, before anything has had a chance to query the
233      inferior's symbol table or similar.  */
234   observer_notify_inferior_created (&current_target, from_tty);
235 }
236 
237 #ifdef PT_GET_PROCESS_STATE
238 
239 void
240 inf_ptrace_post_attach (int pid)
241 {
242   ptrace_event_t pe;
243 
244   /* Set the initial event mask.  */
245   memset (&pe, 0, sizeof pe);
246   pe.pe_set_event |= PTRACE_FORK;
247   if (ptrace (PT_SET_EVENT_MASK, pid,
248 	      (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1)
249     perror_with_name (("ptrace"));
250 }
251 
252 #endif
253 
254 /* Detach from the inferior, optionally passing it the signal
255    specified ARGS.  If FROM_TTY is non-zero, be chatty about it.  */
256 
257 static void
258 inf_ptrace_detach (char *args, int from_tty)
259 {
260   pid_t pid = ptid_get_pid (inferior_ptid);
261   int sig = 0;
262 
263   if (from_tty)
264     {
265       char *exec_file = get_exec_file (0);
266       if (exec_file == 0)
267 	exec_file = "";
268       printf_unfiltered (_("Detaching from program: %s, %s\n"), exec_file,
269 			 target_pid_to_str (pid_to_ptid (pid)));
270       gdb_flush (gdb_stdout);
271     }
272   if (args)
273     sig = atoi (args);
274 
275 #ifdef PT_DETACH
276   /* We'd better not have left any breakpoints in the program or it'll
277      die when it hits one.  Alsno note that this may only work if we
278      previously attached to the inferior.  It *might* work if we
279      started the process ourselves.  */
280   errno = 0;
281   ptrace (PT_DETACH, pid, (PTRACE_TYPE_ARG3)1, sig);
282   if (errno != 0)
283     perror_with_name (("ptrace"));
284   attach_flag = 0;
285 #else
286   error (_("This system does not support detaching from a process"));
287 #endif
288 
289   inferior_ptid = null_ptid;
290   unpush_target (ptrace_ops_hack);
291 }
292 
293 /* Kill the inferior.  */
294 
295 static void
296 inf_ptrace_kill (void)
297 {
298   pid_t pid = ptid_get_pid (inferior_ptid);
299   int status;
300 
301   if (pid == 0)
302     return;
303 
304   ptrace (PT_KILL, pid, (PTRACE_TYPE_ARG3)0, 0);
305   waitpid (pid, &status, 0);
306 
307   target_mourn_inferior ();
308 }
309 
310 /* Stop the inferior.  */
311 
312 static void
313 inf_ptrace_stop (void)
314 {
315   /* Send a SIGINT to the process group.  This acts just like the user
316      typed a ^C on the controlling terminal.  Note that using a
317      negative process number in kill() is a System V-ism.  The proper
318      BSD interface is killpg().  However, all modern BSDs support the
319      System V interface too.  */
320   kill (-inferior_process_group, SIGINT);
321 }
322 
323 /* Resume execution of thread PTID, or all threads if PTID is -1.  If
324    STEP is nonzero, single-step it.  If SIGNAL is nonzero, give it
325    that signal.  */
326 
327 static void
328 inf_ptrace_resume (ptid_t ptid, int step, enum target_signal signal)
329 {
330   pid_t pid = ptid_get_pid (ptid);
331   int request = PT_CONTINUE;
332 
333   if (pid == -1)
334     /* Resume all threads.  Traditionally ptrace() only supports
335        single-threaded processes, so simply resume the inferior.  */
336     pid = ptid_get_pid (inferior_ptid);
337 
338   if (step)
339     {
340       /* If this system does not support PT_STEP, a higher level
341          function will have called single_step() to transmute the step
342          request into a continue request (by setting breakpoints on
343          all possible successor instructions), so we don't have to
344          worry about that here.  */
345       request = PT_STEP;
346     }
347 
348   /* An address of (PTRACE_TYPE_ARG3)1 tells ptrace to continue from
349      where it was.  If GDB wanted it to start some other way, we have
350      already written a new program counter value to the child.  */
351   errno = 0;
352   ptrace (request, pid, (PTRACE_TYPE_ARG3)1, target_signal_to_host (signal));
353   if (errno != 0)
354     perror_with_name (("ptrace"));
355 }
356 
357 /* Wait for the child specified by PTID to do something.  Return the
358    process ID of the child, or MINUS_ONE_PTID in case of error; store
359    the status in *OURSTATUS.  */
360 
361 static ptid_t
362 inf_ptrace_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
363 {
364   pid_t pid;
365   int status, save_errno;
366 
367   do
368     {
369       set_sigint_trap ();
370       set_sigio_trap ();
371 
372       do
373 	{
374 	  pid = waitpid (ptid_get_pid (ptid), &status, 0);
375 	  save_errno = errno;
376 	}
377       while (pid == -1 && errno == EINTR);
378 
379       clear_sigio_trap ();
380       clear_sigint_trap ();
381 
382       if (pid == -1)
383 	{
384 	  fprintf_unfiltered (gdb_stderr,
385 			      _("Child process unexpectedly missing: %s.\n"),
386 			      safe_strerror (save_errno));
387 
388 	  /* Claim it exited with unknown signal.  */
389 	  ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
390 	  ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
391 	  return minus_one_ptid;
392 	}
393 
394       /* Ignore terminated detached child processes.  */
395       if (!WIFSTOPPED (status) && pid != ptid_get_pid (inferior_ptid))
396 	pid = -1;
397     }
398   while (pid == -1);
399 
400 #ifdef PT_GET_PROCESS_STATE
401   if (WIFSTOPPED (status))
402     {
403       ptrace_state_t pe;
404       pid_t fpid;
405 
406       if (ptrace (PT_GET_PROCESS_STATE, pid,
407 		  (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1)
408 	perror_with_name (("ptrace"));
409 
410       switch (pe.pe_report_event)
411 	{
412 	case PTRACE_FORK:
413 	  ourstatus->kind = TARGET_WAITKIND_FORKED;
414 	  ourstatus->value.related_pid = pe.pe_other_pid;
415 
416 	  /* Make sure the other end of the fork is stopped too.  */
417 	  fpid = waitpid (pe.pe_other_pid, &status, 0);
418 	  if (fpid == -1)
419 	    perror_with_name (("waitpid"));
420 
421 	  if (ptrace (PT_GET_PROCESS_STATE, fpid,
422 		      (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1)
423 	    perror_with_name (("ptrace"));
424 
425 	  gdb_assert (pe.pe_report_event == PTRACE_FORK);
426 	  gdb_assert (pe.pe_other_pid == pid);
427 	  if (fpid == ptid_get_pid (inferior_ptid))
428 	    {
429 	      ourstatus->value.related_pid = pe.pe_other_pid;
430 	      return pid_to_ptid (fpid);
431 	    }
432 
433 	  return pid_to_ptid (pid);
434 	}
435     }
436 #endif
437 
438   store_waitstatus (ourstatus, status);
439   return pid_to_ptid (pid);
440 }
441 
442 /* Attempt a transfer all LEN bytes starting at OFFSET between the
443    inferior's OBJECT:ANNEX space and GDB's READBUF/WRITEBUF buffer.
444    Return the number of bytes actually transferred.  */
445 
446 static LONGEST
447 inf_ptrace_xfer_partial (struct target_ops *ops, enum target_object object,
448 			 const char *annex, void *readbuf,
449 			 const void *writebuf,
450 			 ULONGEST offset, LONGEST len)
451 {
452   pid_t pid = ptid_get_pid (inferior_ptid);
453 
454   switch (object)
455     {
456     case TARGET_OBJECT_MEMORY:
457 #ifdef PT_IO
458       /* OpenBSD 3.1, NetBSD 1.6 and FreeBSD 5.0 have a new PT_IO
459 	 request that promises to be much more efficient in reading
460 	 and writing data in the traced process's address space.  */
461       {
462 	struct ptrace_io_desc piod;
463 
464 	/* NOTE: We assume that there are no distinct address spaces
465 	   for instruction and data.  */
466 	piod.piod_op = writebuf ? PIOD_WRITE_I : PIOD_READ_D;
467 	piod.piod_addr = writebuf ? (void *) writebuf : readbuf;
468 	piod.piod_offs = (void *) (long) offset;
469 	piod.piod_len = len;
470 
471 	errno = 0;
472 	if (ptrace (PT_IO, pid, (caddr_t)&piod, 0) == 0)
473 	  /* Return the actual number of bytes read or written.  */
474 	  return piod.piod_len;
475 	/* If the PT_IO request is somehow not supported, fallback on
476 	   using PT_WRITE_D/PT_READ_D.  Otherwise we will return zero
477 	   to indicate failure.  */
478 	if (errno != EINVAL)
479 	  return 0;
480       }
481 #endif
482       {
483 	union
484 	{
485 	  PTRACE_TYPE_RET word;
486 	  char byte[sizeof (PTRACE_TYPE_RET)];
487 	} buffer;
488 	ULONGEST rounded_offset;
489 	LONGEST partial_len;
490 
491 	/* Round the start offset down to the next long word
492 	   boundary.  */
493 	rounded_offset = offset & -(ULONGEST) sizeof (PTRACE_TYPE_RET);
494 
495 	/* Since ptrace will transfer a single word starting at that
496 	   rounded_offset the partial_len needs to be adjusted down to
497 	   that (remember this function only does a single transfer).
498 	   Should the required length be even less, adjust it down
499 	   again.  */
500 	partial_len = (rounded_offset + sizeof (PTRACE_TYPE_RET)) - offset;
501 	if (partial_len > len)
502 	  partial_len = len;
503 
504 	if (writebuf)
505 	  {
506 	    /* If OFFSET:PARTIAL_LEN is smaller than
507 	       ROUNDED_OFFSET:WORDSIZE then a read/modify write will
508 	       be needed.  Read in the entire word.  */
509 	    if (rounded_offset < offset
510 		|| (offset + partial_len
511 		    < rounded_offset + sizeof (PTRACE_TYPE_RET)))
512 	      /* Need part of initial word -- fetch it.  */
513 	      buffer.word = ptrace (PT_READ_I, pid,
514 				    (PTRACE_TYPE_ARG3)(long)rounded_offset, 0);
515 
516 	    /* Copy data to be written over corresponding part of
517 	       buffer.  */
518 	    memcpy (buffer.byte + (offset - rounded_offset),
519 		    writebuf, partial_len);
520 
521 	    errno = 0;
522 	    ptrace (PT_WRITE_D, pid,
523 		    (PTRACE_TYPE_ARG3)(long)rounded_offset, buffer.word);
524 	    if (errno)
525 	      {
526 		/* Using the appropriate one (I or D) is necessary for
527 		   Gould NP1, at least.  */
528 		errno = 0;
529 		ptrace (PT_WRITE_I, pid,
530 			(PTRACE_TYPE_ARG3)(long)rounded_offset, buffer.word);
531 		if (errno)
532 		  return 0;
533 	      }
534 	  }
535 
536 	if (readbuf)
537 	  {
538 	    errno = 0;
539 	    buffer.word = ptrace (PT_READ_I, pid,
540 				  (PTRACE_TYPE_ARG3)(long)rounded_offset, 0);
541 	    if (errno)
542 	      return 0;
543 	    /* Copy appropriate bytes out of the buffer.  */
544 	    memcpy (readbuf, buffer.byte + (offset - rounded_offset),
545 		    partial_len);
546 	  }
547 
548 	return partial_len;
549       }
550 
551     case TARGET_OBJECT_UNWIND_TABLE:
552       return -1;
553 
554     case TARGET_OBJECT_AUXV:
555 #if defined (PT_IO) && defined (PIOD_READ_AUXV)
556       {
557 	struct ptrace_io_desc piod;
558 
559 	if (writebuf)
560 		return -1;
561 	piod.piod_op = PIOD_READ_AUXV;
562 	piod.piod_addr = readbuf;
563 	piod.piod_offs = (void *) (long) offset;
564 	piod.piod_len = len;
565 
566 	errno = 0;
567 	if (ptrace (PT_IO, pid, (caddr_t)&piod, 0) == 0)
568 	  /* Return the actual number of bytes read or written.  */
569 	  return piod.piod_len;
570       }
571 #endif
572       return -1;
573 
574     case TARGET_OBJECT_WCOOKIE:
575       return -1;
576 
577     default:
578       return -1;
579     }
580 }
581 
582 /* Return non-zero if the thread specified by PTID is alive.  */
583 
584 static int
585 inf_ptrace_thread_alive (ptid_t ptid)
586 {
587   /* ??? Is kill the right way to do this?  */
588   return (kill (ptid_get_pid (ptid), 0) != -1);
589 }
590 
591 /* Print status information about what we're accessing.  */
592 
593 static void
594 inf_ptrace_files_info (struct target_ops *ignore)
595 {
596   printf_filtered (_("\tUsing the running image of %s %s.\n"),
597 		   attach_flag ? "attached" : "child",
598 		   target_pid_to_str (inferior_ptid));
599 }
600 
601 /* Create a prototype ptrace target.  The client can override it with
602    local methods.  */
603 
604 struct target_ops *
605 inf_ptrace_target (void)
606 {
607   struct target_ops *t = inf_child_target ();
608 
609   t->to_attach = inf_ptrace_attach;
610   t->to_detach = inf_ptrace_detach;
611   t->to_resume = inf_ptrace_resume;
612   t->to_wait = inf_ptrace_wait;
613   t->to_files_info = inf_ptrace_files_info;
614   t->to_kill = inf_ptrace_kill;
615   t->to_create_inferior = inf_ptrace_create_inferior;
616 #ifdef PT_GET_PROCESS_STATE
617   t->to_follow_fork = inf_ptrace_follow_fork;
618   t->to_post_startup_inferior = inf_ptrace_post_startup_inferior;
619   t->to_post_attach = inf_ptrace_post_attach;
620 #endif
621   t->to_mourn_inferior = inf_ptrace_mourn_inferior;
622   t->to_thread_alive = inf_ptrace_thread_alive;
623   t->to_pid_to_str = normal_pid_to_str;
624   t->to_stop = inf_ptrace_stop;
625   t->to_xfer_partial = inf_ptrace_xfer_partial;
626 
627   ptrace_ops_hack = t;
628   return t;
629 }
630 
631 
632 /* Pointer to a function that returns the offset within the user area
633    where a particular register is stored.  */
634 static CORE_ADDR (*inf_ptrace_register_u_offset)(int);
635 
636 /* Fetch register REGNUM from the inferior.  */
637 
638 static void
639 inf_ptrace_fetch_register (int regnum)
640 {
641   CORE_ADDR addr;
642   size_t size;
643   PTRACE_TYPE_RET *buf;
644   int pid, i;
645 
646   /* Cater for systems like GNU/Linux, that implement threads as
647      seperate processes.  */
648   pid = ptid_get_lwp (inferior_ptid);
649   if (pid == 0)
650     pid = ptid_get_pid (inferior_ptid);
651 
652   /* This isn't really an address, but ptrace thinks of it as one.  */
653   addr = inf_ptrace_register_u_offset (regnum);
654   size = register_size (current_gdbarch, regnum);
655 
656   gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0);
657   buf = alloca (size);
658 
659   /* Read the register contents from the inferior a chuck at the time.  */
660   for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
661     {
662       errno = 0;
663       buf[i] = ptrace (PT_READ_U, pid, (PTRACE_TYPE_ARG3)addr, 0);
664       if (errno != 0)
665 	error (_("Couldn't read register %s (#%d): %s."),
666 	       REGISTER_NAME (regnum), regnum, safe_strerror (errno));
667 
668       addr += sizeof (PTRACE_TYPE_RET);
669     }
670   regcache_raw_supply (current_regcache, regnum, buf);
671 }
672 
673 /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
674    for all registers.  */
675 
676 static void
677 inf_ptrace_fetch_registers (int regnum)
678 {
679   if (regnum == -1)
680     for (regnum = 0; regnum < NUM_REGS; regnum++)
681       inf_ptrace_fetch_register (regnum);
682   else
683     inf_ptrace_fetch_register (regnum);
684 }
685 
686 /* Store register REGNUM into the inferior.  */
687 
688 static void
689 inf_ptrace_store_register (int regnum)
690 {
691   CORE_ADDR addr;
692   size_t size;
693   PTRACE_TYPE_RET *buf;
694   int pid, i;
695 
696   /* Cater for systems like GNU/Linux, that implement threads as
697      seperate processes.  */
698   pid = ptid_get_lwp (inferior_ptid);
699   if (pid == 0)
700     pid = ptid_get_pid (inferior_ptid);
701 
702   /* This isn't really an address, but ptrace thinks of it as one.  */
703   addr = inf_ptrace_register_u_offset (regnum);
704   size = register_size (current_gdbarch, regnum);
705 
706   gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0);
707   buf = alloca (size);
708 
709   /* Write the register contents into the inferior a chunk at the time.  */
710   regcache_raw_collect (current_regcache, regnum, buf);
711   for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
712     {
713       errno = 0;
714       ptrace (PT_WRITE_U, pid, (PTRACE_TYPE_ARG3)addr, buf[i]);
715       if (errno != 0)
716 	error (_("Couldn't write register %s (#%d): %s."),
717 	       REGISTER_NAME (regnum), regnum, safe_strerror (errno));
718 
719       addr += sizeof (PTRACE_TYPE_RET);
720     }
721 }
722 
723 /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
724    this for all registers.  */
725 
726 void
727 inf_ptrace_store_registers (int regnum)
728 {
729   if (regnum == -1)
730     for (regnum = 0; regnum < NUM_REGS; regnum++)
731       inf_ptrace_store_register (regnum);
732   else
733     inf_ptrace_store_register (regnum);
734 }
735 
736 /* Create a "traditional" ptrace target.  REGISTER_U_OFFSET should be
737    a function returning the offset within the user area where a
738    particular register is stored.  */
739 
740 struct target_ops *
741 inf_ptrace_trad_target (CORE_ADDR (*register_u_offset)(int))
742 {
743   struct target_ops *t = inf_ptrace_target();
744 
745   gdb_assert (register_u_offset);
746   inf_ptrace_register_u_offset = register_u_offset;
747   t->to_fetch_registers = inf_ptrace_fetch_registers;
748   t->to_store_registers = inf_ptrace_store_registers;
749 
750   return t;
751 }
752