* libaout.h (enum machine_type): Change M_SPARCLET from 142 to 131.
[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
378static void
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:
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);
24e60978 417 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
1ef980b9 418 break;
24e60978 419 }
1ef980b9 420 context.ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT;
24e60978
SC
421 GetThreadContext (current_thread, &context);
422 exception_count++;
423}
424
425static int
426child_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);
1ef980b9 438 char *p;
24e60978
SC
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:
1ef980b9
SC
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;
24e60978 452 case EXIT_THREAD_DEBUG_EVENT:
1ef980b9
SC
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;
24e60978 457 case CREATE_PROCESS_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_PROCESS_DEBUG_EVENT"));
24e60978
SC
461 break;
462
463 case EXIT_PROCESS_DEBUG_EVENT:
1ef980b9
SC
464 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
465 event.dwProcessId, event.dwThreadId,
466 "EXIT_PROCESS_DEBUG_EVENT"));
24e60978
SC
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:
1ef980b9
SC
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 */
24e60978 483 break;
1ef980b9
SC
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"));
24e60978
SC
493 handle_exception (&event, ourstatus);
494 return current_process_id;
1ef980b9
SC
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;
24e60978 508 default:
1ef980b9
SC
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);
24e60978
SC
513 break;
514 }
1ef980b9
SC
515 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=%d, DBG_CONTINUE);\n",
516 current_process_id, current_thread_id));
24e60978
SC
517 CHECK (ContinueDebugEvent (current_process_id,
518 current_thread_id,
519 DBG_CONTINUE));
520 }
521}
522
24e60978
SC
523/* Attach to process PID, then initialize for debugging it. */
524
525static void
526child_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
24e60978
SC
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
24e60978
SC
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
24e60978
SC
581/* Print status information about what we're accessing. */
582
583static void
584child_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 */
592static void
593child_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
eb708f2e 600/* Start an inferior win32 child process and sets inferior_pid to its pid.
24e60978
SC
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
24e60978
SC
605static void
606child_create_inferior (exec_file, allargs, env)
607 char *exec_file;
608 char *allargs;
609 char **env;
610{
1750a5ef
SC
611 char real_path[MAXPATHLEN];
612 char *winenv;
613 char *temp;
614 int envlen;
615 int i;
616
24e60978
SC
617 STARTUPINFO si;
618 PROCESS_INFORMATION pi;
619 struct target_waitstatus dummy;
620 BOOL ret;
621 DWORD flags;
eb708f2e 622 char *args;
24e60978
SC
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
2dcfc9c7 632 cygwin32_conv_to_win32_path (exec_file, real_path);
24e60978 633
1ef980b9 634 flags = DEBUG_ONLY_THIS_PROCESS;
24e60978
SC
635
636 if (new_group)
637 flags |= CREATE_NEW_PROCESS_GROUP;
638
639 if (new_console)
640 flags |= CREATE_NEW_CONSOLE;
641
3d78f532
SC
642 args = alloca (strlen (real_path) + strlen (allargs) + 2);
643
644 strcpy (args, real_path);
eb708f2e 645
eb708f2e
SC
646 strcat (args, " ");
647 strcat (args, allargs);
648
e88c49c3
DE
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
2dcfc9c7
DE
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. */
e88c49c3
DE
658
659 static const char *conv_path_names[] =
660 {
661 "PATH=",
662 0
663 };
e88c49c3
DE
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 {
2dcfc9c7 671 int j, len;
e88c49c3 672
2dcfc9c7
DE
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)
e88c49c3 677 {
2dcfc9c7
DE
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;
e88c49c3 684 }
e88c49c3 685 }
2dcfc9c7 686 if (conv_path_names[j] == NULL)
e88c49c3
DE
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 {
2dcfc9c7 695 int j, len;
e88c49c3 696
2dcfc9c7
DE
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)
e88c49c3 701 {
2dcfc9c7 702 if (cygwin32_posix_path_list_p (env[i] + len))
e88c49c3
DE
703 {
704 memcpy (temp, env[i], len);
705 cygwin32_posix_to_win32_path_list (env[i] + len, temp + len);
e88c49c3 706 }
2dcfc9c7
DE
707 else
708 strcpy (temp, env[i]);
709 break;
e88c49c3 710 }
e88c49c3 711 }
2dcfc9c7 712 if (conv_path_names[j] == NULL)
e88c49c3 713 strcpy (temp, env[i]);
2dcfc9c7 714
e88c49c3
DE
715 temp += strlen (temp) + 1;
716 }
717
718 /* Final nil string to terminate new env. */
719 *temp = 0;
720 }
1750a5ef 721
1750a5ef 722 ret = CreateProcess (0,
3d78f532 723 args, /* command line */
24e60978
SC
724 NULL, /* Security */
725 NULL, /* thread */
726 TRUE, /* inherit handles */
727 flags, /* start flags */
1750a5ef 728 winenv,
24e60978
SC
729 NULL, /* current directory */
730 &si,
731 &pi);
732 if (!ret)
686941a9 733 error ("Error creating process %s, (error %d)\n", exec_file, GetLastError());
24e60978
SC
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
756static void
757child_mourn_inferior ()
758{
759 unpush_target (&child_ops);
760 generic_mourn_inferior ();
761}
762
24e60978
SC
763/* Send a SIGINT to the process group. This acts just like the user typed a
764 ^C on the controlling terminal. */
765
b607efe7 766static void
24e60978
SC
767child_stop ()
768{
1ef980b9 769 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
24e60978 770 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, 0));
1ef980b9 771 registers_changed(); /* refresh register state */
24e60978
SC
772}
773
774int
eb708f2e
SC
775child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
776 int write, struct target_ops *target)
24e60978
SC
777{
778 DWORD done;
779 if (write)
780 {
1ef980b9
SC
781 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08x\n",
782 len, memaddr));
24e60978
SC
783 WriteProcessMemory (current_process, memaddr, our, len, &done);
784 FlushInstructionCache (current_process, memaddr, len);
785 }
786 else
787 {
1ef980b9
SC
788 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08x\n",
789 len, memaddr));
24e60978
SC
790 ReadProcessMemory (current_process, memaddr, our, len, &done);
791 }
792 return done;
793}
794
795void
796child_kill_inferior (void)
797{
798 CHECK (TerminateProcess (current_process, 0));
799 CHECK (CloseHandle (current_process));
800 CHECK (CloseHandle (current_thread));
1ef980b9 801 target_mourn_inferior(); /* or just child_mourn_inferior? */
24e60978
SC
802}
803
804void
805child_resume (int pid, int step, enum target_signal signal)
806{
1ef980b9
SC
807 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, signal=%d);\n",
808 pid, step, signal));
24e60978
SC
809
810 if (step)
811 {
454ffae5
SC
812#ifdef __PPC__
813 warning ("Single stepping not done.\n");
814#endif
1ef980b9 815#ifdef i386
24e60978
SC
816 /* Single step by setting t bit */
817 child_fetch_inferior_registers (PS_REGNUM);
818 context.EFlags |= FLAG_TRACE_BIT;
454ffae5 819#endif
24e60978
SC
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
1ef980b9
SC
833 DEBUG_EVENTS (("gdb: ContinueDebugEvent (cpid=%d, ctid=%d, DBG_CONTINUE);\n",
834 current_process_id, current_thread_id));
24e60978
SC
835 CHECK (ContinueDebugEvent (current_process_id,
836 current_thread_id,
837 DBG_CONTINUE));
838}
839
840static void
841child_prepare_to_store ()
842{
843 /* Do nothing, since we can store individual regs */
844}
845
846static int
847child_can_run ()
848{
849 return 1;
850}
851
852static void
853child_close ()
854{
1ef980b9 855 DEBUG_EVENTS (("gdb: child_close, inferior_pid=%d\n", inferior_pid));
24e60978 856}
1ef980b9 857
24e60978
SC
858struct 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
902void
903_initialize_inftarg ()
904{
1ef980b9
SC
905 struct cmd_list_element *c;
906
24e60978
SC
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
1ef980b9
SC
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
24e60978
SC
949 add_target (&child_ops);
950}
This page took 0.120572 seconds and 4 git commands to generate.