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