1 /* Target-vector operations for controlling win32 child processes, for GDB.
3 Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
4 Free Software Foundation, Inc.
6 Contributed by Cygnus Solutions, A Red Hat Company.
8 This file is part of GDB.
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.
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.
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. */
25 /* Originally by Steve Chamberlain, sac@cygnus.com */
27 /* We assume we're being built with and will be used for cygwin. */
30 #include "frame.h" /* required by inferior.h */
33 #include "exceptions.h"
36 #include "completer.h"
40 #include <sys/types.h>
45 #include <sys/cygwin.h>
50 #include "gdb_string.h"
51 #include "gdbthread.h"
53 #include <sys/param.h>
59 #include "i386-tdep.h"
60 #include "i387-tdep.h"
62 static struct target_ops win32_ops
;
63 static struct target_so_ops win32_so_ops
;
65 /* If we're not using the old Cygwin header file set, define the
66 following which never should have been in the generic Win32 API
67 headers in the first place since they were our own invention... */
68 #ifndef _GNU_H_WINDOWS_H
71 FLAG_TRACE_BIT
= 0x100,
72 CONTEXT_DEBUGGER
= (CONTEXT_FULL
| CONTEXT_FLOATING_POINT
)
75 #include <sys/procfs.h>
78 #define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \
79 | CONTEXT_EXTENDED_REGISTERS
81 static unsigned dr
[8];
82 static int debug_registers_changed
;
83 static int debug_registers_used
;
85 /* The string sent by cygwin when it processes a signal.
86 FIXME: This should be in a cygwin include file. */
87 #define CYGWIN_SIGNAL_STRING "cygwin: signal"
89 #define CHECK(x) check (x, __FILE__,__LINE__)
90 #define DEBUG_EXEC(x) if (debug_exec) printf_unfiltered x
91 #define DEBUG_EVENTS(x) if (debug_events) printf_unfiltered x
92 #define DEBUG_MEM(x) if (debug_memory) printf_unfiltered x
93 #define DEBUG_EXCEPT(x) if (debug_exceptions) printf_unfiltered x
95 static void win32_stop (void);
96 static int win32_win32_thread_alive (ptid_t
);
97 static void win32_kill_inferior (void);
99 static enum target_signal last_sig
= TARGET_SIGNAL_0
;
100 /* Set if a signal was received from the debugged process */
102 /* Thread information structure used to track information that is
103 not available in gdb's thread structure. */
104 typedef struct thread_info_struct
106 struct thread_info_struct
*next
;
117 static thread_info thread_head
;
119 /* The process and thread handles for the above context. */
121 static DEBUG_EVENT current_event
; /* The current debug event from
123 static HANDLE current_process_handle
; /* Currently executing process */
124 static thread_info
*current_thread
; /* Info on currently selected thread */
125 static DWORD main_thread_id
; /* Thread ID of the main thread */
127 /* Counts of things. */
128 static int exception_count
= 0;
129 static int event_count
= 0;
130 static int saw_create
;
133 static int new_console
= 0;
134 static int new_group
= 1;
135 static int debug_exec
= 0; /* show execution */
136 static int debug_events
= 0; /* show events from kernel */
137 static int debug_memory
= 0; /* show target memory accesses */
138 static int debug_exceptions
= 0; /* show target exceptions */
139 static int useshell
= 0; /* use shell for subprocesses */
141 /* This vector maps GDB's idea of a register's number into an address
142 in the win32 exception context vector.
144 It also contains the bit mask needed to load the register in question.
146 One day we could read a reg, we could inspect the context we
147 already have loaded, if it doesn't have the bit set that we need,
148 we read that set of registers in using GetThreadContext. If the
149 context already contains what we need, we just unpack it. Then to
150 write a register, first we have to ensure that the context contains
151 the other regs of the group, and then we copy the info in and set
154 #define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
155 static const int mappings
[] =
157 context_offset (Eax
),
158 context_offset (Ecx
),
159 context_offset (Edx
),
160 context_offset (Ebx
),
161 context_offset (Esp
),
162 context_offset (Ebp
),
163 context_offset (Esi
),
164 context_offset (Edi
),
165 context_offset (Eip
),
166 context_offset (EFlags
),
167 context_offset (SegCs
),
168 context_offset (SegSs
),
169 context_offset (SegDs
),
170 context_offset (SegEs
),
171 context_offset (SegFs
),
172 context_offset (SegGs
),
173 context_offset (FloatSave
.RegisterArea
[0 * 10]),
174 context_offset (FloatSave
.RegisterArea
[1 * 10]),
175 context_offset (FloatSave
.RegisterArea
[2 * 10]),
176 context_offset (FloatSave
.RegisterArea
[3 * 10]),
177 context_offset (FloatSave
.RegisterArea
[4 * 10]),
178 context_offset (FloatSave
.RegisterArea
[5 * 10]),
179 context_offset (FloatSave
.RegisterArea
[6 * 10]),
180 context_offset (FloatSave
.RegisterArea
[7 * 10]),
181 context_offset (FloatSave
.ControlWord
),
182 context_offset (FloatSave
.StatusWord
),
183 context_offset (FloatSave
.TagWord
),
184 context_offset (FloatSave
.ErrorSelector
),
185 context_offset (FloatSave
.ErrorOffset
),
186 context_offset (FloatSave
.DataSelector
),
187 context_offset (FloatSave
.DataOffset
),
188 context_offset (FloatSave
.ErrorSelector
)
190 context_offset (ExtendedRegisters
[10*16]),
191 context_offset (ExtendedRegisters
[11*16]),
192 context_offset (ExtendedRegisters
[12*16]),
193 context_offset (ExtendedRegisters
[13*16]),
194 context_offset (ExtendedRegisters
[14*16]),
195 context_offset (ExtendedRegisters
[15*16]),
196 context_offset (ExtendedRegisters
[16*16]),
197 context_offset (ExtendedRegisters
[17*16]),
199 context_offset (ExtendedRegisters
[24])
202 #undef context_offset
204 /* This vector maps the target's idea of an exception (extracted
205 from the DEBUG_EVENT structure) to GDB's idea. */
207 struct xlate_exception
210 enum target_signal us
;
213 static const struct xlate_exception
216 {EXCEPTION_ACCESS_VIOLATION
, TARGET_SIGNAL_SEGV
},
217 {STATUS_STACK_OVERFLOW
, TARGET_SIGNAL_SEGV
},
218 {EXCEPTION_BREAKPOINT
, TARGET_SIGNAL_TRAP
},
219 {DBG_CONTROL_C
, TARGET_SIGNAL_INT
},
220 {EXCEPTION_SINGLE_STEP
, TARGET_SIGNAL_TRAP
},
221 {STATUS_FLOAT_DIVIDE_BY_ZERO
, TARGET_SIGNAL_FPE
},
225 check (BOOL ok
, const char *file
, int line
)
228 printf_filtered ("error return %s:%d was %lu\n", file
, line
,
232 /* Find a thread record given a thread id.
233 If get_context then also retrieve the context for this
236 thread_rec (DWORD id
, int get_context
)
240 for (th
= &thread_head
; (th
= th
->next
) != NULL
;)
243 if (!th
->suspend_count
&& get_context
)
245 if (get_context
> 0 && id
!= current_event
.dwThreadId
)
246 th
->suspend_count
= SuspendThread (th
->h
) + 1;
247 else if (get_context
< 0)
248 th
->suspend_count
= -1;
249 th
->reload_context
= 1;
257 /* Add a thread to the thread list */
259 win32_add_thread (DWORD id
, HANDLE h
)
263 if ((th
= thread_rec (id
, FALSE
)))
266 th
= (thread_info
*) xmalloc (sizeof (*th
));
267 memset (th
, 0, sizeof (*th
));
270 th
->next
= thread_head
.next
;
271 thread_head
.next
= th
;
272 add_thread (pid_to_ptid (id
));
273 /* Set the debug registers for the new thread in they are used. */
274 if (debug_registers_used
)
276 /* Only change the value of the debug registers. */
277 th
->context
.ContextFlags
= CONTEXT_DEBUG_REGISTERS
;
278 CHECK (GetThreadContext (th
->h
, &th
->context
));
279 th
->context
.Dr0
= dr
[0];
280 th
->context
.Dr1
= dr
[1];
281 th
->context
.Dr2
= dr
[2];
282 th
->context
.Dr3
= dr
[3];
283 /* th->context.Dr6 = dr[6];
284 FIXME: should we set dr6 also ?? */
285 th
->context
.Dr7
= dr
[7];
286 CHECK (SetThreadContext (th
->h
, &th
->context
));
287 th
->context
.ContextFlags
= 0;
292 /* Clear out any old thread list and reintialize it to a
295 win32_init_thread_list (void)
297 thread_info
*th
= &thread_head
;
299 DEBUG_EVENTS (("gdb: win32_init_thread_list\n"));
301 while (th
->next
!= NULL
)
303 thread_info
*here
= th
->next
;
304 th
->next
= here
->next
;
305 (void) CloseHandle (here
->h
);
308 thread_head
.next
= NULL
;
311 /* Delete a thread from the list of threads */
313 win32_delete_thread (DWORD id
)
318 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (pid_to_ptid (id
)));
319 delete_thread (pid_to_ptid (id
));
321 for (th
= &thread_head
;
322 th
->next
!= NULL
&& th
->next
->id
!= id
;
326 if (th
->next
!= NULL
)
328 thread_info
*here
= th
->next
;
329 th
->next
= here
->next
;
330 CloseHandle (here
->h
);
336 do_win32_fetch_inferior_registers (int r
)
338 char *context_offset
= ((char *) ¤t_thread
->context
) + mappings
[r
];
342 return; /* Windows sometimes uses a non-existent thread id in its
345 if (current_thread
->reload_context
)
347 thread_info
*th
= current_thread
;
348 th
->context
.ContextFlags
= CONTEXT_DEBUGGER_DR
;
349 GetThreadContext (th
->h
, &th
->context
);
350 /* Copy dr values from that thread. */
351 dr
[0] = th
->context
.Dr0
;
352 dr
[1] = th
->context
.Dr1
;
353 dr
[2] = th
->context
.Dr2
;
354 dr
[3] = th
->context
.Dr3
;
355 dr
[6] = th
->context
.Dr6
;
356 dr
[7] = th
->context
.Dr7
;
357 current_thread
->reload_context
= 0;
360 #define I387_ST0_REGNUM I386_ST0_REGNUM
362 if (r
== I387_FISEG_REGNUM
)
364 l
= *((long *) context_offset
) & 0xffff;
365 regcache_raw_supply (current_regcache
, r
, (char *) &l
);
367 else if (r
== I387_FOP_REGNUM
)
369 l
= (*((long *) context_offset
) >> 16) & ((1 << 11) - 1);
370 regcache_raw_supply (current_regcache
, r
, (char *) &l
);
373 regcache_raw_supply (current_regcache
, r
, context_offset
);
376 for (r
= 0; r
< NUM_REGS
; r
++)
377 do_win32_fetch_inferior_registers (r
);
380 #undef I387_ST0_REGNUM
384 win32_fetch_inferior_registers (int r
)
386 current_thread
= thread_rec (PIDGET (inferior_ptid
), TRUE
);
387 /* Check if current_thread exists. Windows sometimes uses a non-existent
388 thread id in its events */
390 do_win32_fetch_inferior_registers (r
);
394 do_win32_store_inferior_registers (int r
)
397 /* Windows sometimes uses a non-existent thread id in its events */;
399 regcache_raw_collect (current_regcache
, r
,
400 ((char *) ¤t_thread
->context
) + mappings
[r
]);
403 for (r
= 0; r
< NUM_REGS
; r
++)
404 do_win32_store_inferior_registers (r
);
408 /* Store a new register value into the current thread context */
410 win32_store_inferior_registers (int r
)
412 current_thread
= thread_rec (PIDGET (inferior_ptid
), TRUE
);
413 /* Check if current_thread exists. Windows sometimes uses a non-existent
414 thread id in its events */
416 do_win32_store_inferior_registers (r
);
419 static int psapi_loaded
= 0;
420 static HMODULE psapi_module_handle
= NULL
;
421 static BOOL
WINAPI (*psapi_EnumProcessModules
) (HANDLE
, HMODULE
*, DWORD
, LPDWORD
) = NULL
;
422 static BOOL
WINAPI (*psapi_GetModuleInformation
) (HANDLE
, HMODULE
, LPMODULEINFO
, DWORD
) = NULL
;
423 static DWORD
WINAPI (*psapi_GetModuleFileNameExA
) (HANDLE
, HMODULE
, LPSTR
, DWORD
) = NULL
;
426 psapi_get_dll_name (DWORD BaseAddress
, char *dll_name_ret
)
432 HMODULE
*DllHandle
= dh_buf
;
437 psapi_EnumProcessModules
== NULL
||
438 psapi_GetModuleInformation
== NULL
||
439 psapi_GetModuleFileNameExA
== NULL
)
444 psapi_module_handle
= LoadLibrary ("psapi.dll");
445 if (!psapi_module_handle
)
447 /* printf_unfiltered ("error loading psapi.dll: %u", GetLastError ()); */
450 psapi_EnumProcessModules
= GetProcAddress (psapi_module_handle
, "EnumProcessModules");
451 psapi_GetModuleInformation
= GetProcAddress (psapi_module_handle
, "GetModuleInformation");
452 psapi_GetModuleFileNameExA
= (void *) GetProcAddress (psapi_module_handle
,
453 "GetModuleFileNameExA");
454 if (psapi_EnumProcessModules
== NULL
||
455 psapi_GetModuleInformation
== NULL
||
456 psapi_GetModuleFileNameExA
== NULL
)
461 ok
= (*psapi_EnumProcessModules
) (current_process_handle
,
466 if (!ok
|| !cbNeeded
)
469 DllHandle
= (HMODULE
*) alloca (cbNeeded
);
473 ok
= (*psapi_EnumProcessModules
) (current_process_handle
,
480 for (i
= 0; i
< (int) (cbNeeded
/ sizeof (HMODULE
)); i
++)
482 if (!(*psapi_GetModuleInformation
) (current_process_handle
,
486 error (_("Can't get module info"));
488 len
= (*psapi_GetModuleFileNameExA
) (current_process_handle
,
493 error (_("Error getting dll name: %u."), (unsigned) GetLastError ());
495 if ((DWORD
) (mi
.lpBaseOfDll
) == BaseAddress
)
500 dll_name_ret
[0] = '\0';
504 /* Encapsulate the information required in a call to
505 symbol_file_add_args */
506 struct safe_symbol_file_add_args
510 struct section_addr_info
*addrs
;
513 struct ui_file
*err
, *out
;
517 /* Maintain a linked list of "so" information. */
523 static struct so_list solib_start
, *solib_end
;
525 /* Call symbol_file_add with stderr redirected. We don't care if there
528 safe_symbol_file_add_stub (void *argv
)
530 #define p ((struct safe_symbol_file_add_args *) argv)
531 struct so_list
*so
= &solib_start
;
533 p
->ret
= symbol_file_add (p
->name
, p
->from_tty
, p
->addrs
, p
->mainline
, p
->flags
);
538 /* Restore gdb's stderr after calling symbol_file_add */
540 safe_symbol_file_add_cleanup (void *p
)
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
;
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
)
558 struct safe_symbol_file_add_args p
;
559 struct cleanup
*cleanup
;
561 cleanup
= make_cleanup (safe_symbol_file_add_cleanup
, &p
);
565 gdb_flush (gdb_stderr
);
566 gdb_flush (gdb_stdout
);
567 gdb_stderr
= ui_file_new ();
568 gdb_stdout
= ui_file_new ();
570 p
.from_tty
= from_tty
;
572 p
.mainline
= mainline
;
574 catch_errors (safe_symbol_file_add_stub
, &p
, "", RETURN_MASK_ERROR
);
576 do_cleanups (cleanup
);
580 /* Get the loaded address of all sections, given that .text was loaded
581 at text_load. Assumes that all sections are subject to the same
582 relocation offset. Returns NULL if problems occur or if the
583 sections were not relocated. */
585 static struct section_addr_info
*
586 get_relocated_section_addrs (bfd
*abfd
, CORE_ADDR text_load
)
588 struct section_addr_info
*result
= NULL
;
589 int section_count
= bfd_count_sections (abfd
);
590 asection
*text_section
= bfd_get_section_by_name (abfd
, ".text");
595 /* Couldn't get the .text section. Weird. */
598 else if (text_load
== (text_vma
= bfd_get_section_vma (abfd
, text_section
)))
600 /* DLL wasn't relocated. */
605 /* Figure out all sections' loaded addresses. The offset here is
606 such that taking a bfd_get_section_vma() result and adding
607 offset will give the real load address of the section. */
609 CORE_ADDR offset
= text_load
- text_vma
;
611 struct section_table
*table_start
= NULL
;
612 struct section_table
*table_end
= NULL
;
613 struct section_table
*iter
= NULL
;
615 build_section_table (abfd
, &table_start
, &table_end
);
617 for (iter
= table_start
; iter
< table_end
; ++iter
)
619 /* Relocated addresses. */
620 iter
->addr
+= offset
;
621 iter
->endaddr
+= offset
;
624 result
= build_section_addr_info_from_section_table (table_start
,
633 /* Add DLL symbol information. */
635 solib_symbols_add (struct so_list
*so
, CORE_ADDR load_addr
)
637 struct section_addr_info
*addrs
= NULL
;
638 static struct objfile
*result
= NULL
;
639 char *name
= so
->so_name
;
642 /* The symbols in a dll are offset by 0x1000, which is the
643 the offset from 0 of the first byte in an image - because
644 of the file header and the section alignment. */
646 if (!name
|| !name
[0])
649 abfd
= bfd_openr (name
, "pei-i386");
653 /* pei failed - try pe */
654 abfd
= bfd_openr (name
, "pe-i386");
659 if (bfd_check_format (abfd
, bfd_object
))
660 addrs
= get_relocated_section_addrs (abfd
, load_addr
);
667 result
= safe_symbol_file_add (name
, 0, addrs
, 0, OBJF_SHARED
);
668 free_section_addr_info (addrs
);
672 /* Fallback on handling just the .text section. */
673 struct cleanup
*my_cleanups
;
675 addrs
= alloc_section_addr_info (1);
676 my_cleanups
= make_cleanup (xfree
, addrs
);
677 addrs
->other
[0].name
= ".text";
678 addrs
->other
[0].addr
= load_addr
;
680 result
= safe_symbol_file_add (name
, 0, addrs
, 0, OBJF_SHARED
);
681 do_cleanups (my_cleanups
);
684 so
->symbols_loaded
= !!result
;
688 /* Remember the maximum DLL length for printing in info dll command. */
689 static int max_dll_name_len
;
692 register_loaded_dll (const char *name
, DWORD load_addr
, int readsyms
)
695 char buf
[MAX_PATH
+ 1];
696 char cwd
[MAX_PATH
+ 1];
698 WIN32_FIND_DATA w32_fd
;
699 HANDLE h
= FindFirstFile(name
, &w32_fd
);
700 MEMORY_BASIC_INFORMATION m
;
703 if (h
== INVALID_HANDLE_VALUE
)
709 if (GetCurrentDirectory (MAX_PATH
+ 1, cwd
))
711 p
= strrchr (buf
, '\\');
714 SetCurrentDirectory (buf
);
715 GetFullPathName (w32_fd
.cFileName
, MAX_PATH
, buf
, &p
);
716 SetCurrentDirectory (cwd
);
720 if (strcasecmp (buf
, "ntdll.dll") == 0)
722 GetSystemDirectory (buf
, sizeof (buf
));
723 strcat (buf
, "\\ntdll.dll");
725 so
= (struct so_list
*) xmalloc (sizeof (struct so_list
));
726 memset (so
, 0, sizeof (*so
));
727 so
->lm_info
= (struct lm_info
*) xmalloc (sizeof (struct lm_info
));
728 so
->lm_info
->load_addr
= load_addr
;
729 cygwin_conv_to_posix_path (buf
, so
->so_name
);
730 strcpy (so
->so_original_name
, so
->so_name
);
732 solib_end
->next
= so
;
734 len
= strlen (so
->so_name
);
735 if (len
> max_dll_name_len
)
736 max_dll_name_len
= len
;
738 solib_symbols_add (so
, (CORE_ADDR
) load_addr
);
743 get_image_name (HANDLE h
, void *address
, int unicode
)
745 static char buf
[(2 * MAX_PATH
) + 1];
746 DWORD size
= unicode
? sizeof (WCHAR
) : sizeof (char);
752 /* Attempt to read the name of the dll that was detected.
753 This is documented to work only when actively debugging
754 a program. It will not work for attached processes. */
758 /* See if we could read the address of a string, and that the
759 address isn't null. */
760 if (!ReadProcessMemory (h
, address
, &address_ptr
, sizeof (address_ptr
), &done
)
761 || done
!= sizeof (address_ptr
) || !address_ptr
)
764 /* Find the length of the string */
765 while (ReadProcessMemory (h
, address_ptr
+ len
++ * size
, &b
, size
, &done
)
766 && (b
[0] != 0 || b
[size
- 1] != 0) && done
== size
)
770 ReadProcessMemory (h
, address_ptr
, buf
, len
, &done
);
773 WCHAR
*unicode_address
= (WCHAR
*) alloca (len
* sizeof (WCHAR
));
774 ReadProcessMemory (h
, address_ptr
, unicode_address
, len
* sizeof (WCHAR
),
777 WideCharToMultiByte (CP_ACP
, 0, unicode_address
, len
, buf
, len
, 0, 0);
783 /* Wait for child to do something. Return pid of child, or -1 in case
784 of error; store status through argument pointer OURSTATUS. */
786 handle_load_dll (void *dummy
)
788 LOAD_DLL_DEBUG_INFO
*event
= ¤t_event
.u
.LoadDll
;
789 char dll_buf
[MAX_PATH
+ 1];
790 char *dll_name
= NULL
;
793 dll_buf
[0] = dll_buf
[sizeof (dll_buf
) - 1] = '\0';
795 if (!psapi_get_dll_name ((DWORD
) (event
->lpBaseOfDll
), dll_buf
))
796 dll_buf
[0] = dll_buf
[sizeof (dll_buf
) - 1] = '\0';
800 if (*dll_name
== '\0')
801 dll_name
= get_image_name (current_process_handle
, event
->lpImageName
, event
->fUnicode
);
805 register_loaded_dll (dll_name
, (DWORD
) event
->lpBaseOfDll
+ 0x1000, auto_solib_add
);
811 win32_free_so (struct so_list
*so
)
818 win32_relocate_section_addresses (struct so_list
*so
,
819 struct section_table
*sec
)
826 win32_solib_create_inferior_hook (void)
828 solib_add (NULL
, 0, NULL
, auto_solib_add
);
833 handle_unload_dll (void *dummy
)
835 DWORD lpBaseOfDll
= (DWORD
) current_event
.u
.UnloadDll
.lpBaseOfDll
+ 0x1000;
838 for (so
= &solib_start
; so
->next
!= NULL
; so
= so
->next
)
839 if (so
->next
->lm_info
->load_addr
== lpBaseOfDll
)
841 struct so_list
*sodel
= so
->next
;
842 so
->next
= sodel
->next
;
848 error (_("Error: dll starting at 0x%lx not found."), (DWORD
) lpBaseOfDll
);
853 /* Clear list of loaded DLLs. */
855 win32_clear_solib (void)
857 solib_start
.next
= NULL
;
858 solib_end
= &solib_start
;
859 max_dll_name_len
= sizeof ("DLL Name") - 1;
863 win32_special_symbol_handling (void)
868 /* Load DLL symbol info. */
870 dll_symbol_command (char *args
, int from_tty
)
876 error (_("dll-symbols requires a file name"));
879 if (n
> 4 && strcasecmp (args
+ n
- 4, ".dll") != 0)
881 char *newargs
= (char *) alloca (n
+ 4 + 1);
882 strcpy (newargs
, args
);
883 strcat (newargs
, ".dll");
887 safe_symbol_file_add (args
, from_tty
, NULL
, 0, OBJF_SHARED
| OBJF_USERLOADED
);
890 /* List currently loaded DLLs. */
892 info_dll_command (char *ignore
, int from_tty
)
894 struct so_list
*so
= &solib_start
;
899 printf_filtered ("%*s Load Address\n", -max_dll_name_len
, "DLL Name");
900 while ((so
= so
->next
) != NULL
)
901 printf_filtered ("%*s %08lx\n", -max_dll_name_len
, so
->so_name
, so
->lm_info
->load_addr
);
906 /* Handle DEBUG_STRING output from child process.
907 Cygwin prepends its messages with a "cygwin:". Interpret this as
908 a Cygwin signal. Otherwise just print the string as a warning. */
910 handle_output_debug_string (struct target_waitstatus
*ourstatus
)
915 if (!target_read_string
916 ((CORE_ADDR
) current_event
.u
.DebugString
.lpDebugStringData
, &s
, 1024, 0)
920 if (strncmp (s
, CYGWIN_SIGNAL_STRING
, sizeof (CYGWIN_SIGNAL_STRING
) - 1) != 0)
922 if (strncmp (s
, "cYg", 3) != 0)
928 int sig
= strtol (s
+ sizeof (CYGWIN_SIGNAL_STRING
) - 1, &p
, 0);
929 gotasig
= target_signal_from_host (sig
);
930 ourstatus
->value
.sig
= gotasig
;
932 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
940 display_selector (HANDLE thread
, DWORD sel
)
943 if (GetThreadSelectorEntry (thread
, sel
, &info
))
946 printf_filtered ("0x%03lx: ", sel
);
947 if (!info
.HighWord
.Bits
.Pres
)
949 puts_filtered ("Segment not present\n");
952 base
= (info
.HighWord
.Bits
.BaseHi
<< 24) +
953 (info
.HighWord
.Bits
.BaseMid
<< 16)
955 limit
= (info
.HighWord
.Bits
.LimitHi
<< 16) + info
.LimitLow
;
956 if (info
.HighWord
.Bits
.Granularity
)
957 limit
= (limit
<< 12) | 0xfff;
958 printf_filtered ("base=0x%08x limit=0x%08x", base
, limit
);
959 if (info
.HighWord
.Bits
.Default_Big
)
960 puts_filtered(" 32-bit ");
962 puts_filtered(" 16-bit ");
963 switch ((info
.HighWord
.Bits
.Type
& 0xf) >> 1)
966 puts_filtered ("Data (Read-Only, Exp-up");
969 puts_filtered ("Data (Read/Write, Exp-up");
972 puts_filtered ("Unused segment (");
975 puts_filtered ("Data (Read/Write, Exp-down");
978 puts_filtered ("Code (Exec-Only, N.Conf");
981 puts_filtered ("Code (Exec/Read, N.Conf");
984 puts_filtered ("Code (Exec-Only, Conf");
987 puts_filtered ("Code (Exec/Read, Conf");
990 printf_filtered ("Unknown type 0x%x",info
.HighWord
.Bits
.Type
);
992 if ((info
.HighWord
.Bits
.Type
& 0x1) == 0)
993 puts_filtered(", N.Acc");
994 puts_filtered (")\n");
995 if ((info
.HighWord
.Bits
.Type
& 0x10) == 0)
996 puts_filtered("System selector ");
997 printf_filtered ("Priviledge level = %d. ", info
.HighWord
.Bits
.Dpl
);
998 if (info
.HighWord
.Bits
.Granularity
)
999 puts_filtered ("Page granular.\n");
1001 puts_filtered ("Byte granular.\n");
1006 printf_filtered ("Invalid selector 0x%lx.\n",sel
);
1012 display_selectors (char * args
, int from_tty
)
1014 if (!current_thread
)
1016 puts_filtered ("Impossible to display selectors now.\n");
1022 puts_filtered ("Selector $cs\n");
1023 display_selector (current_thread
->h
,
1024 current_thread
->context
.SegCs
);
1025 puts_filtered ("Selector $ds\n");
1026 display_selector (current_thread
->h
,
1027 current_thread
->context
.SegDs
);
1028 puts_filtered ("Selector $es\n");
1029 display_selector (current_thread
->h
,
1030 current_thread
->context
.SegEs
);
1031 puts_filtered ("Selector $ss\n");
1032 display_selector (current_thread
->h
,
1033 current_thread
->context
.SegSs
);
1034 puts_filtered ("Selector $fs\n");
1035 display_selector (current_thread
->h
,
1036 current_thread
->context
.SegFs
);
1037 puts_filtered ("Selector $gs\n");
1038 display_selector (current_thread
->h
,
1039 current_thread
->context
.SegGs
);
1044 sel
= parse_and_eval_long (args
);
1045 printf_filtered ("Selector \"%s\"\n",args
);
1046 display_selector (current_thread
->h
, sel
);
1050 static struct cmd_list_element
*info_w32_cmdlist
= NULL
;
1053 info_w32_command (char *args
, int from_tty
)
1055 help_list (info_w32_cmdlist
, "info w32 ", class_info
, gdb_stdout
);
1059 #define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \
1060 printf_unfiltered ("gdb: Target exception %s at 0x%08lx\n", x, \
1061 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress)
1064 handle_exception (struct target_waitstatus
*ourstatus
)
1067 DWORD code
= current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
;
1069 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
1071 /* Record the context of the current thread */
1072 th
= thread_rec (current_event
.dwThreadId
, -1);
1076 case EXCEPTION_ACCESS_VIOLATION
:
1077 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
1078 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
1081 if (find_pc_partial_function ((CORE_ADDR
) current_event
.u
.Exception
1082 .ExceptionRecord
.ExceptionAddress
,
1084 && strncmp (fn
, "KERNEL32!IsBad", strlen ("KERNEL32!IsBad")) == 0)
1088 case STATUS_STACK_OVERFLOW
:
1089 DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
1090 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
1092 case STATUS_FLOAT_DENORMAL_OPERAND
:
1093 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
1094 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1096 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED
:
1097 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
1098 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1100 case STATUS_FLOAT_INEXACT_RESULT
:
1101 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
1102 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1104 case STATUS_FLOAT_INVALID_OPERATION
:
1105 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
1106 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1108 case STATUS_FLOAT_OVERFLOW
:
1109 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
1110 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1112 case STATUS_FLOAT_STACK_CHECK
:
1113 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
1114 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1116 case STATUS_FLOAT_UNDERFLOW
:
1117 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
1118 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1120 case STATUS_FLOAT_DIVIDE_BY_ZERO
:
1121 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
1122 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1124 case STATUS_INTEGER_DIVIDE_BY_ZERO
:
1125 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
1126 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1128 case STATUS_INTEGER_OVERFLOW
:
1129 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
1130 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1132 case EXCEPTION_BREAKPOINT
:
1133 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
1134 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
1137 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
1138 ourstatus
->value
.sig
= TARGET_SIGNAL_INT
;
1140 case DBG_CONTROL_BREAK
:
1141 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
1142 ourstatus
->value
.sig
= TARGET_SIGNAL_INT
;
1144 case EXCEPTION_SINGLE_STEP
:
1145 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
1146 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
1148 case EXCEPTION_ILLEGAL_INSTRUCTION
:
1149 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
1150 ourstatus
->value
.sig
= TARGET_SIGNAL_ILL
;
1152 case EXCEPTION_PRIV_INSTRUCTION
:
1153 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
1154 ourstatus
->value
.sig
= TARGET_SIGNAL_ILL
;
1156 case EXCEPTION_NONCONTINUABLE_EXCEPTION
:
1157 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
1158 ourstatus
->value
.sig
= TARGET_SIGNAL_ILL
;
1161 if (current_event
.u
.Exception
.dwFirstChance
)
1163 printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n",
1164 current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
,
1165 (DWORD
) current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
);
1166 ourstatus
->value
.sig
= TARGET_SIGNAL_UNKNOWN
;
1170 last_sig
= ourstatus
->value
.sig
;
1174 /* Resume all artificially suspended threads if we are continuing
1177 win32_continue (DWORD continue_status
, int id
)
1183 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, %s);\n",
1184 current_event
.dwProcessId
, current_event
.dwThreadId
,
1185 continue_status
== DBG_CONTINUE
?
1186 "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED"));
1187 res
= ContinueDebugEvent (current_event
.dwProcessId
,
1188 current_event
.dwThreadId
,
1190 continue_status
= 0;
1192 for (th
= &thread_head
; (th
= th
->next
) != NULL
;)
1193 if (((id
== -1) || (id
== (int) th
->id
)) && th
->suspend_count
)
1196 for (i
= 0; i
< th
->suspend_count
; i
++)
1197 (void) ResumeThread (th
->h
);
1198 th
->suspend_count
= 0;
1199 if (debug_registers_changed
)
1201 /* Only change the value of the debug registers */
1202 th
->context
.ContextFlags
= CONTEXT_DEBUG_REGISTERS
;
1203 th
->context
.Dr0
= dr
[0];
1204 th
->context
.Dr1
= dr
[1];
1205 th
->context
.Dr2
= dr
[2];
1206 th
->context
.Dr3
= dr
[3];
1207 /* th->context.Dr6 = dr[6];
1208 FIXME: should we set dr6 also ?? */
1209 th
->context
.Dr7
= dr
[7];
1210 CHECK (SetThreadContext (th
->h
, &th
->context
));
1211 th
->context
.ContextFlags
= 0;
1215 debug_registers_changed
= 0;
1219 /* Called in pathological case where Windows fails to send a
1220 CREATE_PROCESS_DEBUG_EVENT after an attach. */
1222 fake_create_process (void)
1224 current_process_handle
= OpenProcess (PROCESS_ALL_ACCESS
, FALSE
,
1225 current_event
.dwProcessId
);
1226 main_thread_id
= current_event
.dwThreadId
;
1227 current_thread
= win32_add_thread (main_thread_id
,
1228 current_event
.u
.CreateThread
.hThread
);
1229 return main_thread_id
;
1232 /* Get the next event from the child. Return 1 if the event requires
1233 handling by WFI (or whatever).
1236 get_win32_debug_event (int pid
, struct target_waitstatus
*ourstatus
)
1239 DWORD continue_status
, event_code
;
1241 static thread_info dummy_thread_info
;
1244 last_sig
= TARGET_SIGNAL_0
;
1246 if (!(debug_event
= WaitForDebugEvent (¤t_event
, 1000)))
1250 continue_status
= DBG_CONTINUE
;
1252 event_code
= current_event
.dwDebugEventCode
;
1253 ourstatus
->kind
= TARGET_WAITKIND_SPURIOUS
;
1258 case CREATE_THREAD_DEBUG_EVENT
:
1259 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1260 (unsigned) current_event
.dwProcessId
,
1261 (unsigned) current_event
.dwThreadId
,
1262 "CREATE_THREAD_DEBUG_EVENT"));
1263 if (saw_create
!= 1)
1265 if (!saw_create
&& attach_flag
)
1267 /* Kludge around a Windows bug where first event is a create
1268 thread event. Caused when attached process does not have
1270 retval
= ourstatus
->value
.related_pid
= fake_create_process ();
1275 /* Record the existence of this thread */
1276 th
= win32_add_thread (current_event
.dwThreadId
,
1277 current_event
.u
.CreateThread
.hThread
);
1279 printf_unfiltered ("[New %s]\n",
1281 pid_to_ptid (current_event
.dwThreadId
)));
1282 retval
= current_event
.dwThreadId
;
1285 case EXIT_THREAD_DEBUG_EVENT
:
1286 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1287 (unsigned) current_event
.dwProcessId
,
1288 (unsigned) current_event
.dwThreadId
,
1289 "EXIT_THREAD_DEBUG_EVENT"));
1290 if (current_event
.dwThreadId
!= main_thread_id
)
1292 win32_delete_thread (current_event
.dwThreadId
);
1293 th
= &dummy_thread_info
;
1297 case CREATE_PROCESS_DEBUG_EVENT
:
1298 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1299 (unsigned) current_event
.dwProcessId
,
1300 (unsigned) current_event
.dwThreadId
,
1301 "CREATE_PROCESS_DEBUG_EVENT"));
1302 CloseHandle (current_event
.u
.CreateProcessInfo
.hFile
);
1303 if (++saw_create
!= 1)
1305 CloseHandle (current_event
.u
.CreateProcessInfo
.hProcess
);
1309 current_process_handle
= current_event
.u
.CreateProcessInfo
.hProcess
;
1311 win32_delete_thread (main_thread_id
);
1312 main_thread_id
= current_event
.dwThreadId
;
1313 /* Add the main thread */
1314 th
= win32_add_thread (main_thread_id
,
1315 current_event
.u
.CreateProcessInfo
.hThread
);
1316 retval
= ourstatus
->value
.related_pid
= current_event
.dwThreadId
;
1319 case EXIT_PROCESS_DEBUG_EVENT
:
1320 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1321 (unsigned) current_event
.dwProcessId
,
1322 (unsigned) current_event
.dwThreadId
,
1323 "EXIT_PROCESS_DEBUG_EVENT"));
1324 if (saw_create
!= 1)
1326 ourstatus
->kind
= TARGET_WAITKIND_EXITED
;
1327 ourstatus
->value
.integer
= current_event
.u
.ExitProcess
.dwExitCode
;
1328 CloseHandle (current_process_handle
);
1329 retval
= main_thread_id
;
1332 case LOAD_DLL_DEBUG_EVENT
:
1333 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1334 (unsigned) current_event
.dwProcessId
,
1335 (unsigned) current_event
.dwThreadId
,
1336 "LOAD_DLL_DEBUG_EVENT"));
1337 CloseHandle (current_event
.u
.LoadDll
.hFile
);
1338 if (saw_create
!= 1)
1340 catch_errors (handle_load_dll
, NULL
, (char *) "", RETURN_MASK_ALL
);
1341 registers_changed (); /* mark all regs invalid */
1342 ourstatus
->kind
= TARGET_WAITKIND_LOADED
;
1343 ourstatus
->value
.integer
= 0;
1344 retval
= main_thread_id
;
1345 re_enable_breakpoints_in_shlibs ();
1348 case UNLOAD_DLL_DEBUG_EVENT
:
1349 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1350 (unsigned) current_event
.dwProcessId
,
1351 (unsigned) current_event
.dwThreadId
,
1352 "UNLOAD_DLL_DEBUG_EVENT"));
1353 if (saw_create
!= 1)
1355 catch_errors (handle_unload_dll
, NULL
, (char *) "", RETURN_MASK_ALL
);
1356 registers_changed (); /* mark all regs invalid */
1357 /* ourstatus->kind = TARGET_WAITKIND_UNLOADED;
1358 does not exist yet. */
1361 case EXCEPTION_DEBUG_EVENT
:
1362 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1363 (unsigned) current_event
.dwProcessId
,
1364 (unsigned) current_event
.dwThreadId
,
1365 "EXCEPTION_DEBUG_EVENT"));
1366 if (saw_create
!= 1)
1368 if (handle_exception (ourstatus
))
1369 retval
= current_event
.dwThreadId
;
1371 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
1374 case OUTPUT_DEBUG_STRING_EVENT
: /* message from the kernel */
1375 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1376 (unsigned) current_event
.dwProcessId
,
1377 (unsigned) current_event
.dwThreadId
,
1378 "OUTPUT_DEBUG_STRING_EVENT"));
1379 if (saw_create
!= 1)
1381 if (handle_output_debug_string (ourstatus
))
1382 retval
= main_thread_id
;
1386 if (saw_create
!= 1)
1388 printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
1389 (DWORD
) current_event
.dwProcessId
,
1390 (DWORD
) current_event
.dwThreadId
);
1391 printf_unfiltered (" unknown event code %ld\n",
1392 current_event
.dwDebugEventCode
);
1396 if (!retval
|| saw_create
!= 1)
1397 CHECK (win32_continue (continue_status
, -1));
1400 inferior_ptid
= pid_to_ptid (retval
);
1401 current_thread
= th
?: thread_rec (current_event
.dwThreadId
, TRUE
);
1408 /* Wait for interesting events to occur in the target process. */
1410 win32_wait (ptid_t ptid
, struct target_waitstatus
*ourstatus
)
1412 int pid
= PIDGET (ptid
);
1414 /* We loop when we get a non-standard exception rather than return
1415 with a SPURIOUS because resume can try and step or modify things,
1416 which needs a current_thread->h. But some of these exceptions mark
1417 the birth or death of threads, which mean that the current thread
1418 isn't necessarily what you think it is. */
1422 int retval
= get_win32_debug_event (pid
, ourstatus
);
1424 return pid_to_ptid (retval
);
1429 if (deprecated_ui_loop_hook
!= NULL
)
1430 detach
= deprecated_ui_loop_hook (0);
1433 win32_kill_inferior ();
1439 do_initial_win32_stuff (DWORD pid
)
1441 extern int stop_after_trap
;
1444 last_sig
= TARGET_SIGNAL_0
;
1446 exception_count
= 0;
1447 debug_registers_changed
= 0;
1448 debug_registers_used
= 0;
1449 for (i
= 0; i
< sizeof (dr
) / sizeof (dr
[0]); i
++)
1451 current_event
.dwProcessId
= pid
;
1452 memset (¤t_event
, 0, sizeof (current_event
));
1453 push_target (&win32_ops
);
1454 disable_breakpoints_in_shlibs (1);
1455 win32_clear_solib ();
1456 clear_proceed_status ();
1457 init_wait_for_inferior ();
1459 target_terminal_init ();
1460 target_terminal_inferior ();
1464 stop_after_trap
= 1;
1465 wait_for_inferior ();
1466 if (stop_signal
!= TARGET_SIGNAL_TRAP
)
1467 resume (0, stop_signal
);
1471 stop_after_trap
= 0;
1475 /* Since Windows XP, detaching from a process is supported by Windows.
1476 The following code tries loading the appropriate functions dynamically.
1477 If loading these functions succeeds use them to actually detach from
1478 the inferior process, otherwise behave as usual, pretending that
1479 detach has worked. */
1480 static BOOL
WINAPI (*DebugSetProcessKillOnExit
)(BOOL
);
1481 static BOOL
WINAPI (*DebugActiveProcessStop
)(DWORD
);
1484 has_detach_ability (void)
1486 static HMODULE kernel32
= NULL
;
1489 kernel32
= LoadLibrary ("kernel32.dll");
1492 if (!DebugSetProcessKillOnExit
)
1493 DebugSetProcessKillOnExit
= GetProcAddress (kernel32
,
1494 "DebugSetProcessKillOnExit");
1495 if (!DebugActiveProcessStop
)
1496 DebugActiveProcessStop
= GetProcAddress (kernel32
,
1497 "DebugActiveProcessStop");
1498 if (DebugSetProcessKillOnExit
&& DebugActiveProcessStop
)
1504 /* Try to set or remove a user privilege to the current process. Return -1
1505 if that fails, the previous setting of that privilege otherwise.
1507 This code is copied from the Cygwin source code and rearranged to allow
1508 dynamically loading of the needed symbols from advapi32 which is only
1509 available on NT/2K/XP. */
1511 set_process_privilege (const char *privilege
, BOOL enable
)
1513 static HMODULE advapi32
= NULL
;
1514 static BOOL
WINAPI (*OpenProcessToken
)(HANDLE
, DWORD
, PHANDLE
);
1515 static BOOL
WINAPI (*LookupPrivilegeValue
)(LPCSTR
, LPCSTR
, PLUID
);
1516 static BOOL
WINAPI (*AdjustTokenPrivileges
)(HANDLE
, BOOL
, PTOKEN_PRIVILEGES
,
1517 DWORD
, PTOKEN_PRIVILEGES
, PDWORD
);
1519 HANDLE token_hdl
= NULL
;
1521 TOKEN_PRIVILEGES new_priv
, orig_priv
;
1525 if (GetVersion () >= 0x80000000) /* No security availbale on 9x/Me */
1530 if (!(advapi32
= LoadLibrary ("advapi32.dll")))
1532 if (!OpenProcessToken
)
1533 OpenProcessToken
= GetProcAddress (advapi32
, "OpenProcessToken");
1534 if (!LookupPrivilegeValue
)
1535 LookupPrivilegeValue
= GetProcAddress (advapi32
,
1536 "LookupPrivilegeValueA");
1537 if (!AdjustTokenPrivileges
)
1538 AdjustTokenPrivileges
= GetProcAddress (advapi32
,
1539 "AdjustTokenPrivileges");
1540 if (!OpenProcessToken
|| !LookupPrivilegeValue
|| !AdjustTokenPrivileges
)
1547 if (!OpenProcessToken (GetCurrentProcess (),
1548 TOKEN_QUERY
| TOKEN_ADJUST_PRIVILEGES
,
1552 if (!LookupPrivilegeValue (NULL
, privilege
, &restore_priv
))
1555 new_priv
.PrivilegeCount
= 1;
1556 new_priv
.Privileges
[0].Luid
= restore_priv
;
1557 new_priv
.Privileges
[0].Attributes
= enable
? SE_PRIVILEGE_ENABLED
: 0;
1559 if (!AdjustTokenPrivileges (token_hdl
, FALSE
, &new_priv
,
1560 sizeof orig_priv
, &orig_priv
, &size
))
1563 /* Disabled, otherwise every `attach' in an unprivileged user session
1564 would raise the "Failed to get SE_DEBUG_NAME privilege" warning in
1566 /* AdjustTokenPrivileges returns TRUE even if the privilege could not
1567 be enabled. GetLastError () returns an correct error code, though. */
1568 if (enable
&& GetLastError () == ERROR_NOT_ALL_ASSIGNED
)
1572 ret
= orig_priv
.Privileges
[0].Attributes
== SE_PRIVILEGE_ENABLED
? 1 : 0;
1576 CloseHandle (token_hdl
);
1581 /* Attach to process PID, then initialize for debugging it. */
1583 win32_attach (char *args
, int from_tty
)
1589 error_no_arg (_("process-id to attach"));
1591 if (set_process_privilege (SE_DEBUG_NAME
, TRUE
) < 0)
1593 printf_unfiltered ("Warning: Failed to get SE_DEBUG_NAME privilege\n");
1594 printf_unfiltered ("This can cause attach to fail on Windows NT/2K/XP\n");
1597 pid
= strtoul (args
, 0, 0); /* Windows pid */
1599 win32_init_thread_list ();
1600 ok
= DebugActiveProcess (pid
);
1605 /* Try fall back to Cygwin pid */
1606 pid
= cygwin_internal (CW_CYGWIN_PID_TO_WINPID
, pid
);
1609 ok
= DebugActiveProcess (pid
);
1612 error (_("Can't attach to process."));
1615 if (has_detach_ability ())
1616 DebugSetProcessKillOnExit (FALSE
);
1622 char *exec_file
= (char *) get_exec_file (0);
1625 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file
,
1626 target_pid_to_str (pid_to_ptid (pid
)));
1628 printf_unfiltered ("Attaching to %s\n",
1629 target_pid_to_str (pid_to_ptid (pid
)));
1631 gdb_flush (gdb_stdout
);
1634 do_initial_win32_stuff (pid
);
1635 target_terminal_ours ();
1639 win32_detach (char *args
, int from_tty
)
1643 if (has_detach_ability ())
1645 delete_command (NULL
, 0);
1646 win32_continue (DBG_CONTINUE
, -1);
1647 if (!DebugActiveProcessStop (current_event
.dwProcessId
))
1649 error (_("Can't detach process %lu (error %lu)"),
1650 current_event
.dwProcessId
, GetLastError ());
1653 DebugSetProcessKillOnExit (FALSE
);
1655 if (detached
&& from_tty
)
1657 char *exec_file
= get_exec_file (0);
1660 printf_unfiltered ("Detaching from program: %s, Pid %lu\n", exec_file
,
1661 current_event
.dwProcessId
);
1662 gdb_flush (gdb_stdout
);
1664 inferior_ptid
= null_ptid
;
1665 unpush_target (&win32_ops
);
1669 win32_pid_to_exec_file (int pid
)
1671 /* Try to find the process path using the Cygwin internal process list
1672 pid isn't a valid pid, unfortunately. Use current_event.dwProcessId
1674 /* TODO: Also find native Windows processes using CW_GETPINFO_FULL. */
1676 static char path
[MAX_PATH
+ 1];
1677 char *path_ptr
= NULL
;
1679 struct external_pinfo
*pinfo
;
1681 cygwin_internal (CW_LOCK_PINFO
, 1000);
1683 (pinfo
= (struct external_pinfo
*)
1684 cygwin_internal (CW_GETPINFO
, cpid
| CW_NEXTPID
));
1687 if (pinfo
->dwProcessId
== current_event
.dwProcessId
) /* Got it */
1689 cygwin_conv_to_full_posix_path (pinfo
->progname
, path
);
1694 cygwin_internal (CW_UNLOCK_PINFO
);
1698 /* Print status information about what we're accessing. */
1701 win32_files_info (struct target_ops
*ignore
)
1703 printf_unfiltered ("\tUsing the running image of %s %s.\n",
1704 attach_flag
? "attached" : "child", target_pid_to_str (inferior_ptid
));
1708 win32_open (char *arg
, int from_tty
)
1710 error (_("Use the \"run\" command to start a Unix child process."));
1713 /* Start an inferior win32 child process and sets inferior_ptid to its pid.
1714 EXEC_FILE is the file to run.
1715 ALLARGS is a string containing the arguments to the program.
1716 ENV is the environment vector to pass. Errors reported with error(). */
1719 win32_create_inferior (char *exec_file
, char *allargs
, char **env
,
1727 PROCESS_INFORMATION pi
;
1731 char real_path
[MAXPATHLEN
];
1733 char shell
[MAX_PATH
+ 1]; /* Path to shell */
1736 int ostdin
, ostdout
, ostderr
;
1737 const char *inferior_io_terminal
= get_inferior_io_terminal ();
1740 error (_("No executable specified, use `target exec'."));
1742 memset (&si
, 0, sizeof (si
));
1743 si
.cb
= sizeof (si
);
1747 flags
= DEBUG_ONLY_THIS_PROCESS
;
1748 cygwin_conv_to_win32_path (exec_file
, real_path
);
1754 sh
= getenv ("SHELL");
1757 cygwin_conv_to_win32_path (sh
, shell
);
1758 newallargs
= alloca (sizeof (" -c 'exec '") + strlen (exec_file
)
1759 + strlen (allargs
) + 2);
1760 sprintf (newallargs
, " -c 'exec %s %s'", exec_file
, allargs
);
1761 allargs
= newallargs
;
1763 flags
= DEBUG_PROCESS
;
1767 flags
|= CREATE_NEW_PROCESS_GROUP
;
1770 flags
|= CREATE_NEW_CONSOLE
;
1774 args
= alloca (strlen (toexec
) + strlen (allargs
) + 2);
1775 strcpy (args
, toexec
);
1777 strcat (args
, allargs
);
1779 /* Prepare the environment vars for CreateProcess. */
1781 /* This code used to assume all env vars were file names and would
1782 translate them all to win32 style. That obviously doesn't work in the
1783 general case. The current rule is that we only translate PATH.
1784 We need to handle PATH because we're about to call CreateProcess and
1785 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
1786 in both posix and win32 environments. cygwin.dll will change it back
1787 to posix style if necessary. */
1789 static const char *conv_path_names
[] =
1795 /* CreateProcess takes the environment list as a null terminated set of
1796 strings (i.e. two nulls terminate the list). */
1798 /* Get total size for env strings. */
1799 for (envlen
= 0, i
= 0; env
[i
] && *env
[i
]; i
++)
1803 for (j
= 0; conv_path_names
[j
]; j
++)
1805 len
= strlen (conv_path_names
[j
]);
1806 if (strncmp (conv_path_names
[j
], env
[i
], len
) == 0)
1808 if (cygwin_posix_path_list_p (env
[i
] + len
))
1810 + cygwin_posix_to_win32_path_list_buf_size (env
[i
] + len
);
1812 envlen
+= strlen (env
[i
]) + 1;
1816 if (conv_path_names
[j
] == NULL
)
1817 envlen
+= strlen (env
[i
]) + 1;
1820 winenv
= alloca (envlen
+ 1);
1822 /* Copy env strings into new buffer. */
1823 for (temp
= winenv
, i
= 0; env
[i
] && *env
[i
]; i
++)
1827 for (j
= 0; conv_path_names
[j
]; j
++)
1829 len
= strlen (conv_path_names
[j
]);
1830 if (strncmp (conv_path_names
[j
], env
[i
], len
) == 0)
1832 if (cygwin_posix_path_list_p (env
[i
] + len
))
1834 memcpy (temp
, env
[i
], len
);
1835 cygwin_posix_to_win32_path_list (env
[i
] + len
, temp
+ len
);
1838 strcpy (temp
, env
[i
]);
1842 if (conv_path_names
[j
] == NULL
)
1843 strcpy (temp
, env
[i
]);
1845 temp
+= strlen (temp
) + 1;
1848 /* Final nil string to terminate new env. */
1852 if (!inferior_io_terminal
)
1853 tty
= ostdin
= ostdout
= ostderr
= -1;
1856 tty
= open (inferior_io_terminal
, O_RDWR
| O_NOCTTY
);
1859 print_sys_errmsg (inferior_io_terminal
, errno
);
1860 ostdin
= ostdout
= ostderr
= -1;
1873 win32_init_thread_list ();
1874 ret
= CreateProcess (0,
1875 args
, /* command line */
1876 NULL
, /* Security */
1878 TRUE
, /* inherit handles */
1879 flags
, /* start flags */
1881 NULL
, /* current directory */
1896 error (_("Error creating process %s, (error %d)."),
1897 exec_file
, (unsigned) GetLastError ());
1899 CloseHandle (pi
.hThread
);
1900 CloseHandle (pi
.hProcess
);
1902 if (useshell
&& shell
[0] != '\0')
1907 do_initial_win32_stuff (pi
.dwProcessId
);
1909 /* win32_continue (DBG_CONTINUE, -1); */
1910 proceed ((CORE_ADDR
) - 1, TARGET_SIGNAL_0
, 0);
1914 win32_mourn_inferior (void)
1916 (void) win32_continue (DBG_CONTINUE
, -1);
1917 i386_cleanup_dregs();
1918 unpush_target (&win32_ops
);
1919 generic_mourn_inferior ();
1922 /* Send a SIGINT to the process group. This acts just like the user typed a
1923 ^C on the controlling terminal. */
1928 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
1929 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT
, current_event
.dwProcessId
));
1930 registers_changed (); /* refresh register state */
1934 win32_xfer_memory (CORE_ADDR memaddr
, gdb_byte
*our
, int len
,
1935 int write
, struct mem_attrib
*mem
,
1936 struct target_ops
*target
)
1941 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
1942 len
, (DWORD
) memaddr
));
1943 if (!WriteProcessMemory (current_process_handle
, (LPVOID
) memaddr
, our
,
1946 FlushInstructionCache (current_process_handle
, (LPCVOID
) memaddr
, len
);
1950 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
1951 len
, (DWORD
) memaddr
));
1952 if (!ReadProcessMemory (current_process_handle
, (LPCVOID
) memaddr
, our
,
1960 win32_kill_inferior (void)
1962 CHECK (TerminateProcess (current_process_handle
, 0));
1966 if (!win32_continue (DBG_CONTINUE
, -1))
1968 if (!WaitForDebugEvent (¤t_event
, INFINITE
))
1970 if (current_event
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
)
1974 CHECK (CloseHandle (current_process_handle
));
1976 /* this may fail in an attached process so don't check. */
1977 if (current_thread
&& current_thread
->h
)
1978 (void) CloseHandle (current_thread
->h
);
1979 target_mourn_inferior (); /* or just win32_mourn_inferior? */
1983 win32_resume (ptid_t ptid
, int step
, enum target_signal sig
)
1986 DWORD continue_status
= DBG_CONTINUE
;
1988 int pid
= PIDGET (ptid
);
1990 if (sig
!= TARGET_SIGNAL_0
)
1992 if (current_event
.dwDebugEventCode
!= EXCEPTION_DEBUG_EVENT
)
1994 DEBUG_EXCEPT(("Cannot continue with signal %d here.\n",sig
));
1996 else if (sig
== last_sig
)
1997 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
2000 /* This code does not seem to work, because
2001 the kernel does probably not consider changes in the ExceptionRecord
2002 structure when passing the exception to the inferior.
2003 Note that this seems possible in the exception handler itself. */
2006 for (i
= 0; xlate
[i
].them
!= -1; i
++)
2007 if (xlate
[i
].us
== sig
)
2009 current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
=
2011 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
2014 if (continue_status
== DBG_CONTINUE
)
2016 DEBUG_EXCEPT(("Cannot continue with signal %d.\n",sig
));
2020 DEBUG_EXCEPT(("Can only continue with recieved signal %d.\n",
2024 last_sig
= TARGET_SIGNAL_0
;
2026 DEBUG_EXEC (("gdb: win32_resume (pid=%d, step=%d, sig=%d);\n",
2029 /* Get context for currently selected thread */
2030 th
= thread_rec (current_event
.dwThreadId
, FALSE
);
2035 /* Single step by setting t bit */
2036 win32_fetch_inferior_registers (PS_REGNUM
);
2037 th
->context
.EFlags
|= FLAG_TRACE_BIT
;
2040 if (th
->context
.ContextFlags
)
2042 if (debug_registers_changed
)
2044 th
->context
.Dr0
= dr
[0];
2045 th
->context
.Dr1
= dr
[1];
2046 th
->context
.Dr2
= dr
[2];
2047 th
->context
.Dr3
= dr
[3];
2048 /* th->context.Dr6 = dr[6];
2049 FIXME: should we set dr6 also ?? */
2050 th
->context
.Dr7
= dr
[7];
2052 CHECK (SetThreadContext (th
->h
, &th
->context
));
2053 th
->context
.ContextFlags
= 0;
2057 /* Allow continuing with the same signal that interrupted us.
2058 Otherwise complain. */
2060 win32_continue (continue_status
, pid
);
2064 win32_prepare_to_store (void)
2066 /* Do nothing, since we can store individual regs */
2070 win32_can_run (void)
2078 DEBUG_EVENTS (("gdb: win32_close, inferior_ptid=%d\n",
2079 PIDGET (inferior_ptid
)));
2082 /* Convert pid to printable format. */
2084 cygwin_pid_to_str (ptid_t ptid
)
2086 static char buf
[80];
2087 int pid
= PIDGET (ptid
);
2089 if ((DWORD
) pid
== current_event
.dwProcessId
)
2090 sprintf (buf
, "process %d", pid
);
2092 sprintf (buf
, "thread %ld.0x%x", current_event
.dwProcessId
, pid
);
2098 struct target_ops
*target
;
2100 } map_code_section_args
;
2103 map_single_dll_code_section (bfd
*abfd
, asection
*sect
, void *obj
)
2107 struct section_table
*new_target_sect_ptr
;
2109 map_code_section_args
*args
= (map_code_section_args
*) obj
;
2110 struct target_ops
*target
= args
->target
;
2111 if (sect
->flags
& SEC_CODE
)
2113 update_coreops
= core_ops
.to_sections
== target
->to_sections
;
2115 if (target
->to_sections
)
2117 old
= target
->to_sections_end
- target
->to_sections
;
2118 target
->to_sections
= (struct section_table
*)
2119 xrealloc ((char *) target
->to_sections
,
2120 (sizeof (struct section_table
)) * (1 + old
));
2125 target
->to_sections
= (struct section_table
*)
2126 xmalloc ((sizeof (struct section_table
)));
2128 target
->to_sections_end
= target
->to_sections
+ (1 + old
);
2130 /* Update the to_sections field in the core_ops structure
2134 core_ops
.to_sections
= target
->to_sections
;
2135 core_ops
.to_sections_end
= target
->to_sections_end
;
2137 new_target_sect_ptr
= target
->to_sections
+ old
;
2138 new_target_sect_ptr
->addr
= args
->addr
+ bfd_section_vma (abfd
, sect
);
2139 new_target_sect_ptr
->endaddr
= args
->addr
+ bfd_section_vma (abfd
, sect
) +
2140 bfd_section_size (abfd
, sect
);;
2141 new_target_sect_ptr
->the_bfd_section
= sect
;
2142 new_target_sect_ptr
->bfd
= abfd
;
2147 dll_code_sections_add (const char *dll_name
, int base_addr
, struct target_ops
*target
)
2150 map_code_section_args map_args
;
2151 asection
*lowest_sect
;
2153 if (dll_name
== NULL
|| target
== NULL
)
2155 name
= xstrdup (dll_name
);
2156 dll_bfd
= bfd_openr (name
, "pei-i386");
2157 if (dll_bfd
== NULL
)
2160 if (bfd_check_format (dll_bfd
, bfd_object
))
2162 lowest_sect
= bfd_get_section_by_name (dll_bfd
, ".text");
2163 if (lowest_sect
== NULL
)
2165 map_args
.target
= target
;
2166 map_args
.addr
= base_addr
- bfd_section_vma (dll_bfd
, lowest_sect
);
2168 bfd_map_over_sections (dll_bfd
, &map_single_dll_code_section
, (void *) (&map_args
));
2175 core_section_load_dll_symbols (bfd
*abfd
, asection
*sect
, void *obj
)
2177 struct target_ops
*target
= (struct target_ops
*) obj
;
2182 struct win32_pstatus
*pstatus
;
2187 struct objfile
*objfile
;
2188 const char *dll_basename
;
2190 if (strncmp (sect
->name
, ".module", 7) != 0)
2193 buf
= (char *) xmalloc (bfd_get_section_size (sect
) + 1);
2196 printf_unfiltered ("memory allocation failed for %s\n", sect
->name
);
2199 if (!bfd_get_section_contents (abfd
, sect
, buf
, 0, bfd_get_section_size (sect
)))
2202 pstatus
= (struct win32_pstatus
*) buf
;
2204 memmove (&base_addr
, &(pstatus
->data
.module_info
.base_address
), sizeof (base_addr
));
2205 dll_name_size
= pstatus
->data
.module_info
.module_name_size
;
2206 if (offsetof (struct win32_pstatus
, data
.module_info
.module_name
) + dll_name_size
> bfd_get_section_size (sect
))
2209 dll_name
= pstatus
->data
.module_info
.module_name
;
2211 if (!(dll_basename
= strrchr (dll_name
, '/')))
2212 dll_basename
= dll_name
;
2216 ALL_OBJFILES (objfile
)
2218 char *objfile_basename
= strrchr (objfile
->name
, '/');
2220 if (objfile_basename
&&
2221 strcasecmp (dll_basename
, objfile_basename
+ 1) == 0)
2225 base_addr
+= 0x1000;
2226 dll_name
= register_loaded_dll (dll_name
, base_addr
, 1);
2228 if (!dll_code_sections_add (dll_name
, (DWORD
) base_addr
, target
))
2229 printf_unfiltered ("%s: Failed to map dll code sections.\n", dll_name
);
2237 static struct so_list
*
2238 win32_current_sos (void)
2240 struct so_list
*head
= solib_start
.next
;
2241 win32_clear_solib ();
2242 if (!head
&& core_bfd
)
2244 bfd_map_over_sections (core_bfd
, &core_section_load_dll_symbols
,
2246 head
= solib_start
.next
;
2247 win32_clear_solib ();
2253 fetch_elf_core_registers (char *core_reg_sect
,
2254 unsigned core_reg_size
,
2259 if (core_reg_size
< sizeof (CONTEXT
))
2261 error (_("Core file register section too small (%u bytes)."), core_reg_size
);
2264 for (r
= 0; r
< NUM_REGS
; r
++)
2265 regcache_raw_supply (current_regcache
, r
, core_reg_sect
+ mappings
[r
]);
2269 init_win32_ops (void)
2271 win32_ops
.to_shortname
= "child";
2272 win32_ops
.to_longname
= "Win32 child process";
2273 win32_ops
.to_doc
= "Win32 child process (started by the \"run\" command).";
2274 win32_ops
.to_open
= win32_open
;
2275 win32_ops
.to_close
= win32_close
;
2276 win32_ops
.to_attach
= win32_attach
;
2277 win32_ops
.to_detach
= win32_detach
;
2278 win32_ops
.to_resume
= win32_resume
;
2279 win32_ops
.to_wait
= win32_wait
;
2280 win32_ops
.to_fetch_registers
= win32_fetch_inferior_registers
;
2281 win32_ops
.to_store_registers
= win32_store_inferior_registers
;
2282 win32_ops
.to_prepare_to_store
= win32_prepare_to_store
;
2283 win32_ops
.deprecated_xfer_memory
= win32_xfer_memory
;
2284 win32_ops
.to_files_info
= win32_files_info
;
2285 win32_ops
.to_insert_breakpoint
= memory_insert_breakpoint
;
2286 win32_ops
.to_remove_breakpoint
= memory_remove_breakpoint
;
2287 win32_ops
.to_terminal_init
= terminal_init_inferior
;
2288 win32_ops
.to_terminal_inferior
= terminal_inferior
;
2289 win32_ops
.to_terminal_ours_for_output
= terminal_ours_for_output
;
2290 win32_ops
.to_terminal_ours
= terminal_ours
;
2291 win32_ops
.to_terminal_save_ours
= terminal_save_ours
;
2292 win32_ops
.to_terminal_info
= child_terminal_info
;
2293 win32_ops
.to_kill
= win32_kill_inferior
;
2294 win32_ops
.to_create_inferior
= win32_create_inferior
;
2295 win32_ops
.to_mourn_inferior
= win32_mourn_inferior
;
2296 win32_ops
.to_can_run
= win32_can_run
;
2297 win32_ops
.to_thread_alive
= win32_win32_thread_alive
;
2298 win32_ops
.to_pid_to_str
= cygwin_pid_to_str
;
2299 win32_ops
.to_stop
= win32_stop
;
2300 win32_ops
.to_stratum
= process_stratum
;
2301 win32_ops
.to_has_all_memory
= 1;
2302 win32_ops
.to_has_memory
= 1;
2303 win32_ops
.to_has_stack
= 1;
2304 win32_ops
.to_has_registers
= 1;
2305 win32_ops
.to_has_execution
= 1;
2306 win32_ops
.to_magic
= OPS_MAGIC
;
2307 win32_ops
.to_pid_to_exec_file
= win32_pid_to_exec_file
;
2309 win32_so_ops
.relocate_section_addresses
= win32_relocate_section_addresses
;
2310 win32_so_ops
.free_so
= win32_free_so
;
2311 win32_so_ops
.clear_solib
= win32_clear_solib
;
2312 win32_so_ops
.solib_create_inferior_hook
= win32_solib_create_inferior_hook
;
2313 win32_so_ops
.special_symbol_handling
= win32_special_symbol_handling
;
2314 win32_so_ops
.current_sos
= win32_current_sos
;
2315 win32_so_ops
.open_symbol_file_object
= NULL
;
2316 win32_so_ops
.in_dynsym_resolve_code
= NULL
;
2318 /* FIXME: Don't do this here. *_gdbarch_init() should set so_ops. */
2319 current_target_so_ops
= &win32_so_ops
;
2323 _initialize_win32_nat (void)
2325 struct cmd_list_element
*c
;
2329 c
= add_com ("dll-symbols", class_files
, dll_symbol_command
,
2330 _("Load dll library symbols from FILE."));
2331 set_cmd_completer (c
, filename_completer
);
2333 add_com_alias ("sharedlibrary", "dll-symbols", class_alias
, 1);
2335 add_setshow_boolean_cmd ("shell", class_support
, &useshell
, _("\
2336 Set use of shell to start subprocess."), _("\
2337 Show use of shell to start subprocess."), NULL
,
2339 NULL
, /* FIXME: i18n: */
2340 &setlist
, &showlist
);
2342 add_setshow_boolean_cmd ("new-console", class_support
, &new_console
, _("\
2343 Set creation of new console when creating child process."), _("\
2344 Show creation of new console when creating child process."), NULL
,
2346 NULL
, /* FIXME: i18n: */
2347 &setlist
, &showlist
);
2349 add_setshow_boolean_cmd ("new-group", class_support
, &new_group
, _("\
2350 Set creation of new group when creating child process."), _("\
2351 Show creation of new group when creating child process."), NULL
,
2353 NULL
, /* FIXME: i18n: */
2354 &setlist
, &showlist
);
2356 add_setshow_boolean_cmd ("debugexec", class_support
, &debug_exec
, _("\
2357 Set whether to display execution in child process."), _("\
2358 Show whether to display execution in child process."), NULL
,
2360 NULL
, /* FIXME: i18n: */
2361 &setlist
, &showlist
);
2363 add_setshow_boolean_cmd ("debugevents", class_support
, &debug_events
, _("\
2364 Set whether to display kernel events in child process."), _("\
2365 Show whether to display kernel events in child process."), NULL
,
2367 NULL
, /* FIXME: i18n: */
2368 &setlist
, &showlist
);
2370 add_setshow_boolean_cmd ("debugmemory", class_support
, &debug_memory
, _("\
2371 Set whether to display memory accesses in child process."), _("\
2372 Show whether to display memory accesses in child process."), NULL
,
2374 NULL
, /* FIXME: i18n: */
2375 &setlist
, &showlist
);
2377 add_setshow_boolean_cmd ("debugexceptions", class_support
,
2378 &debug_exceptions
, _("\
2379 Set whether to display kernel exceptions in child process."), _("\
2380 Show whether to display kernel exceptions in child process."), NULL
,
2382 NULL
, /* FIXME: i18n: */
2383 &setlist
, &showlist
);
2385 add_info ("dll", info_dll_command
, _("Status of loaded DLLs."));
2386 add_info_alias ("sharedlibrary", "dll", 1);
2388 add_prefix_cmd ("w32", class_info
, info_w32_command
,
2389 _("Print information specific to Win32 debugging."),
2390 &info_w32_cmdlist
, "info w32 ", 0, &infolist
);
2392 add_cmd ("selector", class_info
, display_selectors
,
2393 _("Display selectors infos."),
2395 add_target (&win32_ops
);
2398 /* Hardware watchpoint support, adapted from go32-nat.c code. */
2400 /* Pass the address ADDR to the inferior in the I'th debug register.
2401 Here we just store the address in dr array, the registers will be
2402 actually set up when win32_continue is called. */
2404 cygwin_set_dr (int i
, CORE_ADDR addr
)
2407 internal_error (__FILE__
, __LINE__
,
2408 _("Invalid register %d in cygwin_set_dr.\n"), i
);
2409 dr
[i
] = (unsigned) addr
;
2410 debug_registers_changed
= 1;
2411 debug_registers_used
= 1;
2414 /* Pass the value VAL to the inferior in the DR7 debug control
2415 register. Here we just store the address in D_REGS, the watchpoint
2416 will be actually set up in win32_wait. */
2418 cygwin_set_dr7 (unsigned val
)
2421 debug_registers_changed
= 1;
2422 debug_registers_used
= 1;
2425 /* Get the value of the DR6 debug status register from the inferior.
2426 Here we just return the value stored in dr[6]
2427 by the last call to thread_rec for current_event.dwThreadId id. */
2429 cygwin_get_dr6 (void)
2434 /* Determine if the thread referenced by "pid" is alive
2435 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
2436 it means that the pid has died. Otherwise it is assumed to be alive. */
2438 win32_win32_thread_alive (ptid_t ptid
)
2440 int pid
= PIDGET (ptid
);
2442 return WaitForSingleObject (thread_rec (pid
, FALSE
)->h
, 0) == WAIT_OBJECT_0
?
2446 static struct core_fns win32_elf_core_fns
=
2448 bfd_target_elf_flavour
,
2449 default_check_format
,
2450 default_core_sniffer
,
2451 fetch_elf_core_registers
,
2456 _initialize_core_win32 (void)
2458 deprecated_add_core_fns (&win32_elf_core_fns
);
2462 _initialize_check_for_gdb_ini (void)
2465 if (inhibit_gdbinit
)
2468 homedir
= getenv ("HOME");
2472 char *oldini
= (char *) alloca (strlen (homedir
) +
2473 sizeof ("/gdb.ini"));
2474 strcpy (oldini
, homedir
);
2475 p
= strchr (oldini
, '\0');
2476 if (p
> oldini
&& p
[-1] != '/')
2478 strcpy (p
, "gdb.ini");
2479 if (access (oldini
, 0) == 0)
2481 int len
= strlen (oldini
);
2482 char *newini
= alloca (len
+ 1);
2483 sprintf (newini
, "%.*s.gdbinit",
2484 (int) (len
- (sizeof ("gdb.ini") - 1)), oldini
);
2485 warning (_("obsolete '%s' found. Rename to '%s'."), oldini
, newini
);