Change defn of LOCAL_LABEL_PREFIX to ""
[external/binutils.git] / gdb / inftarg.c
1 /* Target-vector operations for controlling Unix child processes, for GDB.
2    Copyright 1990-1996, 1998, 1999 Free Software Foundation, Inc.
3    Contributed by Cygnus Support.
4
5    ## Contains temporary hacks..
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 "frame.h"              /* required by inferior.h */
26 #include "inferior.h"
27 #include "target.h"
28 #include "gdbcore.h"
29 #include "command.h"
30 #include "gdb_stat.h"
31 #include <signal.h>
32 #include <sys/types.h>
33 #include <fcntl.h>
34
35 #include "gdb_wait.h"
36
37 extern struct symtab_and_line *child_enable_exception_callback (enum
38                                                                 exception_event_kind,
39                                                                 int);
40
41 extern struct exception_event_record
42   *child_get_current_exception_event (void);
43
44 extern void _initialize_inftarg (void);
45
46 static void child_prepare_to_store (void);
47
48 #ifndef CHILD_WAIT
49 static int child_wait (int, struct target_waitstatus *);
50 #endif /* CHILD_WAIT */
51
52 #if !defined(CHILD_POST_WAIT)
53 void child_post_wait (int, int);
54 #endif
55
56 static void child_open (char *, int);
57
58 static void child_files_info (struct target_ops *);
59
60 static void child_detach (char *, int);
61
62 static void child_detach_from_process (int, char *, int, int);
63
64 static void child_attach (char *, int);
65
66 static void child_attach_to_process (char *, int, int);
67
68 #if !defined(CHILD_POST_ATTACH)
69 extern void child_post_attach (int);
70 #endif
71
72 static void child_require_attach (char *, int);
73
74 static void child_require_detach (int, char *, int);
75
76 static void ptrace_me (void);
77
78 static void ptrace_him (int);
79
80 static void child_create_inferior (char *, char *, char **);
81
82 static void child_mourn_inferior (void);
83
84 static int child_can_run (void);
85
86 static void child_stop (void);
87
88 #ifndef CHILD_THREAD_ALIVE
89 int child_thread_alive (int);
90 #endif
91
92 static void init_child_ops (void);
93
94 extern char **environ;
95
96 struct target_ops child_ops;
97
98 int child_suppress_run = 0;     /* Non-zero if inftarg should pretend not to
99                                    be a runnable target.  Used by targets
100                                    that can sit atop inftarg, such as HPUX
101                                    thread support.  */
102
103 #ifndef CHILD_WAIT
104
105 /*## */
106 /* Enable HACK for ttrace work.  In
107  * infttrace.c/require_notification_of_events,
108  * this is set to 0 so that the loop in child_wait
109  * won't loop.
110  */
111 int not_same_real_pid = 1;
112 /*## */
113
114
115 /* Wait for child to do something.  Return pid of child, or -1 in case
116    of error; store status through argument pointer OURSTATUS.  */
117
118 static int
119 child_wait (int pid, struct target_waitstatus *ourstatus)
120 {
121   int save_errno;
122   int status;
123   char *execd_pathname = NULL;
124   int exit_status;
125   int related_pid;
126   int syscall_id;
127   enum target_waitkind kind;
128
129   do
130     {
131       set_sigint_trap ();       /* Causes SIGINT to be passed on to the
132                                    attached process. */
133       set_sigio_trap ();
134
135       pid = ptrace_wait (inferior_pid, &status);
136
137       save_errno = errno;
138
139       clear_sigio_trap ();
140
141       clear_sigint_trap ();
142
143       if (pid == -1)
144         {
145           if (save_errno == EINTR)
146             continue;
147
148           fprintf_unfiltered (gdb_stderr, "Child process unexpectedly missing: %s.\n",
149                               safe_strerror (save_errno));
150
151           /* Claim it exited with unknown signal.  */
152           ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
153           ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
154           return -1;
155         }
156
157       /* Did it exit?
158        */
159       if (target_has_exited (pid, status, &exit_status))
160         {
161           /* ??rehrauer: For now, ignore this. */
162           continue;
163         }
164
165       if (!target_thread_alive (pid))
166         {
167           ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
168           return pid;
169         }
170
171       if (target_has_forked (pid, &related_pid)
172           && ((pid == inferior_pid) || (related_pid == inferior_pid)))
173         {
174           ourstatus->kind = TARGET_WAITKIND_FORKED;
175           ourstatus->value.related_pid = related_pid;
176           return pid;
177         }
178
179       if (target_has_vforked (pid, &related_pid)
180           && ((pid == inferior_pid) || (related_pid == inferior_pid)))
181         {
182           ourstatus->kind = TARGET_WAITKIND_VFORKED;
183           ourstatus->value.related_pid = related_pid;
184           return pid;
185         }
186
187       if (target_has_execd (pid, &execd_pathname))
188         {
189           /* Are we ignoring initial exec events?  (This is likely because
190              we're in the process of starting up the inferior, and another
191              (older) mechanism handles those.)  If so, we'll report this
192              as a regular stop, not an exec.
193            */
194           if (inferior_ignoring_startup_exec_events)
195             {
196               inferior_ignoring_startup_exec_events--;
197             }
198           else
199             {
200               ourstatus->kind = TARGET_WAITKIND_EXECD;
201               ourstatus->value.execd_pathname = execd_pathname;
202               return pid;
203             }
204         }
205
206       /* All we must do with these is communicate their occurrence
207          to wait_for_inferior...
208        */
209       if (target_has_syscall_event (pid, &kind, &syscall_id))
210         {
211           ourstatus->kind = kind;
212           ourstatus->value.syscall_id = syscall_id;
213           return pid;
214         }
215
216       /*##  } while (pid != inferior_pid); ## *//* Some other child died or stopped */
217 /* hack for thread testing */
218     }
219   while ((pid != inferior_pid) && not_same_real_pid);
220 /*## */
221
222   store_waitstatus (ourstatus, status);
223   return pid;
224 }
225 #endif /* CHILD_WAIT */
226
227 #if !defined(CHILD_POST_WAIT)
228 void
229 child_post_wait (int pid, int wait_status)
230 {
231   /* This version of Unix doesn't require a meaningful "post wait"
232      operation.
233    */
234 }
235 #endif
236
237
238 #ifndef CHILD_THREAD_ALIVE
239
240 /* Check to see if the given thread is alive.
241
242    FIXME: Is kill() ever the right way to do this?  I doubt it, but
243    for now we're going to try and be compatable with the old thread
244    code.  */
245 int
246 child_thread_alive (int pid)
247 {
248   return (kill (pid, 0) != -1);
249 }
250
251 #endif
252
253 static void
254 child_attach_to_process (char *args, int from_tty, int after_fork)
255 {
256   if (!args)
257     error_no_arg ("process-id to attach");
258
259 #ifndef ATTACH_DETACH
260   error ("Can't attach to a process on this machine.");
261 #else
262   {
263     char *exec_file;
264     int pid;
265     char *dummy;
266
267     dummy = args;
268     pid = strtol (args, &dummy, 0);
269     /* Some targets don't set errno on errors, grrr! */
270     if ((pid == 0) && (args == dummy))
271       error ("Illegal process-id: %s\n", args);
272
273     if (pid == getpid ())       /* Trying to masturbate? */
274       error ("I refuse to debug myself!");
275
276     if (from_tty)
277       {
278         exec_file = (char *) get_exec_file (0);
279
280         if (after_fork)
281           printf_unfiltered ("Attaching after fork to %s\n",
282                              target_pid_to_str (pid));
283         else if (exec_file)
284           printf_unfiltered ("Attaching to program: %s, %s\n", exec_file,
285                              target_pid_to_str (pid));
286         else
287           printf_unfiltered ("Attaching to %s\n", target_pid_to_str (pid));
288
289         gdb_flush (gdb_stdout);
290       }
291
292     if (!after_fork)
293       attach (pid);
294     else
295       REQUIRE_ATTACH (pid);
296
297     inferior_pid = pid;
298     push_target (&child_ops);
299   }
300 #endif /* ATTACH_DETACH */
301 }
302
303
304 /* Attach to process PID, then initialize for debugging it.  */
305
306 static void
307 child_attach (char *args, int from_tty)
308 {
309   child_attach_to_process (args, from_tty, 0);
310 }
311
312 #if !defined(CHILD_POST_ATTACH)
313 void
314 child_post_attach (int pid)
315 {
316   /* This version of Unix doesn't require a meaningful "post attach"
317      operation by a debugger.  */
318 }
319 #endif
320
321 static void
322 child_require_attach (char *args, int from_tty)
323 {
324   child_attach_to_process (args, from_tty, 1);
325 }
326
327 static void
328 child_detach_from_process (int pid, char *args, int from_tty, int after_fork)
329 {
330 #ifdef ATTACH_DETACH
331   {
332     int siggnal = 0;
333
334     if (from_tty)
335       {
336         char *exec_file = get_exec_file (0);
337         if (exec_file == 0)
338           exec_file = "";
339         if (after_fork)
340           printf_unfiltered ("Detaching after fork from %s\n",
341                              target_pid_to_str (pid));
342         else
343           printf_unfiltered ("Detaching from program: %s, %s\n", exec_file,
344                              target_pid_to_str (pid));
345         gdb_flush (gdb_stdout);
346       }
347     if (args)
348       siggnal = atoi (args);
349
350     if (!after_fork)
351       detach (siggnal);
352     else
353       REQUIRE_DETACH (pid, siggnal);
354   }
355 #else
356   error ("This version of Unix does not support detaching a process.");
357 #endif
358 }
359
360 /* Take a program previously attached to and detaches it.
361    The program resumes execution and will no longer stop
362    on signals, etc.  We'd better not have left any breakpoints
363    in the program or it'll die when it hits one.  For this
364    to work, it may be necessary for the process to have been
365    previously attached.  It *might* work if the program was
366    started via the normal ptrace (PTRACE_TRACEME).  */
367
368 static void
369 child_detach (char *args, int from_tty)
370 {
371   child_detach_from_process (inferior_pid, args, from_tty, 0);
372   inferior_pid = 0;
373   unpush_target (&child_ops);
374 }
375
376 static void
377 child_require_detach (int pid, char *args, int from_tty)
378 {
379   child_detach_from_process (pid, args, from_tty, 1);
380 }
381
382
383 /* Get ready to modify the registers array.  On machines which store
384    individual registers, this doesn't need to do anything.  On machines
385    which store all the registers in one fell swoop, this makes sure
386    that registers contains all the registers from the program being
387    debugged.  */
388
389 static void
390 child_prepare_to_store (void)
391 {
392 #ifdef CHILD_PREPARE_TO_STORE
393   CHILD_PREPARE_TO_STORE ();
394 #endif
395 }
396
397 /* Print status information about what we're accessing.  */
398
399 static void
400 child_files_info (struct target_ops *ignore)
401 {
402   printf_unfiltered ("\tUsing the running image of %s %s.\n",
403       attach_flag ? "attached" : "child", target_pid_to_str (inferior_pid));
404 }
405
406 /* ARGSUSED */
407 static void
408 child_open (char *arg, int from_tty)
409 {
410   error ("Use the \"run\" command to start a Unix child process.");
411 }
412
413 /* Stub function which causes the inferior that runs it, to be ptrace-able
414    by its parent process.  */
415
416 static void
417 ptrace_me (void)
418 {
419   /* "Trace me, Dr. Memory!" */
420   call_ptrace (0, 0, (PTRACE_ARG3_TYPE) 0, 0);
421 }
422
423 /* Stub function which causes the GDB that runs it, to start ptrace-ing
424    the child process.  */
425
426 static void
427 ptrace_him (int pid)
428 {
429   push_target (&child_ops);
430
431   /* On some targets, there must be some explicit synchronization
432      between the parent and child processes after the debugger
433      forks, and before the child execs the debuggee program.  This
434      call basically gives permission for the child to exec.
435    */
436
437   target_acknowledge_created_inferior (pid);
438
439   /* START_INFERIOR_TRAPS_EXPECTED is defined in inferior.h,
440    * and will be 1 or 2 depending on whether we're starting
441    * without or with a shell.
442    */
443   startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
444
445   /* On some targets, there must be some explicit actions taken after
446      the inferior has been started up.
447    */
448   target_post_startup_inferior (pid);
449 }
450
451 /* Start an inferior Unix child process and sets inferior_pid to its pid.
452    EXEC_FILE is the file to run.
453    ALLARGS is a string containing the arguments to the program.
454    ENV is the environment vector to pass.  Errors reported with error().  */
455
456 static void
457 child_create_inferior (char *exec_file, char *allargs, char **env)
458 {
459 #ifdef HPUXHPPA
460   fork_inferior (exec_file, allargs, env, ptrace_me, ptrace_him, pre_fork_inferior, NULL);
461 #else
462   fork_inferior (exec_file, allargs, env, ptrace_me, ptrace_him, NULL, NULL);
463 #endif
464   /* We are at the first instruction we care about.  */
465   /* Pedal to the metal... */
466   proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
467 }
468
469 #if !defined(CHILD_POST_STARTUP_INFERIOR)
470 void
471 child_post_startup_inferior (int pid)
472 {
473   /* This version of Unix doesn't require a meaningful "post startup inferior"
474      operation by a debugger.
475    */
476 }
477 #endif
478
479 #if !defined(CHILD_ACKNOWLEDGE_CREATED_INFERIOR)
480 void
481 child_acknowledge_created_inferior (int pid)
482 {
483   /* This version of Unix doesn't require a meaningful "acknowledge created inferior"
484      operation by a debugger.
485    */
486 }
487 #endif
488
489
490 void
491 child_clone_and_follow_inferior (int child_pid, int *followed_child)
492 {
493   clone_and_follow_inferior (child_pid, followed_child);
494
495   /* Don't resume CHILD_PID; it's stopped where it ought to be, until
496      the decision gets made elsewhere how to continue it.
497    */
498 }
499
500
501 #if !defined(CHILD_POST_FOLLOW_INFERIOR_BY_CLONE)
502 void
503 child_post_follow_inferior_by_clone (void)
504 {
505   /* This version of Unix doesn't require a meaningful "post follow inferior"
506      operation by a clone debugger.
507    */
508 }
509 #endif
510
511 #if !defined(CHILD_INSERT_FORK_CATCHPOINT)
512 int
513 child_insert_fork_catchpoint (int pid)
514 {
515   /* This version of Unix doesn't support notification of fork events.  */
516   return 0;
517 }
518 #endif
519
520 #if !defined(CHILD_REMOVE_FORK_CATCHPOINT)
521 int
522 child_remove_fork_catchpoint (int pid)
523 {
524   /* This version of Unix doesn't support notification of fork events.  */
525   return 0;
526 }
527 #endif
528
529 #if !defined(CHILD_INSERT_VFORK_CATCHPOINT)
530 int
531 child_insert_vfork_catchpoint (int pid)
532 {
533   /* This version of Unix doesn't support notification of vfork events.  */
534   return 0;
535 }
536 #endif
537
538 #if !defined(CHILD_REMOVE_VFORK_CATCHPOINT)
539 int
540 child_remove_vfork_catchpoint (int pid)
541 {
542   /* This version of Unix doesn't support notification of vfork events.  */
543   return 0;
544 }
545 #endif
546
547 #if !defined(CHILD_HAS_FORKED)
548 int
549 child_has_forked (int pid, int *child_pid)
550 {
551   /* This version of Unix doesn't support notification of fork events.  */
552   return 0;
553 }
554 #endif
555
556
557 #if !defined(CHILD_HAS_VFORKED)
558 int
559 child_has_vforked (int pid, int *child_pid)
560 {
561   /* This version of Unix doesn't support notification of vfork events.
562    */
563   return 0;
564 }
565 #endif
566
567
568 #if !defined(CHILD_CAN_FOLLOW_VFORK_PRIOR_TO_EXEC)
569 int
570 child_can_follow_vfork_prior_to_exec (void)
571 {
572   /* This version of Unix doesn't support notification of vfork events.
573      However, if it did, it probably wouldn't allow vforks to be followed
574      before the following exec.
575    */
576   return 0;
577 }
578 #endif
579
580
581 #if !defined(CHILD_POST_FOLLOW_VFORK)
582 void
583 child_post_follow_vfork (int parent_pid, int followed_parent, int child_pid,
584                          int followed_child)
585 {
586   /* This version of Unix doesn't require a meaningful "post follow vfork"
587      operation by a clone debugger.
588    */
589 }
590 #endif
591
592 #if !defined(CHILD_INSERT_EXEC_CATCHPOINT)
593 int
594 child_insert_exec_catchpoint (int pid)
595 {
596   /* This version of Unix doesn't support notification of exec events.  */
597   return 0;
598 }
599 #endif
600
601 #if !defined(CHILD_REMOVE_EXEC_CATCHPOINT)
602 int
603 child_remove_exec_catchpoint (int pid)
604 {
605   /* This version of Unix doesn't support notification of exec events.  */
606   return 0;
607 }
608 #endif
609
610 #if !defined(CHILD_HAS_EXECD)
611 int
612 child_has_execd (int pid, char **execd_pathname)
613 {
614   /* This version of Unix doesn't support notification of exec events.
615    */
616   return 0;
617 }
618 #endif
619
620
621 #if !defined(CHILD_REPORTED_EXEC_EVENTS_PER_EXEC_CALL)
622 int
623 child_reported_exec_events_per_exec_call (void)
624 {
625   /* This version of Unix doesn't support notification of exec events.
626    */
627   return 1;
628 }
629 #endif
630
631
632 #if !defined(CHILD_HAS_SYSCALL_EVENT)
633 int
634 child_has_syscall_event (int pid, enum target_waitkind *kind, int *syscall_id)
635 {
636   /* This version of Unix doesn't support notification of syscall events.
637    */
638   return 0;
639 }
640 #endif
641
642
643 #if !defined(CHILD_HAS_EXITED)
644 int
645 child_has_exited (int pid, int wait_status, int *exit_status)
646 {
647   if (WIFEXITED (wait_status))
648     {
649       *exit_status = WEXITSTATUS (wait_status);
650       return 1;
651     }
652
653   if (WIFSIGNALED (wait_status))
654     {
655       *exit_status = 0;         /* ?? Don't know what else to say here. */
656       return 1;
657     }
658
659   /* ?? Do we really need to consult the event state, too?  Assume the
660      wait_state alone suffices.
661    */
662   return 0;
663 }
664 #endif
665
666
667 static void
668 child_mourn_inferior (void)
669 {
670   unpush_target (&child_ops);
671   generic_mourn_inferior ();
672 }
673
674 static int
675 child_can_run (void)
676 {
677   /* This variable is controlled by modules that sit atop inftarg that may layer
678      their own process structure atop that provided here.  hpux-thread.c does
679      this because of the Hpux user-mode level thread model.  */
680
681   return !child_suppress_run;
682 }
683
684 /* Send a SIGINT to the process group.  This acts just like the user typed a
685    ^C on the controlling terminal.
686
687    XXX - This may not be correct for all systems.  Some may want to use
688    killpg() instead of kill (-pgrp). */
689
690 static void
691 child_stop (void)
692 {
693   extern pid_t inferior_process_group;
694
695   kill (-inferior_process_group, SIGINT);
696 }
697
698 #if !defined(CHILD_ENABLE_EXCEPTION_CALLBACK)
699 struct symtab_and_line *
700 child_enable_exception_callback (enum exception_event_kind kind, int enable)
701 {
702   return (struct symtab_and_line *) NULL;
703 }
704 #endif
705
706 #if !defined(CHILD_GET_CURRENT_EXCEPTION_EVENT)
707 struct exception_event_record *
708 child_get_current_exception_event (void)
709 {
710   return (struct exception_event_record *) NULL;
711 }
712 #endif
713
714
715 #if !defined(CHILD_PID_TO_EXEC_FILE)
716 char *
717 child_pid_to_exec_file (int pid)
718 {
719   /* This version of Unix doesn't support translation of a process ID
720      to the filename of the executable file.
721    */
722   return NULL;
723 }
724 #endif
725
726 char *
727 child_core_file_to_sym_file (char *core)
728 {
729   /* The target stratum for a running executable need not support
730      this operation.
731    */
732   return NULL;
733 }
734 \f
735
736 #if !defined(CHILD_PID_TO_STR)
737 char *
738 child_pid_to_str (int pid)
739 {
740   return normal_pid_to_str (pid);
741 }
742 #endif
743
744 static void
745 init_child_ops (void)
746 {
747   child_ops.to_shortname = "child";
748   child_ops.to_longname = "Unix child process";
749   child_ops.to_doc = "Unix child process (started by the \"run\" command).";
750   child_ops.to_open = child_open;
751   child_ops.to_attach = child_attach;
752   child_ops.to_post_attach = child_post_attach;
753   child_ops.to_require_attach = child_require_attach;
754   child_ops.to_detach = child_detach;
755   child_ops.to_require_detach = child_require_detach;
756   child_ops.to_resume = child_resume;
757   child_ops.to_wait = child_wait;
758   child_ops.to_post_wait = child_post_wait;
759   child_ops.to_fetch_registers = fetch_inferior_registers;
760   child_ops.to_store_registers = store_inferior_registers;
761   child_ops.to_prepare_to_store = child_prepare_to_store;
762   child_ops.to_xfer_memory = child_xfer_memory;
763   child_ops.to_files_info = child_files_info;
764   child_ops.to_insert_breakpoint = memory_insert_breakpoint;
765   child_ops.to_remove_breakpoint = memory_remove_breakpoint;
766   child_ops.to_terminal_init = terminal_init_inferior;
767   child_ops.to_terminal_inferior = terminal_inferior;
768   child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
769   child_ops.to_terminal_ours = terminal_ours;
770   child_ops.to_terminal_info = child_terminal_info;
771   child_ops.to_kill = kill_inferior;
772   child_ops.to_create_inferior = child_create_inferior;
773   child_ops.to_post_startup_inferior = child_post_startup_inferior;
774   child_ops.to_acknowledge_created_inferior = child_acknowledge_created_inferior;
775   child_ops.to_clone_and_follow_inferior = child_clone_and_follow_inferior;
776   child_ops.to_post_follow_inferior_by_clone = child_post_follow_inferior_by_clone;
777   child_ops.to_insert_fork_catchpoint = child_insert_fork_catchpoint;
778   child_ops.to_remove_fork_catchpoint = child_remove_fork_catchpoint;
779   child_ops.to_insert_vfork_catchpoint = child_insert_vfork_catchpoint;
780   child_ops.to_remove_vfork_catchpoint = child_remove_vfork_catchpoint;
781   child_ops.to_has_forked = child_has_forked;
782   child_ops.to_has_vforked = child_has_vforked;
783   child_ops.to_can_follow_vfork_prior_to_exec = child_can_follow_vfork_prior_to_exec;
784   child_ops.to_post_follow_vfork = child_post_follow_vfork;
785   child_ops.to_insert_exec_catchpoint = child_insert_exec_catchpoint;
786   child_ops.to_remove_exec_catchpoint = child_remove_exec_catchpoint;
787   child_ops.to_has_execd = child_has_execd;
788   child_ops.to_reported_exec_events_per_exec_call = child_reported_exec_events_per_exec_call;
789   child_ops.to_has_syscall_event = child_has_syscall_event;
790   child_ops.to_has_exited = child_has_exited;
791   child_ops.to_mourn_inferior = child_mourn_inferior;
792   child_ops.to_can_run = child_can_run;
793   child_ops.to_thread_alive = child_thread_alive;
794   child_ops.to_pid_to_str = child_pid_to_str;
795   child_ops.to_stop = child_stop;
796   child_ops.to_enable_exception_callback = child_enable_exception_callback;
797   child_ops.to_get_current_exception_event = child_get_current_exception_event;
798   child_ops.to_pid_to_exec_file = child_pid_to_exec_file;
799   child_ops.to_core_file_to_sym_file = child_core_file_to_sym_file;
800   child_ops.to_stratum = process_stratum;
801   child_ops.to_has_all_memory = 1;
802   child_ops.to_has_memory = 1;
803   child_ops.to_has_stack = 1;
804   child_ops.to_has_registers = 1;
805   child_ops.to_has_execution = 1;
806   child_ops.to_magic = OPS_MAGIC;
807 }
808
809 void
810 _initialize_inftarg (void)
811 {
812 #ifdef HAVE_OPTIONAL_PROC_FS
813   char procname[32];
814   int fd;
815
816   /* If we have an optional /proc filesystem (e.g. under OSF/1),
817      don't add ptrace support if we can access the running GDB via /proc.  */
818 #ifndef PROC_NAME_FMT
819 #define PROC_NAME_FMT "/proc/%05d"
820 #endif
821   sprintf (procname, PROC_NAME_FMT, getpid ());
822   if ((fd = open (procname, O_RDONLY)) >= 0)
823     {
824       close (fd);
825       return;
826     }
827 #endif
828
829   init_child_ops ();
830   add_target (&child_ops);
831 }