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