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