119370Spst/* Target-vector operations for controlling Unix child processes, for GDB. 2130803Smarcel 3130803Smarcel Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 4130803Smarcel 2000, 2002, 2003, 2004 Free Software Foundation, Inc. 5130803Smarcel 619370Spst Contributed by Cygnus Support. 719370Spst 898944Sobrien ## Contains temporary hacks.. 946283Sdfr 1098944Sobrien This file is part of GDB. 1119370Spst 1298944Sobrien This program is free software; you can redistribute it and/or modify 1398944Sobrien it under the terms of the GNU General Public License as published by 1498944Sobrien the Free Software Foundation; either version 2 of the License, or 1598944Sobrien (at your option) any later version. 1619370Spst 1798944Sobrien This program is distributed in the hope that it will be useful, 1898944Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 1998944Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 2098944Sobrien GNU General Public License for more details. 2119370Spst 2298944Sobrien You should have received a copy of the GNU General Public License 2398944Sobrien along with this program; if not, write to the Free Software 2498944Sobrien Foundation, Inc., 59 Temple Place - Suite 330, 2598944Sobrien Boston, MA 02111-1307, USA. */ 2619370Spst 2719370Spst#include "defs.h" 2898944Sobrien#include "frame.h" /* required by inferior.h */ 2919370Spst#include "inferior.h" 3019370Spst#include "target.h" 3119370Spst#include "gdbcore.h" 3219370Spst#include "command.h" 3346283Sdfr#include "gdb_stat.h" 3419370Spst#include <signal.h> 3519370Spst#include <sys/types.h> 3619370Spst#include <fcntl.h> 3719370Spst 3898944Sobrien#include "gdb_wait.h" 39130803Smarcel#include "inflow.h" 4046283Sdfr 4198944Sobrienextern struct symtab_and_line *child_enable_exception_callback (enum 4298944Sobrien exception_event_kind, 4398944Sobrien int); 4446283Sdfr 4598944Sobrienextern struct exception_event_record 4698944Sobrien *child_get_current_exception_event (void); 4746283Sdfr 4898944Sobrienextern void _initialize_inftarg (void); 4946283Sdfr 5098944Sobrienstatic void child_prepare_to_store (void); 5146283Sdfr 5219370Spst#ifndef CHILD_WAIT 5398944Sobrienstatic ptid_t child_wait (ptid_t, struct target_waitstatus *); 5419370Spst#endif /* CHILD_WAIT */ 5519370Spst 5646283Sdfr#if !defined(CHILD_POST_WAIT) 5798944Sobrienvoid child_post_wait (ptid_t, int); 5846283Sdfr#endif 5946283Sdfr 6098944Sobrienstatic void child_open (char *, int); 6119370Spst 6298944Sobrienstatic void child_files_info (struct target_ops *); 6319370Spst 6498944Sobrienstatic void child_detach (char *, int); 6519370Spst 6698944Sobrienstatic void child_attach (char *, int); 6719370Spst 6846283Sdfr#if !defined(CHILD_POST_ATTACH) 6998944Sobrienextern void child_post_attach (int); 7046283Sdfr#endif 7146283Sdfr 7298944Sobrienstatic void ptrace_me (void); 7319370Spst 7498944Sobrienstatic void ptrace_him (int); 7519370Spst 7698944Sobrienstatic void child_create_inferior (char *, char *, char **); 7719370Spst 7898944Sobrienstatic void child_mourn_inferior (void); 7919370Spst 8098944Sobrienstatic int child_can_run (void); 8119370Spst 8298944Sobrienstatic void child_stop (void); 8319370Spst 8446283Sdfr#ifndef CHILD_THREAD_ALIVE 8598944Sobrienint child_thread_alive (ptid_t); 8646283Sdfr#endif 8746283Sdfr 8898944Sobrienstatic void init_child_ops (void); 8946283Sdfr 9019370Spstextern char **environ; 9119370Spst 9246283Sdfrstruct target_ops child_ops; 9319370Spst 9446283Sdfrint child_suppress_run = 0; /* Non-zero if inftarg should pretend not to 9546283Sdfr be a runnable target. Used by targets 9646283Sdfr that can sit atop inftarg, such as HPUX 9746283Sdfr thread support. */ 9819370Spst 9919370Spst#ifndef CHILD_WAIT 10019370Spst 10119370Spst/* Wait for child to do something. Return pid of child, or -1 in case 10219370Spst of error; store status through argument pointer OURSTATUS. */ 10319370Spst 10498944Sobrienstatic ptid_t 10598944Sobrienchild_wait (ptid_t ptid, struct target_waitstatus *ourstatus) 10619370Spst{ 10719370Spst int save_errno; 10819370Spst int status; 10998944Sobrien char *execd_pathname = NULL; 11098944Sobrien int exit_status; 11198944Sobrien int related_pid; 11298944Sobrien int syscall_id; 11398944Sobrien enum target_waitkind kind; 11498944Sobrien int pid; 11519370Spst 11698944Sobrien do 11798944Sobrien { 11898944Sobrien set_sigint_trap (); /* Causes SIGINT to be passed on to the 11998944Sobrien attached process. */ 12098944Sobrien set_sigio_trap (); 12119370Spst 12298944Sobrien pid = ptrace_wait (inferior_ptid, &status); 12346283Sdfr 12498944Sobrien save_errno = errno; 12519370Spst 12698944Sobrien clear_sigio_trap (); 12719370Spst 12898944Sobrien clear_sigint_trap (); 12919370Spst 13098944Sobrien if (pid == -1) 13198944Sobrien { 13298944Sobrien if (save_errno == EINTR) 13398944Sobrien continue; 13446283Sdfr 13598944Sobrien fprintf_unfiltered (gdb_stderr, "Child process unexpectedly missing: %s.\n", 13698944Sobrien safe_strerror (save_errno)); 13746283Sdfr 13898944Sobrien /* Claim it exited with unknown signal. */ 13998944Sobrien ourstatus->kind = TARGET_WAITKIND_SIGNALLED; 14098944Sobrien ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN; 14198944Sobrien return pid_to_ptid (-1); 14298944Sobrien } 14346283Sdfr 14498944Sobrien /* Did it exit? 14598944Sobrien */ 14698944Sobrien if (target_has_exited (pid, status, &exit_status)) 14798944Sobrien { 14898944Sobrien /* ??rehrauer: For now, ignore this. */ 14998944Sobrien continue; 15098944Sobrien } 15146283Sdfr 15298944Sobrien if (!target_thread_alive (pid_to_ptid (pid))) 15398944Sobrien { 15498944Sobrien ourstatus->kind = TARGET_WAITKIND_SPURIOUS; 15598944Sobrien return pid_to_ptid (pid); 15698944Sobrien } 157130803Smarcel } while (pid != PIDGET (inferior_ptid)); /* Some other child died or stopped */ 15846283Sdfr 15919370Spst store_waitstatus (ourstatus, status); 16098944Sobrien return pid_to_ptid (pid); 16119370Spst} 16219370Spst#endif /* CHILD_WAIT */ 16319370Spst 16446283Sdfr#if !defined(CHILD_POST_WAIT) 16546283Sdfrvoid 16698944Sobrienchild_post_wait (ptid_t ptid, int wait_status) 16746283Sdfr{ 16846283Sdfr /* This version of Unix doesn't require a meaningful "post wait" 16946283Sdfr operation. 17098944Sobrien */ 17146283Sdfr} 17246283Sdfr#endif 17346283Sdfr 17498944Sobrien 17519370Spst#ifndef CHILD_THREAD_ALIVE 17619370Spst 17719370Spst/* Check to see if the given thread is alive. 17819370Spst 17919370Spst FIXME: Is kill() ever the right way to do this? I doubt it, but 18019370Spst for now we're going to try and be compatable with the old thread 18119370Spst code. */ 18246283Sdfrint 18398944Sobrienchild_thread_alive (ptid_t ptid) 18419370Spst{ 18598944Sobrien pid_t pid = PIDGET (ptid); 18698944Sobrien 18719370Spst return (kill (pid, 0) != -1); 18819370Spst} 18919370Spst 19019370Spst#endif 19119370Spst 192130803Smarcel/* Attach to process PID, then initialize for debugging it. */ 193130803Smarcel 19419370Spststatic void 195130803Smarcelchild_attach (char *args, int from_tty) 19619370Spst{ 19719370Spst if (!args) 19819370Spst error_no_arg ("process-id to attach"); 19919370Spst 20019370Spst#ifndef ATTACH_DETACH 20119370Spst error ("Can't attach to a process on this machine."); 20219370Spst#else 20319370Spst { 20419370Spst char *exec_file; 20519370Spst int pid; 20646283Sdfr char *dummy; 20719370Spst 20846283Sdfr dummy = args; 20946283Sdfr pid = strtol (args, &dummy, 0); 21046283Sdfr /* Some targets don't set errno on errors, grrr! */ 21146283Sdfr if ((pid == 0) && (args == dummy)) 21246283Sdfr error ("Illegal process-id: %s\n", args); 21319370Spst 21498944Sobrien if (pid == getpid ()) /* Trying to masturbate? */ 21519370Spst error ("I refuse to debug myself!"); 21619370Spst 21719370Spst if (from_tty) 21819370Spst { 21919370Spst exec_file = (char *) get_exec_file (0); 22019370Spst 221130803Smarcel if (exec_file) 22246283Sdfr printf_unfiltered ("Attaching to program: %s, %s\n", exec_file, 22398944Sobrien target_pid_to_str (pid_to_ptid (pid))); 22498944Sobrien else 225130803Smarcel printf_unfiltered ("Attaching to %s\n", 22698944Sobrien target_pid_to_str (pid_to_ptid (pid))); 22719370Spst 22819370Spst gdb_flush (gdb_stdout); 22919370Spst } 23019370Spst 231130803Smarcel attach (pid); 23246283Sdfr 23398944Sobrien inferior_ptid = pid_to_ptid (pid); 23419370Spst push_target (&child_ops); 23519370Spst } 23698944Sobrien#endif /* ATTACH_DETACH */ 23719370Spst} 23819370Spst 23946283Sdfr#if !defined(CHILD_POST_ATTACH) 24046283Sdfrvoid 24198944Sobrienchild_post_attach (int pid) 24246283Sdfr{ 24346283Sdfr /* This version of Unix doesn't require a meaningful "post attach" 24446283Sdfr operation by a debugger. */ 24546283Sdfr} 24646283Sdfr#endif 24746283Sdfr 248130803Smarcel/* Take a program previously attached to and detaches it. 249130803Smarcel The program resumes execution and will no longer stop 250130803Smarcel on signals, etc. We'd better not have left any breakpoints 251130803Smarcel in the program or it'll die when it hits one. For this 252130803Smarcel to work, it may be necessary for the process to have been 253130803Smarcel previously attached. It *might* work if the program was 254130803Smarcel started via the normal ptrace (PTRACE_TRACEME). */ 25546283Sdfr 25646283Sdfrstatic void 257130803Smarcelchild_detach (char *args, int from_tty) 25846283Sdfr{ 25919370Spst#ifdef ATTACH_DETACH 26019370Spst { 26119370Spst int siggnal = 0; 262130803Smarcel int pid = PIDGET (inferior_ptid); 26319370Spst 26419370Spst if (from_tty) 26519370Spst { 26619370Spst char *exec_file = get_exec_file (0); 26719370Spst if (exec_file == 0) 26819370Spst exec_file = ""; 269130803Smarcel printf_unfiltered ("Detaching from program: %s, %s\n", exec_file, 270130803Smarcel target_pid_to_str (pid_to_ptid (pid))); 27119370Spst gdb_flush (gdb_stdout); 27219370Spst } 27319370Spst if (args) 27419370Spst siggnal = atoi (args); 27519370Spst 276130803Smarcel detach (siggnal); 277130803Smarcel 278130803Smarcel inferior_ptid = null_ptid; 279130803Smarcel unpush_target (&child_ops); 28019370Spst } 28119370Spst#else 28219370Spst error ("This version of Unix does not support detaching a process."); 28319370Spst#endif 28419370Spst} 28519370Spst 28619370Spst/* Get ready to modify the registers array. On machines which store 28719370Spst individual registers, this doesn't need to do anything. On machines 28819370Spst which store all the registers in one fell swoop, this makes sure 28919370Spst that registers contains all the registers from the program being 29019370Spst debugged. */ 29119370Spst 29219370Spststatic void 29398944Sobrienchild_prepare_to_store (void) 29419370Spst{ 29519370Spst#ifdef CHILD_PREPARE_TO_STORE 29619370Spst CHILD_PREPARE_TO_STORE (); 29719370Spst#endif 29819370Spst} 29919370Spst 30019370Spst/* Print status information about what we're accessing. */ 30119370Spst 30219370Spststatic void 30398944Sobrienchild_files_info (struct target_ops *ignore) 30419370Spst{ 30519370Spst printf_unfiltered ("\tUsing the running image of %s %s.\n", 30698944Sobrien attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid)); 30719370Spst} 30819370Spst 30919370Spststatic void 31098944Sobrienchild_open (char *arg, int from_tty) 31119370Spst{ 31219370Spst error ("Use the \"run\" command to start a Unix child process."); 31319370Spst} 31419370Spst 31519370Spst/* Stub function which causes the inferior that runs it, to be ptrace-able 31619370Spst by its parent process. */ 31719370Spst 31819370Spststatic void 31998944Sobrienptrace_me (void) 32019370Spst{ 32119370Spst /* "Trace me, Dr. Memory!" */ 32219370Spst call_ptrace (0, 0, (PTRACE_ARG3_TYPE) 0, 0); 32319370Spst} 32419370Spst 32519370Spst/* Stub function which causes the GDB that runs it, to start ptrace-ing 32619370Spst the child process. */ 32719370Spst 32898944Sobrienstatic void 32998944Sobrienptrace_him (int pid) 33019370Spst{ 33119370Spst push_target (&child_ops); 33219370Spst 33346283Sdfr /* On some targets, there must be some explicit synchronization 33446283Sdfr between the parent and child processes after the debugger 33546283Sdfr forks, and before the child execs the debuggee program. This 33646283Sdfr call basically gives permission for the child to exec. 33798944Sobrien */ 33846283Sdfr 33946283Sdfr target_acknowledge_created_inferior (pid); 34046283Sdfr 34146283Sdfr /* START_INFERIOR_TRAPS_EXPECTED is defined in inferior.h, 34246283Sdfr * and will be 1 or 2 depending on whether we're starting 34346283Sdfr * without or with a shell. 34446283Sdfr */ 34519370Spst startup_inferior (START_INFERIOR_TRAPS_EXPECTED); 34646283Sdfr 34746283Sdfr /* On some targets, there must be some explicit actions taken after 34846283Sdfr the inferior has been started up. 34998944Sobrien */ 35098944Sobrien target_post_startup_inferior (pid_to_ptid (pid)); 35119370Spst} 35219370Spst 35398944Sobrien/* Start an inferior Unix child process and sets inferior_ptid to its pid. 35419370Spst EXEC_FILE is the file to run. 35519370Spst ALLARGS is a string containing the arguments to the program. 35619370Spst ENV is the environment vector to pass. Errors reported with error(). */ 35719370Spst 35819370Spststatic void 35998944Sobrienchild_create_inferior (char *exec_file, char *allargs, char **env) 36019370Spst{ 36146283Sdfr#ifdef HPUXHPPA 36246283Sdfr fork_inferior (exec_file, allargs, env, ptrace_me, ptrace_him, pre_fork_inferior, NULL); 36346283Sdfr#else 36498944Sobrien fork_inferior (exec_file, allargs, env, ptrace_me, ptrace_him, NULL, NULL); 36546283Sdfr#endif 36619370Spst /* We are at the first instruction we care about. */ 36719370Spst /* Pedal to the metal... */ 36819370Spst proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0); 36919370Spst} 37019370Spst 37146283Sdfr#if !defined(CHILD_POST_STARTUP_INFERIOR) 37246283Sdfrvoid 37398944Sobrienchild_post_startup_inferior (ptid_t ptid) 37446283Sdfr{ 37546283Sdfr /* This version of Unix doesn't require a meaningful "post startup inferior" 37646283Sdfr operation by a debugger. 37798944Sobrien */ 37846283Sdfr} 37946283Sdfr#endif 38046283Sdfr 38146283Sdfr#if !defined(CHILD_ACKNOWLEDGE_CREATED_INFERIOR) 38246283Sdfrvoid 38398944Sobrienchild_acknowledge_created_inferior (int pid) 38446283Sdfr{ 38546283Sdfr /* This version of Unix doesn't require a meaningful "acknowledge created inferior" 38646283Sdfr operation by a debugger. 38798944Sobrien */ 38846283Sdfr} 38946283Sdfr#endif 39046283Sdfr 39146283Sdfr 39246283Sdfr#if !defined(CHILD_INSERT_FORK_CATCHPOINT) 39346283Sdfrint 39498944Sobrienchild_insert_fork_catchpoint (int pid) 39546283Sdfr{ 39646283Sdfr /* This version of Unix doesn't support notification of fork events. */ 39746283Sdfr return 0; 39846283Sdfr} 39946283Sdfr#endif 40046283Sdfr 40146283Sdfr#if !defined(CHILD_REMOVE_FORK_CATCHPOINT) 40246283Sdfrint 40398944Sobrienchild_remove_fork_catchpoint (int pid) 40446283Sdfr{ 40546283Sdfr /* This version of Unix doesn't support notification of fork events. */ 40646283Sdfr return 0; 40746283Sdfr} 40846283Sdfr#endif 40946283Sdfr 41046283Sdfr#if !defined(CHILD_INSERT_VFORK_CATCHPOINT) 41146283Sdfrint 41298944Sobrienchild_insert_vfork_catchpoint (int pid) 41346283Sdfr{ 41446283Sdfr /* This version of Unix doesn't support notification of vfork events. */ 41546283Sdfr return 0; 41646283Sdfr} 41746283Sdfr#endif 41846283Sdfr 41946283Sdfr#if !defined(CHILD_REMOVE_VFORK_CATCHPOINT) 42046283Sdfrint 42198944Sobrienchild_remove_vfork_catchpoint (int pid) 42246283Sdfr{ 42346283Sdfr /* This version of Unix doesn't support notification of vfork events. */ 42446283Sdfr return 0; 42546283Sdfr} 42646283Sdfr#endif 42746283Sdfr 428130803Smarcel#if !defined(CHILD_FOLLOW_FORK) 42946283Sdfrint 430130803Smarcelchild_follow_fork (int follow_child) 43146283Sdfr{ 432130803Smarcel /* This version of Unix doesn't support following fork or vfork events. */ 43346283Sdfr return 0; 43446283Sdfr} 43546283Sdfr#endif 43646283Sdfr 43746283Sdfr#if !defined(CHILD_INSERT_EXEC_CATCHPOINT) 43846283Sdfrint 43998944Sobrienchild_insert_exec_catchpoint (int pid) 44046283Sdfr{ 44146283Sdfr /* This version of Unix doesn't support notification of exec events. */ 44246283Sdfr return 0; 44346283Sdfr} 44446283Sdfr#endif 44546283Sdfr 44646283Sdfr#if !defined(CHILD_REMOVE_EXEC_CATCHPOINT) 44746283Sdfrint 44898944Sobrienchild_remove_exec_catchpoint (int pid) 44946283Sdfr{ 45046283Sdfr /* This version of Unix doesn't support notification of exec events. */ 45146283Sdfr return 0; 45246283Sdfr} 45346283Sdfr#endif 45446283Sdfr 45546283Sdfr#if !defined(CHILD_REPORTED_EXEC_EVENTS_PER_EXEC_CALL) 45646283Sdfrint 45798944Sobrienchild_reported_exec_events_per_exec_call (void) 45846283Sdfr{ 45946283Sdfr /* This version of Unix doesn't support notification of exec events. 46098944Sobrien */ 46146283Sdfr return 1; 46246283Sdfr} 46346283Sdfr#endif 46446283Sdfr 46546283Sdfr#if !defined(CHILD_HAS_EXITED) 46646283Sdfrint 46798944Sobrienchild_has_exited (int pid, int wait_status, int *exit_status) 46846283Sdfr{ 46946283Sdfr if (WIFEXITED (wait_status)) 47046283Sdfr { 47146283Sdfr *exit_status = WEXITSTATUS (wait_status); 47246283Sdfr return 1; 47346283Sdfr } 47446283Sdfr 47546283Sdfr if (WIFSIGNALED (wait_status)) 47646283Sdfr { 47798944Sobrien *exit_status = 0; /* ?? Don't know what else to say here. */ 47846283Sdfr return 1; 47946283Sdfr } 48046283Sdfr 48146283Sdfr /* ?? Do we really need to consult the event state, too? Assume the 48298944Sobrien wait_state alone suffices. 48346283Sdfr */ 48446283Sdfr return 0; 48546283Sdfr} 48646283Sdfr#endif 48746283Sdfr 48846283Sdfr 48919370Spststatic void 49098944Sobrienchild_mourn_inferior (void) 49119370Spst{ 49219370Spst unpush_target (&child_ops); 49319370Spst generic_mourn_inferior (); 49419370Spst} 49519370Spst 49619370Spststatic int 49798944Sobrienchild_can_run (void) 49819370Spst{ 49946283Sdfr /* This variable is controlled by modules that sit atop inftarg that may layer 50046283Sdfr their own process structure atop that provided here. hpux-thread.c does 50146283Sdfr this because of the Hpux user-mode level thread model. */ 50246283Sdfr 50346283Sdfr return !child_suppress_run; 50419370Spst} 50519370Spst 50619370Spst/* Send a SIGINT to the process group. This acts just like the user typed a 50719370Spst ^C on the controlling terminal. 50819370Spst 50919370Spst XXX - This may not be correct for all systems. Some may want to use 51019370Spst killpg() instead of kill (-pgrp). */ 51119370Spst 51246283Sdfrstatic void 51398944Sobrienchild_stop (void) 51419370Spst{ 51519370Spst kill (-inferior_process_group, SIGINT); 51619370Spst} 51746283Sdfr 51846283Sdfr#if !defined(CHILD_ENABLE_EXCEPTION_CALLBACK) 51946283Sdfrstruct symtab_and_line * 52098944Sobrienchild_enable_exception_callback (enum exception_event_kind kind, int enable) 52146283Sdfr{ 52246283Sdfr return (struct symtab_and_line *) NULL; 52346283Sdfr} 52446283Sdfr#endif 52546283Sdfr 52646283Sdfr#if !defined(CHILD_GET_CURRENT_EXCEPTION_EVENT) 52746283Sdfrstruct exception_event_record * 52898944Sobrienchild_get_current_exception_event (void) 52946283Sdfr{ 53046283Sdfr return (struct exception_event_record *) NULL; 53146283Sdfr} 53246283Sdfr#endif 53346283Sdfr 53446283Sdfr 53546283Sdfr#if !defined(CHILD_PID_TO_EXEC_FILE) 53646283Sdfrchar * 53798944Sobrienchild_pid_to_exec_file (int pid) 53846283Sdfr{ 53946283Sdfr /* This version of Unix doesn't support translation of a process ID 54046283Sdfr to the filename of the executable file. 54198944Sobrien */ 54246283Sdfr return NULL; 54346283Sdfr} 54446283Sdfr#endif 54546283Sdfr 54646283Sdfrchar * 54798944Sobrienchild_core_file_to_sym_file (char *core) 54846283Sdfr{ 54946283Sdfr /* The target stratum for a running executable need not support 55046283Sdfr this operation. 55198944Sobrien */ 55246283Sdfr return NULL; 55346283Sdfr} 55446283Sdfr 555130803Smarcel/* Perform a partial transfer to/from the specified object. For 556130803Smarcel memory transfers, fall back to the old memory xfer functions. */ 557130803Smarcel 558130803Smarcelstatic LONGEST 559130803Smarcelchild_xfer_partial (struct target_ops *ops, enum target_object object, 560130803Smarcel const char *annex, void *readbuf, 561130803Smarcel const void *writebuf, ULONGEST offset, LONGEST len) 562130803Smarcel{ 563130803Smarcel switch (object) 564130803Smarcel { 565130803Smarcel case TARGET_OBJECT_MEMORY: 566130803Smarcel if (readbuf) 567130803Smarcel return child_xfer_memory (offset, readbuf, len, 0/*write*/, 568130803Smarcel NULL, ops); 569130803Smarcel if (writebuf) 570130803Smarcel return child_xfer_memory (offset, readbuf, len, 1/*write*/, 571130803Smarcel NULL, ops); 572130803Smarcel return -1; 573130803Smarcel 574130803Smarcel case TARGET_OBJECT_UNWIND_TABLE: 575130803Smarcel#ifndef NATIVE_XFER_UNWIND_TABLE 576130803Smarcel#define NATIVE_XFER_UNWIND_TABLE(OPS,OBJECT,ANNEX,WRITEBUF,READBUF,OFFSET,LEN) (-1) 577130803Smarcel#endif 578130803Smarcel return NATIVE_XFER_UNWIND_TABLE (ops, object, annex, readbuf, writebuf, 579130803Smarcel offset, len); 580130803Smarcel 581130803Smarcel case TARGET_OBJECT_AUXV: 582130803Smarcel#ifndef NATIVE_XFER_AUXV 583130803Smarcel#define NATIVE_XFER_AUXV(OPS,OBJECT,ANNEX,WRITEBUF,READBUF,OFFSET,LEN) (-1) 584130803Smarcel#endif 585130803Smarcel return NATIVE_XFER_AUXV (ops, object, annex, readbuf, writebuf, 586130803Smarcel offset, len); 587130803Smarcel 588130803Smarcel case TARGET_OBJECT_WCOOKIE: 589130803Smarcel#ifndef NATIVE_XFER_WCOOKIE 590130803Smarcel#define NATIVE_XFER_WCOOKIE(OPS,OBJECT,ANNEX,WRITEBUF,READBUF,OFFSET,LEN) (-1) 591130803Smarcel#endif 592130803Smarcel return NATIVE_XFER_WCOOKIE (ops, object, annex, readbuf, writebuf, 593130803Smarcel offset, len); 594130803Smarcel 595131082Smarcel case TARGET_OBJECT_DIRTY: 596132685Smarcel#ifndef NATIVE_XFER_DIRTY 597132685Smarcel#define NATIVE_XFER_DIRTY(OPS,OBJECT,ANNEX,WRITEBUF,READBUF,OFFSET,LEN) (-1) 598131082Smarcel#endif 599132685Smarcel return NATIVE_XFER_DIRTY (ops, object, annex, readbuf, writebuf, 600131082Smarcel offset, len); 601131082Smarcel 602130803Smarcel default: 603130803Smarcel return -1; 604130803Smarcel } 605130803Smarcel} 606130803Smarcel 60798944Sobrien#if !defined(CHILD_PID_TO_STR) 60898944Sobrienchar * 60998944Sobrienchild_pid_to_str (ptid_t ptid) 61098944Sobrien{ 61198944Sobrien return normal_pid_to_str (ptid); 61298944Sobrien} 61398944Sobrien#endif 61446283Sdfr 61546283Sdfrstatic void 61698944Sobrieninit_child_ops (void) 61746283Sdfr{ 61846283Sdfr child_ops.to_shortname = "child"; 61946283Sdfr child_ops.to_longname = "Unix child process"; 62046283Sdfr child_ops.to_doc = "Unix child process (started by the \"run\" command)."; 62146283Sdfr child_ops.to_open = child_open; 62246283Sdfr child_ops.to_attach = child_attach; 62346283Sdfr child_ops.to_post_attach = child_post_attach; 62446283Sdfr child_ops.to_detach = child_detach; 62546283Sdfr child_ops.to_resume = child_resume; 62646283Sdfr child_ops.to_wait = child_wait; 62746283Sdfr child_ops.to_post_wait = child_post_wait; 62846283Sdfr child_ops.to_fetch_registers = fetch_inferior_registers; 62946283Sdfr child_ops.to_store_registers = store_inferior_registers; 63046283Sdfr child_ops.to_prepare_to_store = child_prepare_to_store; 63146283Sdfr child_ops.to_xfer_memory = child_xfer_memory; 632130803Smarcel child_ops.to_xfer_partial = child_xfer_partial; 63346283Sdfr child_ops.to_files_info = child_files_info; 63446283Sdfr child_ops.to_insert_breakpoint = memory_insert_breakpoint; 63546283Sdfr child_ops.to_remove_breakpoint = memory_remove_breakpoint; 63646283Sdfr child_ops.to_terminal_init = terminal_init_inferior; 63746283Sdfr child_ops.to_terminal_inferior = terminal_inferior; 63846283Sdfr child_ops.to_terminal_ours_for_output = terminal_ours_for_output; 639130803Smarcel child_ops.to_terminal_save_ours = terminal_save_ours; 64046283Sdfr child_ops.to_terminal_ours = terminal_ours; 64146283Sdfr child_ops.to_terminal_info = child_terminal_info; 64246283Sdfr child_ops.to_kill = kill_inferior; 64346283Sdfr child_ops.to_create_inferior = child_create_inferior; 64446283Sdfr child_ops.to_post_startup_inferior = child_post_startup_inferior; 64546283Sdfr child_ops.to_acknowledge_created_inferior = child_acknowledge_created_inferior; 64646283Sdfr child_ops.to_insert_fork_catchpoint = child_insert_fork_catchpoint; 64746283Sdfr child_ops.to_remove_fork_catchpoint = child_remove_fork_catchpoint; 64846283Sdfr child_ops.to_insert_vfork_catchpoint = child_insert_vfork_catchpoint; 64946283Sdfr child_ops.to_remove_vfork_catchpoint = child_remove_vfork_catchpoint; 650130803Smarcel child_ops.to_follow_fork = child_follow_fork; 65146283Sdfr child_ops.to_insert_exec_catchpoint = child_insert_exec_catchpoint; 65246283Sdfr child_ops.to_remove_exec_catchpoint = child_remove_exec_catchpoint; 65346283Sdfr child_ops.to_reported_exec_events_per_exec_call = child_reported_exec_events_per_exec_call; 65446283Sdfr child_ops.to_has_exited = child_has_exited; 65546283Sdfr child_ops.to_mourn_inferior = child_mourn_inferior; 65646283Sdfr child_ops.to_can_run = child_can_run; 65746283Sdfr child_ops.to_thread_alive = child_thread_alive; 65898944Sobrien child_ops.to_pid_to_str = child_pid_to_str; 65946283Sdfr child_ops.to_stop = child_stop; 66046283Sdfr child_ops.to_enable_exception_callback = child_enable_exception_callback; 66146283Sdfr child_ops.to_get_current_exception_event = child_get_current_exception_event; 66246283Sdfr child_ops.to_pid_to_exec_file = child_pid_to_exec_file; 66346283Sdfr child_ops.to_stratum = process_stratum; 66446283Sdfr child_ops.to_has_all_memory = 1; 66546283Sdfr child_ops.to_has_memory = 1; 66646283Sdfr child_ops.to_has_stack = 1; 66746283Sdfr child_ops.to_has_registers = 1; 66846283Sdfr child_ops.to_has_execution = 1; 66946283Sdfr child_ops.to_magic = OPS_MAGIC; 67046283Sdfr} 67119370Spst 67298944Sobrien/* Take over the 'find_mapped_memory' vector from inftarg.c. */ 673130803Smarcelextern void 674130803Smarcelinftarg_set_find_memory_regions (int (*func) (int (*) (CORE_ADDR, 675130803Smarcel unsigned long, 676130803Smarcel int, int, int, 67798944Sobrien void *), 67898944Sobrien void *)) 67998944Sobrien{ 68098944Sobrien child_ops.to_find_memory_regions = func; 68198944Sobrien} 68298944Sobrien 68398944Sobrien/* Take over the 'make_corefile_notes' vector from inftarg.c. */ 684130803Smarcelextern void 68598944Sobrieninftarg_set_make_corefile_notes (char * (*func) (bfd *, int *)) 68698944Sobrien{ 68798944Sobrien child_ops.to_make_corefile_notes = func; 68898944Sobrien} 68998944Sobrien 69019370Spstvoid 69198944Sobrien_initialize_inftarg (void) 69219370Spst{ 69319370Spst#ifdef HAVE_OPTIONAL_PROC_FS 69419370Spst char procname[32]; 69519370Spst int fd; 69619370Spst 69719370Spst /* If we have an optional /proc filesystem (e.g. under OSF/1), 69819370Spst don't add ptrace support if we can access the running GDB via /proc. */ 69919370Spst#ifndef PROC_NAME_FMT 70019370Spst#define PROC_NAME_FMT "/proc/%05d" 70119370Spst#endif 70219370Spst sprintf (procname, PROC_NAME_FMT, getpid ()); 703130803Smarcel fd = open (procname, O_RDONLY); 704130803Smarcel if (fd >= 0) 70519370Spst { 70619370Spst close (fd); 70719370Spst return; 70819370Spst } 70919370Spst#endif 71019370Spst 71146283Sdfr init_child_ops (); 71219370Spst add_target (&child_ops); 71319370Spst} 714