1 /* Low-level child interface to ptrace.
3 Copyright (C) 1988-2015 Free Software Foundation, Inc.
5 This file is part of GDB.
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 3 of the License, or
10 (at your option) any later version.
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.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
27 #include "gdb_ptrace.h"
31 #include "inf-ptrace.h"
32 #include "inf-child.h"
33 #include "gdbthread.h"
37 #ifdef PT_GET_PROCESS_STATE
39 /* Target hook for follow_fork. On entry and at return inferior_ptid is
40 the ptid of the followed inferior. */
43 inf_ptrace_follow_fork (struct target_ops
*ops
, int follow_child
,
48 struct thread_info
*tp
= inferior_thread ();
49 pid_t child_pid
= ptid_get_pid (tp
->pending_follow
.value
.related_pid
);
51 /* Breakpoints have already been detached from the child by
54 if (ptrace (PT_DETACH
, child_pid
, (PTRACE_TYPE_ARG3
)1, 0) == -1)
55 perror_with_name (("ptrace"));
61 #endif /* PT_GET_PROCESS_STATE */
64 /* Prepare to be traced. */
69 /* "Trace me, Dr. Memory!" */
70 ptrace (PT_TRACE_ME
, 0, (PTRACE_TYPE_ARG3
)0, 0);
73 /* Start a new inferior Unix child process. EXEC_FILE is the file to
74 run, ALLARGS is a string containing the arguments to the program.
75 ENV is the environment vector to pass. If FROM_TTY is non-zero, be
79 inf_ptrace_create_inferior (struct target_ops
*ops
,
80 char *exec_file
, char *allargs
, char **env
,
85 /* Do not change either targets above or the same target if already present.
86 The reason is the target stack is shared across multiple inferiors. */
87 int ops_already_pushed
= target_is_pushed (ops
);
88 struct cleanup
*back_to
= make_cleanup (null_cleanup
, NULL
);
90 if (! ops_already_pushed
)
92 /* Clear possible core file with its process_stratum. */
94 make_cleanup_unpush_target (ops
);
97 pid
= fork_inferior (exec_file
, allargs
, env
, inf_ptrace_me
, NULL
,
100 discard_cleanups (back_to
);
102 startup_inferior (START_INFERIOR_TRAPS_EXPECTED
);
104 /* On some targets, there must be some explicit actions taken after
105 the inferior has been started up. */
106 target_post_startup_inferior (pid_to_ptid (pid
));
109 #ifdef PT_GET_PROCESS_STATE
112 inf_ptrace_post_startup_inferior (struct target_ops
*self
, ptid_t pid
)
116 /* Set the initial event mask. */
117 memset (&pe
, 0, sizeof pe
);
118 pe
.pe_set_event
|= PTRACE_FORK
;
119 if (ptrace (PT_SET_EVENT_MASK
, ptid_get_pid (pid
),
120 (PTRACE_TYPE_ARG3
)&pe
, sizeof pe
) == -1)
121 perror_with_name (("ptrace"));
126 /* Clean up a rotting corpse of an inferior after it died. */
129 inf_ptrace_mourn_inferior (struct target_ops
*ops
)
133 /* Wait just one more time to collect the inferior's exit status.
134 Do not check whether this succeeds though, since we may be
135 dealing with a process that we attached to. Such a process will
136 only report its exit status to its original parent. */
137 waitpid (ptid_get_pid (inferior_ptid
), &status
, 0);
139 inf_child_mourn_inferior (ops
);
142 /* Attach to the process specified by ARGS. If FROM_TTY is non-zero,
143 be chatty about it. */
146 inf_ptrace_attach (struct target_ops
*ops
, const char *args
, int from_tty
)
150 struct inferior
*inf
;
152 /* Do not change either targets above or the same target if already present.
153 The reason is the target stack is shared across multiple inferiors. */
154 int ops_already_pushed
= target_is_pushed (ops
);
155 struct cleanup
*back_to
= make_cleanup (null_cleanup
, NULL
);
157 pid
= parse_pid_to_attach (args
);
159 if (pid
== getpid ()) /* Trying to masturbate? */
160 error (_("I refuse to debug myself!"));
162 if (! ops_already_pushed
)
164 /* target_pid_to_str already uses the target. Also clear possible core
165 file with its process_stratum. */
167 make_cleanup_unpush_target (ops
);
172 exec_file
= get_exec_file (0);
175 printf_unfiltered (_("Attaching to program: %s, %s\n"), exec_file
,
176 target_pid_to_str (pid_to_ptid (pid
)));
178 printf_unfiltered (_("Attaching to %s\n"),
179 target_pid_to_str (pid_to_ptid (pid
)));
181 gdb_flush (gdb_stdout
);
186 ptrace (PT_ATTACH
, pid
, (PTRACE_TYPE_ARG3
)0, 0);
188 perror_with_name (("ptrace"));
190 error (_("This system does not support attaching to a process"));
193 inf
= current_inferior ();
194 inferior_appeared (inf
, pid
);
195 inf
->attach_flag
= 1;
196 inferior_ptid
= pid_to_ptid (pid
);
198 /* Always add a main thread. If some target extends the ptrace
199 target, it should decorate the ptid later with more info. */
200 add_thread_silent (inferior_ptid
);
202 discard_cleanups (back_to
);
205 #ifdef PT_GET_PROCESS_STATE
208 inf_ptrace_post_attach (struct target_ops
*self
, int pid
)
212 /* Set the initial event mask. */
213 memset (&pe
, 0, sizeof pe
);
214 pe
.pe_set_event
|= PTRACE_FORK
;
215 if (ptrace (PT_SET_EVENT_MASK
, pid
,
216 (PTRACE_TYPE_ARG3
)&pe
, sizeof pe
) == -1)
217 perror_with_name (("ptrace"));
222 /* Detach from the inferior, optionally passing it the signal
223 specified by ARGS. If FROM_TTY is non-zero, be chatty about it. */
226 inf_ptrace_detach (struct target_ops
*ops
, const char *args
, int from_tty
)
228 pid_t pid
= ptid_get_pid (inferior_ptid
);
233 char *exec_file
= get_exec_file (0);
236 printf_unfiltered (_("Detaching from program: %s, %s\n"), exec_file
,
237 target_pid_to_str (pid_to_ptid (pid
)));
238 gdb_flush (gdb_stdout
);
244 /* We'd better not have left any breakpoints in the program or it'll
245 die when it hits one. Also note that this may only work if we
246 previously attached to the inferior. It *might* work if we
247 started the process ourselves. */
249 ptrace (PT_DETACH
, pid
, (PTRACE_TYPE_ARG3
)1, sig
);
251 perror_with_name (("ptrace"));
253 error (_("This system does not support detaching from a process"));
256 inferior_ptid
= null_ptid
;
257 detach_inferior (pid
);
259 inf_child_maybe_unpush_target (ops
);
262 /* Kill the inferior. */
265 inf_ptrace_kill (struct target_ops
*ops
)
267 pid_t pid
= ptid_get_pid (inferior_ptid
);
273 ptrace (PT_KILL
, pid
, (PTRACE_TYPE_ARG3
)0, 0);
274 waitpid (pid
, &status
, 0);
276 target_mourn_inferior ();
279 /* Stop the inferior. */
282 inf_ptrace_stop (struct target_ops
*self
, ptid_t ptid
)
284 /* Send a SIGINT to the process group. This acts just like the user
285 typed a ^C on the controlling terminal. Note that using a
286 negative process number in kill() is a System V-ism. The proper
287 BSD interface is killpg(). However, all modern BSDs support the
288 System V interface too. */
289 kill (-inferior_process_group (), SIGINT
);
292 /* Resume execution of thread PTID, or all threads if PTID is -1. If
293 STEP is nonzero, single-step it. If SIGNAL is nonzero, give it
297 inf_ptrace_resume (struct target_ops
*ops
,
298 ptid_t ptid
, int step
, enum gdb_signal signal
)
300 pid_t pid
= ptid_get_pid (ptid
);
304 /* Resume all threads. Traditionally ptrace() only supports
305 single-threaded processes, so simply resume the inferior. */
306 pid
= ptid_get_pid (inferior_ptid
);
308 if (catch_syscall_enabled () > 0)
309 request
= PT_SYSCALL
;
311 request
= PT_CONTINUE
;
315 /* If this system does not support PT_STEP, a higher level
316 function will have called single_step() to transmute the step
317 request into a continue request (by setting breakpoints on
318 all possible successor instructions), so we don't have to
319 worry about that here. */
323 /* An address of (PTRACE_TYPE_ARG3)1 tells ptrace to continue from
324 where it was. If GDB wanted it to start some other way, we have
325 already written a new program counter value to the child. */
327 ptrace (request
, pid
, (PTRACE_TYPE_ARG3
)1, gdb_signal_to_host (signal
));
329 perror_with_name (("ptrace"));
332 /* Wait for the child specified by PTID to do something. Return the
333 process ID of the child, or MINUS_ONE_PTID in case of error; store
334 the status in *OURSTATUS. */
337 inf_ptrace_wait (struct target_ops
*ops
,
338 ptid_t ptid
, struct target_waitstatus
*ourstatus
, int options
)
341 int status
, save_errno
;
349 pid
= waitpid (ptid_get_pid (ptid
), &status
, 0);
352 while (pid
== -1 && errno
== EINTR
);
354 clear_sigint_trap ();
358 fprintf_unfiltered (gdb_stderr
,
359 _("Child process unexpectedly missing: %s.\n"),
360 safe_strerror (save_errno
));
362 /* Claim it exited with unknown signal. */
363 ourstatus
->kind
= TARGET_WAITKIND_SIGNALLED
;
364 ourstatus
->value
.sig
= GDB_SIGNAL_UNKNOWN
;
365 return inferior_ptid
;
368 /* Ignore terminated detached child processes. */
369 if (!WIFSTOPPED (status
) && pid
!= ptid_get_pid (inferior_ptid
))
374 #ifdef PT_GET_PROCESS_STATE
375 if (WIFSTOPPED (status
))
380 if (ptrace (PT_GET_PROCESS_STATE
, pid
,
381 (PTRACE_TYPE_ARG3
)&pe
, sizeof pe
) == -1)
382 perror_with_name (("ptrace"));
384 switch (pe
.pe_report_event
)
387 ourstatus
->kind
= TARGET_WAITKIND_FORKED
;
388 ourstatus
->value
.related_pid
= pid_to_ptid (pe
.pe_other_pid
);
390 /* Make sure the other end of the fork is stopped too. */
391 fpid
= waitpid (pe
.pe_other_pid
, &status
, 0);
393 perror_with_name (("waitpid"));
395 if (ptrace (PT_GET_PROCESS_STATE
, fpid
,
396 (PTRACE_TYPE_ARG3
)&pe
, sizeof pe
) == -1)
397 perror_with_name (("ptrace"));
399 gdb_assert (pe
.pe_report_event
== PTRACE_FORK
);
400 gdb_assert (pe
.pe_other_pid
== pid
);
401 if (fpid
== ptid_get_pid (inferior_ptid
))
403 ourstatus
->value
.related_pid
= pid_to_ptid (pe
.pe_other_pid
);
404 return pid_to_ptid (fpid
);
407 return pid_to_ptid (pid
);
412 store_waitstatus (ourstatus
, status
);
413 return pid_to_ptid (pid
);
416 /* Implement the to_xfer_partial target_ops method. */
418 static enum target_xfer_status
419 inf_ptrace_xfer_partial (struct target_ops
*ops
, enum target_object object
,
420 const char *annex
, gdb_byte
*readbuf
,
421 const gdb_byte
*writebuf
,
422 ULONGEST offset
, ULONGEST len
, ULONGEST
*xfered_len
)
424 pid_t pid
= ptid_get_pid (inferior_ptid
);
428 case TARGET_OBJECT_MEMORY
:
430 /* OpenBSD 3.1, NetBSD 1.6 and FreeBSD 5.0 have a new PT_IO
431 request that promises to be much more efficient in reading
432 and writing data in the traced process's address space. */
434 struct ptrace_io_desc piod
;
436 /* NOTE: We assume that there are no distinct address spaces
437 for instruction and data. However, on OpenBSD 3.9 and
438 later, PIOD_WRITE_D doesn't allow changing memory that's
439 mapped read-only. Since most code segments will be
440 read-only, using PIOD_WRITE_D will prevent us from
441 inserting breakpoints, so we use PIOD_WRITE_I instead. */
442 piod
.piod_op
= writebuf
? PIOD_WRITE_I
: PIOD_READ_D
;
443 piod
.piod_addr
= writebuf
? (void *) writebuf
: readbuf
;
444 piod
.piod_offs
= (void *) (long) offset
;
448 if (ptrace (PT_IO
, pid
, (caddr_t
)&piod
, 0) == 0)
450 /* Return the actual number of bytes read or written. */
451 *xfered_len
= piod
.piod_len
;
452 return (piod
.piod_len
== 0) ? TARGET_XFER_EOF
: TARGET_XFER_OK
;
454 /* If the PT_IO request is somehow not supported, fallback on
455 using PT_WRITE_D/PT_READ_D. Otherwise we will return zero
456 to indicate failure. */
458 return TARGET_XFER_EOF
;
464 PTRACE_TYPE_RET word
;
465 gdb_byte byte
[sizeof (PTRACE_TYPE_RET
)];
467 ULONGEST rounded_offset
;
468 ULONGEST partial_len
;
470 /* Round the start offset down to the next long word
472 rounded_offset
= offset
& -(ULONGEST
) sizeof (PTRACE_TYPE_RET
);
474 /* Since ptrace will transfer a single word starting at that
475 rounded_offset the partial_len needs to be adjusted down to
476 that (remember this function only does a single transfer).
477 Should the required length be even less, adjust it down
479 partial_len
= (rounded_offset
+ sizeof (PTRACE_TYPE_RET
)) - offset
;
480 if (partial_len
> len
)
485 /* If OFFSET:PARTIAL_LEN is smaller than
486 ROUNDED_OFFSET:WORDSIZE then a read/modify write will
487 be needed. Read in the entire word. */
488 if (rounded_offset
< offset
489 || (offset
+ partial_len
490 < rounded_offset
+ sizeof (PTRACE_TYPE_RET
)))
491 /* Need part of initial word -- fetch it. */
492 buffer
.word
= ptrace (PT_READ_I
, pid
,
493 (PTRACE_TYPE_ARG3
)(uintptr_t)
496 /* Copy data to be written over corresponding part of
498 memcpy (buffer
.byte
+ (offset
- rounded_offset
),
499 writebuf
, partial_len
);
502 ptrace (PT_WRITE_D
, pid
,
503 (PTRACE_TYPE_ARG3
)(uintptr_t)rounded_offset
,
507 /* Using the appropriate one (I or D) is necessary for
508 Gould NP1, at least. */
510 ptrace (PT_WRITE_I
, pid
,
511 (PTRACE_TYPE_ARG3
)(uintptr_t)rounded_offset
,
514 return TARGET_XFER_EOF
;
521 buffer
.word
= ptrace (PT_READ_I
, pid
,
522 (PTRACE_TYPE_ARG3
)(uintptr_t)rounded_offset
,
525 return TARGET_XFER_EOF
;
526 /* Copy appropriate bytes out of the buffer. */
527 memcpy (readbuf
, buffer
.byte
+ (offset
- rounded_offset
),
531 *xfered_len
= partial_len
;
532 return TARGET_XFER_OK
;
535 case TARGET_OBJECT_UNWIND_TABLE
:
536 return TARGET_XFER_E_IO
;
538 case TARGET_OBJECT_AUXV
:
539 #if defined (PT_IO) && defined (PIOD_READ_AUXV)
540 /* OpenBSD 4.5 has a new PIOD_READ_AUXV operation for the PT_IO
541 request that allows us to read the auxilliary vector. Other
542 BSD's may follow if they feel the need to support PIE. */
544 struct ptrace_io_desc piod
;
547 return TARGET_XFER_E_IO
;
548 piod
.piod_op
= PIOD_READ_AUXV
;
549 piod
.piod_addr
= readbuf
;
550 piod
.piod_offs
= (void *) (long) offset
;
554 if (ptrace (PT_IO
, pid
, (caddr_t
)&piod
, 0) == 0)
556 /* Return the actual number of bytes read or written. */
557 *xfered_len
= piod
.piod_len
;
558 return (piod
.piod_len
== 0) ? TARGET_XFER_EOF
: TARGET_XFER_OK
;
562 return TARGET_XFER_E_IO
;
564 case TARGET_OBJECT_WCOOKIE
:
565 return TARGET_XFER_E_IO
;
568 return TARGET_XFER_E_IO
;
572 /* Return non-zero if the thread specified by PTID is alive. */
575 inf_ptrace_thread_alive (struct target_ops
*ops
, ptid_t ptid
)
577 /* ??? Is kill the right way to do this? */
578 return (kill (ptid_get_pid (ptid
), 0) != -1);
581 /* Print status information about what we're accessing. */
584 inf_ptrace_files_info (struct target_ops
*ignore
)
586 struct inferior
*inf
= current_inferior ();
588 printf_filtered (_("\tUsing the running image of %s %s.\n"),
589 inf
->attach_flag
? "attached" : "child",
590 target_pid_to_str (inferior_ptid
));
594 inf_ptrace_pid_to_str (struct target_ops
*ops
, ptid_t ptid
)
596 return normal_pid_to_str (ptid
);
599 #if defined (PT_IO) && defined (PIOD_READ_AUXV)
601 /* Read one auxv entry from *READPTR, not reading locations >= ENDPTR.
602 Return 0 if *READPTR is already at the end of the buffer.
603 Return -1 if there is insufficient buffer for a whole entry.
604 Return 1 if an entry was read into *TYPEP and *VALP. */
607 inf_ptrace_auxv_parse (struct target_ops
*ops
, gdb_byte
**readptr
,
608 gdb_byte
*endptr
, CORE_ADDR
*typep
, CORE_ADDR
*valp
)
610 struct type
*int_type
= builtin_type (target_gdbarch ())->builtin_int
;
611 struct type
*ptr_type
= builtin_type (target_gdbarch ())->builtin_data_ptr
;
612 const int sizeof_auxv_type
= TYPE_LENGTH (int_type
);
613 const int sizeof_auxv_val
= TYPE_LENGTH (ptr_type
);
614 enum bfd_endian byte_order
= gdbarch_byte_order (target_gdbarch ());
615 gdb_byte
*ptr
= *readptr
;
620 if (endptr
- ptr
< 2 * sizeof_auxv_val
)
623 *typep
= extract_unsigned_integer (ptr
, sizeof_auxv_type
, byte_order
);
624 ptr
+= sizeof_auxv_val
; /* Alignment. */
625 *valp
= extract_unsigned_integer (ptr
, sizeof_auxv_val
, byte_order
);
626 ptr
+= sizeof_auxv_val
;
634 /* Create a prototype ptrace target. The client can override it with
638 inf_ptrace_target (void)
640 struct target_ops
*t
= inf_child_target ();
642 t
->to_attach
= inf_ptrace_attach
;
643 t
->to_detach
= inf_ptrace_detach
;
644 t
->to_resume
= inf_ptrace_resume
;
645 t
->to_wait
= inf_ptrace_wait
;
646 t
->to_files_info
= inf_ptrace_files_info
;
647 t
->to_kill
= inf_ptrace_kill
;
648 t
->to_create_inferior
= inf_ptrace_create_inferior
;
649 #ifdef PT_GET_PROCESS_STATE
650 t
->to_follow_fork
= inf_ptrace_follow_fork
;
651 t
->to_post_startup_inferior
= inf_ptrace_post_startup_inferior
;
652 t
->to_post_attach
= inf_ptrace_post_attach
;
654 t
->to_mourn_inferior
= inf_ptrace_mourn_inferior
;
655 t
->to_thread_alive
= inf_ptrace_thread_alive
;
656 t
->to_pid_to_str
= inf_ptrace_pid_to_str
;
657 t
->to_stop
= inf_ptrace_stop
;
658 t
->to_xfer_partial
= inf_ptrace_xfer_partial
;
659 #if defined (PT_IO) && defined (PIOD_READ_AUXV)
660 t
->to_auxv_parse
= inf_ptrace_auxv_parse
;
667 /* Pointer to a function that returns the offset within the user area
668 where a particular register is stored. */
669 static CORE_ADDR (*inf_ptrace_register_u_offset
)(struct gdbarch
*, int, int);
671 /* Fetch register REGNUM from the inferior. */
674 inf_ptrace_fetch_register (struct regcache
*regcache
, int regnum
)
676 struct gdbarch
*gdbarch
= get_regcache_arch (regcache
);
679 PTRACE_TYPE_RET
*buf
;
682 /* This isn't really an address, but ptrace thinks of it as one. */
683 addr
= inf_ptrace_register_u_offset (gdbarch
, regnum
, 0);
684 if (addr
== (CORE_ADDR
)-1
685 || gdbarch_cannot_fetch_register (gdbarch
, regnum
))
687 regcache_raw_supply (regcache
, regnum
, NULL
);
691 /* Cater for systems like GNU/Linux, that implement threads as
692 separate processes. */
693 pid
= ptid_get_lwp (inferior_ptid
);
695 pid
= ptid_get_pid (inferior_ptid
);
697 size
= register_size (gdbarch
, regnum
);
698 gdb_assert ((size
% sizeof (PTRACE_TYPE_RET
)) == 0);
701 /* Read the register contents from the inferior a chunk at a time. */
702 for (i
= 0; i
< size
/ sizeof (PTRACE_TYPE_RET
); i
++)
705 buf
[i
] = ptrace (PT_READ_U
, pid
, (PTRACE_TYPE_ARG3
)(uintptr_t)addr
, 0);
707 error (_("Couldn't read register %s (#%d): %s."),
708 gdbarch_register_name (gdbarch
, regnum
),
709 regnum
, safe_strerror (errno
));
711 addr
+= sizeof (PTRACE_TYPE_RET
);
713 regcache_raw_supply (regcache
, regnum
, buf
);
716 /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
717 for all registers. */
720 inf_ptrace_fetch_registers (struct target_ops
*ops
,
721 struct regcache
*regcache
, int regnum
)
725 regnum
< gdbarch_num_regs (get_regcache_arch (regcache
));
727 inf_ptrace_fetch_register (regcache
, regnum
);
729 inf_ptrace_fetch_register (regcache
, regnum
);
732 /* Store register REGNUM into the inferior. */
735 inf_ptrace_store_register (const struct regcache
*regcache
, int regnum
)
737 struct gdbarch
*gdbarch
= get_regcache_arch (regcache
);
740 PTRACE_TYPE_RET
*buf
;
743 /* This isn't really an address, but ptrace thinks of it as one. */
744 addr
= inf_ptrace_register_u_offset (gdbarch
, regnum
, 1);
745 if (addr
== (CORE_ADDR
)-1
746 || gdbarch_cannot_store_register (gdbarch
, regnum
))
749 /* Cater for systems like GNU/Linux, that implement threads as
750 separate processes. */
751 pid
= ptid_get_lwp (inferior_ptid
);
753 pid
= ptid_get_pid (inferior_ptid
);
755 size
= register_size (gdbarch
, regnum
);
756 gdb_assert ((size
% sizeof (PTRACE_TYPE_RET
)) == 0);
759 /* Write the register contents into the inferior a chunk at a time. */
760 regcache_raw_collect (regcache
, regnum
, buf
);
761 for (i
= 0; i
< size
/ sizeof (PTRACE_TYPE_RET
); i
++)
764 ptrace (PT_WRITE_U
, pid
, (PTRACE_TYPE_ARG3
)(uintptr_t)addr
, buf
[i
]);
766 error (_("Couldn't write register %s (#%d): %s."),
767 gdbarch_register_name (gdbarch
, regnum
),
768 regnum
, safe_strerror (errno
));
770 addr
+= sizeof (PTRACE_TYPE_RET
);
774 /* Store register REGNUM back into the inferior. If REGNUM is -1, do
775 this for all registers. */
778 inf_ptrace_store_registers (struct target_ops
*ops
,
779 struct regcache
*regcache
, int regnum
)
783 regnum
< gdbarch_num_regs (get_regcache_arch (regcache
));
785 inf_ptrace_store_register (regcache
, regnum
);
787 inf_ptrace_store_register (regcache
, regnum
);
790 /* Create a "traditional" ptrace target. REGISTER_U_OFFSET should be
791 a function returning the offset within the user area where a
792 particular register is stored. */
795 inf_ptrace_trad_target (CORE_ADDR (*register_u_offset
)
796 (struct gdbarch
*, int, int))
798 struct target_ops
*t
= inf_ptrace_target();
800 gdb_assert (register_u_offset
);
801 inf_ptrace_register_u_offset
= register_u_offset
;
802 t
->to_fetch_registers
= inf_ptrace_fetch_registers
;
803 t
->to_store_registers
= inf_ptrace_store_registers
;