* win32-nat.c (mappings): Add ppc registers.
[platform/upstream/binutils.git] / gdb / win32-nat.c
1 /* Target-vector operations for controlling win32 child processes, for GDB.
2    Copyright 1995, 1996
3    Free Software Foundation, Inc.
4
5    Contributed by Cygnus Support.
6    This file is part of GDB.
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without eve nthe implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
21
22 /* by Steve Chamberlain, sac@cygnus.com */
23
24 #include "defs.h"
25 #include "frame.h"              /* required by inferior.h */
26 #include "inferior.h"
27 #include "target.h"
28 #include "wait.h"
29 #include "gdbcore.h"
30 #include "command.h"
31 #include <signal.h>
32 #include <sys/types.h>
33 #include <fcntl.h>
34 #include <windows.h>
35 #include "buildsym.h"
36 #include "gdb_string.h"
37 #include "thread.h"
38 #include "gdbcmd.h"
39 #include <sys/param.h>
40 #define CHECK(x) check (x, __FILE__,__LINE__)
41 #define DEBUG(x) if (remote_debug) printf x
42
43
44 /* Forward declaration */
45 extern struct target_ops child_ops;
46
47 /* The most recently read context. Inspect ContextFlags to see what 
48    bits are valid. */
49
50 static CONTEXT context;
51
52 /* The process and thread handles for the above context. */
53
54 static HANDLE current_process;
55 static HANDLE current_thread;
56 static int current_process_id;
57 static int current_thread_id;
58
59 /* Counts of things. */
60 static int exception_count = 0;
61 static int event_count = 0;
62
63 /* User options. */
64 static int new_console = 0;
65 static int new_group = 0;
66
67 /* This vector maps GDB's idea of a register's number into an address
68    in the win32 exception context vector. 
69
70    It also contains the bit mask needed to load the register in question.  
71
72    One day we could read a reg, we could inspect the context we
73    already have loaded, if it doesn't have the bit set that we need,
74    we read that set of registers in using GetThreadContext.  If the
75    context already contains what we need, we just unpack it. Then to
76    write a register, first we have to ensure that the context contains
77    the other regs of the group, and then we copy the info in and set
78    out bit. */
79
80 struct regmappings
81   {
82     char *incontext;
83     int mask;
84   };
85
86
87 static const struct regmappings  mappings[] =
88 {
89 #ifdef __PPC__
90   {(char *) &context.Gpr0, CONTEXT_INTEGER},
91   {(char *) &context.Gpr1, CONTEXT_INTEGER},
92   {(char *) &context.Gpr2, CONTEXT_INTEGER},
93   {(char *) &context.Gpr3, CONTEXT_INTEGER},
94   {(char *) &context.Gpr4, CONTEXT_INTEGER},
95   {(char *) &context.Gpr5, CONTEXT_INTEGER},
96   {(char *) &context.Gpr6, CONTEXT_INTEGER},
97   {(char *) &context.Gpr7, CONTEXT_INTEGER},
98
99   {(char *) &context.Gpr8, CONTEXT_INTEGER},
100   {(char *) &context.Gpr9, CONTEXT_INTEGER},
101   {(char *) &context.Gpr10, CONTEXT_INTEGER},
102   {(char *) &context.Gpr11, CONTEXT_INTEGER},
103   {(char *) &context.Gpr12, CONTEXT_INTEGER},
104   {(char *) &context.Gpr13, CONTEXT_INTEGER},
105   {(char *) &context.Gpr14, CONTEXT_INTEGER},
106   {(char *) &context.Gpr15, CONTEXT_INTEGER},
107
108   {(char *) &context.Gpr16, CONTEXT_INTEGER},
109   {(char *) &context.Gpr17, CONTEXT_INTEGER},
110   {(char *) &context.Gpr18, CONTEXT_INTEGER},
111   {(char *) &context.Gpr19, CONTEXT_INTEGER},
112   {(char *) &context.Gpr20, CONTEXT_INTEGER},
113   {(char *) &context.Gpr21, CONTEXT_INTEGER},
114   {(char *) &context.Gpr22, CONTEXT_INTEGER},
115   {(char *) &context.Gpr23, CONTEXT_INTEGER},
116
117   {(char *) &context.Gpr24, CONTEXT_INTEGER},
118   {(char *) &context.Gpr25, CONTEXT_INTEGER},
119   {(char *) &context.Gpr26, CONTEXT_INTEGER},
120   {(char *) &context.Gpr27, CONTEXT_INTEGER},
121   {(char *) &context.Gpr28, CONTEXT_INTEGER},
122   {(char *) &context.Gpr29, CONTEXT_INTEGER},
123   {(char *) &context.Gpr30, CONTEXT_INTEGER},
124   {(char *) &context.Gpr31, CONTEXT_INTEGER},
125
126   {(char *) &context.Fpr0, CONTEXT_FLOATING_POINT},
127   {(char *) &context.Fpr1, CONTEXT_FLOATING_POINT},
128   {(char *) &context.Fpr2, CONTEXT_FLOATING_POINT},
129   {(char *) &context.Fpr3, CONTEXT_FLOATING_POINT},
130   {(char *) &context.Fpr4, CONTEXT_FLOATING_POINT},
131   {(char *) &context.Fpr5, CONTEXT_FLOATING_POINT},
132   {(char *) &context.Fpr6, CONTEXT_FLOATING_POINT},
133   {(char *) &context.Fpr7, CONTEXT_FLOATING_POINT},
134
135   {(char *) &context.Fpr8, CONTEXT_FLOATING_POINT},
136   {(char *) &context.Fpr9, CONTEXT_FLOATING_POINT},
137   {(char *) &context.Fpr10, CONTEXT_FLOATING_POINT},
138   {(char *) &context.Fpr11, CONTEXT_FLOATING_POINT},
139   {(char *) &context.Fpr12, CONTEXT_FLOATING_POINT},
140   {(char *) &context.Fpr13, CONTEXT_FLOATING_POINT},
141   {(char *) &context.Fpr14, CONTEXT_FLOATING_POINT},
142   {(char *) &context.Fpr15, CONTEXT_FLOATING_POINT},
143
144   {(char *) &context.Fpr16, CONTEXT_FLOATING_POINT},
145   {(char *) &context.Fpr17, CONTEXT_FLOATING_POINT},
146   {(char *) &context.Fpr18, CONTEXT_FLOATING_POINT},
147   {(char *) &context.Fpr19, CONTEXT_FLOATING_POINT},
148   {(char *) &context.Fpr20, CONTEXT_FLOATING_POINT},
149   {(char *) &context.Fpr21, CONTEXT_FLOATING_POINT},
150   {(char *) &context.Fpr22, CONTEXT_FLOATING_POINT},
151   {(char *) &context.Fpr23, CONTEXT_FLOATING_POINT},
152
153   {(char *) &context.Fpr24, CONTEXT_FLOATING_POINT},
154   {(char *) &context.Fpr25, CONTEXT_FLOATING_POINT},
155   {(char *) &context.Fpr26, CONTEXT_FLOATING_POINT},
156   {(char *) &context.Fpr27, CONTEXT_FLOATING_POINT},
157   {(char *) &context.Fpr28, CONTEXT_FLOATING_POINT},
158   {(char *) &context.Fpr29, CONTEXT_FLOATING_POINT},
159   {(char *) &context.Fpr30, CONTEXT_FLOATING_POINT},
160   {(char *) &context.Fpr31, CONTEXT_FLOATING_POINT},
161
162
163   {(char *) &context.Iar, CONTEXT_CONTROL},
164   {(char *) &context.Msr, CONTEXT_CONTROL},
165   {(char *) &context.Cr,  CONTEXT_INTEGER},
166   {(char *) &context.Lr,  CONTEXT_CONTROL},
167   {(char *) &context.Ctr, CONTEXT_CONTROL},
168
169   {(char *) &context.Xer, CONTEXT_INTEGER},
170   {0,0}, /* MQ, but there isn't one */
171 #else
172   {(char *) &context.Eax, CONTEXT_INTEGER},
173   {(char *) &context.Ecx, CONTEXT_INTEGER},
174   {(char *) &context.Edx, CONTEXT_INTEGER},
175   {(char *) &context.Ebx, CONTEXT_INTEGER},
176   {(char *) &context.Esp, CONTEXT_CONTROL},
177   {(char *) &context.Ebp, CONTEXT_CONTROL},
178   {(char *) &context.Esi, CONTEXT_INTEGER},
179   {(char *) &context.Edi, CONTEXT_INTEGER},
180   {(char *) &context.Eip, CONTEXT_CONTROL},
181   {(char *) &context.EFlags, CONTEXT_CONTROL},
182   {(char *) &context.SegCs, CONTEXT_SEGMENTS},
183   {(char *) &context.SegSs, CONTEXT_SEGMENTS},
184   {(char *) &context.SegDs, CONTEXT_SEGMENTS},
185   {(char *) &context.SegEs, CONTEXT_SEGMENTS},
186   {(char *) &context.SegFs, CONTEXT_SEGMENTS},
187   {(char *) &context.SegGs, CONTEXT_SEGMENTS},
188   {&context.FloatSave.RegisterArea[0 * 10], CONTEXT_FLOATING_POINT},
189   {&context.FloatSave.RegisterArea[1 * 10], CONTEXT_FLOATING_POINT},
190   {&context.FloatSave.RegisterArea[2 * 10], CONTEXT_FLOATING_POINT},
191   {&context.FloatSave.RegisterArea[3 * 10], CONTEXT_FLOATING_POINT},
192   {&context.FloatSave.RegisterArea[4 * 10], CONTEXT_FLOATING_POINT},
193   {&context.FloatSave.RegisterArea[5 * 10], CONTEXT_FLOATING_POINT},
194   {&context.FloatSave.RegisterArea[6 * 10], CONTEXT_FLOATING_POINT},
195   {&context.FloatSave.RegisterArea[7 * 10], CONTEXT_FLOATING_POINT},
196 #endif
197 };
198
199
200 /* This vector maps the target's idea of an exception (extracted
201    from the DEBUG_EVENT structure) to GDB's idea. */
202
203 struct xlate_exception
204   {
205     int them;
206     enum target_signal us;
207   };
208
209
210 static const struct xlate_exception
211   xlate[] =
212 {
213   {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV},
214   {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV},
215   {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP},
216   {DBG_CONTROL_C, TARGET_SIGNAL_INT},
217   {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP},
218   {-1, -1}};
219
220
221 static void 
222 check (BOOL ok, const char *file, int line)
223 {
224   if (!ok)
225     printf_filtered ("error return %s:%d was %d\n", file, line, GetLastError ());
226 }
227
228 static void
229 child_fetch_inferior_registers (int r)
230 {
231   if (r < 0)
232     {
233       for (r = 0; r < NUM_REGS; r++)
234         child_fetch_inferior_registers (r);
235     }
236   else
237     {
238       supply_register (r, mappings[r].incontext);
239     }
240 }
241
242 static void
243 child_store_inferior_registers (int r)
244 {
245   if (r < 0)
246     {
247       for (r = 0; r < NUM_REGS; r++)
248         child_store_inferior_registers (r);
249     }
250   else
251     {
252       read_register_gen (r, mappings[r].incontext);
253     }
254 }
255
256
257 /* Wait for child to do something.  Return pid of child, or -1 in case
258    of error; store status through argument pointer OURSTATUS.  */
259
260
261 static int
262 handle_load_dll (char *eventp)
263 {
264   DEBUG_EVENT * event = (DEBUG_EVENT *)eventp;
265   DWORD dll_name_ptr;
266   DWORD done;
267
268   ReadProcessMemory (current_process,
269                      (DWORD) event->u.LoadDll.lpImageName,
270                      (char *) &dll_name_ptr,
271                      sizeof (dll_name_ptr), &done);
272
273   /* See if we could read the address of a string, and that the 
274      address isn't null. */
275
276   if (done == sizeof (dll_name_ptr) && dll_name_ptr)
277     {
278       char *dll_name;
279       int size = event->u.LoadDll.fUnicode ? sizeof (WCHAR) : sizeof (char);
280       int len = 0;
281       char b[2];
282       do
283         {
284           ReadProcessMemory (current_process,
285                              dll_name_ptr + len * size,
286                              &b,
287                              size,
288                              &done);
289           len++;
290         }
291       while ((b[0] != 0 || b[size - 1] != 0) && done == size);
292
293
294       dll_name = alloca (len);
295
296       if (event->u.LoadDll.fUnicode)
297         {
298           WCHAR *unicode_dll_name = (WCHAR *) alloca (len * sizeof (WCHAR));
299           ReadProcessMemory (current_process,
300                              dll_name_ptr,
301                              unicode_dll_name,
302                              len * sizeof (WCHAR),
303                              &done);
304
305           WideCharToMultiByte (CP_ACP, 0,
306                                unicode_dll_name, len,
307                                dll_name, len, 0, 0);
308         }
309       else
310         {
311           ReadProcessMemory (current_process,
312                              dll_name_ptr,
313                              dll_name,
314                              len,
315                              &done);
316         }
317
318       /* FIXME!! It would be nice to define one symbol which pointed to the 
319          front of the dll if we can't find any symbols. */
320
321       context.ContextFlags = CONTEXT_FULL;
322       GetThreadContext (current_thread, &context);
323
324       /* The symbols in a dll are offset by 0x1000, which is the
325          the offset from 0 of the first byte in an image - because
326          of the file header and the section alignment. 
327          
328          FIXME: Is this the real reason that we need the 0x1000 ? */
329
330
331       symbol_file_add (dll_name, 0,
332                        (int) event->u.LoadDll.lpBaseOfDll + 0x1000, 0, 0, 0);
333
334       /* We strip off the path of the dll for tidiness. */
335       if (strrchr (dll_name, '\\'))
336         dll_name = strrchr (dll_name, '\\') + 1;
337
338       printf_unfiltered ("%x:%s\n", event->u.LoadDll.lpBaseOfDll, dll_name);
339     }
340   return 1;
341 }
342
343
344 static void
345 handle_exception (DEBUG_EVENT * event, struct target_waitstatus *ourstatus)
346 {
347   int i;
348   int done = 0;
349   ourstatus->kind = TARGET_WAITKIND_STOPPED;
350
351   for (i = 0; !done && xlate[i].us > 0; i++)
352     {
353       if (xlate[i].them == event->u.Exception.ExceptionRecord.ExceptionCode)
354         {
355           ourstatus->value.sig = xlate[i].us;
356           done = 1;
357           break;
358         }
359     }
360
361   if (!done)
362     {
363       printf_unfiltered ("Want to know about exception code %08x\n",
364                          event->u.Exception.ExceptionRecord.ExceptionCode);
365       ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
366     }
367   context.ContextFlags = CONTEXT_FULL;
368   GetThreadContext (current_thread, &context);
369   exception_count++;
370 }
371
372 static int
373 child_wait (int pid, struct target_waitstatus *ourstatus)
374 {
375   /* We loop when we get a non-standard exception rather than return
376      with a SPURIOUS because resume can try and step or modify things,
377      which needs a current_thread.  But some of these exceptions mark
378      the birth or death of threads, which mean that the current thread
379      isn't necessarily what you think it is. */
380
381   while (1)
382     {
383       DEBUG_EVENT event;
384       BOOL t = WaitForDebugEvent (&event, INFINITE);
385
386       DEBUG (("%d = WaitForDebugEvent() code=%d pid=%d tid=%d)\n",
387               t,
388               event.dwDebugEventCode,
389               event.dwProcessId,
390               event.dwThreadId));
391
392       event_count++;
393
394       current_thread_id = event.dwThreadId;
395       current_process_id = event.dwProcessId;
396
397       switch (event.dwDebugEventCode)
398         {
399         case CREATE_THREAD_DEBUG_EVENT:
400         case EXIT_THREAD_DEBUG_EVENT:
401         case CREATE_PROCESS_DEBUG_EVENT:
402           break;
403
404         case EXIT_PROCESS_DEBUG_EVENT:
405           ourstatus->kind = TARGET_WAITKIND_EXITED;
406           ourstatus->value.integer = event.u.ExitProcess.dwExitCode;
407           CloseHandle (current_process);
408           CloseHandle (current_thread);
409           return current_process_id;
410           break;
411
412         case LOAD_DLL_DEBUG_EVENT:
413          catch_errors (handle_load_dll,
414                       (char*) &event,
415                       "\n[failed reading symbols from DLL]\n",
416                       RETURN_MASK_ALL);
417          registers_changed();          /* mark all regs invalid */
418           break;
419         case EXCEPTION_DEBUG_EVENT:
420           handle_exception (&event, ourstatus);
421           return current_process_id;
422         default:
423           printf_unfiltered ("waitfor it %d %d %d %d\n", t,
424                              event.dwDebugEventCode,
425                              event.dwProcessId,
426                              event.dwThreadId);
427           break;
428         }
429       CHECK (ContinueDebugEvent (current_process_id,
430                                  current_thread_id,
431                                  DBG_CONTINUE));
432     }
433 }
434
435
436
437
438 /* Attach to process PID, then initialize for debugging it.  */
439
440 static void
441 child_attach (args, from_tty)
442      char *args;
443      int from_tty;
444 {
445   BOOL ok;
446
447   if (!args)
448     error_no_arg ("process-id to attach");
449
450   current_process_id = strtoul (args, 0, 0);
451
452   ok = DebugActiveProcess (current_process_id);
453
454   if (!ok)
455     error ("Can't attach to process.");
456
457
458   exception_count = 0;
459   event_count = 0;
460
461   if (from_tty)
462     {
463       char *exec_file = (char *) get_exec_file (0);
464
465       if (exec_file)
466         printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
467                            target_pid_to_str (current_process_id));
468       else
469         printf_unfiltered ("Attaching to %s\n",
470                            target_pid_to_str (current_process_id));
471
472       gdb_flush (gdb_stdout);
473     }
474
475   inferior_pid = current_process_id;
476   push_target (&child_ops);
477 }
478
479
480 static void
481 child_detach (args, from_tty)
482      char *args;
483      int from_tty;
484 {
485   if (from_tty)
486     {
487       char *exec_file = get_exec_file (0);
488       if (exec_file == 0)
489         exec_file = "";
490       printf_unfiltered ("Detaching from program: %s %s\n", exec_file,
491                          target_pid_to_str (inferior_pid));
492       gdb_flush (gdb_stdout);
493     }
494   inferior_pid = 0;
495   unpush_target (&child_ops);
496 }
497
498
499 /* Print status information about what we're accessing.  */
500
501 static void
502 child_files_info (ignore)
503      struct target_ops *ignore;
504 {
505   printf_unfiltered ("\tUsing the running image of %s %s.\n",
506       attach_flag ? "attached" : "child", target_pid_to_str (inferior_pid));
507 }
508
509 /* ARGSUSED */
510 static void
511 child_open (arg, from_tty)
512      char *arg;
513      int from_tty;
514 {
515   error ("Use the \"run\" command to start a Unix child process.");
516 }
517
518
519 /* Start an inferior win32 child process and sets inferior_pid to its pid.
520    EXEC_FILE is the file to run.
521    ALLARGS is a string containing the arguments to the program.
522    ENV is the environment vector to pass.  Errors reported with error().  */
523
524
525 static void
526 child_create_inferior (exec_file, allargs, env)
527      char *exec_file;
528      char *allargs;
529      char **env;
530 {
531   char real_path[MAXPATHLEN];
532   char *winenv;
533   char *temp;
534   int  envlen;
535   int i;
536
537   STARTUPINFO si;
538   PROCESS_INFORMATION pi;
539   struct target_waitstatus dummy;
540   BOOL ret;
541   DWORD flags;
542   char *args;
543
544   if (!exec_file)
545     {
546       error ("No executable specified, use `target exec'.\n");
547     }
548
549   memset (&si, 0, sizeof (si));
550   si.cb = sizeof (si);
551
552   unix_path_to_dos_path (exec_file, real_path);
553
554   flags = DEBUG_ONLY_THIS_PROCESS | DEBUG_PROCESS;
555
556   if (new_group)
557     flags |= CREATE_NEW_PROCESS_GROUP;
558
559   if (new_console)
560     flags |= CREATE_NEW_CONSOLE;
561
562   args = alloca (strlen (real_path) + strlen (allargs) + 2);
563
564   strcpy (args, real_path);
565
566   strcat (args, " ");
567   strcat (args, allargs);
568
569
570   /* get total size for env strings */
571   for (envlen = 0, i = 0; env[i] && *env[i]; i++)
572     envlen += strlen(env[i]) + 1;       
573
574   winenv = alloca(envlen + 1);  /* allocate new buffer */
575
576   /* copy env strings into new buffer */
577   for (temp = winenv, i = 0; env[i] && *env[i];     i++) 
578     {
579       strcpy(temp, env[i]);
580       temp += strlen(temp) + 1;
581     }
582   *temp = 0;                    /* final nil string to terminate new env */
583
584   ret = CreateProcess (0,
585                        args,    /* command line */
586                        NULL,    /* Security */
587                        NULL,    /* thread */
588                        TRUE,    /* inherit handles */
589                        flags,   /* start flags */
590                        winenv,
591                        NULL,    /* current directory */
592                        &si,
593                        &pi);
594   if (!ret)
595     error ("Error creating process %s, (error %d)\n", exec_file, GetLastError());
596
597   exception_count = 0;
598   event_count = 0;
599
600   inferior_pid = pi.dwProcessId;
601   current_process = pi.hProcess;
602   current_thread = pi.hThread;
603   current_process_id = pi.dwProcessId;
604   current_thread_id = pi.dwThreadId;
605   push_target (&child_ops);
606   init_thread_list ();
607   init_wait_for_inferior ();
608   clear_proceed_status ();
609   target_terminal_init ();
610   target_terminal_inferior ();
611
612   /* Ignore the first trap */
613   child_wait (inferior_pid, &dummy);
614
615   proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
616 }
617
618 static void
619 child_mourn_inferior ()
620 {
621   unpush_target (&child_ops);
622   generic_mourn_inferior ();
623 }
624
625
626 /* Send a SIGINT to the process group.  This acts just like the user typed a
627    ^C on the controlling terminal. */
628
629 void
630 child_stop ()
631 {
632   CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, 0));
633 }
634
635 int
636 child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
637                    int write, struct target_ops *target)
638 {
639   DWORD done;
640   if (write)
641     {
642       WriteProcessMemory (current_process, memaddr, our, len, &done);
643       FlushInstructionCache (current_process, memaddr, len);
644     }
645   else
646     {
647       ReadProcessMemory (current_process, memaddr, our, len, &done);
648     }
649   return done;
650 }
651
652 void
653 child_kill_inferior (void)
654 {
655   CHECK (TerminateProcess (current_process, 0));
656   CHECK (CloseHandle (current_process));
657   CHECK (CloseHandle (current_thread));
658 }
659
660 void
661 child_resume (int pid, int step, enum target_signal signal)
662 {
663   DEBUG (("child_resume (%d, %d, %d);\n", pid, step, signal));
664
665   if (step)
666     {
667 #ifdef __PPC__
668       warning ("Single stepping not done.\n");
669 #endif
670 #ifdef __I386__
671       /* Single step by setting t bit */
672       child_fetch_inferior_registers (PS_REGNUM);
673       context.EFlags |= FLAG_TRACE_BIT;
674 #endif
675     }
676
677   if (context.ContextFlags)
678     {
679       CHECK (SetThreadContext (current_thread, &context));
680       context.ContextFlags = 0;
681     }
682
683   if (signal)
684     {
685       fprintf_unfiltered (gdb_stderr, "Can't send signals to the child.\n");
686     }
687
688   CHECK (ContinueDebugEvent (current_process_id,
689                              current_thread_id,
690                              DBG_CONTINUE));
691 }
692
693 static void
694 child_prepare_to_store ()
695 {
696   /* Do nothing, since we can store individual regs */
697 }
698
699 static int
700 child_can_run ()
701 {
702   return 1;
703 }
704
705 static void
706 child_close ()
707 {
708
709 }
710 struct target_ops child_ops =
711 {
712   "child",                      /* to_shortname */
713   "Win32 child process",        /* to_longname */
714   "Win32 child process (started by the \"run\" command).",      /* to_doc */
715   child_open,                   /* to_open */
716   child_close,                  /* to_close */
717   child_attach,                 /* to_attach */
718   child_detach,                 /* to_detach */
719   child_resume,                 /* to_resume */
720   child_wait,                   /* to_wait */
721   child_fetch_inferior_registers,/* to_fetch_registers */
722   child_store_inferior_registers,/* to_store_registers */
723   child_prepare_to_store,       /* to_child_prepare_to_store */
724   child_xfer_memory,            /* to_xfer_memory */
725   child_files_info,             /* to_files_info */
726   memory_insert_breakpoint,     /* to_insert_breakpoint */
727   memory_remove_breakpoint,     /* to_remove_breakpoint */
728   terminal_init_inferior,       /* to_terminal_init */
729   terminal_inferior,            /* to_terminal_inferior */
730   terminal_ours_for_output,     /* to_terminal_ours_for_output */
731   terminal_ours,                /* to_terminal_ours */
732   child_terminal_info,          /* to_terminal_info */
733   child_kill_inferior,          /* to_kill */
734   0,                            /* to_load */
735   0,                            /* to_lookup_symbol */
736   child_create_inferior,        /* to_create_inferior */
737   child_mourn_inferior,         /* to_mourn_inferior */
738   child_can_run,                /* to_can_run */
739   0,                            /* to_notice_signals */
740   0,                            /* to_thread_alive */
741   child_stop,                   /* to_stop */
742   process_stratum,              /* to_stratum */
743   0,                            /* to_next */
744   1,                            /* to_has_all_memory */
745   1,                            /* to_has_memory */
746   1,                            /* to_has_stack */
747   1,                            /* to_has_registers */
748   1,                            /* to_has_execution */
749   0,                            /* to_sections */
750   0,                            /* to_sections_end */
751   OPS_MAGIC                     /* to_magic */
752 };
753
754 void
755 _initialize_inftarg ()
756 {
757   add_show_from_set
758     (add_set_cmd ("new-console", class_support, var_boolean,
759                   (char *) &new_console,
760                   "Set creation of new console when creating child process.",
761                   &setlist),
762      &showlist);
763
764   add_show_from_set
765     (add_set_cmd ("new-group", class_support, var_boolean,
766                   (char *) &new_group,
767                   "Set creation of new group when creating child process.",
768                   &setlist),
769      &showlist);
770
771   add_target (&child_ops);
772 }