1 /* Target-vector operations for controlling win32 child processes, for GDB.
3 Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free
4 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 */
35 #include "completer.h"
39 #include <sys/types.h>
44 #include <sys/cygwin.h>
49 #include "gdb_string.h"
50 #include "gdbthread.h"
52 #include <sys/param.h>
56 #include "i386-tdep.h"
57 #include "i387-tdep.h"
59 /* The ui's event loop. */
60 extern int (*ui_loop_hook
) (int signo
);
62 /* If we're not using the old Cygwin header file set, define the
63 following which never should have been in the generic Win32 API
64 headers in the first place since they were our own invention... */
65 #ifndef _GNU_H_WINDOWS_H
68 FLAG_TRACE_BIT
= 0x100,
69 CONTEXT_DEBUGGER
= (CONTEXT_FULL
| CONTEXT_FLOATING_POINT
)
72 #include <sys/procfs.h>
75 #define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \
76 | CONTEXT_EXTENDED_REGISTERS
78 static unsigned dr
[8];
79 static int debug_registers_changed
= 0;
80 static int debug_registers_used
= 0;
82 /* The string sent by cygwin when it processes a signal.
83 FIXME: This should be in a cygwin include file. */
84 #define CYGWIN_SIGNAL_STRING "cygwin: signal"
86 #define CHECK(x) check (x, __FILE__,__LINE__)
87 #define DEBUG_EXEC(x) if (debug_exec) printf_unfiltered x
88 #define DEBUG_EVENTS(x) if (debug_events) printf_unfiltered x
89 #define DEBUG_MEM(x) if (debug_memory) printf_unfiltered x
90 #define DEBUG_EXCEPT(x) if (debug_exceptions) printf_unfiltered x
92 /* Forward declaration */
93 extern struct target_ops child_ops
;
95 static void child_stop (void);
96 static int win32_child_thread_alive (ptid_t
);
97 void child_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
;
116 static thread_info thread_head
;
118 /* The process and thread handles for the above context. */
120 static DEBUG_EVENT current_event
; /* The current debug event from
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 */
126 /* Counts of things. */
127 static int exception_count
= 0;
128 static int event_count
= 0;
129 static int saw_create
;
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 */
140 /* This vector maps GDB's idea of a register's number into an address
141 in the win32 exception context vector.
143 It also contains the bit mask needed to load the register in question.
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
153 #define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
154 static const int mappings
[] =
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
)
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]),
198 context_offset (ExtendedRegisters
[24])
201 #undef context_offset
203 /* This vector maps the target's idea of an exception (extracted
204 from the DEBUG_EVENT structure) to GDB's idea. */
206 struct xlate_exception
209 enum target_signal us
;
212 static const struct xlate_exception
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
},
224 check (BOOL ok
, const char *file
, int line
)
227 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;
250 th
->context
.ContextFlags
= CONTEXT_DEBUGGER_DR
;
251 GetThreadContext (th
->h
, &th
->context
);
252 if (id
== current_event
.dwThreadId
)
254 /* Copy dr values from that thread. */
255 dr
[0] = th
->context
.Dr0
;
256 dr
[1] = th
->context
.Dr1
;
257 dr
[2] = th
->context
.Dr2
;
258 dr
[3] = th
->context
.Dr3
;
259 dr
[6] = th
->context
.Dr6
;
260 dr
[7] = th
->context
.Dr7
;
269 /* Add a thread to the thread list */
271 child_add_thread (DWORD id
, HANDLE h
)
275 if ((th
= thread_rec (id
, FALSE
)))
278 th
= (thread_info
*) xmalloc (sizeof (*th
));
279 memset (th
, 0, sizeof (*th
));
282 th
->next
= thread_head
.next
;
283 thread_head
.next
= th
;
284 add_thread (pid_to_ptid (id
));
285 /* Set the debug registers for the new thread in they are used. */
286 if (debug_registers_used
)
288 /* Only change the value of the debug registers. */
289 th
->context
.ContextFlags
= CONTEXT_DEBUG_REGISTERS
;
290 CHECK (GetThreadContext (th
->h
, &th
->context
));
291 th
->context
.Dr0
= dr
[0];
292 th
->context
.Dr1
= dr
[1];
293 th
->context
.Dr2
= dr
[2];
294 th
->context
.Dr3
= dr
[3];
295 /* th->context.Dr6 = dr[6];
296 FIXME: should we set dr6 also ?? */
297 th
->context
.Dr7
= dr
[7];
298 CHECK (SetThreadContext (th
->h
, &th
->context
));
299 th
->context
.ContextFlags
= 0;
304 /* Clear out any old thread list and reintialize it to a
307 child_init_thread_list (void)
309 thread_info
*th
= &thread_head
;
311 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
313 while (th
->next
!= NULL
)
315 thread_info
*here
= th
->next
;
316 th
->next
= here
->next
;
317 (void) CloseHandle (here
->h
);
322 /* Delete a thread from the list of threads */
324 child_delete_thread (DWORD id
)
329 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (pid_to_ptid (id
)));
330 delete_thread (pid_to_ptid (id
));
332 for (th
= &thread_head
;
333 th
->next
!= NULL
&& th
->next
->id
!= id
;
337 if (th
->next
!= NULL
)
339 thread_info
*here
= th
->next
;
340 th
->next
= here
->next
;
341 CloseHandle (here
->h
);
347 do_child_fetch_inferior_registers (int r
)
349 char *context_offset
= ((char *) ¤t_thread
->context
) + mappings
[r
];
352 #define I387_ST0_REGNUM I386_ST0_REGNUM
354 if (r
== I387_FISEG_REGNUM
)
356 l
= *((long *) context_offset
) & 0xffff;
357 supply_register (r
, (char *) &l
);
359 else if (r
== I387_FOP_REGNUM
)
361 l
= (*((long *) context_offset
) >> 16) & ((1 << 11) - 1);
362 supply_register (r
, (char *) &l
);
365 supply_register (r
, context_offset
);
368 for (r
= 0; r
< NUM_REGS
; r
++)
369 do_child_fetch_inferior_registers (r
);
372 #undef I387_ST0_REGNUM
376 child_fetch_inferior_registers (int r
)
378 current_thread
= thread_rec (PIDGET (inferior_ptid
), TRUE
);
379 do_child_fetch_inferior_registers (r
);
383 do_child_store_inferior_registers (int r
)
386 regcache_collect (r
, ((char *) ¤t_thread
->context
) + mappings
[r
]);
389 for (r
= 0; r
< NUM_REGS
; r
++)
390 do_child_store_inferior_registers (r
);
394 /* Store a new register value into the current thread context */
396 child_store_inferior_registers (int r
)
398 current_thread
= thread_rec (PIDGET (inferior_ptid
), TRUE
);
399 do_child_store_inferior_registers (r
);
402 static int psapi_loaded
= 0;
403 static HMODULE psapi_module_handle
= NULL
;
404 static BOOL
WINAPI (*psapi_EnumProcessModules
) (HANDLE
, HMODULE
*, DWORD
, LPDWORD
) = NULL
;
405 static BOOL
WINAPI (*psapi_GetModuleInformation
) (HANDLE
, HMODULE
, LPMODULEINFO
, DWORD
) = NULL
;
406 static DWORD
WINAPI (*psapi_GetModuleFileNameExA
) (HANDLE
, HMODULE
, LPSTR
, DWORD
) = NULL
;
409 psapi_get_dll_name (DWORD BaseAddress
, char *dll_name_ret
)
415 HMODULE
*DllHandle
= dh_buf
;
420 psapi_EnumProcessModules
== NULL
||
421 psapi_GetModuleInformation
== NULL
||
422 psapi_GetModuleFileNameExA
== NULL
)
427 psapi_module_handle
= LoadLibrary ("psapi.dll");
428 if (!psapi_module_handle
)
430 /* printf_unfiltered ("error loading psapi.dll: %u", GetLastError ()); */
433 psapi_EnumProcessModules
= GetProcAddress (psapi_module_handle
, "EnumProcessModules");
434 psapi_GetModuleInformation
= GetProcAddress (psapi_module_handle
, "GetModuleInformation");
435 psapi_GetModuleFileNameExA
= (void *) GetProcAddress (psapi_module_handle
,
436 "GetModuleFileNameExA");
437 if (psapi_EnumProcessModules
== NULL
||
438 psapi_GetModuleInformation
== NULL
||
439 psapi_GetModuleFileNameExA
== NULL
)
444 ok
= (*psapi_EnumProcessModules
) (current_process_handle
,
449 if (!ok
|| !cbNeeded
)
452 DllHandle
= (HMODULE
*) alloca (cbNeeded
);
456 ok
= (*psapi_EnumProcessModules
) (current_process_handle
,
463 for (i
= 0; i
< (int) (cbNeeded
/ sizeof (HMODULE
)); i
++)
465 if (!(*psapi_GetModuleInformation
) (current_process_handle
,
469 error ("Can't get module info");
471 len
= (*psapi_GetModuleFileNameExA
) (current_process_handle
,
476 error ("Error getting dll name: %u\n", (unsigned) GetLastError ());
478 if ((DWORD
) (mi
.lpBaseOfDll
) == BaseAddress
)
483 dll_name_ret
[0] = '\0';
487 /* Encapsulate the information required in a call to
488 symbol_file_add_args */
489 struct safe_symbol_file_add_args
493 struct section_addr_info
*addrs
;
496 struct ui_file
*err
, *out
;
500 /* Maintain a linked list of "so" information. */
503 struct so_stuff
*next
;
507 struct objfile
*objfile
;
509 } solib_start
, *solib_end
;
511 /* Call symbol_file_add with stderr redirected. We don't care if there
514 safe_symbol_file_add_stub (void *argv
)
516 #define p ((struct safe_symbol_file_add_args *)argv)
517 struct so_stuff
*so
= &solib_start
;
519 while ((so
= so
->next
))
520 if (so
->loaded
&& strcasecmp (so
->name
, p
->name
) == 0)
522 p
->ret
= symbol_file_add (p
->name
, p
->from_tty
, p
->addrs
, p
->mainline
, p
->flags
);
527 /* Restore gdb's stderr after calling symbol_file_add */
529 safe_symbol_file_add_cleanup (void *p
)
531 #define sp ((struct safe_symbol_file_add_args *)p)
532 gdb_flush (gdb_stderr
);
533 gdb_flush (gdb_stdout
);
534 ui_file_delete (gdb_stderr
);
535 ui_file_delete (gdb_stdout
);
536 gdb_stderr
= sp
->err
;
537 gdb_stdout
= sp
->out
;
541 /* symbol_file_add wrapper that prevents errors from being displayed. */
542 static struct objfile
*
543 safe_symbol_file_add (char *name
, int from_tty
,
544 struct section_addr_info
*addrs
,
545 int mainline
, int flags
)
547 struct safe_symbol_file_add_args p
;
548 struct cleanup
*cleanup
;
550 cleanup
= make_cleanup (safe_symbol_file_add_cleanup
, &p
);
554 gdb_flush (gdb_stderr
);
555 gdb_flush (gdb_stdout
);
556 gdb_stderr
= ui_file_new ();
557 gdb_stdout
= ui_file_new ();
559 p
.from_tty
= from_tty
;
561 p
.mainline
= mainline
;
563 catch_errors (safe_symbol_file_add_stub
, &p
, "", RETURN_MASK_ERROR
);
565 do_cleanups (cleanup
);
569 /* Remember the maximum DLL length for printing in info dll command. */
570 int max_dll_name_len
;
573 register_loaded_dll (const char *name
, DWORD load_addr
)
576 char ppath
[MAX_PATH
+ 1];
577 char buf
[MAX_PATH
+ 1];
578 char cwd
[MAX_PATH
+ 1];
580 WIN32_FIND_DATA w32_fd
;
581 HANDLE h
= FindFirstFile(name
, &w32_fd
);
582 MEMORY_BASIC_INFORMATION m
;
585 if (h
== INVALID_HANDLE_VALUE
)
591 if (GetCurrentDirectory (MAX_PATH
+ 1, cwd
))
593 p
= strrchr (buf
, '\\');
596 SetCurrentDirectory (buf
);
597 GetFullPathName (w32_fd
.cFileName
, MAX_PATH
, buf
, &p
);
598 SetCurrentDirectory (cwd
);
602 cygwin_conv_to_posix_path (buf
, ppath
);
603 so
= (struct so_stuff
*) xmalloc (sizeof (struct so_stuff
) + strlen (ppath
) + 8 + 1);
605 so
->load_addr
= load_addr
;
606 if (VirtualQueryEx (current_process_handle
, (void *) load_addr
, &m
,
608 so
->end_addr
= (DWORD
) m
.AllocationBase
+ m
.RegionSize
;
610 so
->end_addr
= load_addr
+ 0x2000; /* completely arbitrary */
614 strcpy (so
->name
, ppath
);
616 solib_end
->next
= so
;
618 len
= strlen (ppath
);
619 if (len
> max_dll_name_len
)
620 max_dll_name_len
= len
;
624 get_image_name (HANDLE h
, void *address
, int unicode
)
626 static char buf
[(2 * MAX_PATH
) + 1];
627 DWORD size
= unicode
? sizeof (WCHAR
) : sizeof (char);
633 /* Attempt to read the name of the dll that was detected.
634 This is documented to work only when actively debugging
635 a program. It will not work for attached processes. */
639 /* See if we could read the address of a string, and that the
640 address isn't null. */
641 if (!ReadProcessMemory (h
, address
, &address_ptr
, sizeof (address_ptr
), &done
)
642 || done
!= sizeof (address_ptr
) || !address_ptr
)
645 /* Find the length of the string */
646 while (ReadProcessMemory (h
, address_ptr
+ len
++ * size
, &b
, size
, &done
)
647 && (b
[0] != 0 || b
[size
- 1] != 0) && done
== size
)
651 ReadProcessMemory (h
, address_ptr
, buf
, len
, &done
);
654 WCHAR
*unicode_address
= (WCHAR
*) alloca (len
* sizeof (WCHAR
));
655 ReadProcessMemory (h
, address_ptr
, unicode_address
, len
* sizeof (WCHAR
),
658 WideCharToMultiByte (CP_ACP
, 0, unicode_address
, len
, buf
, len
, 0, 0);
664 /* Wait for child to do something. Return pid of child, or -1 in case
665 of error; store status through argument pointer OURSTATUS. */
667 handle_load_dll (void *dummy
)
669 LOAD_DLL_DEBUG_INFO
*event
= ¤t_event
.u
.LoadDll
;
670 char dll_buf
[MAX_PATH
+ 1];
671 char *dll_name
= NULL
;
674 dll_buf
[0] = dll_buf
[sizeof (dll_buf
) - 1] = '\0';
676 if (!psapi_get_dll_name ((DWORD
) (event
->lpBaseOfDll
), dll_buf
))
677 dll_buf
[0] = dll_buf
[sizeof (dll_buf
) - 1] = '\0';
681 if (*dll_name
== '\0')
682 dll_name
= get_image_name (current_process_handle
, event
->lpImageName
, event
->fUnicode
);
686 register_loaded_dll (dll_name
, (DWORD
) event
->lpBaseOfDll
+ 0x1000);
692 handle_unload_dll (void *dummy
)
694 DWORD lpBaseOfDll
= (DWORD
) current_event
.u
.UnloadDll
.lpBaseOfDll
+ 0x1000;
697 for (so
= &solib_start
; so
->next
!= NULL
; so
= so
->next
)
698 if (so
->next
->load_addr
== lpBaseOfDll
)
700 struct so_stuff
*sodel
= so
->next
;
701 so
->next
= sodel
->next
;
705 free_objfile (sodel
->objfile
);
709 error ("Error: dll starting at 0x%lx not found.\n", (DWORD
) lpBaseOfDll
);
715 solib_address (CORE_ADDR address
)
718 for (so
= &solib_start
; so
->next
!= NULL
; so
= so
->next
)
719 if (address
>= so
->load_addr
&& address
<= so
->end_addr
)
724 /* Return name of last loaded DLL. */
726 child_solib_loaded_library_pathname (int pid
)
728 return !solib_end
|| !solib_end
->name
[0] ? NULL
: solib_end
->name
;
731 /* Clear list of loaded DLLs. */
733 child_clear_solibs (void)
735 struct so_stuff
*so
, *so1
= solib_start
.next
;
737 while ((so
= so1
) != NULL
)
743 solib_start
.next
= NULL
;
744 solib_start
.objfile
= NULL
;
745 solib_end
= &solib_start
;
746 max_dll_name_len
= sizeof ("DLL Name") - 1;
749 /* Get the loaded address of all sections, given that .text was loaded
750 at text_load. Assumes that all sections are subject to the same
751 relocation offset. Returns NULL if problems occur or if the
752 sections were not relocated. */
754 static struct section_addr_info
*
755 get_relocated_section_addrs (bfd
*abfd
, CORE_ADDR text_load
)
757 struct section_addr_info
*result
= NULL
;
758 int section_count
= bfd_count_sections (abfd
);
759 asection
*text_section
= bfd_get_section_by_name (abfd
, ".text");
764 /* Couldn't get the .text section. Weird. */
767 else if (text_load
== (text_vma
= bfd_get_section_vma (abfd
, text_section
)))
769 /* DLL wasn't relocated. */
774 /* Figure out all sections' loaded addresses. The offset here is
775 such that taking a bfd_get_section_vma() result and adding
776 offset will give the real load address of the section. */
778 CORE_ADDR offset
= text_load
- text_vma
;
780 struct section_table
*table_start
= NULL
;
781 struct section_table
*table_end
= NULL
;
782 struct section_table
*iter
= NULL
;
784 build_section_table (abfd
, &table_start
, &table_end
);
786 for (iter
= table_start
; iter
< table_end
; ++iter
)
788 /* Relocated addresses. */
789 iter
->addr
+= offset
;
790 iter
->endaddr
+= offset
;
793 result
= build_section_addr_info_from_section_table (table_start
,
802 /* Add DLL symbol information. */
803 static struct objfile
*
804 solib_symbols_add (char *name
, int from_tty
, CORE_ADDR load_addr
)
806 struct section_addr_info
*addrs
= NULL
;
807 static struct objfile
*result
= NULL
;
810 /* The symbols in a dll are offset by 0x1000, which is the
811 the offset from 0 of the first byte in an image - because
812 of the file header and the section alignment. */
814 if (!name
|| !name
[0])
817 abfd
= bfd_openr (name
, "pei-i386");
821 /* pei failed - try pe */
822 abfd
= bfd_openr (name
, "pe-i386");
827 if (bfd_check_format (abfd
, bfd_object
))
829 addrs
= get_relocated_section_addrs (abfd
, load_addr
);
837 result
= safe_symbol_file_add (name
, from_tty
, addrs
, 0, OBJF_SHARED
);
838 free_section_addr_info (addrs
);
842 /* Fallback on handling just the .text section. */
843 struct cleanup
*my_cleanups
;
845 addrs
= alloc_section_addr_info (1);
846 my_cleanups
= make_cleanup (xfree
, addrs
);
847 addrs
->other
[0].name
= ".text";
848 addrs
->other
[0].addr
= load_addr
;
850 result
= safe_symbol_file_add (name
, from_tty
, addrs
, 0, OBJF_SHARED
);
851 do_cleanups (my_cleanups
);
857 /* Load DLL symbol info. */
859 dll_symbol_command (char *args
, int from_tty
)
865 error ("dll-symbols requires a file name");
868 if (n
> 4 && strcasecmp (args
+ n
- 4, ".dll") != 0)
870 char *newargs
= (char *) alloca (n
+ 4 + 1);
871 strcpy (newargs
, args
);
872 strcat (newargs
, ".dll");
876 safe_symbol_file_add (args
, from_tty
, NULL
, 0, OBJF_SHARED
| OBJF_USERLOADED
);
879 /* List currently loaded DLLs. */
881 info_dll_command (char *ignore
, int from_tty
)
883 struct so_stuff
*so
= &solib_start
;
888 printf_filtered ("%*s Load Address\n", -max_dll_name_len
, "DLL Name");
889 while ((so
= so
->next
) != NULL
)
890 printf_filtered ("%*s %08lx\n", -max_dll_name_len
, so
->name
, so
->load_addr
);
895 /* Handle DEBUG_STRING output from child process.
896 Cygwin prepends its messages with a "cygwin:". Interpret this as
897 a Cygwin signal. Otherwise just print the string as a warning. */
899 handle_output_debug_string (struct target_waitstatus
*ourstatus
)
904 if (!target_read_string
905 ((CORE_ADDR
) current_event
.u
.DebugString
.lpDebugStringData
, &s
, 1024, 0)
909 if (strncmp (s
, CYGWIN_SIGNAL_STRING
, sizeof (CYGWIN_SIGNAL_STRING
) - 1) != 0)
911 if (strncmp (s
, "cYg", 3) != 0)
917 int sig
= strtol (s
+ sizeof (CYGWIN_SIGNAL_STRING
) - 1, &p
, 0);
918 gotasig
= target_signal_from_host (sig
);
919 ourstatus
->value
.sig
= gotasig
;
921 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
929 display_selector (HANDLE thread
, DWORD sel
)
932 if (GetThreadSelectorEntry (thread
, sel
, &info
))
935 printf_filtered ("0x%03lx: ", sel
);
936 if (!info
.HighWord
.Bits
.Pres
)
938 puts_filtered ("Segment not present\n");
941 base
= (info
.HighWord
.Bits
.BaseHi
<< 24) +
942 (info
.HighWord
.Bits
.BaseMid
<< 16)
944 limit
= (info
.HighWord
.Bits
.LimitHi
<< 16) + info
.LimitLow
;
945 if (info
.HighWord
.Bits
.Granularity
)
946 limit
= (limit
<< 12) | 0xfff;
947 printf_filtered ("base=0x%08x limit=0x%08x", base
, limit
);
948 if (info
.HighWord
.Bits
.Default_Big
)
949 puts_filtered(" 32-bit ");
951 puts_filtered(" 16-bit ");
952 switch ((info
.HighWord
.Bits
.Type
& 0xf) >> 1)
955 puts_filtered ("Data (Read-Only, Exp-up");
958 puts_filtered ("Data (Read/Write, Exp-up");
961 puts_filtered ("Unused segment (");
964 puts_filtered ("Data (Read/Write, Exp-down");
967 puts_filtered ("Code (Exec-Only, N.Conf");
970 puts_filtered ("Code (Exec/Read, N.Conf");
973 puts_filtered ("Code (Exec-Only, Conf");
976 puts_filtered ("Code (Exec/Read, Conf");
979 printf_filtered ("Unknown type 0x%x",info
.HighWord
.Bits
.Type
);
981 if ((info
.HighWord
.Bits
.Type
& 0x1) == 0)
982 puts_filtered(", N.Acc");
983 puts_filtered (")\n");
984 if ((info
.HighWord
.Bits
.Type
& 0x10) == 0)
985 puts_filtered("System selector ");
986 printf_filtered ("Priviledge level = %d. ", info
.HighWord
.Bits
.Dpl
);
987 if (info
.HighWord
.Bits
.Granularity
)
988 puts_filtered ("Page granular.\n");
990 puts_filtered ("Byte granular.\n");
995 printf_filtered ("Invalid selector 0x%lx.\n",sel
);
1001 display_selectors (char * args
, int from_tty
)
1003 if (!current_thread
)
1005 puts_filtered ("Impossible to display selectors now.\n");
1011 puts_filtered ("Selector $cs\n");
1012 display_selector (current_thread
->h
,
1013 current_thread
->context
.SegCs
);
1014 puts_filtered ("Selector $ds\n");
1015 display_selector (current_thread
->h
,
1016 current_thread
->context
.SegDs
);
1017 puts_filtered ("Selector $es\n");
1018 display_selector (current_thread
->h
,
1019 current_thread
->context
.SegEs
);
1020 puts_filtered ("Selector $ss\n");
1021 display_selector (current_thread
->h
,
1022 current_thread
->context
.SegSs
);
1023 puts_filtered ("Selector $fs\n");
1024 display_selector (current_thread
->h
,
1025 current_thread
->context
.SegFs
);
1026 puts_filtered ("Selector $gs\n");
1027 display_selector (current_thread
->h
,
1028 current_thread
->context
.SegGs
);
1033 sel
= parse_and_eval_long (args
);
1034 printf_filtered ("Selector \"%s\"\n",args
);
1035 display_selector (current_thread
->h
, sel
);
1039 static struct cmd_list_element
*info_w32_cmdlist
= NULL
;
1042 info_w32_command (char *args
, int from_tty
)
1044 help_list (info_w32_cmdlist
, "info w32 ", class_info
, gdb_stdout
);
1048 #define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \
1049 printf_unfiltered ("gdb: Target exception %s at 0x%08lx\n", x, \
1050 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress)
1053 handle_exception (struct target_waitstatus
*ourstatus
)
1056 DWORD code
= current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
;
1058 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
1060 /* Record the context of the current thread */
1061 th
= thread_rec (current_event
.dwThreadId
, -1);
1065 case EXCEPTION_ACCESS_VIOLATION
:
1066 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
1067 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
1069 case STATUS_STACK_OVERFLOW
:
1070 DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
1071 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
1073 case STATUS_FLOAT_DENORMAL_OPERAND
:
1074 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
1075 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1077 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED
:
1078 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
1079 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1081 case STATUS_FLOAT_INEXACT_RESULT
:
1082 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
1083 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1085 case STATUS_FLOAT_INVALID_OPERATION
:
1086 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
1087 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1089 case STATUS_FLOAT_OVERFLOW
:
1090 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
1091 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1093 case STATUS_FLOAT_STACK_CHECK
:
1094 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
1095 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1097 case STATUS_FLOAT_UNDERFLOW
:
1098 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
1099 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1101 case STATUS_FLOAT_DIVIDE_BY_ZERO
:
1102 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
1103 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1105 case STATUS_INTEGER_DIVIDE_BY_ZERO
:
1106 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
1107 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1109 case STATUS_INTEGER_OVERFLOW
:
1110 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
1111 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1113 case EXCEPTION_BREAKPOINT
:
1114 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
1115 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
1118 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
1119 ourstatus
->value
.sig
= TARGET_SIGNAL_INT
;
1121 case DBG_CONTROL_BREAK
:
1122 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
1123 ourstatus
->value
.sig
= TARGET_SIGNAL_INT
;
1125 case EXCEPTION_SINGLE_STEP
:
1126 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
1127 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
1129 case EXCEPTION_ILLEGAL_INSTRUCTION
:
1130 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
1131 ourstatus
->value
.sig
= TARGET_SIGNAL_ILL
;
1133 case EXCEPTION_PRIV_INSTRUCTION
:
1134 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
1135 ourstatus
->value
.sig
= TARGET_SIGNAL_ILL
;
1137 case EXCEPTION_NONCONTINUABLE_EXCEPTION
:
1138 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
1139 ourstatus
->value
.sig
= TARGET_SIGNAL_ILL
;
1142 if (current_event
.u
.Exception
.dwFirstChance
)
1144 printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n",
1145 current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
,
1146 (DWORD
) current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
);
1147 ourstatus
->value
.sig
= TARGET_SIGNAL_UNKNOWN
;
1151 last_sig
= ourstatus
->value
.sig
;
1155 /* Resume all artificially suspended threads if we are continuing
1158 child_continue (DWORD continue_status
, int id
)
1164 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, %s);\n",
1165 current_event
.dwProcessId
, current_event
.dwThreadId
,
1166 continue_status
== DBG_CONTINUE
?
1167 "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED"));
1168 res
= ContinueDebugEvent (current_event
.dwProcessId
,
1169 current_event
.dwThreadId
,
1171 continue_status
= 0;
1173 for (th
= &thread_head
; (th
= th
->next
) != NULL
;)
1174 if (((id
== -1) || (id
== (int) th
->id
)) && th
->suspend_count
)
1177 for (i
= 0; i
< th
->suspend_count
; i
++)
1178 (void) ResumeThread (th
->h
);
1179 th
->suspend_count
= 0;
1180 if (debug_registers_changed
)
1182 /* Only change the value of the debug reisters */
1183 th
->context
.ContextFlags
= CONTEXT_DEBUG_REGISTERS
;
1184 th
->context
.Dr0
= dr
[0];
1185 th
->context
.Dr1
= dr
[1];
1186 th
->context
.Dr2
= dr
[2];
1187 th
->context
.Dr3
= dr
[3];
1188 /* th->context.Dr6 = dr[6];
1189 FIXME: should we set dr6 also ?? */
1190 th
->context
.Dr7
= dr
[7];
1191 CHECK (SetThreadContext (th
->h
, &th
->context
));
1192 th
->context
.ContextFlags
= 0;
1196 debug_registers_changed
= 0;
1200 /* Get the next event from the child. Return 1 if the event requires
1201 handling by WFI (or whatever).
1204 get_child_debug_event (int pid
, struct target_waitstatus
*ourstatus
)
1207 DWORD continue_status
, event_code
;
1208 thread_info
*th
= NULL
;
1209 static thread_info dummy_thread_info
;
1212 last_sig
= TARGET_SIGNAL_0
;
1214 if (!(debug_event
= WaitForDebugEvent (¤t_event
, 1000)))
1218 continue_status
= DBG_CONTINUE
;
1220 event_code
= current_event
.dwDebugEventCode
;
1221 ourstatus
->kind
= TARGET_WAITKIND_SPURIOUS
;
1225 case CREATE_THREAD_DEBUG_EVENT
:
1226 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1227 (unsigned) current_event
.dwProcessId
,
1228 (unsigned) current_event
.dwThreadId
,
1229 "CREATE_THREAD_DEBUG_EVENT"));
1230 if (saw_create
!= 1)
1232 /* Record the existence of this thread */
1233 th
= child_add_thread (current_event
.dwThreadId
,
1234 current_event
.u
.CreateThread
.hThread
);
1236 printf_unfiltered ("[New %s]\n",
1238 pid_to_ptid (current_event
.dwThreadId
)));
1239 retval
= current_event
.dwThreadId
;
1242 case EXIT_THREAD_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 "EXIT_THREAD_DEBUG_EVENT"));
1247 if (saw_create
!= 1)
1249 child_delete_thread (current_event
.dwThreadId
);
1250 th
= &dummy_thread_info
;
1253 case CREATE_PROCESS_DEBUG_EVENT
:
1254 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1255 (unsigned) current_event
.dwProcessId
,
1256 (unsigned) current_event
.dwThreadId
,
1257 "CREATE_PROCESS_DEBUG_EVENT"));
1258 CloseHandle (current_event
.u
.CreateProcessInfo
.hFile
);
1259 if (++saw_create
!= 1)
1261 CloseHandle (current_event
.u
.CreateProcessInfo
.hProcess
);
1265 current_process_handle
= current_event
.u
.CreateProcessInfo
.hProcess
;
1266 main_thread_id
= current_event
.dwThreadId
;
1267 /* Add the main thread */
1269 th
= child_add_thread (current_event
.dwProcessId
,
1270 current_event
.u
.CreateProcessInfo
.hProcess
);
1272 th
= child_add_thread (main_thread_id
,
1273 current_event
.u
.CreateProcessInfo
.hThread
);
1274 retval
= ourstatus
->value
.related_pid
= current_event
.dwThreadId
;
1277 case EXIT_PROCESS_DEBUG_EVENT
:
1278 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1279 (unsigned) current_event
.dwProcessId
,
1280 (unsigned) current_event
.dwThreadId
,
1281 "EXIT_PROCESS_DEBUG_EVENT"));
1282 if (saw_create
!= 1)
1284 ourstatus
->kind
= TARGET_WAITKIND_EXITED
;
1285 ourstatus
->value
.integer
= current_event
.u
.ExitProcess
.dwExitCode
;
1286 CloseHandle (current_process_handle
);
1287 retval
= main_thread_id
;
1290 case LOAD_DLL_DEBUG_EVENT
:
1291 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1292 (unsigned) current_event
.dwProcessId
,
1293 (unsigned) current_event
.dwThreadId
,
1294 "LOAD_DLL_DEBUG_EVENT"));
1295 CloseHandle (current_event
.u
.LoadDll
.hFile
);
1296 if (saw_create
!= 1)
1298 catch_errors (handle_load_dll
, NULL
, (char *) "", RETURN_MASK_ALL
);
1299 registers_changed (); /* mark all regs invalid */
1300 ourstatus
->kind
= TARGET_WAITKIND_LOADED
;
1301 ourstatus
->value
.integer
= 0;
1302 retval
= main_thread_id
;
1303 re_enable_breakpoints_in_shlibs ();
1306 case UNLOAD_DLL_DEBUG_EVENT
:
1307 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1308 (unsigned) current_event
.dwProcessId
,
1309 (unsigned) current_event
.dwThreadId
,
1310 "UNLOAD_DLL_DEBUG_EVENT"));
1311 if (saw_create
!= 1)
1313 catch_errors (handle_unload_dll
, NULL
, (char *) "", RETURN_MASK_ALL
);
1314 registers_changed (); /* mark all regs invalid */
1315 /* ourstatus->kind = TARGET_WAITKIND_UNLOADED;
1316 does not exist yet. */
1319 case EXCEPTION_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 "EXCEPTION_DEBUG_EVENT"));
1324 if (saw_create
!= 1)
1326 if (handle_exception (ourstatus
))
1327 retval
= current_event
.dwThreadId
;
1330 case OUTPUT_DEBUG_STRING_EVENT
: /* message from the kernel */
1331 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1332 (unsigned) current_event
.dwProcessId
,
1333 (unsigned) current_event
.dwThreadId
,
1334 "OUTPUT_DEBUG_STRING_EVENT"));
1335 if (saw_create
!= 1)
1337 if (handle_output_debug_string (ourstatus
))
1338 retval
= main_thread_id
;
1342 if (saw_create
!= 1)
1344 printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
1345 (DWORD
) current_event
.dwProcessId
,
1346 (DWORD
) current_event
.dwThreadId
);
1347 printf_unfiltered (" unknown event code %ld\n",
1348 current_event
.dwDebugEventCode
);
1352 if (!retval
|| saw_create
!= 1)
1353 CHECK (child_continue (continue_status
, -1));
1356 current_thread
= th
? : thread_rec (current_event
.dwThreadId
, TRUE
);
1357 inferior_ptid
= pid_to_ptid (retval
);
1364 /* Wait for interesting events to occur in the target process. */
1366 child_wait (ptid_t ptid
, struct target_waitstatus
*ourstatus
)
1368 int pid
= PIDGET (ptid
);
1370 /* We loop when we get a non-standard exception rather than return
1371 with a SPURIOUS because resume can try and step or modify things,
1372 which needs a current_thread->h. But some of these exceptions mark
1373 the birth or death of threads, which mean that the current thread
1374 isn't necessarily what you think it is. */
1378 int retval
= get_child_debug_event (pid
, ourstatus
);
1380 return pid_to_ptid (retval
);
1385 if (ui_loop_hook
!= NULL
)
1386 detach
= ui_loop_hook (0);
1389 child_kill_inferior ();
1395 do_initial_child_stuff (DWORD pid
)
1397 extern int stop_after_trap
;
1400 last_sig
= TARGET_SIGNAL_0
;
1402 exception_count
= 0;
1403 debug_registers_changed
= 0;
1404 debug_registers_used
= 0;
1405 for (i
= 0; i
< sizeof (dr
) / sizeof (dr
[0]); i
++)
1407 current_event
.dwProcessId
= pid
;
1408 memset (¤t_event
, 0, sizeof (current_event
));
1409 push_target (&child_ops
);
1410 child_init_thread_list ();
1411 disable_breakpoints_in_shlibs (1);
1412 child_clear_solibs ();
1413 clear_proceed_status ();
1414 init_wait_for_inferior ();
1416 target_terminal_init ();
1417 target_terminal_inferior ();
1421 stop_after_trap
= 1;
1422 wait_for_inferior ();
1423 if (stop_signal
!= TARGET_SIGNAL_TRAP
)
1424 resume (0, stop_signal
);
1428 stop_after_trap
= 0;
1432 /* Since Windows XP, detaching from a process is supported by Windows.
1433 The following code tries loading the appropriate functions dynamically.
1434 If loading these functions succeeds use them to actually detach from
1435 the inferior process, otherwise behave as usual, pretending that
1436 detach has worked. */
1437 static BOOL
WINAPI (*DebugSetProcessKillOnExit
)(BOOL
);
1438 static BOOL
WINAPI (*DebugActiveProcessStop
)(DWORD
);
1441 has_detach_ability (void)
1443 static HMODULE kernel32
= NULL
;
1446 kernel32
= LoadLibrary ("kernel32.dll");
1449 if (!DebugSetProcessKillOnExit
)
1450 DebugSetProcessKillOnExit
= GetProcAddress (kernel32
,
1451 "DebugSetProcessKillOnExit");
1452 if (!DebugActiveProcessStop
)
1453 DebugActiveProcessStop
= GetProcAddress (kernel32
,
1454 "DebugActiveProcessStop");
1455 if (DebugSetProcessKillOnExit
&& DebugActiveProcessStop
)
1461 /* Try to set or remove a user privilege to the current process. Return -1
1462 if that fails, the previous setting of that privilege otherwise.
1464 This code is copied from the Cygwin source code and rearranged to allow
1465 dynamically loading of the needed symbols from advapi32 which is only
1466 available on NT/2K/XP. */
1468 set_process_privilege (const char *privilege
, BOOL enable
)
1470 static HMODULE advapi32
= NULL
;
1471 static BOOL
WINAPI (*OpenProcessToken
)(HANDLE
, DWORD
, PHANDLE
);
1472 static BOOL
WINAPI (*LookupPrivilegeValue
)(LPCSTR
, LPCSTR
, PLUID
);
1473 static BOOL
WINAPI (*AdjustTokenPrivileges
)(HANDLE
, BOOL
, PTOKEN_PRIVILEGES
,
1474 DWORD
, PTOKEN_PRIVILEGES
, PDWORD
);
1476 HANDLE token_hdl
= NULL
;
1478 TOKEN_PRIVILEGES new_priv
, orig_priv
;
1482 if (GetVersion () >= 0x80000000) /* No security availbale on 9x/Me */
1487 if (!(advapi32
= LoadLibrary ("advapi32.dll")))
1489 if (!OpenProcessToken
)
1490 OpenProcessToken
= GetProcAddress (advapi32
, "OpenProcessToken");
1491 if (!LookupPrivilegeValue
)
1492 LookupPrivilegeValue
= GetProcAddress (advapi32
,
1493 "LookupPrivilegeValueA");
1494 if (!AdjustTokenPrivileges
)
1495 AdjustTokenPrivileges
= GetProcAddress (advapi32
,
1496 "AdjustTokenPrivileges");
1497 if (!OpenProcessToken
|| !LookupPrivilegeValue
|| !AdjustTokenPrivileges
)
1504 if (!OpenProcessToken (GetCurrentProcess (),
1505 TOKEN_QUERY
| TOKEN_ADJUST_PRIVILEGES
,
1509 if (!LookupPrivilegeValue (NULL
, privilege
, &restore_priv
))
1512 new_priv
.PrivilegeCount
= 1;
1513 new_priv
.Privileges
[0].Luid
= restore_priv
;
1514 new_priv
.Privileges
[0].Attributes
= enable
? SE_PRIVILEGE_ENABLED
: 0;
1516 if (!AdjustTokenPrivileges (token_hdl
, FALSE
, &new_priv
,
1517 sizeof orig_priv
, &orig_priv
, &size
))
1520 /* Disabled, otherwise every `attach' in an unprivileged user session
1521 would raise the "Failed to get SE_DEBUG_NAME privilege" warning in
1523 /* AdjustTokenPrivileges returns TRUE even if the privilege could not
1524 be enabled. GetLastError () returns an correct error code, though. */
1525 if (enable
&& GetLastError () == ERROR_NOT_ALL_ASSIGNED
)
1529 ret
= orig_priv
.Privileges
[0].Attributes
== SE_PRIVILEGE_ENABLED
? 1 : 0;
1533 CloseHandle (token_hdl
);
1538 /* Attach to process PID, then initialize for debugging it. */
1540 child_attach (char *args
, int from_tty
)
1546 error_no_arg ("process-id to attach");
1548 if (set_process_privilege (SE_DEBUG_NAME
, TRUE
) < 0)
1550 printf_unfiltered ("Warning: Failed to get SE_DEBUG_NAME privilege\n");
1551 printf_unfiltered ("This can cause attach to fail on Windows NT/2K/XP\n");
1554 pid
= strtoul (args
, 0, 0); /* Windows pid */
1556 ok
= DebugActiveProcess (pid
);
1561 /* Try fall back to Cygwin pid */
1562 pid
= cygwin_internal (CW_CYGWIN_PID_TO_WINPID
, pid
);
1565 ok
= DebugActiveProcess (pid
);
1568 error ("Can't attach to process.");
1571 if (has_detach_ability ())
1574 DebugSetProcessKillOnExit (FALSE
);
1579 char *exec_file
= (char *) get_exec_file (0);
1582 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file
,
1583 target_pid_to_str (pid_to_ptid (pid
)));
1585 printf_unfiltered ("Attaching to %s\n",
1586 target_pid_to_str (pid_to_ptid (pid
)));
1588 gdb_flush (gdb_stdout
);
1591 do_initial_child_stuff (pid
);
1592 target_terminal_ours ();
1596 child_detach (char *args
, int from_tty
)
1600 if (has_detach_ability ())
1602 delete_command (NULL
, 0);
1603 child_continue (DBG_CONTINUE
, -1);
1604 if (!DebugActiveProcessStop (current_event
.dwProcessId
))
1606 error ("Can't detach process %lu (error %lu)",
1607 current_event
.dwProcessId
, GetLastError ());
1610 DebugSetProcessKillOnExit (FALSE
);
1612 if (detached
&& from_tty
)
1614 char *exec_file
= get_exec_file (0);
1617 printf_unfiltered ("Detaching from program: %s, Pid %lu\n", exec_file
,
1618 current_event
.dwProcessId
);
1619 gdb_flush (gdb_stdout
);
1621 inferior_ptid
= null_ptid
;
1622 unpush_target (&child_ops
);
1625 /* Print status information about what we're accessing. */
1628 child_files_info (struct target_ops
*ignore
)
1630 printf_unfiltered ("\tUsing the running image of %s %s.\n",
1631 attach_flag
? "attached" : "child", target_pid_to_str (inferior_ptid
));
1635 child_open (char *arg
, int from_tty
)
1637 error ("Use the \"run\" command to start a Unix child process.");
1640 /* Start an inferior win32 child process and sets inferior_ptid to its pid.
1641 EXEC_FILE is the file to run.
1642 ALLARGS is a string containing the arguments to the program.
1643 ENV is the environment vector to pass. Errors reported with error(). */
1646 child_create_inferior (char *exec_file
, char *allargs
, char **env
)
1653 PROCESS_INFORMATION pi
;
1657 char real_path
[MAXPATHLEN
];
1659 char shell
[MAX_PATH
+ 1]; /* Path to shell */
1662 int ostdin
, ostdout
, ostderr
;
1665 error ("No executable specified, use `target exec'.\n");
1667 memset (&si
, 0, sizeof (si
));
1668 si
.cb
= sizeof (si
);
1672 flags
= DEBUG_ONLY_THIS_PROCESS
;
1673 cygwin_conv_to_win32_path (exec_file
, real_path
);
1679 sh
= getenv ("SHELL");
1682 cygwin_conv_to_win32_path (sh
, shell
);
1683 newallargs
= alloca (sizeof (" -c 'exec '") + strlen (exec_file
)
1684 + strlen (allargs
) + 2);
1685 sprintf (newallargs
, " -c 'exec %s %s'", exec_file
, allargs
);
1686 allargs
= newallargs
;
1688 flags
= DEBUG_PROCESS
;
1692 flags
|= CREATE_NEW_PROCESS_GROUP
;
1695 flags
|= CREATE_NEW_CONSOLE
;
1697 args
= alloca (strlen (toexec
) + strlen (allargs
) + 2);
1698 strcpy (args
, toexec
);
1700 strcat (args
, allargs
);
1702 /* Prepare the environment vars for CreateProcess. */
1704 /* This code used to assume all env vars were file names and would
1705 translate them all to win32 style. That obviously doesn't work in the
1706 general case. The current rule is that we only translate PATH.
1707 We need to handle PATH because we're about to call CreateProcess and
1708 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
1709 in both posix and win32 environments. cygwin.dll will change it back
1710 to posix style if necessary. */
1712 static const char *conv_path_names
[] =
1718 /* CreateProcess takes the environment list as a null terminated set of
1719 strings (i.e. two nulls terminate the list). */
1721 /* Get total size for env strings. */
1722 for (envlen
= 0, i
= 0; env
[i
] && *env
[i
]; i
++)
1726 for (j
= 0; conv_path_names
[j
]; j
++)
1728 len
= strlen (conv_path_names
[j
]);
1729 if (strncmp (conv_path_names
[j
], env
[i
], len
) == 0)
1731 if (cygwin_posix_path_list_p (env
[i
] + len
))
1733 + cygwin_posix_to_win32_path_list_buf_size (env
[i
] + len
);
1735 envlen
+= strlen (env
[i
]) + 1;
1739 if (conv_path_names
[j
] == NULL
)
1740 envlen
+= strlen (env
[i
]) + 1;
1743 winenv
= alloca (envlen
+ 1);
1745 /* Copy env strings into new buffer. */
1746 for (temp
= winenv
, i
= 0; env
[i
] && *env
[i
]; i
++)
1750 for (j
= 0; conv_path_names
[j
]; j
++)
1752 len
= strlen (conv_path_names
[j
]);
1753 if (strncmp (conv_path_names
[j
], env
[i
], len
) == 0)
1755 if (cygwin_posix_path_list_p (env
[i
] + len
))
1757 memcpy (temp
, env
[i
], len
);
1758 cygwin_posix_to_win32_path_list (env
[i
] + len
, temp
+ len
);
1761 strcpy (temp
, env
[i
]);
1765 if (conv_path_names
[j
] == NULL
)
1766 strcpy (temp
, env
[i
]);
1768 temp
+= strlen (temp
) + 1;
1771 /* Final nil string to terminate new env. */
1775 if (!inferior_io_terminal
)
1776 tty
= ostdin
= ostdout
= ostderr
= -1;
1779 tty
= open (inferior_io_terminal
, O_RDWR
| O_NOCTTY
);
1782 print_sys_errmsg (inferior_io_terminal
, errno
);
1783 ostdin
= ostdout
= ostderr
= -1;
1796 ret
= CreateProcess (0,
1797 args
, /* command line */
1798 NULL
, /* Security */
1800 TRUE
, /* inherit handles */
1801 flags
, /* start flags */
1803 NULL
, /* current directory */
1818 error ("Error creating process %s, (error %d)\n", exec_file
, (unsigned) GetLastError ());
1820 CloseHandle (pi
.hThread
);
1821 CloseHandle (pi
.hProcess
);
1823 if (useshell
&& shell
[0] != '\0')
1828 do_initial_child_stuff (pi
.dwProcessId
);
1830 /* child_continue (DBG_CONTINUE, -1); */
1831 proceed ((CORE_ADDR
) - 1, TARGET_SIGNAL_0
, 0);
1835 child_mourn_inferior (void)
1837 (void) child_continue (DBG_CONTINUE
, -1);
1838 i386_cleanup_dregs();
1839 unpush_target (&child_ops
);
1840 generic_mourn_inferior ();
1843 /* Send a SIGINT to the process group. This acts just like the user typed a
1844 ^C on the controlling terminal. */
1849 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
1850 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT
, current_event
.dwProcessId
));
1851 registers_changed (); /* refresh register state */
1855 child_xfer_memory (CORE_ADDR memaddr
, char *our
, int len
,
1856 int write
, struct mem_attrib
*mem
,
1857 struct target_ops
*target
)
1862 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
1863 len
, (DWORD
) memaddr
));
1864 if (!WriteProcessMemory (current_process_handle
, (LPVOID
) memaddr
, our
,
1867 FlushInstructionCache (current_process_handle
, (LPCVOID
) memaddr
, len
);
1871 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
1872 len
, (DWORD
) memaddr
));
1873 if (!ReadProcessMemory (current_process_handle
, (LPCVOID
) memaddr
, our
,
1881 child_kill_inferior (void)
1883 CHECK (TerminateProcess (current_process_handle
, 0));
1887 if (!child_continue (DBG_CONTINUE
, -1))
1889 if (!WaitForDebugEvent (¤t_event
, INFINITE
))
1891 if (current_event
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
)
1895 CHECK (CloseHandle (current_process_handle
));
1897 /* this may fail in an attached process so don't check. */
1898 (void) CloseHandle (current_thread
->h
);
1899 target_mourn_inferior (); /* or just child_mourn_inferior? */
1903 child_resume (ptid_t ptid
, int step
, enum target_signal sig
)
1906 DWORD continue_status
= DBG_CONTINUE
;
1908 int pid
= PIDGET (ptid
);
1910 if (sig
!= TARGET_SIGNAL_0
)
1912 if (current_event
.dwDebugEventCode
!= EXCEPTION_DEBUG_EVENT
)
1914 DEBUG_EXCEPT(("Cannot continue with signal %d here.\n",sig
));
1916 else if (sig
== last_sig
)
1917 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
1920 /* This code does not seem to work, because
1921 the kernel does probably not consider changes in the ExceptionRecord
1922 structure when passing the exception to the inferior.
1923 Note that this seems possible in the exception handler itself. */
1926 for (i
= 0; xlate
[i
].them
!= -1; i
++)
1927 if (xlate
[i
].us
== sig
)
1929 current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
=
1931 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
1934 if (continue_status
== DBG_CONTINUE
)
1936 DEBUG_EXCEPT(("Cannot continue with signal %d.\n",sig
));
1940 DEBUG_EXCEPT(("Can only continue with recieved signal %d.\n",
1944 last_sig
= TARGET_SIGNAL_0
;
1946 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1949 /* Get context for currently selected thread */
1950 th
= thread_rec (current_event
.dwThreadId
, FALSE
);
1955 /* Single step by setting t bit */
1956 child_fetch_inferior_registers (PS_REGNUM
);
1957 th
->context
.EFlags
|= FLAG_TRACE_BIT
;
1960 if (th
->context
.ContextFlags
)
1962 if (debug_registers_changed
)
1964 th
->context
.Dr0
= dr
[0];
1965 th
->context
.Dr1
= dr
[1];
1966 th
->context
.Dr2
= dr
[2];
1967 th
->context
.Dr3
= dr
[3];
1968 /* th->context.Dr6 = dr[6];
1969 FIXME: should we set dr6 also ?? */
1970 th
->context
.Dr7
= dr
[7];
1972 CHECK (SetThreadContext (th
->h
, &th
->context
));
1973 th
->context
.ContextFlags
= 0;
1977 /* Allow continuing with the same signal that interrupted us.
1978 Otherwise complain. */
1980 child_continue (continue_status
, pid
);
1984 child_prepare_to_store (void)
1986 /* Do nothing, since we can store individual regs */
1990 child_can_run (void)
1998 DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n",
1999 PIDGET (inferior_ptid
)));
2002 struct target_ops child_ops
;
2005 init_child_ops (void)
2007 child_ops
.to_shortname
= "child";
2008 child_ops
.to_longname
= "Win32 child process";
2009 child_ops
.to_doc
= "Win32 child process (started by the \"run\" command).";
2010 child_ops
.to_open
= child_open
;
2011 child_ops
.to_close
= child_close
;
2012 child_ops
.to_attach
= child_attach
;
2013 child_ops
.to_detach
= child_detach
;
2014 child_ops
.to_resume
= child_resume
;
2015 child_ops
.to_wait
= child_wait
;
2016 child_ops
.to_fetch_registers
= child_fetch_inferior_registers
;
2017 child_ops
.to_store_registers
= child_store_inferior_registers
;
2018 child_ops
.to_prepare_to_store
= child_prepare_to_store
;
2019 child_ops
.to_xfer_memory
= child_xfer_memory
;
2020 child_ops
.to_files_info
= child_files_info
;
2021 child_ops
.to_insert_breakpoint
= memory_insert_breakpoint
;
2022 child_ops
.to_remove_breakpoint
= memory_remove_breakpoint
;
2023 child_ops
.to_terminal_init
= terminal_init_inferior
;
2024 child_ops
.to_terminal_inferior
= terminal_inferior
;
2025 child_ops
.to_terminal_ours_for_output
= terminal_ours_for_output
;
2026 child_ops
.to_terminal_ours
= terminal_ours
;
2027 child_ops
.to_terminal_save_ours
= terminal_save_ours
;
2028 child_ops
.to_terminal_info
= child_terminal_info
;
2029 child_ops
.to_kill
= child_kill_inferior
;
2030 child_ops
.to_create_inferior
= child_create_inferior
;
2031 child_ops
.to_mourn_inferior
= child_mourn_inferior
;
2032 child_ops
.to_can_run
= child_can_run
;
2033 child_ops
.to_thread_alive
= win32_child_thread_alive
;
2034 child_ops
.to_pid_to_str
= cygwin_pid_to_str
;
2035 child_ops
.to_stop
= child_stop
;
2036 child_ops
.to_stratum
= process_stratum
;
2037 child_ops
.to_has_all_memory
= 1;
2038 child_ops
.to_has_memory
= 1;
2039 child_ops
.to_has_stack
= 1;
2040 child_ops
.to_has_registers
= 1;
2041 child_ops
.to_has_execution
= 1;
2042 child_ops
.to_magic
= OPS_MAGIC
;
2046 _initialize_win32_nat (void)
2048 struct cmd_list_element
*c
;
2052 c
= add_com ("dll-symbols", class_files
, dll_symbol_command
,
2053 "Load dll library symbols from FILE.");
2054 set_cmd_completer (c
, filename_completer
);
2056 add_com_alias ("sharedlibrary", "dll-symbols", class_alias
, 1);
2058 add_show_from_set (add_set_cmd ("shell", class_support
, var_boolean
,
2060 "Set use of shell to start subprocess.",
2064 add_show_from_set (add_set_cmd ("new-console", class_support
, var_boolean
,
2065 (char *) &new_console
,
2066 "Set creation of new console when creating child process.",
2070 add_show_from_set (add_set_cmd ("new-group", class_support
, var_boolean
,
2071 (char *) &new_group
,
2072 "Set creation of new group when creating child process.",
2076 add_show_from_set (add_set_cmd ("debugexec", class_support
, var_boolean
,
2077 (char *) &debug_exec
,
2078 "Set whether to display execution in child process.",
2082 add_show_from_set (add_set_cmd ("debugevents", class_support
, var_boolean
,
2083 (char *) &debug_events
,
2084 "Set whether to display kernel events in child process.",
2088 add_show_from_set (add_set_cmd ("debugmemory", class_support
, var_boolean
,
2089 (char *) &debug_memory
,
2090 "Set whether to display memory accesses in child process.",
2094 add_show_from_set (add_set_cmd ("debugexceptions", class_support
, var_boolean
,
2095 (char *) &debug_exceptions
,
2096 "Set whether to display kernel exceptions in child process.",
2100 add_info ("dll", info_dll_command
, "Status of loaded DLLs.");
2101 add_info_alias ("sharedlibrary", "dll", 1);
2103 add_prefix_cmd ("w32", class_info
, info_w32_command
,
2104 "Print information specific to Win32 debugging.",
2105 &info_w32_cmdlist
, "info w32 ", 0, &infolist
);
2107 add_cmd ("selector", class_info
, display_selectors
,
2108 "Display selectors infos.",
2111 add_target (&child_ops
);
2114 /* Hardware watchpoint support, adapted from go32-nat.c code. */
2116 /* Pass the address ADDR to the inferior in the I'th debug register.
2117 Here we just store the address in dr array, the registers will be
2118 actually set up when child_continue is called. */
2120 cygwin_set_dr (int i
, CORE_ADDR addr
)
2123 internal_error (__FILE__
, __LINE__
,
2124 "Invalid register %d in cygwin_set_dr.\n", i
);
2125 dr
[i
] = (unsigned) addr
;
2126 debug_registers_changed
= 1;
2127 debug_registers_used
= 1;
2130 /* Pass the value VAL to the inferior in the DR7 debug control
2131 register. Here we just store the address in D_REGS, the watchpoint
2132 will be actually set up in child_wait. */
2134 cygwin_set_dr7 (unsigned val
)
2137 debug_registers_changed
= 1;
2138 debug_registers_used
= 1;
2141 /* Get the value of the DR6 debug status register from the inferior.
2142 Here we just return the value stored in dr[6]
2143 by the last call to thread_rec for current_event.dwThreadId id. */
2145 cygwin_get_dr6 (void)
2151 /* Determine if the thread referenced by "pid" is alive
2152 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
2153 it means that the pid has died. Otherwise it is assumed to be alive. */
2155 win32_child_thread_alive (ptid_t ptid
)
2157 int pid
= PIDGET (ptid
);
2159 return WaitForSingleObject (thread_rec (pid
, FALSE
)->h
, 0) == WAIT_OBJECT_0
?
2163 /* Convert pid to printable format. */
2165 cygwin_pid_to_str (ptid_t ptid
)
2167 static char buf
[80];
2168 int pid
= PIDGET (ptid
);
2170 if ((DWORD
) pid
== current_event
.dwProcessId
)
2171 sprintf (buf
, "process %d", pid
);
2173 sprintf (buf
, "thread %ld.0x%x", current_event
.dwProcessId
, pid
);
2178 core_dll_symbols_add (char *dll_name
, DWORD base_addr
)
2180 struct objfile
*objfile
;
2181 char *objfile_basename
;
2182 const char *dll_basename
;
2184 if (!(dll_basename
= strrchr (dll_name
, '/')))
2185 dll_basename
= dll_name
;
2189 ALL_OBJFILES (objfile
)
2191 objfile_basename
= strrchr (objfile
->name
, '/');
2193 if (objfile_basename
&&
2194 strcmp (dll_basename
, objfile_basename
+ 1) == 0)
2196 printf_unfiltered ("%08lx:%s (symbols previously loaded)\n",
2197 base_addr
, dll_name
);
2202 register_loaded_dll (dll_name
, base_addr
+ 0x1000);
2203 solib_symbols_add (dll_name
, 0, (CORE_ADDR
) base_addr
+ 0x1000);
2211 struct target_ops
*target
;
2213 } map_code_section_args
;
2216 map_single_dll_code_section (bfd
* abfd
, asection
* sect
, void *obj
)
2220 struct section_table
*new_target_sect_ptr
;
2222 map_code_section_args
*args
= (map_code_section_args
*) obj
;
2223 struct target_ops
*target
= args
->target
;
2224 if (sect
->flags
& SEC_CODE
)
2226 update_coreops
= core_ops
.to_sections
== target
->to_sections
;
2228 if (target
->to_sections
)
2230 old
= target
->to_sections_end
- target
->to_sections
;
2231 target
->to_sections
= (struct section_table
*)
2232 xrealloc ((char *) target
->to_sections
,
2233 (sizeof (struct section_table
)) * (1 + old
));
2238 target
->to_sections
= (struct section_table
*)
2239 xmalloc ((sizeof (struct section_table
)));
2241 target
->to_sections_end
= target
->to_sections
+ (1 + old
);
2243 /* Update the to_sections field in the core_ops structure
2247 core_ops
.to_sections
= target
->to_sections
;
2248 core_ops
.to_sections_end
= target
->to_sections_end
;
2250 new_target_sect_ptr
= target
->to_sections
+ old
;
2251 new_target_sect_ptr
->addr
= args
->addr
+ bfd_section_vma (abfd
, sect
);
2252 new_target_sect_ptr
->endaddr
= args
->addr
+ bfd_section_vma (abfd
, sect
) +
2253 bfd_section_size (abfd
, sect
);;
2254 new_target_sect_ptr
->the_bfd_section
= sect
;
2255 new_target_sect_ptr
->bfd
= abfd
;
2260 dll_code_sections_add (const char *dll_name
, int base_addr
, struct target_ops
*target
)
2263 map_code_section_args map_args
;
2264 asection
*lowest_sect
;
2266 if (dll_name
== NULL
|| target
== NULL
)
2268 name
= xstrdup (dll_name
);
2269 dll_bfd
= bfd_openr (name
, "pei-i386");
2270 if (dll_bfd
== NULL
)
2273 if (bfd_check_format (dll_bfd
, bfd_object
))
2275 lowest_sect
= bfd_get_section_by_name (dll_bfd
, ".text");
2276 if (lowest_sect
== NULL
)
2278 map_args
.target
= target
;
2279 map_args
.addr
= base_addr
- bfd_section_vma (dll_bfd
, lowest_sect
);
2281 bfd_map_over_sections (dll_bfd
, &map_single_dll_code_section
, (void *) (&map_args
));
2288 core_section_load_dll_symbols (bfd
* abfd
, asection
* sect
, void *obj
)
2290 struct target_ops
*target
= (struct target_ops
*) obj
;
2295 char *dll_name
= NULL
;
2297 struct win32_pstatus
*pstatus
;
2300 if (strncmp (sect
->name
, ".module", 7))
2303 buf
= (char *) xmalloc (sect
->_raw_size
+ 1);
2306 printf_unfiltered ("memory allocation failed for %s\n", sect
->name
);
2309 if (!bfd_get_section_contents (abfd
, sect
, buf
, 0, sect
->_raw_size
))
2312 pstatus
= (struct win32_pstatus
*) buf
;
2314 memmove (&base_addr
, &(pstatus
->data
.module_info
.base_address
), sizeof (base_addr
));
2315 dll_name_size
= pstatus
->data
.module_info
.module_name_size
;
2316 if (offsetof (struct win32_pstatus
, data
.module_info
.module_name
) + dll_name_size
> sect
->_raw_size
)
2319 dll_name
= (char *) xmalloc (dll_name_size
+ 1);
2322 printf_unfiltered ("memory allocation failed for %s\n", sect
->name
);
2325 strncpy (dll_name
, pstatus
->data
.module_info
.module_name
, dll_name_size
);
2327 while ((p
= strchr (dll_name
, '\\')))
2330 if (!core_dll_symbols_add (dll_name
, (DWORD
) base_addr
))
2331 printf_unfiltered ("%s: Failed to load dll symbols.\n", dll_name
);
2333 if (!dll_code_sections_add (dll_name
, (DWORD
) base_addr
+ 0x1000, target
))
2334 printf_unfiltered ("%s: Failed to map dll code sections.\n", dll_name
);
2345 child_solib_add (char *filename
, int from_tty
, struct target_ops
*target
,
2352 child_clear_solibs ();
2353 bfd_map_over_sections (core_bfd
, &core_section_load_dll_symbols
, target
);
2357 if (solib_end
&& solib_end
->name
)
2358 solib_end
->objfile
= solib_symbols_add (solib_end
->name
, from_tty
,
2359 solib_end
->load_addr
);
2364 fetch_elf_core_registers (char *core_reg_sect
,
2365 unsigned core_reg_size
,
2370 if (core_reg_size
< sizeof (CONTEXT
))
2372 error ("Core file register section too small (%u bytes).", core_reg_size
);
2375 for (r
= 0; r
< NUM_REGS
; r
++)
2376 supply_register (r
, core_reg_sect
+ mappings
[r
]);
2379 static struct core_fns win32_elf_core_fns
=
2381 bfd_target_elf_flavour
,
2382 default_check_format
,
2383 default_core_sniffer
,
2384 fetch_elf_core_registers
,
2389 _initialize_core_win32 (void)
2391 add_core_fns (&win32_elf_core_fns
);
2395 _initialize_check_for_gdb_ini (void)
2398 if (inhibit_gdbinit
)
2401 homedir
= getenv ("HOME");
2405 char *oldini
= (char *) alloca (strlen (homedir
) +
2406 sizeof ("/gdb.ini"));
2407 strcpy (oldini
, homedir
);
2408 p
= strchr (oldini
, '\0');
2409 if (p
> oldini
&& p
[-1] != '/')
2411 strcpy (p
, "gdb.ini");
2412 if (access (oldini
, 0) == 0)
2414 int len
= strlen (oldini
);
2415 char *newini
= alloca (len
+ 1);
2416 sprintf (newini
, "%.*s.gdbinit",
2417 (int) (len
- (sizeof ("gdb.ini") - 1)), oldini
);
2418 warning ("obsolete '%s' found. Rename to '%s'.", oldini
, newini
);