* Makefile.in (all): Change gdb dependency to gdb$(EXEEXT).
[deliverable/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
cad9cd60
GN
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20*/
24e60978
SC
21
22/* by Steve Chamberlain, sac@cygnus.com */
23
e88c49c3
DE
24/* We assume we're being built with and will be used for cygwin32. */
25
24e60978
SC
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>
cad9cd60
GN
36#include <stdlib.h>
37
38#ifdef _MSC_VER
28444bf3 39#include "windefs.h"
cad9cd60
GN
40#else /* other WIN32 compiler */
41#include <windows.h>
42#endif
43
24e60978 44#include "buildsym.h"
1ef980b9
SC
45#include "symfile.h"
46#include "objfiles.h"
24e60978 47#include "gdb_string.h"
fdfa3315 48#include "gdbthread.h"
24e60978 49#include "gdbcmd.h"
1750a5ef 50#include <sys/param.h>
e88c49c3 51#include <unistd.h>
24e60978 52
1ef980b9
SC
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
24e60978
SC
58
59/* Forward declaration */
60extern struct target_ops child_ops;
61
b607efe7
FF
62static void child_stop PARAMS ((void));
63
24e60978
SC
64/* The most recently read context. Inspect ContextFlags to see what
65 bits are valid. */
66
67static CONTEXT context;
68
69/* The process and thread handles for the above context. */
70
71static HANDLE current_process;
72static HANDLE current_thread;
73static int current_process_id;
74static int current_thread_id;
75
76/* Counts of things. */
77static int exception_count = 0;
78static int event_count = 0;
79
80/* User options. */
81static int new_console = 0;
82static int new_group = 0;
1ef980b9
SC
83static int debug_exec = 0; /* show execution */
84static int debug_events = 0; /* show events from kernel */
85static int debug_memory = 0; /* show target memory accesses */
86static int debug_exceptions = 0; /* show target exceptions */
24e60978
SC
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
101struct regmappings
102 {
103 char *incontext;
104 int mask;
105 };
106
454ffae5 107static const struct regmappings mappings[] =
24e60978 108{
454ffae5
SC
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
454ffae5
SC
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
24e60978
SC
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},
454ffae5 215#endif
24e60978
SC
216};
217
24e60978
SC
218/* This vector maps the target's idea of an exception (extracted
219 from the DEBUG_EVENT structure) to GDB's idea. */
220
221struct xlate_exception
222 {
223 int them;
224 enum target_signal us;
225 };
226
24e60978
SC
227static const struct xlate_exception
228 xlate[] =
229{
230 {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV},
9cbf6c0e 231 {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV},
24e60978
SC
232 {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP},
233 {DBG_CONTROL_C, TARGET_SIGNAL_INT},
234 {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP},
235 {-1, -1}};
236
24e60978
SC
237static void
238check (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
244static void
245child_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
258static void
259child_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
1750a5ef
SC
276static int
277handle_load_dll (char *eventp)
24e60978 278{
1750a5ef 279 DEBUG_EVENT * event = (DEBUG_EVENT *)eventp;
24e60978
SC
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 {
1ef980b9
SC
293 char *dll_name, *dll_basename;
294 struct objfile *objfile;
295 char unix_dll_name[MAX_PATH];
24e60978
SC
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
24e60978
SC
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
2dcfc9c7
DE
334 /* FIXME: Can we delete this call? */
335 cygwin32_conv_to_posix_path (dll_name, unix_dll_name);
1ef980b9 336
24e60978
SC
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
1ef980b9
SC
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 }
1ef980b9
SC
357
358 context.ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT;
24e60978
SC
359 GetThreadContext (current_thread, &context);
360
1750a5ef
SC
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
1ef980b9 368 symbol_file_add (unix_dll_name, 0,
1750a5ef 369 (int) event->u.LoadDll.lpBaseOfDll + 0x1000, 0, 0, 0);
24e60978 370
1ef980b9
SC
371 printf_unfiltered ("%x:%s\n", event->u.LoadDll.lpBaseOfDll,
372 unix_dll_name);
24e60978 373 }
1750a5ef 374 return 1;
24e60978
SC
375}
376
377
36339ecd 378static int
24e60978
SC
379handle_exception (DEBUG_EVENT * event, struct target_waitstatus *ourstatus)
380{
381 int i;
382 int done = 0;
383 ourstatus->kind = TARGET_WAITKIND_STOPPED;
384
24e60978 385
1ef980b9 386 switch (event->u.Exception.ExceptionRecord.ExceptionCode)
24e60978 387 {
1ef980b9
SC
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:
36339ecd
ILT
414 /* This may be a structured exception handling exception. In
415 that case, we want to let the program try to handle it, and
416 only break if we see the exception a second time. */
417 if (event->u.Exception.dwFirstChance)
418 return 0;
419
1ef980b9
SC
420 printf_unfiltered ("gdb: unknown target exception 0x%08x at 0x%08x\n",
421 event->u.Exception.ExceptionRecord.ExceptionCode,
422 event->u.Exception.ExceptionRecord.ExceptionAddress);
24e60978 423 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
1ef980b9 424 break;
24e60978 425 }
1ef980b9 426 context.ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT;
24e60978
SC
427 GetThreadContext (current_thread, &context);
428 exception_count++;
36339ecd 429 return 1;
24e60978
SC
430}
431
432static int
433child_wait (int pid, struct target_waitstatus *ourstatus)
434{
435 /* We loop when we get a non-standard exception rather than return
436 with a SPURIOUS because resume can try and step or modify things,
437 which needs a current_thread. But some of these exceptions mark
438 the birth or death of threads, which mean that the current thread
439 isn't necessarily what you think it is. */
440
441 while (1)
442 {
443 DEBUG_EVENT event;
444 BOOL t = WaitForDebugEvent (&event, INFINITE);
1ef980b9 445 char *p;
36339ecd 446 DWORD continue_status;
24e60978
SC
447
448 event_count++;
449
450 current_thread_id = event.dwThreadId;
451 current_process_id = event.dwProcessId;
452
36339ecd
ILT
453 continue_status = DBG_CONTINUE;
454
24e60978
SC
455 switch (event.dwDebugEventCode)
456 {
457 case CREATE_THREAD_DEBUG_EVENT:
1ef980b9
SC
458 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
459 event.dwProcessId, event.dwThreadId,
460 "CREATE_THREAD_DEBUG_EVENT"));
461 break;
24e60978 462 case EXIT_THREAD_DEBUG_EVENT:
1ef980b9
SC
463 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
464 event.dwProcessId, event.dwThreadId,
465 "EXIT_THREAD_DEBUG_EVENT"));
466 break;
24e60978 467 case CREATE_PROCESS_DEBUG_EVENT:
1ef980b9
SC
468 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
469 event.dwProcessId, event.dwThreadId,
470 "CREATE_PROCESS_DEBUG_EVENT"));
24e60978
SC
471 break;
472
473 case EXIT_PROCESS_DEBUG_EVENT:
1ef980b9
SC
474 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
475 event.dwProcessId, event.dwThreadId,
476 "EXIT_PROCESS_DEBUG_EVENT"));
24e60978
SC
477 ourstatus->kind = TARGET_WAITKIND_EXITED;
478 ourstatus->value.integer = event.u.ExitProcess.dwExitCode;
479 CloseHandle (current_process);
480 CloseHandle (current_thread);
481 return current_process_id;
482 break;
483
484 case LOAD_DLL_DEBUG_EVENT:
1ef980b9
SC
485 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
486 event.dwProcessId, event.dwThreadId,
487 "LOAD_DLL_DEBUG_EVENT"));
488 catch_errors (handle_load_dll,
489 (char*) &event,
490 "\n[failed reading symbols from DLL]\n",
491 RETURN_MASK_ALL);
492 registers_changed(); /* mark all regs invalid */
24e60978 493 break;
1ef980b9
SC
494 case UNLOAD_DLL_DEBUG_EVENT:
495 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
496 event.dwProcessId, event.dwThreadId,
497 "UNLOAD_DLL_DEBUG_EVENT"));
498 break; /* FIXME: don't know what to do here */
499 case EXCEPTION_DEBUG_EVENT:
500 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
501 event.dwProcessId, event.dwThreadId,
502 "EXCEPTION_DEBUG_EVENT"));
36339ecd
ILT
503 if (handle_exception (&event, ourstatus))
504 return current_process_id;
505 continue_status = DBG_EXCEPTION_NOT_HANDLED;
506 break;
1ef980b9
SC
507
508 case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */
509 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
510 event.dwProcessId, event.dwThreadId,
511 "OUTPUT_DEBUG_STRING_EVENT"));
512 if (target_read_string
513 ((CORE_ADDR) event.u.DebugString.lpDebugStringData,
514 &p, 1024, 0) && p && *p)
515 {
516 warning(p);
517 free(p);
518 }
519 break;
24e60978 520 default:
1ef980b9
SC
521 printf_unfiltered ("gdb: kernel event for pid=%d tid=%d\n",
522 event.dwProcessId, event.dwThreadId);
523 printf_unfiltered (" unknown event code %d\n",
524 event.dwDebugEventCode);
24e60978
SC
525 break;
526 }
1ef980b9
SC
527 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=%d, DBG_CONTINUE);\n",
528 current_process_id, current_thread_id));
24e60978
SC
529 CHECK (ContinueDebugEvent (current_process_id,
530 current_thread_id,
36339ecd 531 continue_status));
24e60978
SC
532 }
533}
534
24e60978
SC
535/* Attach to process PID, then initialize for debugging it. */
536
537static void
538child_attach (args, from_tty)
539 char *args;
540 int from_tty;
541{
542 BOOL ok;
543
544 if (!args)
545 error_no_arg ("process-id to attach");
546
547 current_process_id = strtoul (args, 0, 0);
548
549 ok = DebugActiveProcess (current_process_id);
550
551 if (!ok)
552 error ("Can't attach to process.");
553
24e60978
SC
554 exception_count = 0;
555 event_count = 0;
556
557 if (from_tty)
558 {
559 char *exec_file = (char *) get_exec_file (0);
560
561 if (exec_file)
562 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
563 target_pid_to_str (current_process_id));
564 else
565 printf_unfiltered ("Attaching to %s\n",
566 target_pid_to_str (current_process_id));
567
568 gdb_flush (gdb_stdout);
569 }
570
571 inferior_pid = current_process_id;
572 push_target (&child_ops);
573}
574
24e60978
SC
575static void
576child_detach (args, from_tty)
577 char *args;
578 int from_tty;
579{
580 if (from_tty)
581 {
582 char *exec_file = get_exec_file (0);
583 if (exec_file == 0)
584 exec_file = "";
585 printf_unfiltered ("Detaching from program: %s %s\n", exec_file,
586 target_pid_to_str (inferior_pid));
587 gdb_flush (gdb_stdout);
588 }
589 inferior_pid = 0;
590 unpush_target (&child_ops);
591}
592
24e60978
SC
593/* Print status information about what we're accessing. */
594
595static void
596child_files_info (ignore)
597 struct target_ops *ignore;
598{
599 printf_unfiltered ("\tUsing the running image of %s %s.\n",
600 attach_flag ? "attached" : "child", target_pid_to_str (inferior_pid));
601}
602
603/* ARGSUSED */
604static void
605child_open (arg, from_tty)
606 char *arg;
607 int from_tty;
608{
609 error ("Use the \"run\" command to start a Unix child process.");
610}
611
eb708f2e 612/* Start an inferior win32 child process and sets inferior_pid to its pid.
24e60978
SC
613 EXEC_FILE is the file to run.
614 ALLARGS is a string containing the arguments to the program.
615 ENV is the environment vector to pass. Errors reported with error(). */
616
24e60978
SC
617static void
618child_create_inferior (exec_file, allargs, env)
619 char *exec_file;
620 char *allargs;
621 char **env;
622{
1750a5ef
SC
623 char real_path[MAXPATHLEN];
624 char *winenv;
625 char *temp;
626 int envlen;
627 int i;
628
24e60978
SC
629 STARTUPINFO si;
630 PROCESS_INFORMATION pi;
631 struct target_waitstatus dummy;
632 BOOL ret;
633 DWORD flags;
eb708f2e 634 char *args;
24e60978
SC
635
636 if (!exec_file)
637 {
638 error ("No executable specified, use `target exec'.\n");
639 }
640
641 memset (&si, 0, sizeof (si));
642 si.cb = sizeof (si);
643
2dcfc9c7 644 cygwin32_conv_to_win32_path (exec_file, real_path);
24e60978 645
1ef980b9 646 flags = DEBUG_ONLY_THIS_PROCESS;
24e60978
SC
647
648 if (new_group)
649 flags |= CREATE_NEW_PROCESS_GROUP;
650
651 if (new_console)
652 flags |= CREATE_NEW_CONSOLE;
653
3d78f532
SC
654 args = alloca (strlen (real_path) + strlen (allargs) + 2);
655
656 strcpy (args, real_path);
eb708f2e 657
eb708f2e
SC
658 strcat (args, " ");
659 strcat (args, allargs);
660
e88c49c3
DE
661 /* Prepare the environment vars for CreateProcess. */
662 {
663 /* This code use to assume all env vars were file names and would
664 translate them all to win32 style. That obviously doesn't work in the
2dcfc9c7
DE
665 general case. The current rule is that we only translate PATH.
666 We need to handle PATH because we're about to call CreateProcess and
667 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
668 in both posix and win32 environments. cygwin.dll will change it back
669 to posix style if necessary. */
e88c49c3
DE
670
671 static const char *conv_path_names[] =
672 {
673 "PATH=",
674 0
675 };
e88c49c3
DE
676
677 /* CreateProcess takes the environment list as a null terminated set of
678 strings (i.e. two nulls terminate the list). */
679
680 /* Get total size for env strings. */
681 for (envlen = 0, i = 0; env[i] && *env[i]; i++)
682 {
2dcfc9c7 683 int j, len;
e88c49c3 684
2dcfc9c7
DE
685 for (j = 0; conv_path_names[j]; j++)
686 {
687 len = strlen (conv_path_names[j]);
688 if (strncmp (conv_path_names[j], env[i], len) == 0)
e88c49c3 689 {
2dcfc9c7
DE
690 if (cygwin32_posix_path_list_p (env[i] + len))
691 envlen += len
692 + cygwin32_posix_to_win32_path_list_buf_size (env[i] + len);
693 else
694 envlen += strlen (env[i]) + 1;
695 break;
e88c49c3 696 }
e88c49c3 697 }
2dcfc9c7 698 if (conv_path_names[j] == NULL)
e88c49c3
DE
699 envlen += strlen (env[i]) + 1;
700 }
701
702 winenv = alloca (envlen + 1);
703
704 /* Copy env strings into new buffer. */
705 for (temp = winenv, i = 0; env[i] && *env[i]; i++)
706 {
2dcfc9c7 707 int j, len;
e88c49c3 708
2dcfc9c7
DE
709 for (j = 0; conv_path_names[j]; j++)
710 {
711 len = strlen (conv_path_names[j]);
712 if (strncmp (conv_path_names[j], env[i], len) == 0)
e88c49c3 713 {
2dcfc9c7 714 if (cygwin32_posix_path_list_p (env[i] + len))
e88c49c3
DE
715 {
716 memcpy (temp, env[i], len);
717 cygwin32_posix_to_win32_path_list (env[i] + len, temp + len);
e88c49c3 718 }
2dcfc9c7
DE
719 else
720 strcpy (temp, env[i]);
721 break;
e88c49c3 722 }
e88c49c3 723 }
2dcfc9c7 724 if (conv_path_names[j] == NULL)
e88c49c3 725 strcpy (temp, env[i]);
2dcfc9c7 726
e88c49c3
DE
727 temp += strlen (temp) + 1;
728 }
729
730 /* Final nil string to terminate new env. */
731 *temp = 0;
732 }
1750a5ef 733
1750a5ef 734 ret = CreateProcess (0,
3d78f532 735 args, /* command line */
24e60978
SC
736 NULL, /* Security */
737 NULL, /* thread */
738 TRUE, /* inherit handles */
739 flags, /* start flags */
1750a5ef 740 winenv,
24e60978
SC
741 NULL, /* current directory */
742 &si,
743 &pi);
744 if (!ret)
686941a9 745 error ("Error creating process %s, (error %d)\n", exec_file, GetLastError());
24e60978
SC
746
747 exception_count = 0;
748 event_count = 0;
749
750 inferior_pid = pi.dwProcessId;
751 current_process = pi.hProcess;
752 current_thread = pi.hThread;
753 current_process_id = pi.dwProcessId;
754 current_thread_id = pi.dwThreadId;
755 push_target (&child_ops);
756 init_thread_list ();
757 init_wait_for_inferior ();
758 clear_proceed_status ();
759 target_terminal_init ();
760 target_terminal_inferior ();
761
762 /* Ignore the first trap */
763 child_wait (inferior_pid, &dummy);
764
765 proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
766}
767
768static void
769child_mourn_inferior ()
770{
771 unpush_target (&child_ops);
772 generic_mourn_inferior ();
773}
774
24e60978
SC
775/* Send a SIGINT to the process group. This acts just like the user typed a
776 ^C on the controlling terminal. */
777
b607efe7 778static void
24e60978
SC
779child_stop ()
780{
1ef980b9 781 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
24e60978 782 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, 0));
1ef980b9 783 registers_changed(); /* refresh register state */
24e60978
SC
784}
785
786int
eb708f2e
SC
787child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
788 int write, struct target_ops *target)
24e60978
SC
789{
790 DWORD done;
791 if (write)
792 {
1ef980b9
SC
793 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08x\n",
794 len, memaddr));
24e60978
SC
795 WriteProcessMemory (current_process, memaddr, our, len, &done);
796 FlushInstructionCache (current_process, memaddr, len);
797 }
798 else
799 {
1ef980b9
SC
800 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08x\n",
801 len, memaddr));
24e60978
SC
802 ReadProcessMemory (current_process, memaddr, our, len, &done);
803 }
804 return done;
805}
806
807void
808child_kill_inferior (void)
809{
810 CHECK (TerminateProcess (current_process, 0));
811 CHECK (CloseHandle (current_process));
812 CHECK (CloseHandle (current_thread));
1ef980b9 813 target_mourn_inferior(); /* or just child_mourn_inferior? */
24e60978
SC
814}
815
816void
817child_resume (int pid, int step, enum target_signal signal)
818{
1ef980b9
SC
819 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, signal=%d);\n",
820 pid, step, signal));
24e60978
SC
821
822 if (step)
823 {
454ffae5
SC
824#ifdef __PPC__
825 warning ("Single stepping not done.\n");
826#endif
1ef980b9 827#ifdef i386
24e60978
SC
828 /* Single step by setting t bit */
829 child_fetch_inferior_registers (PS_REGNUM);
830 context.EFlags |= FLAG_TRACE_BIT;
454ffae5 831#endif
24e60978
SC
832 }
833
834 if (context.ContextFlags)
835 {
836 CHECK (SetThreadContext (current_thread, &context));
837 context.ContextFlags = 0;
838 }
839
840 if (signal)
841 {
842 fprintf_unfiltered (gdb_stderr, "Can't send signals to the child.\n");
843 }
844
1ef980b9
SC
845 DEBUG_EVENTS (("gdb: ContinueDebugEvent (cpid=%d, ctid=%d, DBG_CONTINUE);\n",
846 current_process_id, current_thread_id));
24e60978
SC
847 CHECK (ContinueDebugEvent (current_process_id,
848 current_thread_id,
849 DBG_CONTINUE));
850}
851
852static void
853child_prepare_to_store ()
854{
855 /* Do nothing, since we can store individual regs */
856}
857
858static int
859child_can_run ()
860{
861 return 1;
862}
863
864static void
865child_close ()
866{
1ef980b9 867 DEBUG_EVENTS (("gdb: child_close, inferior_pid=%d\n", inferior_pid));
24e60978 868}
1ef980b9 869
24e60978
SC
870struct target_ops child_ops =
871{
872 "child", /* to_shortname */
873 "Win32 child process", /* to_longname */
874 "Win32 child process (started by the \"run\" command).", /* to_doc */
875 child_open, /* to_open */
876 child_close, /* to_close */
877 child_attach, /* to_attach */
878 child_detach, /* to_detach */
879 child_resume, /* to_resume */
880 child_wait, /* to_wait */
881 child_fetch_inferior_registers,/* to_fetch_registers */
882 child_store_inferior_registers,/* to_store_registers */
883 child_prepare_to_store, /* to_child_prepare_to_store */
884 child_xfer_memory, /* to_xfer_memory */
885 child_files_info, /* to_files_info */
886 memory_insert_breakpoint, /* to_insert_breakpoint */
887 memory_remove_breakpoint, /* to_remove_breakpoint */
888 terminal_init_inferior, /* to_terminal_init */
889 terminal_inferior, /* to_terminal_inferior */
890 terminal_ours_for_output, /* to_terminal_ours_for_output */
891 terminal_ours, /* to_terminal_ours */
892 child_terminal_info, /* to_terminal_info */
893 child_kill_inferior, /* to_kill */
894 0, /* to_load */
895 0, /* to_lookup_symbol */
896 child_create_inferior, /* to_create_inferior */
897 child_mourn_inferior, /* to_mourn_inferior */
898 child_can_run, /* to_can_run */
899 0, /* to_notice_signals */
900 0, /* to_thread_alive */
901 child_stop, /* to_stop */
902 process_stratum, /* to_stratum */
903 0, /* to_next */
904 1, /* to_has_all_memory */
905 1, /* to_has_memory */
906 1, /* to_has_stack */
907 1, /* to_has_registers */
908 1, /* to_has_execution */
909 0, /* to_sections */
910 0, /* to_sections_end */
911 OPS_MAGIC /* to_magic */
912};
913
914void
915_initialize_inftarg ()
916{
1ef980b9
SC
917 struct cmd_list_element *c;
918
24e60978
SC
919 add_show_from_set
920 (add_set_cmd ("new-console", class_support, var_boolean,
921 (char *) &new_console,
922 "Set creation of new console when creating child process.",
923 &setlist),
924 &showlist);
925
926 add_show_from_set
927 (add_set_cmd ("new-group", class_support, var_boolean,
928 (char *) &new_group,
929 "Set creation of new group when creating child process.",
930 &setlist),
931 &showlist);
932
1ef980b9
SC
933 add_show_from_set
934 (add_set_cmd ("debugexec", class_support, var_boolean,
935 (char *) &debug_exec,
936 "Set whether to display execution in child process.",
937 &setlist),
938 &showlist);
939
940 add_show_from_set
941 (add_set_cmd ("debugevents", class_support, var_boolean,
942 (char *) &debug_events,
943 "Set whether to display kernel events in child process.",
944 &setlist),
945 &showlist);
946
947 add_show_from_set
948 (add_set_cmd ("debugmemory", class_support, var_boolean,
949 (char *) &debug_memory,
950 "Set whether to display memory accesses in child process.",
951 &setlist),
952 &showlist);
953
954 add_show_from_set
955 (add_set_cmd ("debugexceptions", class_support, var_boolean,
956 (char *) &debug_exceptions,
957 "Set whether to display kernel exceptions in child process.",
958 &setlist),
959 &showlist);
960
24e60978
SC
961 add_target (&child_ops);
962}
This page took 0.170711 seconds and 4 git commands to generate.