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