* config/tc-mips.c (md_parse_option): Fix typo in comment.
[deliverable/binutils-gdb.git] / gdb / windows-nat.c
1 /* Target-vector operations for controlling win32 child processes, for GDB.
2
3 Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
4 Free Software Foundation, Inc.
5
6 Contributed by Cygnus Solutions, A Red Hat Company.
7
8 This file is part of GDB.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without eve nthe implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
24
25 /* Originally by Steve Chamberlain, sac@cygnus.com */
26
27 /* We assume we're being built with and will be used for cygwin. */
28
29 #include "defs.h"
30 #include "frame.h" /* required by inferior.h */
31 #include "inferior.h"
32 #include "target.h"
33 #include "exceptions.h"
34 #include "gdbcore.h"
35 #include "command.h"
36 #include "completer.h"
37 #include "regcache.h"
38 #include "top.h"
39 #include <signal.h>
40 #include <sys/types.h>
41 #include <fcntl.h>
42 #include <stdlib.h>
43 #include <windows.h>
44 #include <imagehlp.h>
45 #include <sys/cygwin.h>
46
47 #include "buildsym.h"
48 #include "symfile.h"
49 #include "objfiles.h"
50 #include "gdb_string.h"
51 #include "gdbthread.h"
52 #include "gdbcmd.h"
53 #include <sys/param.h>
54 #include <unistd.h>
55 #include "exec.h"
56 #include "solist.h"
57
58 #include "i386-tdep.h"
59 #include "i387-tdep.h"
60
61 static struct target_ops win32_ops;
62 static struct target_so_ops win32_so_ops;
63
64 /* If we're not using the old Cygwin header file set, define the
65 following which never should have been in the generic Win32 API
66 headers in the first place since they were our own invention... */
67 #ifndef _GNU_H_WINDOWS_H
68 enum
69 {
70 FLAG_TRACE_BIT = 0x100,
71 CONTEXT_DEBUGGER = (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
72 };
73 #endif
74 #include <sys/procfs.h>
75 #include <psapi.h>
76
77 #define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \
78 | CONTEXT_EXTENDED_REGISTERS
79
80 static unsigned dr[8];
81 static int debug_registers_changed;
82 static int debug_registers_used;
83
84 /* The string sent by cygwin when it processes a signal.
85 FIXME: This should be in a cygwin include file. */
86 #define CYGWIN_SIGNAL_STRING "cygwin: signal"
87
88 #define CHECK(x) check (x, __FILE__,__LINE__)
89 #define DEBUG_EXEC(x) if (debug_exec) printf_unfiltered x
90 #define DEBUG_EVENTS(x) if (debug_events) printf_unfiltered x
91 #define DEBUG_MEM(x) if (debug_memory) printf_unfiltered x
92 #define DEBUG_EXCEPT(x) if (debug_exceptions) printf_unfiltered x
93
94 static void win32_stop (void);
95 static int win32_win32_thread_alive (ptid_t);
96 static void win32_kill_inferior (void);
97
98 static enum target_signal last_sig = TARGET_SIGNAL_0;
99 /* Set if a signal was received from the debugged process */
100
101 /* Thread information structure used to track information that is
102 not available in gdb's thread structure. */
103 typedef struct thread_info_struct
104 {
105 struct thread_info_struct *next;
106 DWORD id;
107 HANDLE h;
108 char *name;
109 int suspend_count;
110 int reload_context;
111 CONTEXT context;
112 STACKFRAME sf;
113 }
114 thread_info;
115
116 static thread_info thread_head;
117
118 /* The process and thread handles for the above context. */
119
120 static DEBUG_EVENT current_event; /* The current debug event from
121 WaitForDebugEvent */
122 static HANDLE current_process_handle; /* Currently executing process */
123 static thread_info *current_thread; /* Info on currently selected thread */
124 static DWORD main_thread_id; /* Thread ID of the main thread */
125
126 /* Counts of things. */
127 static int exception_count = 0;
128 static int event_count = 0;
129 static int saw_create;
130
131 /* User options. */
132 static int new_console = 0;
133 static int new_group = 1;
134 static int debug_exec = 0; /* show execution */
135 static int debug_events = 0; /* show events from kernel */
136 static int debug_memory = 0; /* show target memory accesses */
137 static int debug_exceptions = 0; /* show target exceptions */
138 static int useshell = 0; /* use shell for subprocesses */
139
140 /* This vector maps GDB's idea of a register's number into an address
141 in the win32 exception context vector.
142
143 It also contains the bit mask needed to load the register in question.
144
145 One day we could read a reg, we could inspect the context we
146 already have loaded, if it doesn't have the bit set that we need,
147 we read that set of registers in using GetThreadContext. If the
148 context already contains what we need, we just unpack it. Then to
149 write a register, first we have to ensure that the context contains
150 the other regs of the group, and then we copy the info in and set
151 out bit. */
152
153 #define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
154 static const int mappings[] =
155 {
156 context_offset (Eax),
157 context_offset (Ecx),
158 context_offset (Edx),
159 context_offset (Ebx),
160 context_offset (Esp),
161 context_offset (Ebp),
162 context_offset (Esi),
163 context_offset (Edi),
164 context_offset (Eip),
165 context_offset (EFlags),
166 context_offset (SegCs),
167 context_offset (SegSs),
168 context_offset (SegDs),
169 context_offset (SegEs),
170 context_offset (SegFs),
171 context_offset (SegGs),
172 context_offset (FloatSave.RegisterArea[0 * 10]),
173 context_offset (FloatSave.RegisterArea[1 * 10]),
174 context_offset (FloatSave.RegisterArea[2 * 10]),
175 context_offset (FloatSave.RegisterArea[3 * 10]),
176 context_offset (FloatSave.RegisterArea[4 * 10]),
177 context_offset (FloatSave.RegisterArea[5 * 10]),
178 context_offset (FloatSave.RegisterArea[6 * 10]),
179 context_offset (FloatSave.RegisterArea[7 * 10]),
180 context_offset (FloatSave.ControlWord),
181 context_offset (FloatSave.StatusWord),
182 context_offset (FloatSave.TagWord),
183 context_offset (FloatSave.ErrorSelector),
184 context_offset (FloatSave.ErrorOffset),
185 context_offset (FloatSave.DataSelector),
186 context_offset (FloatSave.DataOffset),
187 context_offset (FloatSave.ErrorSelector)
188 /* XMM0-7 */ ,
189 context_offset (ExtendedRegisters[10*16]),
190 context_offset (ExtendedRegisters[11*16]),
191 context_offset (ExtendedRegisters[12*16]),
192 context_offset (ExtendedRegisters[13*16]),
193 context_offset (ExtendedRegisters[14*16]),
194 context_offset (ExtendedRegisters[15*16]),
195 context_offset (ExtendedRegisters[16*16]),
196 context_offset (ExtendedRegisters[17*16]),
197 /* MXCSR */
198 context_offset (ExtendedRegisters[24])
199 };
200
201 #undef context_offset
202
203 /* This vector maps the target's idea of an exception (extracted
204 from the DEBUG_EVENT structure) to GDB's idea. */
205
206 struct xlate_exception
207 {
208 int them;
209 enum target_signal us;
210 };
211
212 static const struct xlate_exception
213 xlate[] =
214 {
215 {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV},
216 {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV},
217 {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP},
218 {DBG_CONTROL_C, TARGET_SIGNAL_INT},
219 {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP},
220 {STATUS_FLOAT_DIVIDE_BY_ZERO, TARGET_SIGNAL_FPE},
221 {-1, -1}};
222
223 static void
224 check (BOOL ok, const char *file, int line)
225 {
226 if (!ok)
227 printf_filtered ("error return %s:%d was %lu\n", file, line,
228 GetLastError ());
229 }
230
231 /* Find a thread record given a thread id.
232 If get_context then also retrieve the context for this
233 thread. */
234 static thread_info *
235 thread_rec (DWORD id, int get_context)
236 {
237 thread_info *th;
238
239 for (th = &thread_head; (th = th->next) != NULL;)
240 if (th->id == id)
241 {
242 if (!th->suspend_count && get_context)
243 {
244 if (get_context > 0 && id != current_event.dwThreadId)
245 th->suspend_count = SuspendThread (th->h) + 1;
246 else if (get_context < 0)
247 th->suspend_count = -1;
248 th->reload_context = 1;
249 }
250 return th;
251 }
252
253 return NULL;
254 }
255
256 /* Add a thread to the thread list */
257 static thread_info *
258 win32_add_thread (DWORD id, HANDLE h)
259 {
260 thread_info *th;
261
262 if ((th = thread_rec (id, FALSE)))
263 return th;
264
265 th = (thread_info *) xmalloc (sizeof (*th));
266 memset (th, 0, sizeof (*th));
267 th->id = id;
268 th->h = h;
269 th->next = thread_head.next;
270 thread_head.next = th;
271 add_thread (pid_to_ptid (id));
272 /* Set the debug registers for the new thread in they are used. */
273 if (debug_registers_used)
274 {
275 /* Only change the value of the debug registers. */
276 th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
277 CHECK (GetThreadContext (th->h, &th->context));
278 th->context.Dr0 = dr[0];
279 th->context.Dr1 = dr[1];
280 th->context.Dr2 = dr[2];
281 th->context.Dr3 = dr[3];
282 /* th->context.Dr6 = dr[6];
283 FIXME: should we set dr6 also ?? */
284 th->context.Dr7 = dr[7];
285 CHECK (SetThreadContext (th->h, &th->context));
286 th->context.ContextFlags = 0;
287 }
288 return th;
289 }
290
291 /* Clear out any old thread list and reintialize it to a
292 pristine state. */
293 static void
294 win32_init_thread_list (void)
295 {
296 thread_info *th = &thread_head;
297
298 DEBUG_EVENTS (("gdb: win32_init_thread_list\n"));
299 init_thread_list ();
300 while (th->next != NULL)
301 {
302 thread_info *here = th->next;
303 th->next = here->next;
304 (void) CloseHandle (here->h);
305 xfree (here);
306 }
307 thread_head.next = NULL;
308 }
309
310 /* Delete a thread from the list of threads */
311 static void
312 win32_delete_thread (DWORD id)
313 {
314 thread_info *th;
315
316 if (info_verbose)
317 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (pid_to_ptid (id)));
318 delete_thread (pid_to_ptid (id));
319
320 for (th = &thread_head;
321 th->next != NULL && th->next->id != id;
322 th = th->next)
323 continue;
324
325 if (th->next != NULL)
326 {
327 thread_info *here = th->next;
328 th->next = here->next;
329 CloseHandle (here->h);
330 xfree (here);
331 }
332 }
333
334 static void
335 do_win32_fetch_inferior_registers (int r)
336 {
337 char *context_offset = ((char *) &current_thread->context) + mappings[r];
338 long l;
339
340 if (!current_thread)
341 return; /* Windows sometimes uses a non-existent thread id in its
342 events */
343
344 if (current_thread->reload_context)
345 {
346 thread_info *th = current_thread;
347 th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
348 GetThreadContext (th->h, &th->context);
349 /* Copy dr values from that thread. */
350 dr[0] = th->context.Dr0;
351 dr[1] = th->context.Dr1;
352 dr[2] = th->context.Dr2;
353 dr[3] = th->context.Dr3;
354 dr[6] = th->context.Dr6;
355 dr[7] = th->context.Dr7;
356 current_thread->reload_context = 0;
357 }
358
359 #define I387_ST0_REGNUM I386_ST0_REGNUM
360
361 if (r == I387_FISEG_REGNUM)
362 {
363 l = *((long *) context_offset) & 0xffff;
364 regcache_raw_supply (current_regcache, r, (char *) &l);
365 }
366 else if (r == I387_FOP_REGNUM)
367 {
368 l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
369 regcache_raw_supply (current_regcache, r, (char *) &l);
370 }
371 else if (r >= 0)
372 regcache_raw_supply (current_regcache, r, context_offset);
373 else
374 {
375 for (r = 0; r < NUM_REGS; r++)
376 do_win32_fetch_inferior_registers (r);
377 }
378
379 #undef I387_ST0_REGNUM
380 }
381
382 static void
383 win32_fetch_inferior_registers (int r)
384 {
385 current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
386 /* Check if current_thread exists. Windows sometimes uses a non-existent
387 thread id in its events */
388 if (current_thread)
389 do_win32_fetch_inferior_registers (r);
390 }
391
392 static void
393 do_win32_store_inferior_registers (int r)
394 {
395 if (!current_thread)
396 /* Windows sometimes uses a non-existent thread id in its events */;
397 else if (r >= 0)
398 regcache_raw_collect (current_regcache, r,
399 ((char *) &current_thread->context) + mappings[r]);
400 else
401 {
402 for (r = 0; r < NUM_REGS; r++)
403 do_win32_store_inferior_registers (r);
404 }
405 }
406
407 /* Store a new register value into the current thread context */
408 static void
409 win32_store_inferior_registers (int r)
410 {
411 current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
412 /* Check if current_thread exists. Windows sometimes uses a non-existent
413 thread id in its events */
414 if (current_thread)
415 do_win32_store_inferior_registers (r);
416 }
417
418 static int psapi_loaded = 0;
419 static HMODULE psapi_module_handle = NULL;
420 static BOOL WINAPI (*psapi_EnumProcessModules) (HANDLE, HMODULE *, DWORD, LPDWORD) = NULL;
421 static BOOL WINAPI (*psapi_GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO, DWORD) = NULL;
422 static DWORD WINAPI (*psapi_GetModuleFileNameExA) (HANDLE, HMODULE, LPSTR, DWORD) = NULL;
423
424 static int
425 psapi_get_dll_name (DWORD BaseAddress, char *dll_name_ret)
426 {
427 DWORD len;
428 MODULEINFO mi;
429 int i;
430 HMODULE dh_buf[1];
431 HMODULE *DllHandle = dh_buf;
432 DWORD cbNeeded;
433 BOOL ok;
434
435 if (!psapi_loaded ||
436 psapi_EnumProcessModules == NULL ||
437 psapi_GetModuleInformation == NULL ||
438 psapi_GetModuleFileNameExA == NULL)
439 {
440 if (psapi_loaded)
441 goto failed;
442 psapi_loaded = 1;
443 psapi_module_handle = LoadLibrary ("psapi.dll");
444 if (!psapi_module_handle)
445 {
446 /* printf_unfiltered ("error loading psapi.dll: %u", GetLastError ()); */
447 goto failed;
448 }
449 psapi_EnumProcessModules = GetProcAddress (psapi_module_handle, "EnumProcessModules");
450 psapi_GetModuleInformation = GetProcAddress (psapi_module_handle, "GetModuleInformation");
451 psapi_GetModuleFileNameExA = (void *) GetProcAddress (psapi_module_handle,
452 "GetModuleFileNameExA");
453 if (psapi_EnumProcessModules == NULL ||
454 psapi_GetModuleInformation == NULL ||
455 psapi_GetModuleFileNameExA == NULL)
456 goto failed;
457 }
458
459 cbNeeded = 0;
460 ok = (*psapi_EnumProcessModules) (current_process_handle,
461 DllHandle,
462 sizeof (HMODULE),
463 &cbNeeded);
464
465 if (!ok || !cbNeeded)
466 goto failed;
467
468 DllHandle = (HMODULE *) alloca (cbNeeded);
469 if (!DllHandle)
470 goto failed;
471
472 ok = (*psapi_EnumProcessModules) (current_process_handle,
473 DllHandle,
474 cbNeeded,
475 &cbNeeded);
476 if (!ok)
477 goto failed;
478
479 for (i = 0; i < (int) (cbNeeded / sizeof (HMODULE)); i++)
480 {
481 if (!(*psapi_GetModuleInformation) (current_process_handle,
482 DllHandle[i],
483 &mi,
484 sizeof (mi)))
485 error (_("Can't get module info"));
486
487 len = (*psapi_GetModuleFileNameExA) (current_process_handle,
488 DllHandle[i],
489 dll_name_ret,
490 MAX_PATH);
491 if (len == 0)
492 error (_("Error getting dll name: %u."), (unsigned) GetLastError ());
493
494 if ((DWORD) (mi.lpBaseOfDll) == BaseAddress)
495 return 1;
496 }
497
498 failed:
499 dll_name_ret[0] = '\0';
500 return 0;
501 }
502
503 /* Encapsulate the information required in a call to
504 symbol_file_add_args */
505 struct safe_symbol_file_add_args
506 {
507 char *name;
508 int from_tty;
509 struct section_addr_info *addrs;
510 int mainline;
511 int flags;
512 struct ui_file *err, *out;
513 struct objfile *ret;
514 };
515
516 /* Maintain a linked list of "so" information. */
517 struct lm_info
518 {
519 DWORD load_addr;
520 DWORD end_addr;
521 };
522
523 static struct so_list solib_start, *solib_end;
524
525 /* Call symbol_file_add with stderr redirected. We don't care if there
526 are errors. */
527 static int
528 safe_symbol_file_add_stub (void *argv)
529 {
530 #define p ((struct safe_symbol_file_add_args *) argv)
531 struct so_list *so = &solib_start;
532
533 p->ret = symbol_file_add (p->name, p->from_tty, p->addrs, p->mainline, p->flags);
534 return !!p->ret;
535 #undef p
536 }
537
538 /* Restore gdb's stderr after calling symbol_file_add */
539 static void
540 safe_symbol_file_add_cleanup (void *p)
541 {
542 #define sp ((struct safe_symbol_file_add_args *)p)
543 gdb_flush (gdb_stderr);
544 gdb_flush (gdb_stdout);
545 ui_file_delete (gdb_stderr);
546 ui_file_delete (gdb_stdout);
547 gdb_stderr = sp->err;
548 gdb_stdout = sp->out;
549 #undef sp
550 }
551
552 /* symbol_file_add wrapper that prevents errors from being displayed. */
553 static struct objfile *
554 safe_symbol_file_add (char *name, int from_tty,
555 struct section_addr_info *addrs,
556 int mainline, int flags)
557 {
558 struct safe_symbol_file_add_args p;
559 struct cleanup *cleanup;
560
561 cleanup = make_cleanup (safe_symbol_file_add_cleanup, &p);
562
563 p.err = gdb_stderr;
564 p.out = gdb_stdout;
565 gdb_flush (gdb_stderr);
566 gdb_flush (gdb_stdout);
567 gdb_stderr = ui_file_new ();
568 gdb_stdout = ui_file_new ();
569 p.name = name;
570 p.from_tty = from_tty;
571 p.addrs = addrs;
572 p.mainline = mainline;
573 p.flags = flags;
574 catch_errors (safe_symbol_file_add_stub, &p, "", RETURN_MASK_ERROR);
575
576 do_cleanups (cleanup);
577 return p.ret;
578 }
579
580 /* Remember the maximum DLL length for printing in info dll command. */
581 static int max_dll_name_len;
582
583 static void
584 register_loaded_dll (const char *name, DWORD load_addr)
585 {
586 struct so_list *so;
587 char ppath[MAX_PATH + 1];
588 char buf[MAX_PATH + 1];
589 char cwd[MAX_PATH + 1];
590 char *p;
591 WIN32_FIND_DATA w32_fd;
592 HANDLE h = FindFirstFile(name, &w32_fd);
593 MEMORY_BASIC_INFORMATION m;
594 size_t len;
595
596 if (h == INVALID_HANDLE_VALUE)
597 strcpy (buf, name);
598 else
599 {
600 FindClose (h);
601 strcpy (buf, name);
602 if (GetCurrentDirectory (MAX_PATH + 1, cwd))
603 {
604 p = strrchr (buf, '\\');
605 if (p)
606 p[1] = '\0';
607 SetCurrentDirectory (buf);
608 GetFullPathName (w32_fd.cFileName, MAX_PATH, buf, &p);
609 SetCurrentDirectory (cwd);
610 }
611 }
612
613 if (strcasecmp (buf, "ntdll.dll") == 0)
614 {
615 GetSystemDirectory (buf, sizeof (buf));
616 strcat (buf, "\\ntdll.dll");
617 }
618 cygwin_conv_to_posix_path (buf, ppath);
619 so = (struct so_list *) xmalloc (sizeof (struct so_list) + strlen (ppath) + 8 + 1);
620 memset (so, 0, sizeof (*so));
621 so->lm_info = (struct lm_info *) xmalloc (sizeof (struct lm_info));
622 so->lm_info->load_addr = load_addr;
623 if (VirtualQueryEx (current_process_handle, (void *) load_addr, &m,
624 sizeof (m)))
625 so->lm_info->end_addr = (DWORD) m.AllocationBase + m.RegionSize;
626 else
627 so->lm_info->end_addr = load_addr + 0x2000; /* completely arbitrary */
628
629 so->next = NULL;
630 strcpy (so->so_name, ppath);
631
632 solib_end->next = so;
633 solib_end = so;
634 len = strlen (ppath);
635 if (len > max_dll_name_len)
636 max_dll_name_len = len;
637 }
638
639 static char *
640 get_image_name (HANDLE h, void *address, int unicode)
641 {
642 static char buf[(2 * MAX_PATH) + 1];
643 DWORD size = unicode ? sizeof (WCHAR) : sizeof (char);
644 char *address_ptr;
645 int len = 0;
646 char b[2];
647 DWORD done;
648
649 /* Attempt to read the name of the dll that was detected.
650 This is documented to work only when actively debugging
651 a program. It will not work for attached processes. */
652 if (address == NULL)
653 return NULL;
654
655 /* See if we could read the address of a string, and that the
656 address isn't null. */
657 if (!ReadProcessMemory (h, address, &address_ptr, sizeof (address_ptr), &done)
658 || done != sizeof (address_ptr) || !address_ptr)
659 return NULL;
660
661 /* Find the length of the string */
662 while (ReadProcessMemory (h, address_ptr + len++ * size, &b, size, &done)
663 && (b[0] != 0 || b[size - 1] != 0) && done == size)
664 continue;
665
666 if (!unicode)
667 ReadProcessMemory (h, address_ptr, buf, len, &done);
668 else
669 {
670 WCHAR *unicode_address = (WCHAR *) alloca (len * sizeof (WCHAR));
671 ReadProcessMemory (h, address_ptr, unicode_address, len * sizeof (WCHAR),
672 &done);
673
674 WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf, len, 0, 0);
675 }
676
677 return buf;
678 }
679
680 /* Wait for child to do something. Return pid of child, or -1 in case
681 of error; store status through argument pointer OURSTATUS. */
682 static int
683 handle_load_dll (void *dummy)
684 {
685 LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
686 char dll_buf[MAX_PATH + 1];
687 char *dll_name = NULL;
688 char *p;
689
690 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
691
692 if (!psapi_get_dll_name ((DWORD) (event->lpBaseOfDll), dll_buf))
693 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
694
695 dll_name = dll_buf;
696
697 if (*dll_name == '\0')
698 dll_name = get_image_name (current_process_handle, event->lpImageName, event->fUnicode);
699 if (!dll_name)
700 return 1;
701
702 register_loaded_dll (dll_name, (DWORD) event->lpBaseOfDll + 0x1000);
703
704 return 1;
705 }
706
707 static void
708 win32_free_so (struct so_list *so)
709 {
710 if (so->objfile)
711 free_objfile (so->objfile);
712 if (so->lm_info)
713 xfree (so->lm_info);
714 }
715
716 static struct so_list *
717 win32_current_sos (void)
718 {
719 return solib_start.next;
720 }
721
722 static void
723 win32_relocate_section_addresses (struct so_list *so,
724 struct section_table *sec)
725 {
726 /* FIXME */
727 return;
728 }
729
730 static int
731 handle_unload_dll (void *dummy)
732 {
733 DWORD lpBaseOfDll = (DWORD) current_event.u.UnloadDll.lpBaseOfDll + 0x1000;
734 struct so_list *so;
735
736 for (so = &solib_start; so->next != NULL; so = so->next)
737 if (so->next->lm_info->load_addr == lpBaseOfDll)
738 {
739 struct so_list *sodel = so->next;
740 so->next = sodel->next;
741 if (!so->next)
742 solib_end = so;
743 free_so (sodel);
744 return 1;
745 }
746 error (_("Error: dll starting at 0x%lx not found."), (DWORD) lpBaseOfDll);
747
748 return 0;
749 }
750
751 /* Clear list of loaded DLLs. */
752 static void
753 win32_clear_solib (void)
754 {
755 struct so_list *so, *so1 = solib_start.next;
756
757 solib_start.next = NULL;
758 solib_end = &solib_start;
759 max_dll_name_len = sizeof ("DLL Name") - 1;
760 }
761
762 /* Load DLL symbol info. */
763 void
764 dll_symbol_command (char *args, int from_tty)
765 {
766 int n;
767 dont_repeat ();
768
769 if (args == NULL)
770 error (_("dll-symbols requires a file name"));
771
772 n = strlen (args);
773 if (n > 4 && strcasecmp (args + n - 4, ".dll") != 0)
774 {
775 char *newargs = (char *) alloca (n + 4 + 1);
776 strcpy (newargs, args);
777 strcat (newargs, ".dll");
778 args = newargs;
779 }
780
781 safe_symbol_file_add (args, from_tty, NULL, 0, OBJF_SHARED | OBJF_USERLOADED);
782 }
783
784 /* List currently loaded DLLs. */
785 static void
786 info_dll_command (char *ignore, int from_tty)
787 {
788 struct so_list *so = &solib_start;
789
790 if (!so->next)
791 return;
792
793 printf_filtered ("%*s Load Address\n", -max_dll_name_len, "DLL Name");
794 while ((so = so->next) != NULL)
795 printf_filtered ("%*s %08lx\n", -max_dll_name_len, so->so_name, so->lm_info->load_addr);
796
797 return;
798 }
799
800 /* Handle DEBUG_STRING output from child process.
801 Cygwin prepends its messages with a "cygwin:". Interpret this as
802 a Cygwin signal. Otherwise just print the string as a warning. */
803 static int
804 handle_output_debug_string (struct target_waitstatus *ourstatus)
805 {
806 char *s;
807 int gotasig = FALSE;
808
809 if (!target_read_string
810 ((CORE_ADDR) current_event.u.DebugString.lpDebugStringData, &s, 1024, 0)
811 || !s || !*s)
812 return gotasig;
813
814 if (strncmp (s, CYGWIN_SIGNAL_STRING, sizeof (CYGWIN_SIGNAL_STRING) - 1) != 0)
815 {
816 if (strncmp (s, "cYg", 3) != 0)
817 warning (("%s"), s);
818 }
819 else
820 {
821 char *p;
822 int sig = strtol (s + sizeof (CYGWIN_SIGNAL_STRING) - 1, &p, 0);
823 gotasig = target_signal_from_host (sig);
824 ourstatus->value.sig = gotasig;
825 if (gotasig)
826 ourstatus->kind = TARGET_WAITKIND_STOPPED;
827 }
828
829 xfree (s);
830 return gotasig;
831 }
832
833 static int
834 display_selector (HANDLE thread, DWORD sel)
835 {
836 LDT_ENTRY info;
837 if (GetThreadSelectorEntry (thread, sel, &info))
838 {
839 int base, limit;
840 printf_filtered ("0x%03lx: ", sel);
841 if (!info.HighWord.Bits.Pres)
842 {
843 puts_filtered ("Segment not present\n");
844 return 0;
845 }
846 base = (info.HighWord.Bits.BaseHi << 24) +
847 (info.HighWord.Bits.BaseMid << 16)
848 + info.BaseLow;
849 limit = (info.HighWord.Bits.LimitHi << 16) + info.LimitLow;
850 if (info.HighWord.Bits.Granularity)
851 limit = (limit << 12) | 0xfff;
852 printf_filtered ("base=0x%08x limit=0x%08x", base, limit);
853 if (info.HighWord.Bits.Default_Big)
854 puts_filtered(" 32-bit ");
855 else
856 puts_filtered(" 16-bit ");
857 switch ((info.HighWord.Bits.Type & 0xf) >> 1)
858 {
859 case 0:
860 puts_filtered ("Data (Read-Only, Exp-up");
861 break;
862 case 1:
863 puts_filtered ("Data (Read/Write, Exp-up");
864 break;
865 case 2:
866 puts_filtered ("Unused segment (");
867 break;
868 case 3:
869 puts_filtered ("Data (Read/Write, Exp-down");
870 break;
871 case 4:
872 puts_filtered ("Code (Exec-Only, N.Conf");
873 break;
874 case 5:
875 puts_filtered ("Code (Exec/Read, N.Conf");
876 break;
877 case 6:
878 puts_filtered ("Code (Exec-Only, Conf");
879 break;
880 case 7:
881 puts_filtered ("Code (Exec/Read, Conf");
882 break;
883 default:
884 printf_filtered ("Unknown type 0x%x",info.HighWord.Bits.Type);
885 }
886 if ((info.HighWord.Bits.Type & 0x1) == 0)
887 puts_filtered(", N.Acc");
888 puts_filtered (")\n");
889 if ((info.HighWord.Bits.Type & 0x10) == 0)
890 puts_filtered("System selector ");
891 printf_filtered ("Priviledge level = %d. ", info.HighWord.Bits.Dpl);
892 if (info.HighWord.Bits.Granularity)
893 puts_filtered ("Page granular.\n");
894 else
895 puts_filtered ("Byte granular.\n");
896 return 1;
897 }
898 else
899 {
900 printf_filtered ("Invalid selector 0x%lx.\n",sel);
901 return 0;
902 }
903 }
904
905 static void
906 display_selectors (char * args, int from_tty)
907 {
908 if (!current_thread)
909 {
910 puts_filtered ("Impossible to display selectors now.\n");
911 return;
912 }
913 if (!args)
914 {
915
916 puts_filtered ("Selector $cs\n");
917 display_selector (current_thread->h,
918 current_thread->context.SegCs);
919 puts_filtered ("Selector $ds\n");
920 display_selector (current_thread->h,
921 current_thread->context.SegDs);
922 puts_filtered ("Selector $es\n");
923 display_selector (current_thread->h,
924 current_thread->context.SegEs);
925 puts_filtered ("Selector $ss\n");
926 display_selector (current_thread->h,
927 current_thread->context.SegSs);
928 puts_filtered ("Selector $fs\n");
929 display_selector (current_thread->h,
930 current_thread->context.SegFs);
931 puts_filtered ("Selector $gs\n");
932 display_selector (current_thread->h,
933 current_thread->context.SegGs);
934 }
935 else
936 {
937 int sel;
938 sel = parse_and_eval_long (args);
939 printf_filtered ("Selector \"%s\"\n",args);
940 display_selector (current_thread->h, sel);
941 }
942 }
943
944 static struct cmd_list_element *info_w32_cmdlist = NULL;
945
946 static void
947 info_w32_command (char *args, int from_tty)
948 {
949 help_list (info_w32_cmdlist, "info w32 ", class_info, gdb_stdout);
950 }
951
952
953 #define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \
954 printf_unfiltered ("gdb: Target exception %s at 0x%08lx\n", x, \
955 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress)
956
957 static int
958 handle_exception (struct target_waitstatus *ourstatus)
959 {
960 thread_info *th;
961 DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
962
963 ourstatus->kind = TARGET_WAITKIND_STOPPED;
964
965 /* Record the context of the current thread */
966 th = thread_rec (current_event.dwThreadId, -1);
967
968 switch (code)
969 {
970 case EXCEPTION_ACCESS_VIOLATION:
971 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
972 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
973 {
974 char *fn;
975 if (find_pc_partial_function ((CORE_ADDR) current_event.u.Exception
976 .ExceptionRecord.ExceptionAddress,
977 &fn, NULL, NULL)
978 && strncmp (fn, "KERNEL32!IsBad", strlen ("KERNEL32!IsBad")) == 0)
979 return 0;
980 }
981 break;
982 case STATUS_STACK_OVERFLOW:
983 DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
984 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
985 break;
986 case STATUS_FLOAT_DENORMAL_OPERAND:
987 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
988 ourstatus->value.sig = TARGET_SIGNAL_FPE;
989 break;
990 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
991 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
992 ourstatus->value.sig = TARGET_SIGNAL_FPE;
993 break;
994 case STATUS_FLOAT_INEXACT_RESULT:
995 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
996 ourstatus->value.sig = TARGET_SIGNAL_FPE;
997 break;
998 case STATUS_FLOAT_INVALID_OPERATION:
999 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
1000 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1001 break;
1002 case STATUS_FLOAT_OVERFLOW:
1003 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
1004 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1005 break;
1006 case STATUS_FLOAT_STACK_CHECK:
1007 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
1008 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1009 break;
1010 case STATUS_FLOAT_UNDERFLOW:
1011 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
1012 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1013 break;
1014 case STATUS_FLOAT_DIVIDE_BY_ZERO:
1015 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
1016 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1017 break;
1018 case STATUS_INTEGER_DIVIDE_BY_ZERO:
1019 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
1020 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1021 break;
1022 case STATUS_INTEGER_OVERFLOW:
1023 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
1024 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1025 break;
1026 case EXCEPTION_BREAKPOINT:
1027 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
1028 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1029 break;
1030 case DBG_CONTROL_C:
1031 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
1032 ourstatus->value.sig = TARGET_SIGNAL_INT;
1033 break;
1034 case DBG_CONTROL_BREAK:
1035 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
1036 ourstatus->value.sig = TARGET_SIGNAL_INT;
1037 break;
1038 case EXCEPTION_SINGLE_STEP:
1039 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
1040 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1041 break;
1042 case EXCEPTION_ILLEGAL_INSTRUCTION:
1043 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
1044 ourstatus->value.sig = TARGET_SIGNAL_ILL;
1045 break;
1046 case EXCEPTION_PRIV_INSTRUCTION:
1047 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
1048 ourstatus->value.sig = TARGET_SIGNAL_ILL;
1049 break;
1050 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
1051 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
1052 ourstatus->value.sig = TARGET_SIGNAL_ILL;
1053 break;
1054 default:
1055 if (current_event.u.Exception.dwFirstChance)
1056 return 0;
1057 printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n",
1058 current_event.u.Exception.ExceptionRecord.ExceptionCode,
1059 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress);
1060 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
1061 break;
1062 }
1063 exception_count++;
1064 last_sig = ourstatus->value.sig;
1065 return 1;
1066 }
1067
1068 /* Resume all artificially suspended threads if we are continuing
1069 execution */
1070 static BOOL
1071 win32_continue (DWORD continue_status, int id)
1072 {
1073 int i;
1074 thread_info *th;
1075 BOOL res;
1076
1077 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, %s);\n",
1078 current_event.dwProcessId, current_event.dwThreadId,
1079 continue_status == DBG_CONTINUE ?
1080 "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED"));
1081 res = ContinueDebugEvent (current_event.dwProcessId,
1082 current_event.dwThreadId,
1083 continue_status);
1084 continue_status = 0;
1085 if (res)
1086 for (th = &thread_head; (th = th->next) != NULL;)
1087 if (((id == -1) || (id == (int) th->id)) && th->suspend_count)
1088 {
1089
1090 for (i = 0; i < th->suspend_count; i++)
1091 (void) ResumeThread (th->h);
1092 th->suspend_count = 0;
1093 if (debug_registers_changed)
1094 {
1095 /* Only change the value of the debug registers */
1096 th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
1097 th->context.Dr0 = dr[0];
1098 th->context.Dr1 = dr[1];
1099 th->context.Dr2 = dr[2];
1100 th->context.Dr3 = dr[3];
1101 /* th->context.Dr6 = dr[6];
1102 FIXME: should we set dr6 also ?? */
1103 th->context.Dr7 = dr[7];
1104 CHECK (SetThreadContext (th->h, &th->context));
1105 th->context.ContextFlags = 0;
1106 }
1107 }
1108
1109 debug_registers_changed = 0;
1110 return res;
1111 }
1112
1113 /* Called in pathological case where Windows fails to send a
1114 CREATE_PROCESS_DEBUG_EVENT after an attach. */
1115 static DWORD
1116 fake_create_process (void)
1117 {
1118 current_process_handle = OpenProcess (PROCESS_ALL_ACCESS, FALSE,
1119 current_event.dwProcessId);
1120 main_thread_id = current_event.dwThreadId;
1121 current_thread = win32_add_thread (main_thread_id,
1122 current_event.u.CreateThread.hThread);
1123 return main_thread_id;
1124 }
1125
1126 /* Get the next event from the child. Return 1 if the event requires
1127 handling by WFI (or whatever).
1128 */
1129 static int
1130 get_win32_debug_event (int pid, struct target_waitstatus *ourstatus)
1131 {
1132 BOOL debug_event;
1133 DWORD continue_status, event_code;
1134 thread_info *th;
1135 static thread_info dummy_thread_info;
1136 int retval = 0;
1137
1138 last_sig = TARGET_SIGNAL_0;
1139
1140 if (!(debug_event = WaitForDebugEvent (&current_event, 1000)))
1141 goto out;
1142
1143 event_count++;
1144 continue_status = DBG_CONTINUE;
1145
1146 event_code = current_event.dwDebugEventCode;
1147 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
1148 th = NULL;
1149
1150 switch (event_code)
1151 {
1152 case CREATE_THREAD_DEBUG_EVENT:
1153 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1154 (unsigned) current_event.dwProcessId,
1155 (unsigned) current_event.dwThreadId,
1156 "CREATE_THREAD_DEBUG_EVENT"));
1157 if (saw_create != 1)
1158 {
1159 if (!saw_create && attach_flag)
1160 {
1161 /* Kludge around a Windows bug where first event is a create
1162 thread event. Caused when attached process does not have
1163 a main thread. */
1164 retval = ourstatus->value.related_pid = fake_create_process ();
1165 saw_create++;
1166 }
1167 break;
1168 }
1169 /* Record the existence of this thread */
1170 th = win32_add_thread (current_event.dwThreadId,
1171 current_event.u.CreateThread.hThread);
1172 if (info_verbose)
1173 printf_unfiltered ("[New %s]\n",
1174 target_pid_to_str (
1175 pid_to_ptid (current_event.dwThreadId)));
1176 retval = current_event.dwThreadId;
1177 break;
1178
1179 case EXIT_THREAD_DEBUG_EVENT:
1180 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1181 (unsigned) current_event.dwProcessId,
1182 (unsigned) current_event.dwThreadId,
1183 "EXIT_THREAD_DEBUG_EVENT"));
1184 if (current_event.dwThreadId != main_thread_id)
1185 {
1186 win32_delete_thread (current_event.dwThreadId);
1187 th = &dummy_thread_info;
1188 }
1189 break;
1190
1191 case CREATE_PROCESS_DEBUG_EVENT:
1192 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1193 (unsigned) current_event.dwProcessId,
1194 (unsigned) current_event.dwThreadId,
1195 "CREATE_PROCESS_DEBUG_EVENT"));
1196 CloseHandle (current_event.u.CreateProcessInfo.hFile);
1197 if (++saw_create != 1)
1198 {
1199 CloseHandle (current_event.u.CreateProcessInfo.hProcess);
1200 break;
1201 }
1202
1203 current_process_handle = current_event.u.CreateProcessInfo.hProcess;
1204 if (main_thread_id)
1205 win32_delete_thread (main_thread_id);
1206 main_thread_id = current_event.dwThreadId;
1207 /* Add the main thread */
1208 th = win32_add_thread (main_thread_id,
1209 current_event.u.CreateProcessInfo.hThread);
1210 retval = ourstatus->value.related_pid = current_event.dwThreadId;
1211 break;
1212
1213 case EXIT_PROCESS_DEBUG_EVENT:
1214 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1215 (unsigned) current_event.dwProcessId,
1216 (unsigned) current_event.dwThreadId,
1217 "EXIT_PROCESS_DEBUG_EVENT"));
1218 if (saw_create != 1)
1219 break;
1220 ourstatus->kind = TARGET_WAITKIND_EXITED;
1221 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
1222 CloseHandle (current_process_handle);
1223 retval = main_thread_id;
1224 break;
1225
1226 case LOAD_DLL_DEBUG_EVENT:
1227 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1228 (unsigned) current_event.dwProcessId,
1229 (unsigned) current_event.dwThreadId,
1230 "LOAD_DLL_DEBUG_EVENT"));
1231 CloseHandle (current_event.u.LoadDll.hFile);
1232 if (saw_create != 1)
1233 break;
1234 catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
1235 registers_changed (); /* mark all regs invalid */
1236 ourstatus->kind = TARGET_WAITKIND_LOADED;
1237 ourstatus->value.integer = 0;
1238 retval = main_thread_id;
1239 re_enable_breakpoints_in_shlibs ();
1240 break;
1241
1242 case UNLOAD_DLL_DEBUG_EVENT:
1243 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1244 (unsigned) current_event.dwProcessId,
1245 (unsigned) current_event.dwThreadId,
1246 "UNLOAD_DLL_DEBUG_EVENT"));
1247 if (saw_create != 1)
1248 break;
1249 catch_errors (handle_unload_dll, NULL, (char *) "", RETURN_MASK_ALL);
1250 registers_changed (); /* mark all regs invalid */
1251 /* ourstatus->kind = TARGET_WAITKIND_UNLOADED;
1252 does not exist yet. */
1253 break;
1254
1255 case EXCEPTION_DEBUG_EVENT:
1256 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1257 (unsigned) current_event.dwProcessId,
1258 (unsigned) current_event.dwThreadId,
1259 "EXCEPTION_DEBUG_EVENT"));
1260 if (saw_create != 1)
1261 break;
1262 if (handle_exception (ourstatus))
1263 retval = current_event.dwThreadId;
1264 else
1265 continue_status = DBG_EXCEPTION_NOT_HANDLED;
1266 break;
1267
1268 case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */
1269 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1270 (unsigned) current_event.dwProcessId,
1271 (unsigned) current_event.dwThreadId,
1272 "OUTPUT_DEBUG_STRING_EVENT"));
1273 if (saw_create != 1)
1274 break;
1275 if (handle_output_debug_string (ourstatus))
1276 retval = main_thread_id;
1277 break;
1278
1279 default:
1280 if (saw_create != 1)
1281 break;
1282 printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
1283 (DWORD) current_event.dwProcessId,
1284 (DWORD) current_event.dwThreadId);
1285 printf_unfiltered (" unknown event code %ld\n",
1286 current_event.dwDebugEventCode);
1287 break;
1288 }
1289
1290 if (!retval || saw_create != 1)
1291 CHECK (win32_continue (continue_status, -1));
1292 else
1293 {
1294 inferior_ptid = pid_to_ptid (retval);
1295 current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE);
1296 }
1297
1298 out:
1299 return retval;
1300 }
1301
1302 /* Wait for interesting events to occur in the target process. */
1303 static ptid_t
1304 win32_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
1305 {
1306 int pid = PIDGET (ptid);
1307
1308 /* We loop when we get a non-standard exception rather than return
1309 with a SPURIOUS because resume can try and step or modify things,
1310 which needs a current_thread->h. But some of these exceptions mark
1311 the birth or death of threads, which mean that the current thread
1312 isn't necessarily what you think it is. */
1313
1314 while (1)
1315 {
1316 int retval = get_win32_debug_event (pid, ourstatus);
1317 if (retval)
1318 return pid_to_ptid (retval);
1319 else
1320 {
1321 int detach = 0;
1322
1323 if (deprecated_ui_loop_hook != NULL)
1324 detach = deprecated_ui_loop_hook (0);
1325
1326 if (detach)
1327 win32_kill_inferior ();
1328 }
1329 }
1330 }
1331
1332 static void
1333 do_initial_win32_stuff (DWORD pid)
1334 {
1335 extern int stop_after_trap;
1336 int i;
1337
1338 last_sig = TARGET_SIGNAL_0;
1339 event_count = 0;
1340 exception_count = 0;
1341 debug_registers_changed = 0;
1342 debug_registers_used = 0;
1343 for (i = 0; i < sizeof (dr) / sizeof (dr[0]); i++)
1344 dr[i] = 0;
1345 current_event.dwProcessId = pid;
1346 memset (&current_event, 0, sizeof (current_event));
1347 push_target (&win32_ops);
1348 disable_breakpoints_in_shlibs (1);
1349 win32_clear_solib ();
1350 clear_proceed_status ();
1351 init_wait_for_inferior ();
1352
1353 target_terminal_init ();
1354 target_terminal_inferior ();
1355
1356 while (1)
1357 {
1358 stop_after_trap = 1;
1359 wait_for_inferior ();
1360 if (stop_signal != TARGET_SIGNAL_TRAP)
1361 resume (0, stop_signal);
1362 else
1363 break;
1364 }
1365 stop_after_trap = 0;
1366 return;
1367 }
1368
1369 /* Since Windows XP, detaching from a process is supported by Windows.
1370 The following code tries loading the appropriate functions dynamically.
1371 If loading these functions succeeds use them to actually detach from
1372 the inferior process, otherwise behave as usual, pretending that
1373 detach has worked. */
1374 static BOOL WINAPI (*DebugSetProcessKillOnExit)(BOOL);
1375 static BOOL WINAPI (*DebugActiveProcessStop)(DWORD);
1376
1377 static int
1378 has_detach_ability (void)
1379 {
1380 static HMODULE kernel32 = NULL;
1381
1382 if (!kernel32)
1383 kernel32 = LoadLibrary ("kernel32.dll");
1384 if (kernel32)
1385 {
1386 if (!DebugSetProcessKillOnExit)
1387 DebugSetProcessKillOnExit = GetProcAddress (kernel32,
1388 "DebugSetProcessKillOnExit");
1389 if (!DebugActiveProcessStop)
1390 DebugActiveProcessStop = GetProcAddress (kernel32,
1391 "DebugActiveProcessStop");
1392 if (DebugSetProcessKillOnExit && DebugActiveProcessStop)
1393 return 1;
1394 }
1395 return 0;
1396 }
1397
1398 /* Try to set or remove a user privilege to the current process. Return -1
1399 if that fails, the previous setting of that privilege otherwise.
1400
1401 This code is copied from the Cygwin source code and rearranged to allow
1402 dynamically loading of the needed symbols from advapi32 which is only
1403 available on NT/2K/XP. */
1404 static int
1405 set_process_privilege (const char *privilege, BOOL enable)
1406 {
1407 static HMODULE advapi32 = NULL;
1408 static BOOL WINAPI (*OpenProcessToken)(HANDLE, DWORD, PHANDLE);
1409 static BOOL WINAPI (*LookupPrivilegeValue)(LPCSTR, LPCSTR, PLUID);
1410 static BOOL WINAPI (*AdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES,
1411 DWORD, PTOKEN_PRIVILEGES, PDWORD);
1412
1413 HANDLE token_hdl = NULL;
1414 LUID restore_priv;
1415 TOKEN_PRIVILEGES new_priv, orig_priv;
1416 int ret = -1;
1417 DWORD size;
1418
1419 if (GetVersion () >= 0x80000000) /* No security availbale on 9x/Me */
1420 return 0;
1421
1422 if (!advapi32)
1423 {
1424 if (!(advapi32 = LoadLibrary ("advapi32.dll")))
1425 goto out;
1426 if (!OpenProcessToken)
1427 OpenProcessToken = GetProcAddress (advapi32, "OpenProcessToken");
1428 if (!LookupPrivilegeValue)
1429 LookupPrivilegeValue = GetProcAddress (advapi32,
1430 "LookupPrivilegeValueA");
1431 if (!AdjustTokenPrivileges)
1432 AdjustTokenPrivileges = GetProcAddress (advapi32,
1433 "AdjustTokenPrivileges");
1434 if (!OpenProcessToken || !LookupPrivilegeValue || !AdjustTokenPrivileges)
1435 {
1436 advapi32 = NULL;
1437 goto out;
1438 }
1439 }
1440
1441 if (!OpenProcessToken (GetCurrentProcess (),
1442 TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
1443 &token_hdl))
1444 goto out;
1445
1446 if (!LookupPrivilegeValue (NULL, privilege, &restore_priv))
1447 goto out;
1448
1449 new_priv.PrivilegeCount = 1;
1450 new_priv.Privileges[0].Luid = restore_priv;
1451 new_priv.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
1452
1453 if (!AdjustTokenPrivileges (token_hdl, FALSE, &new_priv,
1454 sizeof orig_priv, &orig_priv, &size))
1455 goto out;
1456 #if 0
1457 /* Disabled, otherwise every `attach' in an unprivileged user session
1458 would raise the "Failed to get SE_DEBUG_NAME privilege" warning in
1459 win32_attach(). */
1460 /* AdjustTokenPrivileges returns TRUE even if the privilege could not
1461 be enabled. GetLastError () returns an correct error code, though. */
1462 if (enable && GetLastError () == ERROR_NOT_ALL_ASSIGNED)
1463 goto out;
1464 #endif
1465
1466 ret = orig_priv.Privileges[0].Attributes == SE_PRIVILEGE_ENABLED ? 1 : 0;
1467
1468 out:
1469 if (token_hdl)
1470 CloseHandle (token_hdl);
1471
1472 return ret;
1473 }
1474
1475 /* Attach to process PID, then initialize for debugging it. */
1476 static void
1477 win32_attach (char *args, int from_tty)
1478 {
1479 BOOL ok;
1480 DWORD pid;
1481
1482 if (!args)
1483 error_no_arg (_("process-id to attach"));
1484
1485 if (set_process_privilege (SE_DEBUG_NAME, TRUE) < 0)
1486 {
1487 printf_unfiltered ("Warning: Failed to get SE_DEBUG_NAME privilege\n");
1488 printf_unfiltered ("This can cause attach to fail on Windows NT/2K/XP\n");
1489 }
1490
1491 pid = strtoul (args, 0, 0); /* Windows pid */
1492
1493 win32_init_thread_list ();
1494 ok = DebugActiveProcess (pid);
1495 saw_create = 0;
1496
1497 if (!ok)
1498 {
1499 /* Try fall back to Cygwin pid */
1500 pid = cygwin_internal (CW_CYGWIN_PID_TO_WINPID, pid);
1501
1502 if (pid > 0)
1503 ok = DebugActiveProcess (pid);
1504
1505 if (!ok)
1506 error (_("Can't attach to process."));
1507 }
1508
1509 if (has_detach_ability ())
1510 DebugSetProcessKillOnExit (FALSE);
1511
1512 attach_flag = 1;
1513
1514 if (from_tty)
1515 {
1516 char *exec_file = (char *) get_exec_file (0);
1517
1518 if (exec_file)
1519 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
1520 target_pid_to_str (pid_to_ptid (pid)));
1521 else
1522 printf_unfiltered ("Attaching to %s\n",
1523 target_pid_to_str (pid_to_ptid (pid)));
1524
1525 gdb_flush (gdb_stdout);
1526 }
1527
1528 do_initial_win32_stuff (pid);
1529 target_terminal_ours ();
1530 }
1531
1532 static void
1533 win32_detach (char *args, int from_tty)
1534 {
1535 int detached = 1;
1536
1537 if (has_detach_ability ())
1538 {
1539 delete_command (NULL, 0);
1540 win32_continue (DBG_CONTINUE, -1);
1541 if (!DebugActiveProcessStop (current_event.dwProcessId))
1542 {
1543 error (_("Can't detach process %lu (error %lu)"),
1544 current_event.dwProcessId, GetLastError ());
1545 detached = 0;
1546 }
1547 DebugSetProcessKillOnExit (FALSE);
1548 }
1549 if (detached && from_tty)
1550 {
1551 char *exec_file = get_exec_file (0);
1552 if (exec_file == 0)
1553 exec_file = "";
1554 printf_unfiltered ("Detaching from program: %s, Pid %lu\n", exec_file,
1555 current_event.dwProcessId);
1556 gdb_flush (gdb_stdout);
1557 }
1558 inferior_ptid = null_ptid;
1559 unpush_target (&win32_ops);
1560 }
1561
1562 static char *
1563 win32_pid_to_exec_file (int pid)
1564 {
1565 /* Try to find the process path using the Cygwin internal process list
1566 pid isn't a valid pid, unfortunately. Use current_event.dwProcessId
1567 instead. */
1568 /* TODO: Also find native Windows processes using CW_GETPINFO_FULL. */
1569
1570 static char path[MAX_PATH + 1];
1571 char *path_ptr = NULL;
1572 int cpid;
1573 struct external_pinfo *pinfo;
1574
1575 cygwin_internal (CW_LOCK_PINFO, 1000);
1576 for (cpid = 0;
1577 (pinfo = (struct external_pinfo *)
1578 cygwin_internal (CW_GETPINFO, cpid | CW_NEXTPID));
1579 cpid = pinfo->pid)
1580 {
1581 if (pinfo->dwProcessId == current_event.dwProcessId) /* Got it */
1582 {
1583 cygwin_conv_to_full_posix_path (pinfo->progname, path);
1584 path_ptr = path;
1585 break;
1586 }
1587 }
1588 cygwin_internal (CW_UNLOCK_PINFO);
1589 return path_ptr;
1590 }
1591
1592 /* Print status information about what we're accessing. */
1593
1594 static void
1595 win32_files_info (struct target_ops *ignore)
1596 {
1597 printf_unfiltered ("\tUsing the running image of %s %s.\n",
1598 attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid));
1599 }
1600
1601 static void
1602 win32_open (char *arg, int from_tty)
1603 {
1604 error (_("Use the \"run\" command to start a Unix child process."));
1605 }
1606
1607 /* Start an inferior win32 child process and sets inferior_ptid to its pid.
1608 EXEC_FILE is the file to run.
1609 ALLARGS is a string containing the arguments to the program.
1610 ENV is the environment vector to pass. Errors reported with error(). */
1611
1612 static void
1613 win32_create_inferior (char *exec_file, char *allargs, char **env,
1614 int from_tty)
1615 {
1616 char *winenv;
1617 char *temp;
1618 int envlen;
1619 int i;
1620 STARTUPINFO si;
1621 PROCESS_INFORMATION pi;
1622 BOOL ret;
1623 DWORD flags;
1624 char *args;
1625 char real_path[MAXPATHLEN];
1626 char *toexec;
1627 char shell[MAX_PATH + 1]; /* Path to shell */
1628 const char *sh;
1629 int tty;
1630 int ostdin, ostdout, ostderr;
1631 const char *inferior_io_terminal = get_inferior_io_terminal ();
1632
1633 if (!exec_file)
1634 error (_("No executable specified, use `target exec'."));
1635
1636 memset (&si, 0, sizeof (si));
1637 si.cb = sizeof (si);
1638
1639 if (!useshell)
1640 {
1641 flags = DEBUG_ONLY_THIS_PROCESS;
1642 cygwin_conv_to_win32_path (exec_file, real_path);
1643 toexec = real_path;
1644 }
1645 else
1646 {
1647 char *newallargs;
1648 sh = getenv ("SHELL");
1649 if (!sh)
1650 sh = "/bin/sh";
1651 cygwin_conv_to_win32_path (sh, shell);
1652 newallargs = alloca (sizeof (" -c 'exec '") + strlen (exec_file)
1653 + strlen (allargs) + 2);
1654 sprintf (newallargs, " -c 'exec %s %s'", exec_file, allargs);
1655 allargs = newallargs;
1656 toexec = shell;
1657 flags = DEBUG_PROCESS;
1658 }
1659
1660 if (new_group)
1661 flags |= CREATE_NEW_PROCESS_GROUP;
1662
1663 if (new_console)
1664 flags |= CREATE_NEW_CONSOLE;
1665
1666 attach_flag = 0;
1667
1668 args = alloca (strlen (toexec) + strlen (allargs) + 2);
1669 strcpy (args, toexec);
1670 strcat (args, " ");
1671 strcat (args, allargs);
1672
1673 /* Prepare the environment vars for CreateProcess. */
1674 {
1675 /* This code used to assume all env vars were file names and would
1676 translate them all to win32 style. That obviously doesn't work in the
1677 general case. The current rule is that we only translate PATH.
1678 We need to handle PATH because we're about to call CreateProcess and
1679 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
1680 in both posix and win32 environments. cygwin.dll will change it back
1681 to posix style if necessary. */
1682
1683 static const char *conv_path_names[] =
1684 {
1685 "PATH=",
1686 0
1687 };
1688
1689 /* CreateProcess takes the environment list as a null terminated set of
1690 strings (i.e. two nulls terminate the list). */
1691
1692 /* Get total size for env strings. */
1693 for (envlen = 0, i = 0; env[i] && *env[i]; i++)
1694 {
1695 int j, len;
1696
1697 for (j = 0; conv_path_names[j]; j++)
1698 {
1699 len = strlen (conv_path_names[j]);
1700 if (strncmp (conv_path_names[j], env[i], len) == 0)
1701 {
1702 if (cygwin_posix_path_list_p (env[i] + len))
1703 envlen += len
1704 + cygwin_posix_to_win32_path_list_buf_size (env[i] + len);
1705 else
1706 envlen += strlen (env[i]) + 1;
1707 break;
1708 }
1709 }
1710 if (conv_path_names[j] == NULL)
1711 envlen += strlen (env[i]) + 1;
1712 }
1713
1714 winenv = alloca (envlen + 1);
1715
1716 /* Copy env strings into new buffer. */
1717 for (temp = winenv, i = 0; env[i] && *env[i]; i++)
1718 {
1719 int j, len;
1720
1721 for (j = 0; conv_path_names[j]; j++)
1722 {
1723 len = strlen (conv_path_names[j]);
1724 if (strncmp (conv_path_names[j], env[i], len) == 0)
1725 {
1726 if (cygwin_posix_path_list_p (env[i] + len))
1727 {
1728 memcpy (temp, env[i], len);
1729 cygwin_posix_to_win32_path_list (env[i] + len, temp + len);
1730 }
1731 else
1732 strcpy (temp, env[i]);
1733 break;
1734 }
1735 }
1736 if (conv_path_names[j] == NULL)
1737 strcpy (temp, env[i]);
1738
1739 temp += strlen (temp) + 1;
1740 }
1741
1742 /* Final nil string to terminate new env. */
1743 *temp = 0;
1744 }
1745
1746 if (!inferior_io_terminal)
1747 tty = ostdin = ostdout = ostderr = -1;
1748 else
1749 {
1750 tty = open (inferior_io_terminal, O_RDWR | O_NOCTTY);
1751 if (tty < 0)
1752 {
1753 print_sys_errmsg (inferior_io_terminal, errno);
1754 ostdin = ostdout = ostderr = -1;
1755 }
1756 else
1757 {
1758 ostdin = dup (0);
1759 ostdout = dup (1);
1760 ostderr = dup (2);
1761 dup2 (tty, 0);
1762 dup2 (tty, 1);
1763 dup2 (tty, 2);
1764 }
1765 }
1766
1767 win32_init_thread_list ();
1768 ret = CreateProcess (0,
1769 args, /* command line */
1770 NULL, /* Security */
1771 NULL, /* thread */
1772 TRUE, /* inherit handles */
1773 flags, /* start flags */
1774 winenv,
1775 NULL, /* current directory */
1776 &si,
1777 &pi);
1778 if (tty >= 0)
1779 {
1780 close (tty);
1781 dup2 (ostdin, 0);
1782 dup2 (ostdout, 1);
1783 dup2 (ostderr, 2);
1784 close (ostdin);
1785 close (ostdout);
1786 close (ostderr);
1787 }
1788
1789 if (!ret)
1790 error (_("Error creating process %s, (error %d)."),
1791 exec_file, (unsigned) GetLastError ());
1792
1793 CloseHandle (pi.hThread);
1794 CloseHandle (pi.hProcess);
1795
1796 if (useshell && shell[0] != '\0')
1797 saw_create = -1;
1798 else
1799 saw_create = 0;
1800
1801 do_initial_win32_stuff (pi.dwProcessId);
1802
1803 /* win32_continue (DBG_CONTINUE, -1); */
1804 proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
1805 }
1806
1807 static void
1808 win32_mourn_inferior (void)
1809 {
1810 (void) win32_continue (DBG_CONTINUE, -1);
1811 i386_cleanup_dregs();
1812 unpush_target (&win32_ops);
1813 generic_mourn_inferior ();
1814 }
1815
1816 /* Send a SIGINT to the process group. This acts just like the user typed a
1817 ^C on the controlling terminal. */
1818
1819 static void
1820 win32_stop (void)
1821 {
1822 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
1823 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
1824 registers_changed (); /* refresh register state */
1825 }
1826
1827 static int
1828 win32_xfer_memory (CORE_ADDR memaddr, gdb_byte *our, int len,
1829 int write, struct mem_attrib *mem,
1830 struct target_ops *target)
1831 {
1832 DWORD done = 0;
1833 if (write)
1834 {
1835 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
1836 len, (DWORD) memaddr));
1837 if (!WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our,
1838 len, &done))
1839 done = 0;
1840 FlushInstructionCache (current_process_handle, (LPCVOID) memaddr, len);
1841 }
1842 else
1843 {
1844 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
1845 len, (DWORD) memaddr));
1846 if (!ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our,
1847 len, &done))
1848 done = 0;
1849 }
1850 return done;
1851 }
1852
1853 static void
1854 win32_kill_inferior (void)
1855 {
1856 CHECK (TerminateProcess (current_process_handle, 0));
1857
1858 for (;;)
1859 {
1860 if (!win32_continue (DBG_CONTINUE, -1))
1861 break;
1862 if (!WaitForDebugEvent (&current_event, INFINITE))
1863 break;
1864 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
1865 break;
1866 }
1867
1868 CHECK (CloseHandle (current_process_handle));
1869
1870 /* this may fail in an attached process so don't check. */
1871 if (current_thread && current_thread->h)
1872 (void) CloseHandle (current_thread->h);
1873 target_mourn_inferior (); /* or just win32_mourn_inferior? */
1874 }
1875
1876 static void
1877 win32_resume (ptid_t ptid, int step, enum target_signal sig)
1878 {
1879 thread_info *th;
1880 DWORD continue_status = DBG_CONTINUE;
1881
1882 int pid = PIDGET (ptid);
1883
1884 if (sig != TARGET_SIGNAL_0)
1885 {
1886 if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
1887 {
1888 DEBUG_EXCEPT(("Cannot continue with signal %d here.\n",sig));
1889 }
1890 else if (sig == last_sig)
1891 continue_status = DBG_EXCEPTION_NOT_HANDLED;
1892 else
1893 #if 0
1894 /* This code does not seem to work, because
1895 the kernel does probably not consider changes in the ExceptionRecord
1896 structure when passing the exception to the inferior.
1897 Note that this seems possible in the exception handler itself. */
1898 {
1899 int i;
1900 for (i = 0; xlate[i].them != -1; i++)
1901 if (xlate[i].us == sig)
1902 {
1903 current_event.u.Exception.ExceptionRecord.ExceptionCode =
1904 xlate[i].them;
1905 continue_status = DBG_EXCEPTION_NOT_HANDLED;
1906 break;
1907 }
1908 if (continue_status == DBG_CONTINUE)
1909 {
1910 DEBUG_EXCEPT(("Cannot continue with signal %d.\n",sig));
1911 }
1912 }
1913 #endif
1914 DEBUG_EXCEPT(("Can only continue with recieved signal %d.\n",
1915 last_sig));
1916 }
1917
1918 last_sig = TARGET_SIGNAL_0;
1919
1920 DEBUG_EXEC (("gdb: win32_resume (pid=%d, step=%d, sig=%d);\n",
1921 pid, step, sig));
1922
1923 /* Get context for currently selected thread */
1924 th = thread_rec (current_event.dwThreadId, FALSE);
1925 if (th)
1926 {
1927 if (step)
1928 {
1929 /* Single step by setting t bit */
1930 win32_fetch_inferior_registers (PS_REGNUM);
1931 th->context.EFlags |= FLAG_TRACE_BIT;
1932 }
1933
1934 if (th->context.ContextFlags)
1935 {
1936 if (debug_registers_changed)
1937 {
1938 th->context.Dr0 = dr[0];
1939 th->context.Dr1 = dr[1];
1940 th->context.Dr2 = dr[2];
1941 th->context.Dr3 = dr[3];
1942 /* th->context.Dr6 = dr[6];
1943 FIXME: should we set dr6 also ?? */
1944 th->context.Dr7 = dr[7];
1945 }
1946 CHECK (SetThreadContext (th->h, &th->context));
1947 th->context.ContextFlags = 0;
1948 }
1949 }
1950
1951 /* Allow continuing with the same signal that interrupted us.
1952 Otherwise complain. */
1953
1954 win32_continue (continue_status, pid);
1955 }
1956
1957 static void
1958 win32_prepare_to_store (void)
1959 {
1960 /* Do nothing, since we can store individual regs */
1961 }
1962
1963 static int
1964 win32_can_run (void)
1965 {
1966 return 1;
1967 }
1968
1969 static void
1970 win32_close (int x)
1971 {
1972 DEBUG_EVENTS (("gdb: win32_close, inferior_ptid=%d\n",
1973 PIDGET (inferior_ptid)));
1974 }
1975
1976 /* Convert pid to printable format. */
1977 static char *
1978 cygwin_pid_to_str (ptid_t ptid)
1979 {
1980 static char buf[80];
1981 int pid = PIDGET (ptid);
1982
1983 if ((DWORD) pid == current_event.dwProcessId)
1984 sprintf (buf, "process %d", pid);
1985 else
1986 sprintf (buf, "thread %ld.0x%x", current_event.dwProcessId, pid);
1987 return buf;
1988 }
1989
1990 static void
1991 init_win32_ops (void)
1992 {
1993 win32_ops.to_shortname = "child";
1994 win32_ops.to_longname = "Win32 child process";
1995 win32_ops.to_doc = "Win32 child process (started by the \"run\" command).";
1996 win32_ops.to_open = win32_open;
1997 win32_ops.to_close = win32_close;
1998 win32_ops.to_attach = win32_attach;
1999 win32_ops.to_detach = win32_detach;
2000 win32_ops.to_resume = win32_resume;
2001 win32_ops.to_wait = win32_wait;
2002 win32_ops.to_fetch_registers = win32_fetch_inferior_registers;
2003 win32_ops.to_store_registers = win32_store_inferior_registers;
2004 win32_ops.to_prepare_to_store = win32_prepare_to_store;
2005 win32_ops.deprecated_xfer_memory = win32_xfer_memory;
2006 win32_ops.to_files_info = win32_files_info;
2007 win32_ops.to_insert_breakpoint = memory_insert_breakpoint;
2008 win32_ops.to_remove_breakpoint = memory_remove_breakpoint;
2009 win32_ops.to_terminal_init = terminal_init_inferior;
2010 win32_ops.to_terminal_inferior = terminal_inferior;
2011 win32_ops.to_terminal_ours_for_output = terminal_ours_for_output;
2012 win32_ops.to_terminal_ours = terminal_ours;
2013 win32_ops.to_terminal_save_ours = terminal_save_ours;
2014 win32_ops.to_terminal_info = child_terminal_info;
2015 win32_ops.to_kill = win32_kill_inferior;
2016 win32_ops.to_create_inferior = win32_create_inferior;
2017 win32_ops.to_mourn_inferior = win32_mourn_inferior;
2018 win32_ops.to_can_run = win32_can_run;
2019 win32_ops.to_thread_alive = win32_win32_thread_alive;
2020 win32_ops.to_pid_to_str = cygwin_pid_to_str;
2021 win32_ops.to_stop = win32_stop;
2022 win32_ops.to_stratum = process_stratum;
2023 win32_ops.to_has_all_memory = 1;
2024 win32_ops.to_has_memory = 1;
2025 win32_ops.to_has_stack = 1;
2026 win32_ops.to_has_registers = 1;
2027 win32_ops.to_has_execution = 1;
2028 win32_ops.to_magic = OPS_MAGIC;
2029 win32_ops.to_pid_to_exec_file = win32_pid_to_exec_file;
2030
2031 win32_so_ops.relocate_section_addresses = win32_relocate_section_addresses;
2032 win32_so_ops.free_so = win32_free_so;
2033 win32_so_ops.clear_solib = win32_clear_solib;
2034 win32_so_ops.solib_create_inferior_hook = NULL;
2035 win32_so_ops.special_symbol_handling = NULL;
2036 win32_so_ops.current_sos = win32_current_sos;
2037 win32_so_ops.open_symbol_file_object = NULL;
2038 win32_so_ops.in_dynsym_resolve_code = NULL;
2039
2040 /* FIXME: Don't do this here. *_gdbarch_init() should set so_ops. */
2041 current_target_so_ops = &win32_so_ops;
2042 }
2043
2044 void
2045 _initialize_win32_nat (void)
2046 {
2047 struct cmd_list_element *c;
2048
2049 init_win32_ops ();
2050
2051 c = add_com ("dll-symbols", class_files, dll_symbol_command,
2052 _("Load dll library symbols from FILE."));
2053 set_cmd_completer (c, filename_completer);
2054
2055 add_com_alias ("sharedlibrary", "dll-symbols", class_alias, 1);
2056
2057 add_setshow_boolean_cmd ("shell", class_support, &useshell, _("\
2058 Set use of shell to start subprocess."), _("\
2059 Show use of shell to start subprocess."), NULL,
2060 NULL,
2061 NULL, /* FIXME: i18n: */
2062 &setlist, &showlist);
2063
2064 add_setshow_boolean_cmd ("new-console", class_support, &new_console, _("\
2065 Set creation of new console when creating child process."), _("\
2066 Show creation of new console when creating child process."), NULL,
2067 NULL,
2068 NULL, /* FIXME: i18n: */
2069 &setlist, &showlist);
2070
2071 add_setshow_boolean_cmd ("new-group", class_support, &new_group, _("\
2072 Set creation of new group when creating child process."), _("\
2073 Show creation of new group when creating child process."), NULL,
2074 NULL,
2075 NULL, /* FIXME: i18n: */
2076 &setlist, &showlist);
2077
2078 add_setshow_boolean_cmd ("debugexec", class_support, &debug_exec, _("\
2079 Set whether to display execution in child process."), _("\
2080 Show whether to display execution in child process."), NULL,
2081 NULL,
2082 NULL, /* FIXME: i18n: */
2083 &setlist, &showlist);
2084
2085 add_setshow_boolean_cmd ("debugevents", class_support, &debug_events, _("\
2086 Set whether to display kernel events in child process."), _("\
2087 Show whether to display kernel events in child process."), NULL,
2088 NULL,
2089 NULL, /* FIXME: i18n: */
2090 &setlist, &showlist);
2091
2092 add_setshow_boolean_cmd ("debugmemory", class_support, &debug_memory, _("\
2093 Set whether to display memory accesses in child process."), _("\
2094 Show whether to display memory accesses in child process."), NULL,
2095 NULL,
2096 NULL, /* FIXME: i18n: */
2097 &setlist, &showlist);
2098
2099 add_setshow_boolean_cmd ("debugexceptions", class_support,
2100 &debug_exceptions, _("\
2101 Set whether to display kernel exceptions in child process."), _("\
2102 Show whether to display kernel exceptions in child process."), NULL,
2103 NULL,
2104 NULL, /* FIXME: i18n: */
2105 &setlist, &showlist);
2106
2107 add_info ("dll", info_dll_command, _("Status of loaded DLLs."));
2108 add_info_alias ("sharedlibrary", "dll", 1);
2109
2110 add_prefix_cmd ("w32", class_info, info_w32_command,
2111 _("Print information specific to Win32 debugging."),
2112 &info_w32_cmdlist, "info w32 ", 0, &infolist);
2113
2114 add_cmd ("selector", class_info, display_selectors,
2115 _("Display selectors infos."),
2116 &info_w32_cmdlist);
2117 add_target (&win32_ops);
2118 }
2119
2120 /* Hardware watchpoint support, adapted from go32-nat.c code. */
2121
2122 /* Pass the address ADDR to the inferior in the I'th debug register.
2123 Here we just store the address in dr array, the registers will be
2124 actually set up when win32_continue is called. */
2125 void
2126 cygwin_set_dr (int i, CORE_ADDR addr)
2127 {
2128 if (i < 0 || i > 3)
2129 internal_error (__FILE__, __LINE__,
2130 _("Invalid register %d in cygwin_set_dr.\n"), i);
2131 dr[i] = (unsigned) addr;
2132 debug_registers_changed = 1;
2133 debug_registers_used = 1;
2134 }
2135
2136 /* Pass the value VAL to the inferior in the DR7 debug control
2137 register. Here we just store the address in D_REGS, the watchpoint
2138 will be actually set up in win32_wait. */
2139 void
2140 cygwin_set_dr7 (unsigned val)
2141 {
2142 dr[7] = val;
2143 debug_registers_changed = 1;
2144 debug_registers_used = 1;
2145 }
2146
2147 /* Get the value of the DR6 debug status register from the inferior.
2148 Here we just return the value stored in dr[6]
2149 by the last call to thread_rec for current_event.dwThreadId id. */
2150 unsigned
2151 cygwin_get_dr6 (void)
2152 {
2153 return dr[6];
2154 }
2155
2156 /* Determine if the thread referenced by "pid" is alive
2157 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
2158 it means that the pid has died. Otherwise it is assumed to be alive. */
2159 static int
2160 win32_win32_thread_alive (ptid_t ptid)
2161 {
2162 int pid = PIDGET (ptid);
2163
2164 return WaitForSingleObject (thread_rec (pid, FALSE)->h, 0) == WAIT_OBJECT_0 ?
2165 FALSE : TRUE;
2166 }
2167
2168 static void
2169 fetch_elf_core_registers (char *core_reg_sect,
2170 unsigned core_reg_size,
2171 int which,
2172 CORE_ADDR reg_addr)
2173 {
2174 int r;
2175 if (core_reg_size < sizeof (CONTEXT))
2176 {
2177 error (_("Core file register section too small (%u bytes)."), core_reg_size);
2178 return;
2179 }
2180 for (r = 0; r < NUM_REGS; r++)
2181 regcache_raw_supply (current_regcache, r, core_reg_sect + mappings[r]);
2182 }
2183
2184 static struct core_fns win32_elf_core_fns =
2185 {
2186 bfd_target_elf_flavour,
2187 default_check_format,
2188 default_core_sniffer,
2189 fetch_elf_core_registers,
2190 NULL
2191 };
2192
2193 void
2194 _initialize_core_win32 (void)
2195 {
2196 deprecated_add_core_fns (&win32_elf_core_fns);
2197 }
2198
2199 void
2200 _initialize_check_for_gdb_ini (void)
2201 {
2202 char *homedir;
2203 if (inhibit_gdbinit)
2204 return;
2205
2206 homedir = getenv ("HOME");
2207 if (homedir)
2208 {
2209 char *p;
2210 char *oldini = (char *) alloca (strlen (homedir) +
2211 sizeof ("/gdb.ini"));
2212 strcpy (oldini, homedir);
2213 p = strchr (oldini, '\0');
2214 if (p > oldini && p[-1] != '/')
2215 *p++ = '/';
2216 strcpy (p, "gdb.ini");
2217 if (access (oldini, 0) == 0)
2218 {
2219 int len = strlen (oldini);
2220 char *newini = alloca (len + 1);
2221 sprintf (newini, "%.*s.gdbinit",
2222 (int) (len - (sizeof ("gdb.ini") - 1)), oldini);
2223 warning (_("obsolete '%s' found. Rename to '%s'."), oldini, newini);
2224 }
2225 }
2226 }
This page took 0.121187 seconds and 4 git commands to generate.