1 /* Target-vector operations for controlling win32 child processes, for GDB.
3 Free Software Foundation, Inc.
5 Contributed by Cygnus Support.
6 This file is part of GDB.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without eve nthe implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 /* by Steve Chamberlain, sac@cygnus.com */
25 #include "frame.h" /* required by inferior.h */
32 #include <sys/types.h>
36 #include "gdb_string.h"
39 #include <sys/param.h>
40 #define CHECK(x) check (x, __FILE__,__LINE__)
41 #define DEBUG(x) if (remote_debug) printf x
44 /* Forward declaration */
45 extern struct target_ops child_ops;
47 /* The most recently read context. Inspect ContextFlags to see what
50 static CONTEXT context;
52 /* The process and thread handles for the above context. */
54 static HANDLE current_process;
55 static HANDLE current_thread;
56 static int current_process_id;
57 static int current_thread_id;
59 /* Counts of things. */
60 static int exception_count = 0;
61 static int event_count = 0;
64 static int new_console = 0;
65 static int new_group = 0;
67 /* This vector maps GDB's idea of a register's number into an address
68 in the win32 exception context vector.
70 It also contains the bit mask needed to load the register in question.
72 One day we could read a reg, we could inspect the context we
73 already have loaded, if it doesn't have the bit set that we need,
74 we read that set of registers in using GetThreadContext. If the
75 context already contains what we need, we just unpack it. Then to
76 write a register, first we have to ensure that the context contains
77 the other regs of the group, and then we copy the info in and set
87 static const struct regmappings mappings[] =
90 {(char *) &context.Gpr0, CONTEXT_INTEGER},
91 {(char *) &context.Gpr1, CONTEXT_INTEGER},
92 {(char *) &context.Gpr2, CONTEXT_INTEGER},
93 {(char *) &context.Gpr3, CONTEXT_INTEGER},
94 {(char *) &context.Gpr4, CONTEXT_INTEGER},
95 {(char *) &context.Gpr5, CONTEXT_INTEGER},
96 {(char *) &context.Gpr6, CONTEXT_INTEGER},
97 {(char *) &context.Gpr7, CONTEXT_INTEGER},
99 {(char *) &context.Gpr8, CONTEXT_INTEGER},
100 {(char *) &context.Gpr9, CONTEXT_INTEGER},
101 {(char *) &context.Gpr10, CONTEXT_INTEGER},
102 {(char *) &context.Gpr11, CONTEXT_INTEGER},
103 {(char *) &context.Gpr12, CONTEXT_INTEGER},
104 {(char *) &context.Gpr13, CONTEXT_INTEGER},
105 {(char *) &context.Gpr14, CONTEXT_INTEGER},
106 {(char *) &context.Gpr15, CONTEXT_INTEGER},
108 {(char *) &context.Gpr16, CONTEXT_INTEGER},
109 {(char *) &context.Gpr17, CONTEXT_INTEGER},
110 {(char *) &context.Gpr18, CONTEXT_INTEGER},
111 {(char *) &context.Gpr19, CONTEXT_INTEGER},
112 {(char *) &context.Gpr20, CONTEXT_INTEGER},
113 {(char *) &context.Gpr21, CONTEXT_INTEGER},
114 {(char *) &context.Gpr22, CONTEXT_INTEGER},
115 {(char *) &context.Gpr23, CONTEXT_INTEGER},
117 {(char *) &context.Gpr24, CONTEXT_INTEGER},
118 {(char *) &context.Gpr25, CONTEXT_INTEGER},
119 {(char *) &context.Gpr26, CONTEXT_INTEGER},
120 {(char *) &context.Gpr27, CONTEXT_INTEGER},
121 {(char *) &context.Gpr28, CONTEXT_INTEGER},
122 {(char *) &context.Gpr29, CONTEXT_INTEGER},
123 {(char *) &context.Gpr30, CONTEXT_INTEGER},
124 {(char *) &context.Gpr31, CONTEXT_INTEGER},
126 {(char *) &context.Fpr0, CONTEXT_FLOATING_POINT},
127 {(char *) &context.Fpr1, CONTEXT_FLOATING_POINT},
128 {(char *) &context.Fpr2, CONTEXT_FLOATING_POINT},
129 {(char *) &context.Fpr3, CONTEXT_FLOATING_POINT},
130 {(char *) &context.Fpr4, CONTEXT_FLOATING_POINT},
131 {(char *) &context.Fpr5, CONTEXT_FLOATING_POINT},
132 {(char *) &context.Fpr6, CONTEXT_FLOATING_POINT},
133 {(char *) &context.Fpr7, CONTEXT_FLOATING_POINT},
135 {(char *) &context.Fpr8, CONTEXT_FLOATING_POINT},
136 {(char *) &context.Fpr9, CONTEXT_FLOATING_POINT},
137 {(char *) &context.Fpr10, CONTEXT_FLOATING_POINT},
138 {(char *) &context.Fpr11, CONTEXT_FLOATING_POINT},
139 {(char *) &context.Fpr12, CONTEXT_FLOATING_POINT},
140 {(char *) &context.Fpr13, CONTEXT_FLOATING_POINT},
141 {(char *) &context.Fpr14, CONTEXT_FLOATING_POINT},
142 {(char *) &context.Fpr15, CONTEXT_FLOATING_POINT},
144 {(char *) &context.Fpr16, CONTEXT_FLOATING_POINT},
145 {(char *) &context.Fpr17, CONTEXT_FLOATING_POINT},
146 {(char *) &context.Fpr18, CONTEXT_FLOATING_POINT},
147 {(char *) &context.Fpr19, CONTEXT_FLOATING_POINT},
148 {(char *) &context.Fpr20, CONTEXT_FLOATING_POINT},
149 {(char *) &context.Fpr21, CONTEXT_FLOATING_POINT},
150 {(char *) &context.Fpr22, CONTEXT_FLOATING_POINT},
151 {(char *) &context.Fpr23, CONTEXT_FLOATING_POINT},
153 {(char *) &context.Fpr24, CONTEXT_FLOATING_POINT},
154 {(char *) &context.Fpr25, CONTEXT_FLOATING_POINT},
155 {(char *) &context.Fpr26, CONTEXT_FLOATING_POINT},
156 {(char *) &context.Fpr27, CONTEXT_FLOATING_POINT},
157 {(char *) &context.Fpr28, CONTEXT_FLOATING_POINT},
158 {(char *) &context.Fpr29, CONTEXT_FLOATING_POINT},
159 {(char *) &context.Fpr30, CONTEXT_FLOATING_POINT},
160 {(char *) &context.Fpr31, CONTEXT_FLOATING_POINT},
163 {(char *) &context.Iar, CONTEXT_CONTROL},
164 {(char *) &context.Msr, CONTEXT_CONTROL},
165 {(char *) &context.Cr, CONTEXT_INTEGER},
166 {(char *) &context.Lr, CONTEXT_CONTROL},
167 {(char *) &context.Ctr, CONTEXT_CONTROL},
169 {(char *) &context.Xer, CONTEXT_INTEGER},
170 {0,0}, /* MQ, but there isn't one */
172 {(char *) &context.Eax, CONTEXT_INTEGER},
173 {(char *) &context.Ecx, CONTEXT_INTEGER},
174 {(char *) &context.Edx, CONTEXT_INTEGER},
175 {(char *) &context.Ebx, CONTEXT_INTEGER},
176 {(char *) &context.Esp, CONTEXT_CONTROL},
177 {(char *) &context.Ebp, CONTEXT_CONTROL},
178 {(char *) &context.Esi, CONTEXT_INTEGER},
179 {(char *) &context.Edi, CONTEXT_INTEGER},
180 {(char *) &context.Eip, CONTEXT_CONTROL},
181 {(char *) &context.EFlags, CONTEXT_CONTROL},
182 {(char *) &context.SegCs, CONTEXT_SEGMENTS},
183 {(char *) &context.SegSs, CONTEXT_SEGMENTS},
184 {(char *) &context.SegDs, CONTEXT_SEGMENTS},
185 {(char *) &context.SegEs, CONTEXT_SEGMENTS},
186 {(char *) &context.SegFs, CONTEXT_SEGMENTS},
187 {(char *) &context.SegGs, CONTEXT_SEGMENTS},
188 {&context.FloatSave.RegisterArea[0 * 10], CONTEXT_FLOATING_POINT},
189 {&context.FloatSave.RegisterArea[1 * 10], CONTEXT_FLOATING_POINT},
190 {&context.FloatSave.RegisterArea[2 * 10], CONTEXT_FLOATING_POINT},
191 {&context.FloatSave.RegisterArea[3 * 10], CONTEXT_FLOATING_POINT},
192 {&context.FloatSave.RegisterArea[4 * 10], CONTEXT_FLOATING_POINT},
193 {&context.FloatSave.RegisterArea[5 * 10], CONTEXT_FLOATING_POINT},
194 {&context.FloatSave.RegisterArea[6 * 10], CONTEXT_FLOATING_POINT},
195 {&context.FloatSave.RegisterArea[7 * 10], CONTEXT_FLOATING_POINT},
200 /* This vector maps the target's idea of an exception (extracted
201 from the DEBUG_EVENT structure) to GDB's idea. */
203 struct xlate_exception
206 enum target_signal us;
210 static const struct xlate_exception
213 {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV},
214 {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV},
215 {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP},
216 {DBG_CONTROL_C, TARGET_SIGNAL_INT},
217 {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP},
222 check (BOOL ok, const char *file, int line)
225 printf_filtered ("error return %s:%d was %d\n", file, line, GetLastError ());
229 child_fetch_inferior_registers (int r)
233 for (r = 0; r < NUM_REGS; r++)
234 child_fetch_inferior_registers (r);
238 supply_register (r, mappings[r].incontext);
243 child_store_inferior_registers (int r)
247 for (r = 0; r < NUM_REGS; r++)
248 child_store_inferior_registers (r);
252 read_register_gen (r, mappings[r].incontext);
257 /* Wait for child to do something. Return pid of child, or -1 in case
258 of error; store status through argument pointer OURSTATUS. */
262 handle_load_dll (char *eventp)
264 DEBUG_EVENT * event = (DEBUG_EVENT *)eventp;
268 ReadProcessMemory (current_process,
269 (DWORD) event->u.LoadDll.lpImageName,
270 (char *) &dll_name_ptr,
271 sizeof (dll_name_ptr), &done);
273 /* See if we could read the address of a string, and that the
274 address isn't null. */
276 if (done == sizeof (dll_name_ptr) && dll_name_ptr)
279 int size = event->u.LoadDll.fUnicode ? sizeof (WCHAR) : sizeof (char);
284 ReadProcessMemory (current_process,
285 dll_name_ptr + len * size,
291 while ((b[0] != 0 || b[size - 1] != 0) && done == size);
294 dll_name = alloca (len);
296 if (event->u.LoadDll.fUnicode)
298 WCHAR *unicode_dll_name = (WCHAR *) alloca (len * sizeof (WCHAR));
299 ReadProcessMemory (current_process,
302 len * sizeof (WCHAR),
305 WideCharToMultiByte (CP_ACP, 0,
306 unicode_dll_name, len,
307 dll_name, len, 0, 0);
311 ReadProcessMemory (current_process,
318 /* FIXME!! It would be nice to define one symbol which pointed to the
319 front of the dll if we can't find any symbols. */
321 context.ContextFlags = CONTEXT_FULL;
322 GetThreadContext (current_thread, &context);
324 /* The symbols in a dll are offset by 0x1000, which is the
325 the offset from 0 of the first byte in an image - because
326 of the file header and the section alignment.
328 FIXME: Is this the real reason that we need the 0x1000 ? */
331 symbol_file_add (dll_name, 0,
332 (int) event->u.LoadDll.lpBaseOfDll + 0x1000, 0, 0, 0);
334 /* We strip off the path of the dll for tidiness. */
335 if (strrchr (dll_name, '\\'))
336 dll_name = strrchr (dll_name, '\\') + 1;
338 printf_unfiltered ("%x:%s\n", event->u.LoadDll.lpBaseOfDll, dll_name);
345 handle_exception (DEBUG_EVENT * event, struct target_waitstatus *ourstatus)
349 ourstatus->kind = TARGET_WAITKIND_STOPPED;
351 for (i = 0; !done && xlate[i].us > 0; i++)
353 if (xlate[i].them == event->u.Exception.ExceptionRecord.ExceptionCode)
355 ourstatus->value.sig = xlate[i].us;
363 printf_unfiltered ("Want to know about exception code %08x\n",
364 event->u.Exception.ExceptionRecord.ExceptionCode);
365 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
367 context.ContextFlags = CONTEXT_FULL;
368 GetThreadContext (current_thread, &context);
373 child_wait (int pid, struct target_waitstatus *ourstatus)
375 /* We loop when we get a non-standard exception rather than return
376 with a SPURIOUS because resume can try and step or modify things,
377 which needs a current_thread. But some of these exceptions mark
378 the birth or death of threads, which mean that the current thread
379 isn't necessarily what you think it is. */
384 BOOL t = WaitForDebugEvent (&event, INFINITE);
386 DEBUG (("%d = WaitForDebugEvent() code=%d pid=%d tid=%d)\n",
388 event.dwDebugEventCode,
394 current_thread_id = event.dwThreadId;
395 current_process_id = event.dwProcessId;
397 switch (event.dwDebugEventCode)
399 case CREATE_THREAD_DEBUG_EVENT:
400 case EXIT_THREAD_DEBUG_EVENT:
401 case CREATE_PROCESS_DEBUG_EVENT:
404 case EXIT_PROCESS_DEBUG_EVENT:
405 ourstatus->kind = TARGET_WAITKIND_EXITED;
406 ourstatus->value.integer = event.u.ExitProcess.dwExitCode;
407 CloseHandle (current_process);
408 CloseHandle (current_thread);
409 return current_process_id;
412 case LOAD_DLL_DEBUG_EVENT:
413 catch_errors (handle_load_dll,
415 "\n[failed reading symbols from DLL]\n",
417 registers_changed(); /* mark all regs invalid */
419 case EXCEPTION_DEBUG_EVENT:
420 handle_exception (&event, ourstatus);
421 return current_process_id;
423 printf_unfiltered ("waitfor it %d %d %d %d\n", t,
424 event.dwDebugEventCode,
429 CHECK (ContinueDebugEvent (current_process_id,
438 /* Attach to process PID, then initialize for debugging it. */
441 child_attach (args, from_tty)
448 error_no_arg ("process-id to attach");
450 current_process_id = strtoul (args, 0, 0);
452 ok = DebugActiveProcess (current_process_id);
455 error ("Can't attach to process.");
463 char *exec_file = (char *) get_exec_file (0);
466 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
467 target_pid_to_str (current_process_id));
469 printf_unfiltered ("Attaching to %s\n",
470 target_pid_to_str (current_process_id));
472 gdb_flush (gdb_stdout);
475 inferior_pid = current_process_id;
476 push_target (&child_ops);
481 child_detach (args, from_tty)
487 char *exec_file = get_exec_file (0);
490 printf_unfiltered ("Detaching from program: %s %s\n", exec_file,
491 target_pid_to_str (inferior_pid));
492 gdb_flush (gdb_stdout);
495 unpush_target (&child_ops);
499 /* Print status information about what we're accessing. */
502 child_files_info (ignore)
503 struct target_ops *ignore;
505 printf_unfiltered ("\tUsing the running image of %s %s.\n",
506 attach_flag ? "attached" : "child", target_pid_to_str (inferior_pid));
511 child_open (arg, from_tty)
515 error ("Use the \"run\" command to start a Unix child process.");
519 /* Start an inferior win32 child process and sets inferior_pid to its pid.
520 EXEC_FILE is the file to run.
521 ALLARGS is a string containing the arguments to the program.
522 ENV is the environment vector to pass. Errors reported with error(). */
526 child_create_inferior (exec_file, allargs, env)
531 char real_path[MAXPATHLEN];
538 PROCESS_INFORMATION pi;
539 struct target_waitstatus dummy;
546 error ("No executable specified, use `target exec'.\n");
549 memset (&si, 0, sizeof (si));
552 unix_path_to_dos_path (exec_file, real_path);
554 flags = DEBUG_ONLY_THIS_PROCESS | DEBUG_PROCESS;
557 flags |= CREATE_NEW_PROCESS_GROUP;
560 flags |= CREATE_NEW_CONSOLE;
562 args = alloca (strlen (real_path) + strlen (allargs) + 2);
564 strcpy (args, real_path);
567 strcat (args, allargs);
570 /* get total size for env strings */
571 for (envlen = 0, i = 0; env[i] && *env[i]; i++)
572 envlen += strlen(env[i]) + 1;
574 winenv = alloca(envlen + 1); /* allocate new buffer */
576 /* copy env strings into new buffer */
577 for (temp = winenv, i = 0; env[i] && *env[i]; i++)
579 strcpy(temp, env[i]);
580 temp += strlen(temp) + 1;
582 *temp = 0; /* final nil string to terminate new env */
584 ret = CreateProcess (0,
585 args, /* command line */
588 TRUE, /* inherit handles */
589 flags, /* start flags */
591 NULL, /* current directory */
595 error ("Error creating process %s, (error %d)\n", exec_file, GetLastError());
600 inferior_pid = pi.dwProcessId;
601 current_process = pi.hProcess;
602 current_thread = pi.hThread;
603 current_process_id = pi.dwProcessId;
604 current_thread_id = pi.dwThreadId;
605 push_target (&child_ops);
607 init_wait_for_inferior ();
608 clear_proceed_status ();
609 target_terminal_init ();
610 target_terminal_inferior ();
612 /* Ignore the first trap */
613 child_wait (inferior_pid, &dummy);
615 proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
619 child_mourn_inferior ()
621 unpush_target (&child_ops);
622 generic_mourn_inferior ();
626 /* Send a SIGINT to the process group. This acts just like the user typed a
627 ^C on the controlling terminal. */
632 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, 0));
636 child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
637 int write, struct target_ops *target)
642 WriteProcessMemory (current_process, memaddr, our, len, &done);
643 FlushInstructionCache (current_process, memaddr, len);
647 ReadProcessMemory (current_process, memaddr, our, len, &done);
653 child_kill_inferior (void)
655 CHECK (TerminateProcess (current_process, 0));
656 CHECK (CloseHandle (current_process));
657 CHECK (CloseHandle (current_thread));
661 child_resume (int pid, int step, enum target_signal signal)
663 DEBUG (("child_resume (%d, %d, %d);\n", pid, step, signal));
668 warning ("Single stepping not done.\n");
671 /* Single step by setting t bit */
672 child_fetch_inferior_registers (PS_REGNUM);
673 context.EFlags |= FLAG_TRACE_BIT;
677 if (context.ContextFlags)
679 CHECK (SetThreadContext (current_thread, &context));
680 context.ContextFlags = 0;
685 fprintf_unfiltered (gdb_stderr, "Can't send signals to the child.\n");
688 CHECK (ContinueDebugEvent (current_process_id,
694 child_prepare_to_store ()
696 /* Do nothing, since we can store individual regs */
710 struct target_ops child_ops =
712 "child", /* to_shortname */
713 "Win32 child process", /* to_longname */
714 "Win32 child process (started by the \"run\" command).", /* to_doc */
715 child_open, /* to_open */
716 child_close, /* to_close */
717 child_attach, /* to_attach */
718 child_detach, /* to_detach */
719 child_resume, /* to_resume */
720 child_wait, /* to_wait */
721 child_fetch_inferior_registers,/* to_fetch_registers */
722 child_store_inferior_registers,/* to_store_registers */
723 child_prepare_to_store, /* to_child_prepare_to_store */
724 child_xfer_memory, /* to_xfer_memory */
725 child_files_info, /* to_files_info */
726 memory_insert_breakpoint, /* to_insert_breakpoint */
727 memory_remove_breakpoint, /* to_remove_breakpoint */
728 terminal_init_inferior, /* to_terminal_init */
729 terminal_inferior, /* to_terminal_inferior */
730 terminal_ours_for_output, /* to_terminal_ours_for_output */
731 terminal_ours, /* to_terminal_ours */
732 child_terminal_info, /* to_terminal_info */
733 child_kill_inferior, /* to_kill */
735 0, /* to_lookup_symbol */
736 child_create_inferior, /* to_create_inferior */
737 child_mourn_inferior, /* to_mourn_inferior */
738 child_can_run, /* to_can_run */
739 0, /* to_notice_signals */
740 0, /* to_thread_alive */
741 child_stop, /* to_stop */
742 process_stratum, /* to_stratum */
744 1, /* to_has_all_memory */
745 1, /* to_has_memory */
746 1, /* to_has_stack */
747 1, /* to_has_registers */
748 1, /* to_has_execution */
750 0, /* to_sections_end */
751 OPS_MAGIC /* to_magic */
755 _initialize_inftarg ()
758 (add_set_cmd ("new-console", class_support, var_boolean,
759 (char *) &new_console,
760 "Set creation of new console when creating child process.",
765 (add_set_cmd ("new-group", class_support, var_boolean,
767 "Set creation of new group when creating child process.",
771 add_target (&child_ops);