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 "tm.h" /* required for SSE registers */
31 #include "frame.h" /* required by inferior.h */
36 #include "completer.h"
39 #include "i386-tdep.h"
41 #include <sys/types.h>
46 #include <sys/cygwin.h>
51 #include "gdb_string.h"
52 #include "gdbthread.h"
54 #include <sys/param.h>
57 /* The ui's event loop. */
58 extern int (*ui_loop_hook
) (int signo
);
60 /* If we're not using the old Cygwin header file set, define the
61 following which never should have been in the generic Win32 API
62 headers in the first place since they were our own invention... */
63 #ifndef _GNU_H_WINDOWS_H
66 FLAG_TRACE_BIT
= 0x100,
67 CONTEXT_DEBUGGER
= (CONTEXT_FULL
| CONTEXT_FLOATING_POINT
)
70 #include <sys/procfs.h>
74 #define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \
75 | CONTEXT_EXTENDED_REGISTERS
77 #define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS
80 static unsigned dr
[8];
81 static int debug_registers_changed
= 0;
82 static int debug_registers_used
= 0;
84 /* The string sent by cygwin when it processes a signal.
85 FIXME: This should be in a cygwin include file. */
86 #define CYGWIN_SIGNAL_STRING "cygwin: signal"
88 #define CHECK(x) check (x, __FILE__,__LINE__)
89 #define DEBUG_EXEC(x) if (debug_exec) printf_unfiltered x
90 #define DEBUG_EVENTS(x) if (debug_events) printf_unfiltered x
91 #define DEBUG_MEM(x) if (debug_memory) printf_unfiltered x
92 #define DEBUG_EXCEPT(x) if (debug_exceptions) printf_unfiltered x
94 /* Forward declaration */
95 extern struct target_ops child_ops
;
97 static void child_stop (void);
98 static int win32_child_thread_alive (ptid_t
);
99 void child_kill_inferior (void);
101 static enum target_signal last_sig
= TARGET_SIGNAL_0
;
102 /* Set if a signal was received from the debugged process */
104 /* Thread information structure used to track information that is
105 not available in gdb's thread structure. */
106 typedef struct thread_info_struct
108 struct thread_info_struct
*next
;
118 static thread_info thread_head
;
120 /* The process and thread handles for the above context. */
122 static DEBUG_EVENT current_event
; /* The current debug event from
124 static HANDLE current_process_handle
; /* Currently executing process */
125 static thread_info
*current_thread
; /* Info on currently selected thread */
126 static DWORD main_thread_id
; /* Thread ID of the main thread */
128 /* Counts of things. */
129 static int exception_count
= 0;
130 static int event_count
= 0;
131 static int saw_create
;
134 static int new_console
= 0;
135 static int new_group
= 1;
136 static int debug_exec
= 0; /* show execution */
137 static int debug_events
= 0; /* show events from kernel */
138 static int debug_memory
= 0; /* show target memory accesses */
139 static int debug_exceptions
= 0; /* show target exceptions */
140 static int useshell
= 0; /* use shell for subprocesses */
142 /* This vector maps GDB's idea of a register's number into an address
143 in the win32 exception context vector.
145 It also contains the bit mask needed to load the register in question.
147 One day we could read a reg, we could inspect the context we
148 already have loaded, if it doesn't have the bit set that we need,
149 we read that set of registers in using GetThreadContext. If the
150 context already contains what we need, we just unpack it. Then to
151 write a register, first we have to ensure that the context contains
152 the other regs of the group, and then we copy the info in and set
155 #define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
156 static const int mappings
[] =
158 context_offset (Eax
),
159 context_offset (Ecx
),
160 context_offset (Edx
),
161 context_offset (Ebx
),
162 context_offset (Esp
),
163 context_offset (Ebp
),
164 context_offset (Esi
),
165 context_offset (Edi
),
166 context_offset (Eip
),
167 context_offset (EFlags
),
168 context_offset (SegCs
),
169 context_offset (SegSs
),
170 context_offset (SegDs
),
171 context_offset (SegEs
),
172 context_offset (SegFs
),
173 context_offset (SegGs
),
174 context_offset (FloatSave
.RegisterArea
[0 * 10]),
175 context_offset (FloatSave
.RegisterArea
[1 * 10]),
176 context_offset (FloatSave
.RegisterArea
[2 * 10]),
177 context_offset (FloatSave
.RegisterArea
[3 * 10]),
178 context_offset (FloatSave
.RegisterArea
[4 * 10]),
179 context_offset (FloatSave
.RegisterArea
[5 * 10]),
180 context_offset (FloatSave
.RegisterArea
[6 * 10]),
181 context_offset (FloatSave
.RegisterArea
[7 * 10]),
182 context_offset (FloatSave
.ControlWord
),
183 context_offset (FloatSave
.StatusWord
),
184 context_offset (FloatSave
.TagWord
),
185 context_offset (FloatSave
.ErrorSelector
),
186 context_offset (FloatSave
.ErrorOffset
),
187 context_offset (FloatSave
.DataSelector
),
188 context_offset (FloatSave
.DataOffset
),
189 context_offset (FloatSave
.ErrorSelector
)
192 context_offset (ExtendedRegisters
[10*16]),
193 context_offset (ExtendedRegisters
[11*16]),
194 context_offset (ExtendedRegisters
[12*16]),
195 context_offset (ExtendedRegisters
[13*16]),
196 context_offset (ExtendedRegisters
[14*16]),
197 context_offset (ExtendedRegisters
[15*16]),
198 context_offset (ExtendedRegisters
[16*16]),
199 context_offset (ExtendedRegisters
[17*16]),
201 context_offset (ExtendedRegisters
[24])
205 #undef context_offset
207 /* This vector maps the target's idea of an exception (extracted
208 from the DEBUG_EVENT structure) to GDB's idea. */
210 struct xlate_exception
213 enum target_signal us
;
216 static const struct xlate_exception
219 {EXCEPTION_ACCESS_VIOLATION
, TARGET_SIGNAL_SEGV
},
220 {STATUS_STACK_OVERFLOW
, TARGET_SIGNAL_SEGV
},
221 {EXCEPTION_BREAKPOINT
, TARGET_SIGNAL_TRAP
},
222 {DBG_CONTROL_C
, TARGET_SIGNAL_INT
},
223 {EXCEPTION_SINGLE_STEP
, TARGET_SIGNAL_TRAP
},
224 {STATUS_FLOAT_DIVIDE_BY_ZERO
, TARGET_SIGNAL_FPE
},
228 check (BOOL ok
, const char *file
, int line
)
231 printf_filtered ("error return %s:%d was %lu\n", file
, line
,
236 /* Find a thread record given a thread id.
237 If get_context then also retrieve the context for this
240 thread_rec (DWORD id
, int get_context
)
244 for (th
= &thread_head
; (th
= th
->next
) != NULL
;)
247 if (!th
->suspend_count
&& get_context
)
249 if (get_context
> 0 && id
!= current_event
.dwThreadId
)
250 th
->suspend_count
= SuspendThread (th
->h
) + 1;
251 else if (get_context
< 0)
252 th
->suspend_count
= -1;
254 th
->context
.ContextFlags
= CONTEXT_DEBUGGER_DR
;
255 GetThreadContext (th
->h
, &th
->context
);
256 if (id
== current_event
.dwThreadId
)
258 /* Copy dr values from that thread. */
259 dr
[0] = th
->context
.Dr0
;
260 dr
[1] = th
->context
.Dr1
;
261 dr
[2] = th
->context
.Dr2
;
262 dr
[3] = th
->context
.Dr3
;
263 dr
[6] = th
->context
.Dr6
;
264 dr
[7] = th
->context
.Dr7
;
273 /* Add a thread to the thread list */
275 child_add_thread (DWORD id
, HANDLE h
)
279 if ((th
= thread_rec (id
, FALSE
)))
282 th
= (thread_info
*) xmalloc (sizeof (*th
));
283 memset (th
, 0, sizeof (*th
));
286 th
->next
= thread_head
.next
;
287 thread_head
.next
= th
;
288 add_thread (pid_to_ptid (id
));
289 /* Set the debug registers for the new thread in they are used. */
290 if (debug_registers_used
)
292 /* Only change the value of the debug registers. */
293 th
->context
.ContextFlags
= CONTEXT_DEBUG_REGISTERS
;
294 CHECK (GetThreadContext (th
->h
, &th
->context
));
295 th
->context
.Dr0
= dr
[0];
296 th
->context
.Dr1
= dr
[1];
297 th
->context
.Dr2
= dr
[2];
298 th
->context
.Dr3
= dr
[3];
299 /* th->context.Dr6 = dr[6];
300 FIXME: should we set dr6 also ?? */
301 th
->context
.Dr7
= dr
[7];
302 CHECK (SetThreadContext (th
->h
, &th
->context
));
303 th
->context
.ContextFlags
= 0;
308 /* Clear out any old thread list and reintialize it to a
311 child_init_thread_list (void)
313 thread_info
*th
= &thread_head
;
315 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
317 while (th
->next
!= NULL
)
319 thread_info
*here
= th
->next
;
320 th
->next
= here
->next
;
321 (void) CloseHandle (here
->h
);
326 /* Delete a thread from the list of threads */
328 child_delete_thread (DWORD id
)
333 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (pid_to_ptid (id
)));
334 delete_thread (pid_to_ptid (id
));
336 for (th
= &thread_head
;
337 th
->next
!= NULL
&& th
->next
->id
!= id
;
341 if (th
->next
!= NULL
)
343 thread_info
*here
= th
->next
;
344 th
->next
= here
->next
;
345 CloseHandle (here
->h
);
351 do_child_fetch_inferior_registers (int r
)
353 char *context_offset
= ((char *) ¤t_thread
->context
) + mappings
[r
];
357 l
= *((long *) context_offset
) & 0xffff;
358 supply_register (r
, (char *) &l
);
360 else if (r
== FOP_REGNUM
)
362 l
= (*((long *) context_offset
) >> 16) & ((1 << 11) - 1);
363 supply_register (r
, (char *) &l
);
366 supply_register (r
, context_offset
);
369 for (r
= 0; r
< NUM_REGS
; r
++)
370 do_child_fetch_inferior_registers (r
);
375 child_fetch_inferior_registers (int r
)
377 current_thread
= thread_rec (PIDGET (inferior_ptid
), TRUE
);
378 do_child_fetch_inferior_registers (r
);
382 do_child_store_inferior_registers (int r
)
385 regcache_collect (r
, ((char *) ¤t_thread
->context
) + mappings
[r
]);
388 for (r
= 0; r
< NUM_REGS
; r
++)
389 do_child_store_inferior_registers (r
);
393 /* Store a new register value into the current thread context */
395 child_store_inferior_registers (int r
)
397 current_thread
= thread_rec (PIDGET (inferior_ptid
), TRUE
);
398 do_child_store_inferior_registers (r
);
401 static int psapi_loaded
= 0;
402 static HMODULE psapi_module_handle
= NULL
;
403 static BOOL
WINAPI (*psapi_EnumProcessModules
) (HANDLE
, HMODULE
*, DWORD
, LPDWORD
) = NULL
;
404 static BOOL
WINAPI (*psapi_GetModuleInformation
) (HANDLE
, HMODULE
, LPMODULEINFO
, DWORD
) = NULL
;
405 static DWORD
WINAPI (*psapi_GetModuleFileNameExA
) (HANDLE
, HMODULE
, LPSTR
, DWORD
) = NULL
;
408 psapi_get_dll_name (DWORD BaseAddress
, char *dll_name_ret
)
414 HMODULE
*DllHandle
= dh_buf
;
419 psapi_EnumProcessModules
== NULL
||
420 psapi_GetModuleInformation
== NULL
||
421 psapi_GetModuleFileNameExA
== NULL
)
426 psapi_module_handle
= LoadLibrary ("psapi.dll");
427 if (!psapi_module_handle
)
429 /* printf_unfiltered ("error loading psapi.dll: %u", GetLastError ()); */
432 psapi_EnumProcessModules
= GetProcAddress (psapi_module_handle
, "EnumProcessModules");
433 psapi_GetModuleInformation
= GetProcAddress (psapi_module_handle
, "GetModuleInformation");
434 psapi_GetModuleFileNameExA
= (void *) GetProcAddress (psapi_module_handle
,
435 "GetModuleFileNameExA");
436 if (psapi_EnumProcessModules
== NULL
||
437 psapi_GetModuleInformation
== NULL
||
438 psapi_GetModuleFileNameExA
== NULL
)
443 ok
= (*psapi_EnumProcessModules
) (current_process_handle
,
448 if (!ok
|| !cbNeeded
)
451 DllHandle
= (HMODULE
*) alloca (cbNeeded
);
455 ok
= (*psapi_EnumProcessModules
) (current_process_handle
,
462 for (i
= 0; i
< (int) (cbNeeded
/ sizeof (HMODULE
)); i
++)
464 if (!(*psapi_GetModuleInformation
) (current_process_handle
,
468 error ("Can't get module info");
470 len
= (*psapi_GetModuleFileNameExA
) (current_process_handle
,
475 error ("Error getting dll name: %u\n", (unsigned) GetLastError ());
477 if ((DWORD
) (mi
.lpBaseOfDll
) == BaseAddress
)
482 dll_name_ret
[0] = '\0';
486 /* Encapsulate the information required in a call to
487 symbol_file_add_args */
488 struct safe_symbol_file_add_args
492 struct section_addr_info
*addrs
;
495 struct ui_file
*err
, *out
;
499 /* Maintain a linked list of "so" information. */
502 struct so_stuff
*next
;
506 struct objfile
*objfile
;
508 } solib_start
, *solib_end
;
510 /* Call symbol_file_add with stderr redirected. We don't care if there
513 safe_symbol_file_add_stub (void *argv
)
515 #define p ((struct safe_symbol_file_add_args *)argv)
516 struct so_stuff
*so
= &solib_start
;
518 while ((so
= so
->next
))
519 if (so
->loaded
&& strcasecmp (so
->name
, p
->name
) == 0)
521 p
->ret
= symbol_file_add (p
->name
, p
->from_tty
, p
->addrs
, p
->mainline
, p
->flags
);
526 /* Restore gdb's stderr after calling symbol_file_add */
528 safe_symbol_file_add_cleanup (void *p
)
530 #define sp ((struct safe_symbol_file_add_args *)p)
531 gdb_flush (gdb_stderr
);
532 gdb_flush (gdb_stdout
);
533 ui_file_delete (gdb_stderr
);
534 ui_file_delete (gdb_stdout
);
535 gdb_stderr
= sp
->err
;
536 gdb_stdout
= sp
->out
;
540 /* symbol_file_add wrapper that prevents errors from being displayed. */
541 static struct objfile
*
542 safe_symbol_file_add (char *name
, int from_tty
,
543 struct section_addr_info
*addrs
,
544 int mainline
, int flags
)
546 struct safe_symbol_file_add_args p
;
547 struct cleanup
*cleanup
;
549 cleanup
= make_cleanup (safe_symbol_file_add_cleanup
, &p
);
553 gdb_flush (gdb_stderr
);
554 gdb_flush (gdb_stdout
);
555 gdb_stderr
= ui_file_new ();
556 gdb_stdout
= ui_file_new ();
558 p
.from_tty
= from_tty
;
560 p
.mainline
= mainline
;
562 catch_errors (safe_symbol_file_add_stub
, &p
, "", RETURN_MASK_ERROR
);
564 do_cleanups (cleanup
);
568 /* Remember the maximum DLL length for printing in info dll command. */
569 int max_dll_name_len
;
572 register_loaded_dll (const char *name
, DWORD load_addr
)
575 char ppath
[MAX_PATH
+ 1];
576 char buf
[MAX_PATH
+ 1];
577 char cwd
[MAX_PATH
+ 1];
579 WIN32_FIND_DATA w32_fd
;
580 HANDLE h
= FindFirstFile(name
, &w32_fd
);
581 MEMORY_BASIC_INFORMATION m
;
584 if (h
== INVALID_HANDLE_VALUE
)
590 if (GetCurrentDirectory (MAX_PATH
+ 1, cwd
))
592 p
= strrchr (buf
, '\\');
595 SetCurrentDirectory (buf
);
596 GetFullPathName (w32_fd
.cFileName
, MAX_PATH
, buf
, &p
);
597 SetCurrentDirectory (cwd
);
601 cygwin_conv_to_posix_path (buf
, ppath
);
602 so
= (struct so_stuff
*) xmalloc (sizeof (struct so_stuff
) + strlen (ppath
) + 8 + 1);
604 so
->load_addr
= load_addr
;
605 if (!VirtualQueryEx (current_process_handle
, (void *) load_addr
, &m
,
607 so
->end_addr
= (DWORD
) m
.AllocationBase
+ m
.RegionSize
;
609 so
->end_addr
= load_addr
+ 0x2000; /* completely arbitrary */
613 strcpy (so
->name
, ppath
);
615 solib_end
->next
= so
;
617 len
= strlen (ppath
);
618 if (len
> max_dll_name_len
)
619 max_dll_name_len
= len
;
623 get_image_name (HANDLE h
, void *address
, int unicode
)
625 static char buf
[(2 * MAX_PATH
) + 1];
626 DWORD size
= unicode
? sizeof (WCHAR
) : sizeof (char);
632 /* Attempt to read the name of the dll that was detected.
633 This is documented to work only when actively debugging
634 a program. It will not work for attached processes. */
638 ReadProcessMemory (h
, address
, &address_ptr
, sizeof (address_ptr
), &done
);
640 /* See if we could read the address of a string, and that the
641 address isn't null. */
643 if (done
!= sizeof (address_ptr
) || !address_ptr
)
646 /* Find the length of the string */
649 ReadProcessMemory (h
, address_ptr
+ len
* size
, &b
, size
, &done
);
652 while ((b
[0] != 0 || b
[size
- 1] != 0) && done
== size
);
655 ReadProcessMemory (h
, address_ptr
, buf
, len
, &done
);
658 WCHAR
*unicode_address
= (WCHAR
*) alloca (len
* sizeof (WCHAR
));
659 ReadProcessMemory (h
, address_ptr
, unicode_address
, len
* sizeof (WCHAR
),
662 WideCharToMultiByte (CP_ACP
, 0, unicode_address
, len
, buf
, len
, 0, 0);
668 /* Wait for child to do something. Return pid of child, or -1 in case
669 of error; store status through argument pointer OURSTATUS. */
671 handle_load_dll (void *dummy
)
673 LOAD_DLL_DEBUG_INFO
*event
= ¤t_event
.u
.LoadDll
;
674 char dll_buf
[MAX_PATH
+ 1];
675 char *dll_name
= NULL
;
678 dll_buf
[0] = dll_buf
[sizeof (dll_buf
) - 1] = '\0';
680 if (!psapi_get_dll_name ((DWORD
) (event
->lpBaseOfDll
), dll_buf
))
681 dll_buf
[0] = dll_buf
[sizeof (dll_buf
) - 1] = '\0';
685 if (*dll_name
== '\0')
686 dll_name
= get_image_name (current_process_handle
, event
->lpImageName
, event
->fUnicode
);
690 register_loaded_dll (dll_name
, (DWORD
) event
->lpBaseOfDll
+ 0x1000);
696 handle_unload_dll (void *dummy
)
698 DWORD lpBaseOfDll
= (DWORD
) current_event
.u
.UnloadDll
.lpBaseOfDll
+ 0x1000;
701 for (so
= &solib_start
; so
->next
!= NULL
; so
= so
->next
)
702 if (so
->next
->load_addr
== lpBaseOfDll
)
704 struct so_stuff
*sodel
= so
->next
;
705 so
->next
= sodel
->next
;
709 free_objfile (sodel
->objfile
);
713 error ("Error: dll starting at 0x%lx not found.\n", (DWORD
) lpBaseOfDll
);
719 solib_address (CORE_ADDR address
)
722 for (so
= &solib_start
; so
->next
!= NULL
; so
= so
->next
)
723 if (address
>= so
->load_addr
&& address
<= so
->end_addr
)
728 /* Return name of last loaded DLL. */
730 child_solib_loaded_library_pathname (int pid
)
732 return !solib_end
|| !solib_end
->name
[0] ? NULL
: solib_end
->name
;
735 /* Clear list of loaded DLLs. */
737 child_clear_solibs (void)
739 struct so_stuff
*so
, *so1
= solib_start
.next
;
741 while ((so
= so1
) != NULL
)
747 solib_start
.next
= NULL
;
748 solib_start
.objfile
= NULL
;
749 solib_end
= &solib_start
;
750 max_dll_name_len
= sizeof ("DLL Name") - 1;
753 /* Get the loaded address of all sections, given that .text was loaded
754 at text_load. Assumes that all sections are subject to the same
755 relocation offset. Returns NULL if problems occur or if the
756 sections were not relocated. */
758 static struct section_addr_info
*
759 get_relocated_section_addrs (bfd
*abfd
, CORE_ADDR text_load
)
761 struct section_addr_info
*result
= NULL
;
762 int section_count
= bfd_count_sections (abfd
);
763 asection
*text_section
= bfd_get_section_by_name (abfd
, ".text");
768 /* Couldn't get the .text section. Weird. */
771 else if (text_load
== (text_vma
= bfd_get_section_vma (abfd
, text_section
)))
773 /* DLL wasn't relocated. */
778 /* Figure out all sections' loaded addresses. The offset here is
779 such that taking a bfd_get_section_vma() result and adding
780 offset will give the real load address of the section. */
782 CORE_ADDR offset
= text_load
- text_vma
;
784 struct section_table
*table_start
= NULL
;
785 struct section_table
*table_end
= NULL
;
786 struct section_table
*iter
= NULL
;
788 build_section_table (abfd
, &table_start
, &table_end
);
790 for (iter
= table_start
; iter
< table_end
; ++iter
)
792 /* Relocated addresses. */
793 iter
->addr
+= offset
;
794 iter
->endaddr
+= offset
;
797 result
= build_section_addr_info_from_section_table (table_start
,
806 /* Add DLL symbol information. */
807 static struct objfile
*
808 solib_symbols_add (char *name
, int from_tty
, CORE_ADDR load_addr
)
810 struct section_addr_info
*section_addrs_ptr
= NULL
;
811 static struct objfile
*result
= NULL
;
814 /* The symbols in a dll are offset by 0x1000, which is the
815 the offset from 0 of the first byte in an image - because
816 of the file header and the section alignment. */
818 if (!name
|| !name
[0])
821 abfd
= bfd_openr (name
, "pei-i386");
825 /* pei failed - try pe */
826 abfd
= bfd_openr (name
, "pe-i386");
831 if (bfd_check_format (abfd
, bfd_object
))
833 section_addrs_ptr
= get_relocated_section_addrs (abfd
, load_addr
);
839 if (section_addrs_ptr
)
841 result
= safe_symbol_file_add (name
, from_tty
, section_addrs_ptr
,
844 free_section_addr_info (section_addrs_ptr
);
849 /* Fallback on handling just the .text section. */
850 struct section_addr_info section_addrs
;
852 memset (§ion_addrs
, 0, sizeof (section_addrs
));
853 section_addrs
.other
[0].name
= ".text";
854 section_addrs
.other
[0].addr
= load_addr
;
856 result
= safe_symbol_file_add (name
, from_tty
, §ion_addrs
,
863 /* Load DLL symbol info. */
865 dll_symbol_command (char *args
, int from_tty
)
871 error ("dll-symbols requires a file name");
874 if (n
> 4 && strcasecmp (args
+ n
- 4, ".dll") != 0)
876 char *newargs
= (char *) alloca (n
+ 4 + 1);
877 strcpy (newargs
, args
);
878 strcat (newargs
, ".dll");
882 safe_symbol_file_add (args
, from_tty
, NULL
, 0, OBJF_SHARED
| OBJF_USERLOADED
);
885 /* List currently loaded DLLs. */
887 info_dll_command (char *ignore
, int from_tty
)
889 struct so_stuff
*so
= &solib_start
;
894 printf_filtered ("%*s Load Address\n", -max_dll_name_len
, "DLL Name");
895 while ((so
= so
->next
) != NULL
)
896 printf_filtered ("%*s %08lx\n", -max_dll_name_len
, so
->name
, so
->load_addr
);
901 /* Handle DEBUG_STRING output from child process.
902 Cygwin prepends its messages with a "cygwin:". Interpret this as
903 a Cygwin signal. Otherwise just print the string as a warning. */
905 handle_output_debug_string (struct target_waitstatus
*ourstatus
)
910 if (!target_read_string
911 ((CORE_ADDR
) current_event
.u
.DebugString
.lpDebugStringData
, &s
, 1024, 0)
915 if (strncmp (s
, CYGWIN_SIGNAL_STRING
, sizeof (CYGWIN_SIGNAL_STRING
) - 1) != 0)
917 if (strncmp (s
, "cYg", 3) != 0)
923 int sig
= strtol (s
+ sizeof (CYGWIN_SIGNAL_STRING
) - 1, &p
, 0);
924 gotasig
= target_signal_from_host (sig
);
925 ourstatus
->value
.sig
= gotasig
;
927 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
935 display_selector (HANDLE thread
, DWORD sel
)
938 if (GetThreadSelectorEntry (thread
, sel
, &info
))
941 printf_filtered ("0x%03lx: ", sel
);
942 if (!info
.HighWord
.Bits
.Pres
)
944 puts_filtered ("Segment not present\n");
947 base
= (info
.HighWord
.Bits
.BaseHi
<< 24) +
948 (info
.HighWord
.Bits
.BaseMid
<< 16)
950 limit
= (info
.HighWord
.Bits
.LimitHi
<< 16) + info
.LimitLow
;
951 if (info
.HighWord
.Bits
.Granularity
)
952 limit
= (limit
<< 12) | 0xfff;
953 printf_filtered ("base=0x%08x limit=0x%08x", base
, limit
);
954 if (info
.HighWord
.Bits
.Default_Big
)
955 puts_filtered(" 32-bit ");
957 puts_filtered(" 16-bit ");
958 switch ((info
.HighWord
.Bits
.Type
& 0xf) >> 1)
961 puts_filtered ("Data (Read-Only, Exp-up");
964 puts_filtered ("Data (Read/Write, Exp-up");
967 puts_filtered ("Unused segment (");
970 puts_filtered ("Data (Read/Write, Exp-down");
973 puts_filtered ("Code (Exec-Only, N.Conf");
976 puts_filtered ("Code (Exec/Read, N.Conf");
979 puts_filtered ("Code (Exec-Only, Conf");
982 puts_filtered ("Code (Exec/Read, Conf");
985 printf_filtered ("Unknown type 0x%x",info
.HighWord
.Bits
.Type
);
987 if ((info
.HighWord
.Bits
.Type
& 0x1) == 0)
988 puts_filtered(", N.Acc");
989 puts_filtered (")\n");
990 if ((info
.HighWord
.Bits
.Type
& 0x10) == 0)
991 puts_filtered("System selector ");
992 printf_filtered ("Priviledge level = %d. ", info
.HighWord
.Bits
.Dpl
);
993 if (info
.HighWord
.Bits
.Granularity
)
994 puts_filtered ("Page granular.\n");
996 puts_filtered ("Byte granular.\n");
1001 printf_filtered ("Invalid selector 0x%lx.\n",sel
);
1007 display_selectors (char * args
, int from_tty
)
1009 if (!current_thread
)
1011 puts_filtered ("Impossible to display selectors now.\n");
1017 puts_filtered ("Selector $cs\n");
1018 display_selector (current_thread
->h
,
1019 current_thread
->context
.SegCs
);
1020 puts_filtered ("Selector $ds\n");
1021 display_selector (current_thread
->h
,
1022 current_thread
->context
.SegDs
);
1023 puts_filtered ("Selector $es\n");
1024 display_selector (current_thread
->h
,
1025 current_thread
->context
.SegEs
);
1026 puts_filtered ("Selector $ss\n");
1027 display_selector (current_thread
->h
,
1028 current_thread
->context
.SegSs
);
1029 puts_filtered ("Selector $fs\n");
1030 display_selector (current_thread
->h
,
1031 current_thread
->context
.SegFs
);
1032 puts_filtered ("Selector $gs\n");
1033 display_selector (current_thread
->h
,
1034 current_thread
->context
.SegGs
);
1039 sel
= parse_and_eval_long (args
);
1040 printf_filtered ("Selector \"%s\"\n",args
);
1041 display_selector (current_thread
->h
, sel
);
1045 static struct cmd_list_element
*info_w32_cmdlist
= NULL
;
1048 info_w32_command (char *args
, int from_tty
)
1050 help_list (info_w32_cmdlist
, "info w32 ", class_info
, gdb_stdout
);
1054 #define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \
1055 printf_unfiltered ("gdb: Target exception %s at 0x%08lx\n", x, \
1056 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress)
1059 handle_exception (struct target_waitstatus
*ourstatus
)
1062 DWORD code
= current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
;
1064 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
1066 /* Record the context of the current thread */
1067 th
= thread_rec (current_event
.dwThreadId
, -1);
1071 case EXCEPTION_ACCESS_VIOLATION
:
1072 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
1073 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
1075 case STATUS_STACK_OVERFLOW
:
1076 DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
1077 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
1079 case STATUS_FLOAT_DENORMAL_OPERAND
:
1080 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
1081 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1083 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED
:
1084 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
1085 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1087 case STATUS_FLOAT_INEXACT_RESULT
:
1088 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
1089 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1091 case STATUS_FLOAT_INVALID_OPERATION
:
1092 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
1093 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1095 case STATUS_FLOAT_OVERFLOW
:
1096 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
1097 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1099 case STATUS_FLOAT_STACK_CHECK
:
1100 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
1101 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1103 case STATUS_FLOAT_UNDERFLOW
:
1104 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
1105 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1107 case STATUS_FLOAT_DIVIDE_BY_ZERO
:
1108 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
1109 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1111 case STATUS_INTEGER_DIVIDE_BY_ZERO
:
1112 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
1113 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1115 case STATUS_INTEGER_OVERFLOW
:
1116 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
1117 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1119 case EXCEPTION_BREAKPOINT
:
1120 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
1121 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
1124 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
1125 ourstatus
->value
.sig
= TARGET_SIGNAL_INT
;
1127 case DBG_CONTROL_BREAK
:
1128 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
1129 ourstatus
->value
.sig
= TARGET_SIGNAL_INT
;
1131 case EXCEPTION_SINGLE_STEP
:
1132 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
1133 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
1135 case EXCEPTION_ILLEGAL_INSTRUCTION
:
1136 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
1137 ourstatus
->value
.sig
= TARGET_SIGNAL_ILL
;
1139 case EXCEPTION_PRIV_INSTRUCTION
:
1140 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
1141 ourstatus
->value
.sig
= TARGET_SIGNAL_ILL
;
1143 case EXCEPTION_NONCONTINUABLE_EXCEPTION
:
1144 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
1145 ourstatus
->value
.sig
= TARGET_SIGNAL_ILL
;
1148 if (current_event
.u
.Exception
.dwFirstChance
)
1150 printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n",
1151 current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
,
1152 (DWORD
) current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
);
1153 ourstatus
->value
.sig
= TARGET_SIGNAL_UNKNOWN
;
1157 last_sig
= ourstatus
->value
.sig
;
1161 /* Resume all artificially suspended threads if we are continuing
1164 child_continue (DWORD continue_status
, int id
)
1170 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, %s);\n",
1171 current_event
.dwProcessId
, current_event
.dwThreadId
,
1172 continue_status
== DBG_CONTINUE
?
1173 "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED"));
1174 res
= ContinueDebugEvent (current_event
.dwProcessId
,
1175 current_event
.dwThreadId
,
1177 continue_status
= 0;
1179 for (th
= &thread_head
; (th
= th
->next
) != NULL
;)
1180 if (((id
== -1) || (id
== (int) th
->id
)) && th
->suspend_count
)
1183 for (i
= 0; i
< th
->suspend_count
; i
++)
1184 (void) ResumeThread (th
->h
);
1185 th
->suspend_count
= 0;
1186 if (debug_registers_changed
)
1188 /* Only change the value of the debug reisters */
1189 th
->context
.ContextFlags
= CONTEXT_DEBUG_REGISTERS
;
1190 th
->context
.Dr0
= dr
[0];
1191 th
->context
.Dr1
= dr
[1];
1192 th
->context
.Dr2
= dr
[2];
1193 th
->context
.Dr3
= dr
[3];
1194 /* th->context.Dr6 = dr[6];
1195 FIXME: should we set dr6 also ?? */
1196 th
->context
.Dr7
= dr
[7];
1197 CHECK (SetThreadContext (th
->h
, &th
->context
));
1198 th
->context
.ContextFlags
= 0;
1202 debug_registers_changed
= 0;
1206 /* Get the next event from the child. Return 1 if the event requires
1207 handling by WFI (or whatever).
1210 get_child_debug_event (int pid
, struct target_waitstatus
*ourstatus
)
1213 DWORD continue_status
, event_code
;
1214 thread_info
*th
= NULL
;
1215 static thread_info dummy_thread_info
;
1218 last_sig
= TARGET_SIGNAL_0
;
1220 if (!(debug_event
= WaitForDebugEvent (¤t_event
, 1000)))
1224 continue_status
= DBG_CONTINUE
;
1226 event_code
= current_event
.dwDebugEventCode
;
1227 ourstatus
->kind
= TARGET_WAITKIND_SPURIOUS
;
1231 case CREATE_THREAD_DEBUG_EVENT
:
1232 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1233 (unsigned) current_event
.dwProcessId
,
1234 (unsigned) current_event
.dwThreadId
,
1235 "CREATE_THREAD_DEBUG_EVENT"));
1236 if (saw_create
!= 1)
1238 /* Record the existence of this thread */
1239 th
= child_add_thread (current_event
.dwThreadId
,
1240 current_event
.u
.CreateThread
.hThread
);
1242 printf_unfiltered ("[New %s]\n",
1244 pid_to_ptid (current_event
.dwThreadId
)));
1245 retval
= current_event
.dwThreadId
;
1248 case EXIT_THREAD_DEBUG_EVENT
:
1249 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1250 (unsigned) current_event
.dwProcessId
,
1251 (unsigned) current_event
.dwThreadId
,
1252 "EXIT_THREAD_DEBUG_EVENT"));
1253 if (saw_create
!= 1)
1255 child_delete_thread (current_event
.dwThreadId
);
1256 th
= &dummy_thread_info
;
1259 case CREATE_PROCESS_DEBUG_EVENT
:
1260 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1261 (unsigned) current_event
.dwProcessId
,
1262 (unsigned) current_event
.dwThreadId
,
1263 "CREATE_PROCESS_DEBUG_EVENT"));
1264 CloseHandle (current_event
.u
.CreateProcessInfo
.hFile
);
1265 if (++saw_create
!= 1)
1267 CloseHandle (current_event
.u
.CreateProcessInfo
.hProcess
);
1271 current_process_handle
= current_event
.u
.CreateProcessInfo
.hProcess
;
1272 main_thread_id
= current_event
.dwThreadId
;
1273 /* Add the main thread */
1275 th
= child_add_thread (current_event
.dwProcessId
,
1276 current_event
.u
.CreateProcessInfo
.hProcess
);
1278 th
= child_add_thread (main_thread_id
,
1279 current_event
.u
.CreateProcessInfo
.hThread
);
1280 retval
= ourstatus
->value
.related_pid
= current_event
.dwThreadId
;
1283 case EXIT_PROCESS_DEBUG_EVENT
:
1284 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1285 (unsigned) current_event
.dwProcessId
,
1286 (unsigned) current_event
.dwThreadId
,
1287 "EXIT_PROCESS_DEBUG_EVENT"));
1288 if (saw_create
!= 1)
1290 ourstatus
->kind
= TARGET_WAITKIND_EXITED
;
1291 ourstatus
->value
.integer
= current_event
.u
.ExitProcess
.dwExitCode
;
1292 CloseHandle (current_process_handle
);
1293 retval
= main_thread_id
;
1296 case LOAD_DLL_DEBUG_EVENT
:
1297 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1298 (unsigned) current_event
.dwProcessId
,
1299 (unsigned) current_event
.dwThreadId
,
1300 "LOAD_DLL_DEBUG_EVENT"));
1301 CloseHandle (current_event
.u
.LoadDll
.hFile
);
1302 if (saw_create
!= 1)
1304 catch_errors (handle_load_dll
, NULL
, (char *) "", RETURN_MASK_ALL
);
1305 registers_changed (); /* mark all regs invalid */
1306 ourstatus
->kind
= TARGET_WAITKIND_LOADED
;
1307 ourstatus
->value
.integer
= 0;
1308 retval
= main_thread_id
;
1309 re_enable_breakpoints_in_shlibs ();
1312 case UNLOAD_DLL_DEBUG_EVENT
:
1313 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1314 (unsigned) current_event
.dwProcessId
,
1315 (unsigned) current_event
.dwThreadId
,
1316 "UNLOAD_DLL_DEBUG_EVENT"));
1317 if (saw_create
!= 1)
1319 catch_errors (handle_unload_dll
, NULL
, (char *) "", RETURN_MASK_ALL
);
1320 registers_changed (); /* mark all regs invalid */
1321 /* ourstatus->kind = TARGET_WAITKIND_UNLOADED;
1322 does not exist yet. */
1325 case EXCEPTION_DEBUG_EVENT
:
1326 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1327 (unsigned) current_event
.dwProcessId
,
1328 (unsigned) current_event
.dwThreadId
,
1329 "EXCEPTION_DEBUG_EVENT"));
1330 if (saw_create
!= 1)
1332 if (handle_exception (ourstatus
))
1333 retval
= current_event
.dwThreadId
;
1336 case OUTPUT_DEBUG_STRING_EVENT
: /* message from the kernel */
1337 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1338 (unsigned) current_event
.dwProcessId
,
1339 (unsigned) current_event
.dwThreadId
,
1340 "OUTPUT_DEBUG_STRING_EVENT"));
1341 if (saw_create
!= 1)
1343 if (handle_output_debug_string (ourstatus
))
1344 retval
= main_thread_id
;
1348 if (saw_create
!= 1)
1350 printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
1351 (DWORD
) current_event
.dwProcessId
,
1352 (DWORD
) current_event
.dwThreadId
);
1353 printf_unfiltered (" unknown event code %ld\n",
1354 current_event
.dwDebugEventCode
);
1358 if (!retval
|| saw_create
!= 1)
1359 CHECK (child_continue (continue_status
, -1));
1362 current_thread
= th
? : thread_rec (current_event
.dwThreadId
, TRUE
);
1363 inferior_ptid
= pid_to_ptid (retval
);
1370 /* Wait for interesting events to occur in the target process. */
1372 child_wait (ptid_t ptid
, struct target_waitstatus
*ourstatus
)
1374 int pid
= PIDGET (ptid
);
1376 /* We loop when we get a non-standard exception rather than return
1377 with a SPURIOUS because resume can try and step or modify things,
1378 which needs a current_thread->h. But some of these exceptions mark
1379 the birth or death of threads, which mean that the current thread
1380 isn't necessarily what you think it is. */
1384 int retval
= get_child_debug_event (pid
, ourstatus
);
1386 return pid_to_ptid (retval
);
1391 if (ui_loop_hook
!= NULL
)
1392 detach
= ui_loop_hook (0);
1395 child_kill_inferior ();
1401 do_initial_child_stuff (DWORD pid
)
1403 extern int stop_after_trap
;
1406 last_sig
= TARGET_SIGNAL_0
;
1408 exception_count
= 0;
1409 debug_registers_changed
= 0;
1410 debug_registers_used
= 0;
1411 for (i
= 0; i
< sizeof (dr
) / sizeof (dr
[0]); i
++)
1413 current_event
.dwProcessId
= pid
;
1414 memset (¤t_event
, 0, sizeof (current_event
));
1415 push_target (&child_ops
);
1416 child_init_thread_list ();
1417 disable_breakpoints_in_shlibs (1);
1418 child_clear_solibs ();
1419 clear_proceed_status ();
1420 init_wait_for_inferior ();
1422 target_terminal_init ();
1423 target_terminal_inferior ();
1427 stop_after_trap
= 1;
1428 wait_for_inferior ();
1429 if (stop_signal
!= TARGET_SIGNAL_TRAP
)
1430 resume (0, stop_signal
);
1434 stop_after_trap
= 0;
1438 /* Since Windows XP, detaching from a process is supported by Windows.
1439 The following code tries loading the appropriate functions dynamically.
1440 If loading these functions succeeds use them to actually detach from
1441 the inferior process, otherwise behave as usual, pretending that
1442 detach has worked. */
1443 static BOOL
WINAPI (*DebugSetProcessKillOnExit
)(BOOL
);
1444 static BOOL
WINAPI (*DebugActiveProcessStop
)(DWORD
);
1447 has_detach_ability (void)
1449 static HMODULE kernel32
= NULL
;
1452 kernel32
= LoadLibrary ("kernel32.dll");
1455 if (!DebugSetProcessKillOnExit
)
1456 DebugSetProcessKillOnExit
= GetProcAddress (kernel32
,
1457 "DebugSetProcessKillOnExit");
1458 if (!DebugActiveProcessStop
)
1459 DebugActiveProcessStop
= GetProcAddress (kernel32
,
1460 "DebugActiveProcessStop");
1461 if (DebugSetProcessKillOnExit
&& DebugActiveProcessStop
)
1467 /* Try to set or remove a user privilege to the current process. Return -1
1468 if that fails, the previous setting of that privilege otherwise.
1470 This code is copied from the Cygwin source code and rearranged to allow
1471 dynamically loading of the needed symbols from advapi32 which is only
1472 available on NT/2K/XP. */
1474 set_process_privilege (const char *privilege
, BOOL enable
)
1476 static HMODULE advapi32
= NULL
;
1477 static BOOL
WINAPI (*OpenProcessToken
)(HANDLE
, DWORD
, PHANDLE
);
1478 static BOOL
WINAPI (*LookupPrivilegeValue
)(LPCSTR
, LPCSTR
, PLUID
);
1479 static BOOL
WINAPI (*AdjustTokenPrivileges
)(HANDLE
, BOOL
, PTOKEN_PRIVILEGES
,
1480 DWORD
, PTOKEN_PRIVILEGES
, PDWORD
);
1482 HANDLE token_hdl
= NULL
;
1484 TOKEN_PRIVILEGES new_priv
, orig_priv
;
1488 if (GetVersion () >= 0x80000000) /* No security availbale on 9x/Me */
1493 if (!(advapi32
= LoadLibrary ("advapi32.dll")))
1495 if (!OpenProcessToken
)
1496 OpenProcessToken
= GetProcAddress (advapi32
, "OpenProcessToken");
1497 if (!LookupPrivilegeValue
)
1498 LookupPrivilegeValue
= GetProcAddress (advapi32
,
1499 "LookupPrivilegeValueA");
1500 if (!AdjustTokenPrivileges
)
1501 AdjustTokenPrivileges
= GetProcAddress (advapi32
,
1502 "AdjustTokenPrivileges");
1503 if (!OpenProcessToken
|| !LookupPrivilegeValue
|| !AdjustTokenPrivileges
)
1510 if (!OpenProcessToken (GetCurrentProcess (),
1511 TOKEN_QUERY
| TOKEN_ADJUST_PRIVILEGES
,
1515 if (!LookupPrivilegeValue (NULL
, privilege
, &restore_priv
))
1518 new_priv
.PrivilegeCount
= 1;
1519 new_priv
.Privileges
[0].Luid
= restore_priv
;
1520 new_priv
.Privileges
[0].Attributes
= enable
? SE_PRIVILEGE_ENABLED
: 0;
1522 if (!AdjustTokenPrivileges (token_hdl
, FALSE
, &new_priv
,
1523 sizeof orig_priv
, &orig_priv
, &size
))
1526 /* Disabled, otherwise every `attach' in an unprivileged user session
1527 would raise the "Failed to get SE_DEBUG_NAME privilege" warning in
1529 /* AdjustTokenPrivileges returns TRUE even if the privilege could not
1530 be enabled. GetLastError () returns an correct error code, though. */
1531 if (enable
&& GetLastError () == ERROR_NOT_ALL_ASSIGNED
)
1535 ret
= orig_priv
.Privileges
[0].Attributes
== SE_PRIVILEGE_ENABLED
? 1 : 0;
1539 CloseHandle (token_hdl
);
1544 /* Attach to process PID, then initialize for debugging it. */
1546 child_attach (char *args
, int from_tty
)
1552 error_no_arg ("process-id to attach");
1554 if (set_process_privilege (SE_DEBUG_NAME
, TRUE
) < 0)
1556 printf_unfiltered ("Warning: Failed to get SE_DEBUG_NAME privilege\n");
1557 printf_unfiltered ("This can cause attach to fail on Windows NT/2K/XP\n");
1560 pid
= strtoul (args
, 0, 0); /* Windows pid */
1562 ok
= DebugActiveProcess (pid
);
1567 /* Try fall back to Cygwin pid */
1568 pid
= cygwin_internal (CW_CYGWIN_PID_TO_WINPID
, pid
);
1571 ok
= DebugActiveProcess (pid
);
1574 error ("Can't attach to process.");
1577 if (has_detach_ability ())
1580 DebugSetProcessKillOnExit (FALSE
);
1585 char *exec_file
= (char *) get_exec_file (0);
1588 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file
,
1589 target_pid_to_str (pid_to_ptid (pid
)));
1591 printf_unfiltered ("Attaching to %s\n",
1592 target_pid_to_str (pid_to_ptid (pid
)));
1594 gdb_flush (gdb_stdout
);
1597 do_initial_child_stuff (pid
);
1598 target_terminal_ours ();
1602 child_detach (char *args
, int from_tty
)
1606 if (has_detach_ability ())
1608 delete_command (NULL
, 0);
1609 child_continue (DBG_CONTINUE
, -1);
1610 if (!DebugActiveProcessStop (current_event
.dwProcessId
))
1612 error ("Can't detach process %lu (error %lu)",
1613 current_event
.dwProcessId
, GetLastError ());
1616 DebugSetProcessKillOnExit (FALSE
);
1618 if (detached
&& from_tty
)
1620 char *exec_file
= get_exec_file (0);
1623 printf_unfiltered ("Detaching from program: %s, Pid %lu\n", exec_file
,
1624 current_event
.dwProcessId
);
1625 gdb_flush (gdb_stdout
);
1627 inferior_ptid
= null_ptid
;
1628 unpush_target (&child_ops
);
1631 /* Print status information about what we're accessing. */
1634 child_files_info (struct target_ops
*ignore
)
1636 printf_unfiltered ("\tUsing the running image of %s %s.\n",
1637 attach_flag
? "attached" : "child", target_pid_to_str (inferior_ptid
));
1642 child_open (char *arg
, int from_tty
)
1644 error ("Use the \"run\" command to start a Unix child process.");
1647 /* Start an inferior win32 child process and sets inferior_ptid to its pid.
1648 EXEC_FILE is the file to run.
1649 ALLARGS is a string containing the arguments to the program.
1650 ENV is the environment vector to pass. Errors reported with error(). */
1653 child_create_inferior (char *exec_file
, char *allargs
, char **env
)
1660 PROCESS_INFORMATION pi
;
1664 char real_path
[MAXPATHLEN
];
1666 char shell
[MAX_PATH
+ 1]; /* Path to shell */
1669 int ostdin
, ostdout
, ostderr
;
1672 error ("No executable specified, use `target exec'.\n");
1674 memset (&si
, 0, sizeof (si
));
1675 si
.cb
= sizeof (si
);
1679 flags
= DEBUG_ONLY_THIS_PROCESS
;
1680 cygwin_conv_to_win32_path (exec_file
, real_path
);
1686 sh
= getenv ("SHELL");
1689 cygwin_conv_to_win32_path (sh
, shell
);
1690 newallargs
= alloca (sizeof (" -c 'exec '") + strlen (exec_file
)
1691 + strlen (allargs
) + 2);
1692 sprintf (newallargs
, " -c 'exec %s %s'", exec_file
, allargs
);
1693 allargs
= newallargs
;
1695 flags
= DEBUG_PROCESS
;
1699 flags
|= CREATE_NEW_PROCESS_GROUP
;
1702 flags
|= CREATE_NEW_CONSOLE
;
1704 args
= alloca (strlen (toexec
) + strlen (allargs
) + 2);
1705 strcpy (args
, toexec
);
1707 strcat (args
, allargs
);
1709 /* Prepare the environment vars for CreateProcess. */
1711 /* This code used to assume all env vars were file names and would
1712 translate them all to win32 style. That obviously doesn't work in the
1713 general case. The current rule is that we only translate PATH.
1714 We need to handle PATH because we're about to call CreateProcess and
1715 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
1716 in both posix and win32 environments. cygwin.dll will change it back
1717 to posix style if necessary. */
1719 static const char *conv_path_names
[] =
1725 /* CreateProcess takes the environment list as a null terminated set of
1726 strings (i.e. two nulls terminate the list). */
1728 /* Get total size for env strings. */
1729 for (envlen
= 0, i
= 0; env
[i
] && *env
[i
]; i
++)
1733 for (j
= 0; conv_path_names
[j
]; j
++)
1735 len
= strlen (conv_path_names
[j
]);
1736 if (strncmp (conv_path_names
[j
], env
[i
], len
) == 0)
1738 if (cygwin_posix_path_list_p (env
[i
] + len
))
1740 + cygwin_posix_to_win32_path_list_buf_size (env
[i
] + len
);
1742 envlen
+= strlen (env
[i
]) + 1;
1746 if (conv_path_names
[j
] == NULL
)
1747 envlen
+= strlen (env
[i
]) + 1;
1750 winenv
= alloca (envlen
+ 1);
1752 /* Copy env strings into new buffer. */
1753 for (temp
= winenv
, i
= 0; env
[i
] && *env
[i
]; i
++)
1757 for (j
= 0; conv_path_names
[j
]; j
++)
1759 len
= strlen (conv_path_names
[j
]);
1760 if (strncmp (conv_path_names
[j
], env
[i
], len
) == 0)
1762 if (cygwin_posix_path_list_p (env
[i
] + len
))
1764 memcpy (temp
, env
[i
], len
);
1765 cygwin_posix_to_win32_path_list (env
[i
] + len
, temp
+ len
);
1768 strcpy (temp
, env
[i
]);
1772 if (conv_path_names
[j
] == NULL
)
1773 strcpy (temp
, env
[i
]);
1775 temp
+= strlen (temp
) + 1;
1778 /* Final nil string to terminate new env. */
1782 if (!inferior_io_terminal
)
1783 tty
= ostdin
= ostdout
= ostderr
= -1;
1786 tty
= open (inferior_io_terminal
, O_RDWR
| O_NOCTTY
);
1789 print_sys_errmsg (inferior_io_terminal
, errno
);
1790 ostdin
= ostdout
= ostderr
= -1;
1803 ret
= CreateProcess (0,
1804 args
, /* command line */
1805 NULL
, /* Security */
1807 TRUE
, /* inherit handles */
1808 flags
, /* start flags */
1810 NULL
, /* current directory */
1825 error ("Error creating process %s, (error %d)\n", exec_file
, (unsigned) GetLastError ());
1827 CloseHandle (pi
.hThread
);
1828 CloseHandle (pi
.hProcess
);
1830 if (useshell
&& shell
[0] != '\0')
1835 do_initial_child_stuff (pi
.dwProcessId
);
1837 /* child_continue (DBG_CONTINUE, -1); */
1838 proceed ((CORE_ADDR
) - 1, TARGET_SIGNAL_0
, 0);
1842 child_mourn_inferior (void)
1844 (void) child_continue (DBG_CONTINUE
, -1);
1845 i386_cleanup_dregs();
1846 unpush_target (&child_ops
);
1847 generic_mourn_inferior ();
1850 /* Send a SIGINT to the process group. This acts just like the user typed a
1851 ^C on the controlling terminal. */
1856 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
1857 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT
, current_event
.dwProcessId
));
1858 registers_changed (); /* refresh register state */
1862 child_xfer_memory (CORE_ADDR memaddr
, char *our
, int len
,
1863 int write
, struct mem_attrib
*mem
,
1864 struct target_ops
*target
)
1869 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
1870 len
, (DWORD
) memaddr
));
1871 WriteProcessMemory (current_process_handle
, (LPVOID
) memaddr
, our
,
1873 FlushInstructionCache (current_process_handle
, (LPCVOID
) memaddr
, len
);
1877 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
1878 len
, (DWORD
) memaddr
));
1879 ReadProcessMemory (current_process_handle
, (LPCVOID
) memaddr
, our
, len
,
1886 child_kill_inferior (void)
1888 CHECK (TerminateProcess (current_process_handle
, 0));
1892 if (!child_continue (DBG_CONTINUE
, -1))
1894 if (!WaitForDebugEvent (¤t_event
, INFINITE
))
1896 if (current_event
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
)
1900 CHECK (CloseHandle (current_process_handle
));
1902 /* this may fail in an attached process so don't check. */
1903 (void) CloseHandle (current_thread
->h
);
1904 target_mourn_inferior (); /* or just child_mourn_inferior? */
1908 child_resume (ptid_t ptid
, int step
, enum target_signal sig
)
1911 DWORD continue_status
= DBG_CONTINUE
;
1913 int pid
= PIDGET (ptid
);
1915 if (sig
!= TARGET_SIGNAL_0
)
1917 if (current_event
.dwDebugEventCode
!= EXCEPTION_DEBUG_EVENT
)
1919 DEBUG_EXCEPT(("Cannot continue with signal %d here.\n",sig
));
1921 else if (sig
== last_sig
)
1922 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
1925 /* This code does not seem to work, because
1926 the kernel does probably not consider changes in the ExceptionRecord
1927 structure when passing the exception to the inferior.
1928 Note that this seems possible in the exception handler itself. */
1931 for (i
= 0; xlate
[i
].them
!= -1; i
++)
1932 if (xlate
[i
].us
== sig
)
1934 current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
=
1936 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
1939 if (continue_status
== DBG_CONTINUE
)
1941 DEBUG_EXCEPT(("Cannot continue with signal %d.\n",sig
));
1945 DEBUG_EXCEPT(("Can only continue with recieved signal %d.\n",
1949 last_sig
= TARGET_SIGNAL_0
;
1951 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1954 /* Get context for currently selected thread */
1955 th
= thread_rec (current_event
.dwThreadId
, FALSE
);
1960 /* Single step by setting t bit */
1961 child_fetch_inferior_registers (PS_REGNUM
);
1962 th
->context
.EFlags
|= FLAG_TRACE_BIT
;
1965 if (th
->context
.ContextFlags
)
1967 if (debug_registers_changed
)
1969 th
->context
.Dr0
= dr
[0];
1970 th
->context
.Dr1
= dr
[1];
1971 th
->context
.Dr2
= dr
[2];
1972 th
->context
.Dr3
= dr
[3];
1973 /* th->context.Dr6 = dr[6];
1974 FIXME: should we set dr6 also ?? */
1975 th
->context
.Dr7
= dr
[7];
1977 CHECK (SetThreadContext (th
->h
, &th
->context
));
1978 th
->context
.ContextFlags
= 0;
1982 /* Allow continuing with the same signal that interrupted us.
1983 Otherwise complain. */
1985 child_continue (continue_status
, pid
);
1989 child_prepare_to_store (void)
1991 /* Do nothing, since we can store individual regs */
1995 child_can_run (void)
2003 DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n",
2004 PIDGET (inferior_ptid
)));
2007 struct target_ops child_ops
;
2010 init_child_ops (void)
2012 child_ops
.to_shortname
= "child";
2013 child_ops
.to_longname
= "Win32 child process";
2014 child_ops
.to_doc
= "Win32 child process (started by the \"run\" command).";
2015 child_ops
.to_open
= child_open
;
2016 child_ops
.to_close
= child_close
;
2017 child_ops
.to_attach
= child_attach
;
2018 child_ops
.to_detach
= child_detach
;
2019 child_ops
.to_resume
= child_resume
;
2020 child_ops
.to_wait
= child_wait
;
2021 child_ops
.to_fetch_registers
= child_fetch_inferior_registers
;
2022 child_ops
.to_store_registers
= child_store_inferior_registers
;
2023 child_ops
.to_prepare_to_store
= child_prepare_to_store
;
2024 child_ops
.to_xfer_memory
= child_xfer_memory
;
2025 child_ops
.to_files_info
= child_files_info
;
2026 child_ops
.to_insert_breakpoint
= memory_insert_breakpoint
;
2027 child_ops
.to_remove_breakpoint
= memory_remove_breakpoint
;
2028 child_ops
.to_terminal_init
= terminal_init_inferior
;
2029 child_ops
.to_terminal_inferior
= terminal_inferior
;
2030 child_ops
.to_terminal_ours_for_output
= terminal_ours_for_output
;
2031 child_ops
.to_terminal_ours
= terminal_ours
;
2032 child_ops
.to_terminal_save_ours
= terminal_save_ours
;
2033 child_ops
.to_terminal_info
= child_terminal_info
;
2034 child_ops
.to_kill
= child_kill_inferior
;
2035 child_ops
.to_create_inferior
= child_create_inferior
;
2036 child_ops
.to_mourn_inferior
= child_mourn_inferior
;
2037 child_ops
.to_can_run
= child_can_run
;
2038 child_ops
.to_thread_alive
= win32_child_thread_alive
;
2039 child_ops
.to_pid_to_str
= cygwin_pid_to_str
;
2040 child_ops
.to_stop
= child_stop
;
2041 child_ops
.to_stratum
= process_stratum
;
2042 child_ops
.to_has_all_memory
= 1;
2043 child_ops
.to_has_memory
= 1;
2044 child_ops
.to_has_stack
= 1;
2045 child_ops
.to_has_registers
= 1;
2046 child_ops
.to_has_execution
= 1;
2047 child_ops
.to_magic
= OPS_MAGIC
;
2051 _initialize_win32_nat (void)
2053 struct cmd_list_element
*c
;
2057 c
= add_com ("dll-symbols", class_files
, dll_symbol_command
,
2058 "Load dll library symbols from FILE.");
2059 set_cmd_completer (c
, filename_completer
);
2061 add_com_alias ("sharedlibrary", "dll-symbols", class_alias
, 1);
2063 add_show_from_set (add_set_cmd ("shell", class_support
, var_boolean
,
2065 "Set use of shell to start subprocess.",
2069 add_show_from_set (add_set_cmd ("new-console", class_support
, var_boolean
,
2070 (char *) &new_console
,
2071 "Set creation of new console when creating child process.",
2075 add_show_from_set (add_set_cmd ("new-group", class_support
, var_boolean
,
2076 (char *) &new_group
,
2077 "Set creation of new group when creating child process.",
2081 add_show_from_set (add_set_cmd ("debugexec", class_support
, var_boolean
,
2082 (char *) &debug_exec
,
2083 "Set whether to display execution in child process.",
2087 add_show_from_set (add_set_cmd ("debugevents", class_support
, var_boolean
,
2088 (char *) &debug_events
,
2089 "Set whether to display kernel events in child process.",
2093 add_show_from_set (add_set_cmd ("debugmemory", class_support
, var_boolean
,
2094 (char *) &debug_memory
,
2095 "Set whether to display memory accesses in child process.",
2099 add_show_from_set (add_set_cmd ("debugexceptions", class_support
, var_boolean
,
2100 (char *) &debug_exceptions
,
2101 "Set whether to display kernel exceptions in child process.",
2105 add_info ("dll", info_dll_command
, "Status of loaded DLLs.");
2106 add_info_alias ("sharedlibrary", "dll", 1);
2108 add_prefix_cmd ("w32", class_info
, info_w32_command
,
2109 "Print information specific to Win32 debugging.",
2110 &info_w32_cmdlist
, "info w32 ", 0, &infolist
);
2112 add_cmd ("selector", class_info
, display_selectors
,
2113 "Display selectors infos.",
2116 add_target (&child_ops
);
2119 /* Hardware watchpoint support, adapted from go32-nat.c code. */
2121 /* Pass the address ADDR to the inferior in the I'th debug register.
2122 Here we just store the address in dr array, the registers will be
2123 actually set up when child_continue is called. */
2125 cygwin_set_dr (int i
, CORE_ADDR addr
)
2128 internal_error (__FILE__
, __LINE__
,
2129 "Invalid register %d in cygwin_set_dr.\n", i
);
2130 dr
[i
] = (unsigned) addr
;
2131 debug_registers_changed
= 1;
2132 debug_registers_used
= 1;
2135 /* Pass the value VAL to the inferior in the DR7 debug control
2136 register. Here we just store the address in D_REGS, the watchpoint
2137 will be actually set up in child_wait. */
2139 cygwin_set_dr7 (unsigned val
)
2142 debug_registers_changed
= 1;
2143 debug_registers_used
= 1;
2146 /* Get the value of the DR6 debug status register from the inferior.
2147 Here we just return the value stored in dr[6]
2148 by the last call to thread_rec for current_event.dwThreadId id. */
2150 cygwin_get_dr6 (void)
2156 /* Determine if the thread referenced by "pid" is alive
2157 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
2158 it means that the pid has died. Otherwise it is assumed to be alive. */
2160 win32_child_thread_alive (ptid_t ptid
)
2162 int pid
= PIDGET (ptid
);
2164 return WaitForSingleObject (thread_rec (pid
, FALSE
)->h
, 0) == WAIT_OBJECT_0
?
2168 /* Convert pid to printable format. */
2170 cygwin_pid_to_str (ptid_t ptid
)
2172 static char buf
[80];
2173 int pid
= PIDGET (ptid
);
2175 if ((DWORD
) pid
== current_event
.dwProcessId
)
2176 sprintf (buf
, "process %d", pid
);
2178 sprintf (buf
, "thread %ld.0x%x", current_event
.dwProcessId
, pid
);
2183 core_dll_symbols_add (char *dll_name
, DWORD base_addr
)
2185 struct objfile
*objfile
;
2186 char *objfile_basename
;
2187 const char *dll_basename
;
2189 if (!(dll_basename
= strrchr (dll_name
, '/')))
2190 dll_basename
= dll_name
;
2194 ALL_OBJFILES (objfile
)
2196 objfile_basename
= strrchr (objfile
->name
, '/');
2198 if (objfile_basename
&&
2199 strcmp (dll_basename
, objfile_basename
+ 1) == 0)
2201 printf_unfiltered ("%08lx:%s (symbols previously loaded)\n",
2202 base_addr
, dll_name
);
2207 register_loaded_dll (dll_name
, base_addr
+ 0x1000);
2208 solib_symbols_add (dll_name
, 0, (CORE_ADDR
) base_addr
+ 0x1000);
2216 struct target_ops
*target
;
2219 map_code_section_args
;
2222 map_single_dll_code_section (bfd
* abfd
, asection
* sect
, void *obj
)
2226 struct section_table
*new_target_sect_ptr
;
2228 map_code_section_args
*args
= (map_code_section_args
*) obj
;
2229 struct target_ops
*target
= args
->target
;
2230 if (sect
->flags
& SEC_CODE
)
2232 update_coreops
= core_ops
.to_sections
== target
->to_sections
;
2234 if (target
->to_sections
)
2236 old
= target
->to_sections_end
- target
->to_sections
;
2237 target
->to_sections
= (struct section_table
*)
2238 xrealloc ((char *) target
->to_sections
,
2239 (sizeof (struct section_table
)) * (1 + old
));
2244 target
->to_sections
= (struct section_table
*)
2245 xmalloc ((sizeof (struct section_table
)));
2247 target
->to_sections_end
= target
->to_sections
+ (1 + old
);
2249 /* Update the to_sections field in the core_ops structure
2253 core_ops
.to_sections
= target
->to_sections
;
2254 core_ops
.to_sections_end
= target
->to_sections_end
;
2256 new_target_sect_ptr
= target
->to_sections
+ old
;
2257 new_target_sect_ptr
->addr
= args
->addr
+ bfd_section_vma (abfd
, sect
);
2258 new_target_sect_ptr
->endaddr
= args
->addr
+ bfd_section_vma (abfd
, sect
) +
2259 bfd_section_size (abfd
, sect
);;
2260 new_target_sect_ptr
->the_bfd_section
= sect
;
2261 new_target_sect_ptr
->bfd
= abfd
;
2266 dll_code_sections_add (const char *dll_name
, int base_addr
, struct target_ops
*target
)
2269 map_code_section_args map_args
;
2270 asection
*lowest_sect
;
2272 if (dll_name
== NULL
|| target
== NULL
)
2274 name
= xstrdup (dll_name
);
2275 dll_bfd
= bfd_openr (name
, "pei-i386");
2276 if (dll_bfd
== NULL
)
2279 if (bfd_check_format (dll_bfd
, bfd_object
))
2281 lowest_sect
= bfd_get_section_by_name (dll_bfd
, ".text");
2282 if (lowest_sect
== NULL
)
2284 map_args
.target
= target
;
2285 map_args
.addr
= base_addr
- bfd_section_vma (dll_bfd
, lowest_sect
);
2287 bfd_map_over_sections (dll_bfd
, &map_single_dll_code_section
, (void *) (&map_args
));
2294 core_section_load_dll_symbols (bfd
* abfd
, asection
* sect
, void *obj
)
2296 struct target_ops
*target
= (struct target_ops
*) obj
;
2301 char *dll_name
= NULL
;
2303 struct win32_pstatus
*pstatus
;
2306 if (strncmp (sect
->name
, ".module", 7))
2309 buf
= (char *) xmalloc (sect
->_raw_size
+ 1);
2312 printf_unfiltered ("memory allocation failed for %s\n", sect
->name
);
2315 if (!bfd_get_section_contents (abfd
, sect
, buf
, 0, sect
->_raw_size
))
2318 pstatus
= (struct win32_pstatus
*) buf
;
2320 memmove (&base_addr
, &(pstatus
->data
.module_info
.base_address
), sizeof (base_addr
));
2321 dll_name_size
= pstatus
->data
.module_info
.module_name_size
;
2322 if (offsetof (struct win32_pstatus
, data
.module_info
.module_name
) + dll_name_size
> sect
->_raw_size
)
2325 dll_name
= (char *) xmalloc (dll_name_size
+ 1);
2328 printf_unfiltered ("memory allocation failed for %s\n", sect
->name
);
2331 strncpy (dll_name
, pstatus
->data
.module_info
.module_name
, dll_name_size
);
2333 while ((p
= strchr (dll_name
, '\\')))
2336 if (!core_dll_symbols_add (dll_name
, (DWORD
) base_addr
))
2337 printf_unfiltered ("%s: Failed to load dll symbols.\n", dll_name
);
2339 if (!dll_code_sections_add (dll_name
, (DWORD
) base_addr
+ 0x1000, target
))
2340 printf_unfiltered ("%s: Failed to map dll code sections.\n", dll_name
);
2351 child_solib_add (char *filename
, int from_tty
, struct target_ops
*target
,
2358 child_clear_solibs ();
2359 bfd_map_over_sections (core_bfd
, &core_section_load_dll_symbols
, target
);
2363 if (solib_end
&& solib_end
->name
)
2364 solib_end
->objfile
= solib_symbols_add (solib_end
->name
, from_tty
,
2365 solib_end
->load_addr
);
2370 fetch_elf_core_registers (char *core_reg_sect
,
2371 unsigned core_reg_size
,
2376 if (core_reg_size
< sizeof (CONTEXT
))
2378 error ("Core file register section too small (%u bytes).", core_reg_size
);
2381 for (r
= 0; r
< NUM_REGS
; r
++)
2382 supply_register (r
, core_reg_sect
+ mappings
[r
]);
2385 static struct core_fns win32_elf_core_fns
=
2387 bfd_target_elf_flavour
,
2388 default_check_format
,
2389 default_core_sniffer
,
2390 fetch_elf_core_registers
,
2395 _initialize_core_win32 (void)
2397 add_core_fns (&win32_elf_core_fns
);
2401 _initialize_check_for_gdb_ini (void)
2404 if (inhibit_gdbinit
)
2407 homedir
= getenv ("HOME");
2411 char *oldini
= (char *) alloca (strlen (homedir
) +
2412 sizeof ("/gdb.ini"));
2413 strcpy (oldini
, homedir
);
2414 p
= strchr (oldini
, '\0');
2415 if (p
> oldini
&& p
[-1] != '/')
2417 strcpy (p
, "gdb.ini");
2418 if (access (oldini
, 0) == 0)
2420 int len
= strlen (oldini
);
2421 char *newini
= alloca (len
+ 1);
2422 sprintf (newini
, "%.*s.gdbinit",
2423 (int) (len
- (sizeof ("gdb.ini") - 1)), oldini
);
2424 warning ("obsolete '%s' found. Rename to '%s'.", oldini
, newini
);