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