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
;
80 static int debug_registers_used
;
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
;
117 static thread_info thread_head
;
119 /* The process and thread handles for the above context. */
121 static DEBUG_EVENT current_event
; /* The current debug event from
123 static HANDLE current_process_handle
; /* Currently executing process */
124 static thread_info
*current_thread
; /* Info on currently selected thread */
125 static DWORD main_thread_id
; /* Thread ID of the main thread */
127 /* Counts of things. */
128 static int exception_count
= 0;
129 static int event_count
= 0;
130 static int saw_create
;
133 static int new_console
= 0;
134 static int new_group
= 1;
135 static int debug_exec
= 0; /* show execution */
136 static int debug_events
= 0; /* show events from kernel */
137 static int debug_memory
= 0; /* show target memory accesses */
138 static int debug_exceptions
= 0; /* show target exceptions */
139 static int useshell
= 0; /* use shell for subprocesses */
141 /* This vector maps GDB's idea of a register's number into an address
142 in the win32 exception context vector.
144 It also contains the bit mask needed to load the register in question.
146 One day we could read a reg, we could inspect the context we
147 already have loaded, if it doesn't have the bit set that we need,
148 we read that set of registers in using GetThreadContext. If the
149 context already contains what we need, we just unpack it. Then to
150 write a register, first we have to ensure that the context contains
151 the other regs of the group, and then we copy the info in and set
154 #define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
155 static const int mappings
[] =
157 context_offset (Eax
),
158 context_offset (Ecx
),
159 context_offset (Edx
),
160 context_offset (Ebx
),
161 context_offset (Esp
),
162 context_offset (Ebp
),
163 context_offset (Esi
),
164 context_offset (Edi
),
165 context_offset (Eip
),
166 context_offset (EFlags
),
167 context_offset (SegCs
),
168 context_offset (SegSs
),
169 context_offset (SegDs
),
170 context_offset (SegEs
),
171 context_offset (SegFs
),
172 context_offset (SegGs
),
173 context_offset (FloatSave
.RegisterArea
[0 * 10]),
174 context_offset (FloatSave
.RegisterArea
[1 * 10]),
175 context_offset (FloatSave
.RegisterArea
[2 * 10]),
176 context_offset (FloatSave
.RegisterArea
[3 * 10]),
177 context_offset (FloatSave
.RegisterArea
[4 * 10]),
178 context_offset (FloatSave
.RegisterArea
[5 * 10]),
179 context_offset (FloatSave
.RegisterArea
[6 * 10]),
180 context_offset (FloatSave
.RegisterArea
[7 * 10]),
181 context_offset (FloatSave
.ControlWord
),
182 context_offset (FloatSave
.StatusWord
),
183 context_offset (FloatSave
.TagWord
),
184 context_offset (FloatSave
.ErrorSelector
),
185 context_offset (FloatSave
.ErrorOffset
),
186 context_offset (FloatSave
.DataSelector
),
187 context_offset (FloatSave
.DataOffset
),
188 context_offset (FloatSave
.ErrorSelector
)
190 context_offset (ExtendedRegisters
[10*16]),
191 context_offset (ExtendedRegisters
[11*16]),
192 context_offset (ExtendedRegisters
[12*16]),
193 context_offset (ExtendedRegisters
[13*16]),
194 context_offset (ExtendedRegisters
[14*16]),
195 context_offset (ExtendedRegisters
[15*16]),
196 context_offset (ExtendedRegisters
[16*16]),
197 context_offset (ExtendedRegisters
[17*16]),
199 context_offset (ExtendedRegisters
[24])
202 #undef context_offset
204 /* This vector maps the target's idea of an exception (extracted
205 from the DEBUG_EVENT structure) to GDB's idea. */
207 struct xlate_exception
210 enum target_signal us
;
213 static const struct xlate_exception
216 {EXCEPTION_ACCESS_VIOLATION
, TARGET_SIGNAL_SEGV
},
217 {STATUS_STACK_OVERFLOW
, TARGET_SIGNAL_SEGV
},
218 {EXCEPTION_BREAKPOINT
, TARGET_SIGNAL_TRAP
},
219 {DBG_CONTROL_C
, TARGET_SIGNAL_INT
},
220 {EXCEPTION_SINGLE_STEP
, TARGET_SIGNAL_TRAP
},
221 {STATUS_FLOAT_DIVIDE_BY_ZERO
, TARGET_SIGNAL_FPE
},
225 check (BOOL ok
, const char *file
, int line
)
228 printf_filtered ("error return %s:%d was %lu\n", file
, line
,
232 /* Find a thread record given a thread id.
233 If get_context then also retrieve the context for this
236 thread_rec (DWORD id
, int get_context
)
240 for (th
= &thread_head
; (th
= th
->next
) != NULL
;)
243 if (!th
->suspend_count
&& get_context
)
245 if (get_context
> 0 && id
!= current_event
.dwThreadId
)
246 th
->suspend_count
= SuspendThread (th
->h
) + 1;
247 else if (get_context
< 0)
248 th
->suspend_count
= -1;
249 th
->reload_context
= 1;
257 /* Add a thread to the thread list */
259 child_add_thread (DWORD id
, HANDLE h
)
263 if ((th
= thread_rec (id
, FALSE
)))
266 th
= (thread_info
*) xmalloc (sizeof (*th
));
267 memset (th
, 0, sizeof (*th
));
270 th
->next
= thread_head
.next
;
271 thread_head
.next
= th
;
272 add_thread (pid_to_ptid (id
));
273 /* Set the debug registers for the new thread in they are used. */
274 if (debug_registers_used
)
276 /* Only change the value of the debug registers. */
277 th
->context
.ContextFlags
= CONTEXT_DEBUG_REGISTERS
;
278 CHECK (GetThreadContext (th
->h
, &th
->context
));
279 th
->context
.Dr0
= dr
[0];
280 th
->context
.Dr1
= dr
[1];
281 th
->context
.Dr2
= dr
[2];
282 th
->context
.Dr3
= dr
[3];
283 /* th->context.Dr6 = dr[6];
284 FIXME: should we set dr6 also ?? */
285 th
->context
.Dr7
= dr
[7];
286 CHECK (SetThreadContext (th
->h
, &th
->context
));
287 th
->context
.ContextFlags
= 0;
292 /* Clear out any old thread list and reintialize it to a
295 child_init_thread_list (void)
297 thread_info
*th
= &thread_head
;
299 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
301 while (th
->next
!= NULL
)
303 thread_info
*here
= th
->next
;
304 th
->next
= here
->next
;
305 (void) CloseHandle (here
->h
);
310 /* Delete a thread from the list of threads */
312 child_delete_thread (DWORD id
)
317 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (pid_to_ptid (id
)));
318 delete_thread (pid_to_ptid (id
));
320 for (th
= &thread_head
;
321 th
->next
!= NULL
&& th
->next
->id
!= id
;
325 if (th
->next
!= NULL
)
327 thread_info
*here
= th
->next
;
328 th
->next
= here
->next
;
329 CloseHandle (here
->h
);
335 do_child_fetch_inferior_registers (int r
)
337 char *context_offset
= ((char *) ¤t_thread
->context
) + mappings
[r
];
343 if (current_thread
->reload_context
)
345 thread_info
*th
= current_thread
;
346 th
->context
.ContextFlags
= CONTEXT_DEBUGGER_DR
;
347 GetThreadContext (th
->h
, &th
->context
);
348 /* Copy dr values from that thread. */
349 dr
[0] = th
->context
.Dr0
;
350 dr
[1] = th
->context
.Dr1
;
351 dr
[2] = th
->context
.Dr2
;
352 dr
[3] = th
->context
.Dr3
;
353 dr
[6] = th
->context
.Dr6
;
354 dr
[7] = th
->context
.Dr7
;
355 current_thread
->reload_context
= 0;
358 #define I387_ST0_REGNUM I386_ST0_REGNUM
360 if (r
== I387_FISEG_REGNUM
)
362 l
= *((long *) context_offset
) & 0xffff;
363 supply_register (r
, (char *) &l
);
365 else if (r
== I387_FOP_REGNUM
)
367 l
= (*((long *) context_offset
) >> 16) & ((1 << 11) - 1);
368 supply_register (r
, (char *) &l
);
371 supply_register (r
, context_offset
);
374 for (r
= 0; r
< NUM_REGS
; r
++)
375 do_child_fetch_inferior_registers (r
);
378 #undef I387_ST0_REGNUM
382 child_fetch_inferior_registers (int r
)
384 current_thread
= thread_rec (PIDGET (inferior_ptid
), TRUE
);
386 do_child_fetch_inferior_registers (r
);
390 do_child_store_inferior_registers (int r
)
395 regcache_collect (r
, ((char *) ¤t_thread
->context
) + mappings
[r
]);
398 for (r
= 0; r
< NUM_REGS
; r
++)
399 do_child_store_inferior_registers (r
);
403 /* Store a new register value into the current thread context */
405 child_store_inferior_registers (int r
)
407 current_thread
= thread_rec (PIDGET (inferior_ptid
), TRUE
);
409 do_child_store_inferior_registers (r
);
412 static int psapi_loaded
= 0;
413 static HMODULE psapi_module_handle
= NULL
;
414 static BOOL
WINAPI (*psapi_EnumProcessModules
) (HANDLE
, HMODULE
*, DWORD
, LPDWORD
) = NULL
;
415 static BOOL
WINAPI (*psapi_GetModuleInformation
) (HANDLE
, HMODULE
, LPMODULEINFO
, DWORD
) = NULL
;
416 static DWORD
WINAPI (*psapi_GetModuleFileNameExA
) (HANDLE
, HMODULE
, LPSTR
, DWORD
) = NULL
;
419 psapi_get_dll_name (DWORD BaseAddress
, char *dll_name_ret
)
425 HMODULE
*DllHandle
= dh_buf
;
430 psapi_EnumProcessModules
== NULL
||
431 psapi_GetModuleInformation
== NULL
||
432 psapi_GetModuleFileNameExA
== NULL
)
437 psapi_module_handle
= LoadLibrary ("psapi.dll");
438 if (!psapi_module_handle
)
440 /* printf_unfiltered ("error loading psapi.dll: %u", GetLastError ()); */
443 psapi_EnumProcessModules
= GetProcAddress (psapi_module_handle
, "EnumProcessModules");
444 psapi_GetModuleInformation
= GetProcAddress (psapi_module_handle
, "GetModuleInformation");
445 psapi_GetModuleFileNameExA
= (void *) GetProcAddress (psapi_module_handle
,
446 "GetModuleFileNameExA");
447 if (psapi_EnumProcessModules
== NULL
||
448 psapi_GetModuleInformation
== NULL
||
449 psapi_GetModuleFileNameExA
== NULL
)
454 ok
= (*psapi_EnumProcessModules
) (current_process_handle
,
459 if (!ok
|| !cbNeeded
)
462 DllHandle
= (HMODULE
*) alloca (cbNeeded
);
466 ok
= (*psapi_EnumProcessModules
) (current_process_handle
,
473 for (i
= 0; i
< (int) (cbNeeded
/ sizeof (HMODULE
)); i
++)
475 if (!(*psapi_GetModuleInformation
) (current_process_handle
,
479 error ("Can't get module info");
481 len
= (*psapi_GetModuleFileNameExA
) (current_process_handle
,
486 error ("Error getting dll name: %u\n", (unsigned) GetLastError ());
488 if ((DWORD
) (mi
.lpBaseOfDll
) == BaseAddress
)
493 dll_name_ret
[0] = '\0';
497 /* Encapsulate the information required in a call to
498 symbol_file_add_args */
499 struct safe_symbol_file_add_args
503 struct section_addr_info
*addrs
;
506 struct ui_file
*err
, *out
;
510 /* Maintain a linked list of "so" information. */
513 struct so_stuff
*next
;
517 struct objfile
*objfile
;
519 } solib_start
, *solib_end
;
521 /* Call symbol_file_add with stderr redirected. We don't care if there
524 safe_symbol_file_add_stub (void *argv
)
526 #define p ((struct safe_symbol_file_add_args *)argv)
527 struct so_stuff
*so
= &solib_start
;
529 while ((so
= so
->next
))
530 if (so
->loaded
&& strcasecmp (so
->name
, p
->name
) == 0)
532 p
->ret
= symbol_file_add (p
->name
, p
->from_tty
, p
->addrs
, p
->mainline
, p
->flags
);
537 /* Restore gdb's stderr after calling symbol_file_add */
539 safe_symbol_file_add_cleanup (void *p
)
541 #define sp ((struct safe_symbol_file_add_args *)p)
542 gdb_flush (gdb_stderr
);
543 gdb_flush (gdb_stdout
);
544 ui_file_delete (gdb_stderr
);
545 ui_file_delete (gdb_stdout
);
546 gdb_stderr
= sp
->err
;
547 gdb_stdout
= sp
->out
;
551 /* symbol_file_add wrapper that prevents errors from being displayed. */
552 static struct objfile
*
553 safe_symbol_file_add (char *name
, int from_tty
,
554 struct section_addr_info
*addrs
,
555 int mainline
, int flags
)
557 struct safe_symbol_file_add_args p
;
558 struct cleanup
*cleanup
;
560 cleanup
= make_cleanup (safe_symbol_file_add_cleanup
, &p
);
564 gdb_flush (gdb_stderr
);
565 gdb_flush (gdb_stdout
);
566 gdb_stderr
= ui_file_new ();
567 gdb_stdout
= ui_file_new ();
569 p
.from_tty
= from_tty
;
571 p
.mainline
= mainline
;
573 catch_errors (safe_symbol_file_add_stub
, &p
, "", RETURN_MASK_ERROR
);
575 do_cleanups (cleanup
);
579 /* Remember the maximum DLL length for printing in info dll command. */
580 int max_dll_name_len
;
583 register_loaded_dll (const char *name
, DWORD load_addr
)
586 char ppath
[MAX_PATH
+ 1];
587 char buf
[MAX_PATH
+ 1];
588 char cwd
[MAX_PATH
+ 1];
590 WIN32_FIND_DATA w32_fd
;
591 HANDLE h
= FindFirstFile(name
, &w32_fd
);
592 MEMORY_BASIC_INFORMATION m
;
595 if (h
== INVALID_HANDLE_VALUE
)
601 if (GetCurrentDirectory (MAX_PATH
+ 1, cwd
))
603 p
= strrchr (buf
, '\\');
606 SetCurrentDirectory (buf
);
607 GetFullPathName (w32_fd
.cFileName
, MAX_PATH
, buf
, &p
);
608 SetCurrentDirectory (cwd
);
612 cygwin_conv_to_posix_path (buf
, ppath
);
613 so
= (struct so_stuff
*) xmalloc (sizeof (struct so_stuff
) + strlen (ppath
) + 8 + 1);
615 so
->load_addr
= load_addr
;
616 if (VirtualQueryEx (current_process_handle
, (void *) load_addr
, &m
,
618 so
->end_addr
= (DWORD
) m
.AllocationBase
+ m
.RegionSize
;
620 so
->end_addr
= load_addr
+ 0x2000; /* completely arbitrary */
624 strcpy (so
->name
, ppath
);
626 solib_end
->next
= so
;
628 len
= strlen (ppath
);
629 if (len
> max_dll_name_len
)
630 max_dll_name_len
= len
;
634 get_image_name (HANDLE h
, void *address
, int unicode
)
636 static char buf
[(2 * MAX_PATH
) + 1];
637 DWORD size
= unicode
? sizeof (WCHAR
) : sizeof (char);
643 /* Attempt to read the name of the dll that was detected.
644 This is documented to work only when actively debugging
645 a program. It will not work for attached processes. */
649 /* See if we could read the address of a string, and that the
650 address isn't null. */
651 if (!ReadProcessMemory (h
, address
, &address_ptr
, sizeof (address_ptr
), &done
)
652 || done
!= sizeof (address_ptr
) || !address_ptr
)
655 /* Find the length of the string */
656 while (ReadProcessMemory (h
, address_ptr
+ len
++ * size
, &b
, size
, &done
)
657 && (b
[0] != 0 || b
[size
- 1] != 0) && done
== size
)
661 ReadProcessMemory (h
, address_ptr
, buf
, len
, &done
);
664 WCHAR
*unicode_address
= (WCHAR
*) alloca (len
* sizeof (WCHAR
));
665 ReadProcessMemory (h
, address_ptr
, unicode_address
, len
* sizeof (WCHAR
),
668 WideCharToMultiByte (CP_ACP
, 0, unicode_address
, len
, buf
, len
, 0, 0);
674 /* Wait for child to do something. Return pid of child, or -1 in case
675 of error; store status through argument pointer OURSTATUS. */
677 handle_load_dll (void *dummy
)
679 LOAD_DLL_DEBUG_INFO
*event
= ¤t_event
.u
.LoadDll
;
680 char dll_buf
[MAX_PATH
+ 1];
681 char *dll_name
= NULL
;
684 dll_buf
[0] = dll_buf
[sizeof (dll_buf
) - 1] = '\0';
686 if (!psapi_get_dll_name ((DWORD
) (event
->lpBaseOfDll
), dll_buf
))
687 dll_buf
[0] = dll_buf
[sizeof (dll_buf
) - 1] = '\0';
691 if (*dll_name
== '\0')
692 dll_name
= get_image_name (current_process_handle
, event
->lpImageName
, event
->fUnicode
);
696 register_loaded_dll (dll_name
, (DWORD
) event
->lpBaseOfDll
+ 0x1000);
702 handle_unload_dll (void *dummy
)
704 DWORD lpBaseOfDll
= (DWORD
) current_event
.u
.UnloadDll
.lpBaseOfDll
+ 0x1000;
707 for (so
= &solib_start
; so
->next
!= NULL
; so
= so
->next
)
708 if (so
->next
->load_addr
== lpBaseOfDll
)
710 struct so_stuff
*sodel
= so
->next
;
711 so
->next
= sodel
->next
;
715 free_objfile (sodel
->objfile
);
719 error ("Error: dll starting at 0x%lx not found.\n", (DWORD
) lpBaseOfDll
);
725 solib_address (CORE_ADDR address
)
728 for (so
= &solib_start
; so
->next
!= NULL
; so
= so
->next
)
729 if (address
>= so
->load_addr
&& address
<= so
->end_addr
)
734 /* Return name of last loaded DLL. */
736 child_solib_loaded_library_pathname (int pid
)
738 return !solib_end
|| !solib_end
->name
[0] ? NULL
: solib_end
->name
;
741 /* Clear list of loaded DLLs. */
743 child_clear_solibs (void)
745 struct so_stuff
*so
, *so1
= solib_start
.next
;
747 while ((so
= so1
) != NULL
)
753 solib_start
.next
= NULL
;
754 solib_start
.objfile
= NULL
;
755 solib_end
= &solib_start
;
756 max_dll_name_len
= sizeof ("DLL Name") - 1;
759 /* Get the loaded address of all sections, given that .text was loaded
760 at text_load. Assumes that all sections are subject to the same
761 relocation offset. Returns NULL if problems occur or if the
762 sections were not relocated. */
764 static struct section_addr_info
*
765 get_relocated_section_addrs (bfd
*abfd
, CORE_ADDR text_load
)
767 struct section_addr_info
*result
= NULL
;
768 int section_count
= bfd_count_sections (abfd
);
769 asection
*text_section
= bfd_get_section_by_name (abfd
, ".text");
774 /* Couldn't get the .text section. Weird. */
777 else if (text_load
== (text_vma
= bfd_get_section_vma (abfd
, text_section
)))
779 /* DLL wasn't relocated. */
784 /* Figure out all sections' loaded addresses. The offset here is
785 such that taking a bfd_get_section_vma() result and adding
786 offset will give the real load address of the section. */
788 CORE_ADDR offset
= text_load
- text_vma
;
790 struct section_table
*table_start
= NULL
;
791 struct section_table
*table_end
= NULL
;
792 struct section_table
*iter
= NULL
;
794 build_section_table (abfd
, &table_start
, &table_end
);
796 for (iter
= table_start
; iter
< table_end
; ++iter
)
798 /* Relocated addresses. */
799 iter
->addr
+= offset
;
800 iter
->endaddr
+= offset
;
803 result
= build_section_addr_info_from_section_table (table_start
,
812 /* Add DLL symbol information. */
813 static struct objfile
*
814 solib_symbols_add (char *name
, int from_tty
, CORE_ADDR load_addr
)
816 struct section_addr_info
*addrs
= NULL
;
817 static struct objfile
*result
= NULL
;
820 /* The symbols in a dll are offset by 0x1000, which is the
821 the offset from 0 of the first byte in an image - because
822 of the file header and the section alignment. */
824 if (!name
|| !name
[0])
827 abfd
= bfd_openr (name
, "pei-i386");
831 /* pei failed - try pe */
832 abfd
= bfd_openr (name
, "pe-i386");
837 if (bfd_check_format (abfd
, bfd_object
))
839 addrs
= get_relocated_section_addrs (abfd
, load_addr
);
847 result
= safe_symbol_file_add (name
, from_tty
, addrs
, 0, OBJF_SHARED
);
848 free_section_addr_info (addrs
);
852 /* Fallback on handling just the .text section. */
853 struct cleanup
*my_cleanups
;
855 addrs
= alloc_section_addr_info (1);
856 my_cleanups
= make_cleanup (xfree
, addrs
);
857 addrs
->other
[0].name
= ".text";
858 addrs
->other
[0].addr
= load_addr
;
860 result
= safe_symbol_file_add (name
, from_tty
, addrs
, 0, OBJF_SHARED
);
861 do_cleanups (my_cleanups
);
867 /* Load DLL symbol info. */
869 dll_symbol_command (char *args
, int from_tty
)
875 error ("dll-symbols requires a file name");
878 if (n
> 4 && strcasecmp (args
+ n
- 4, ".dll") != 0)
880 char *newargs
= (char *) alloca (n
+ 4 + 1);
881 strcpy (newargs
, args
);
882 strcat (newargs
, ".dll");
886 safe_symbol_file_add (args
, from_tty
, NULL
, 0, OBJF_SHARED
| OBJF_USERLOADED
);
889 /* List currently loaded DLLs. */
891 info_dll_command (char *ignore
, int from_tty
)
893 struct so_stuff
*so
= &solib_start
;
898 printf_filtered ("%*s Load Address\n", -max_dll_name_len
, "DLL Name");
899 while ((so
= so
->next
) != NULL
)
900 printf_filtered ("%*s %08lx\n", -max_dll_name_len
, so
->name
, so
->load_addr
);
905 /* Handle DEBUG_STRING output from child process.
906 Cygwin prepends its messages with a "cygwin:". Interpret this as
907 a Cygwin signal. Otherwise just print the string as a warning. */
909 handle_output_debug_string (struct target_waitstatus
*ourstatus
)
914 if (!target_read_string
915 ((CORE_ADDR
) current_event
.u
.DebugString
.lpDebugStringData
, &s
, 1024, 0)
919 if (strncmp (s
, CYGWIN_SIGNAL_STRING
, sizeof (CYGWIN_SIGNAL_STRING
) - 1) != 0)
921 if (strncmp (s
, "cYg", 3) != 0)
927 int sig
= strtol (s
+ sizeof (CYGWIN_SIGNAL_STRING
) - 1, &p
, 0);
928 gotasig
= target_signal_from_host (sig
);
929 ourstatus
->value
.sig
= gotasig
;
931 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
939 display_selector (HANDLE thread
, DWORD sel
)
942 if (GetThreadSelectorEntry (thread
, sel
, &info
))
945 printf_filtered ("0x%03lx: ", sel
);
946 if (!info
.HighWord
.Bits
.Pres
)
948 puts_filtered ("Segment not present\n");
951 base
= (info
.HighWord
.Bits
.BaseHi
<< 24) +
952 (info
.HighWord
.Bits
.BaseMid
<< 16)
954 limit
= (info
.HighWord
.Bits
.LimitHi
<< 16) + info
.LimitLow
;
955 if (info
.HighWord
.Bits
.Granularity
)
956 limit
= (limit
<< 12) | 0xfff;
957 printf_filtered ("base=0x%08x limit=0x%08x", base
, limit
);
958 if (info
.HighWord
.Bits
.Default_Big
)
959 puts_filtered(" 32-bit ");
961 puts_filtered(" 16-bit ");
962 switch ((info
.HighWord
.Bits
.Type
& 0xf) >> 1)
965 puts_filtered ("Data (Read-Only, Exp-up");
968 puts_filtered ("Data (Read/Write, Exp-up");
971 puts_filtered ("Unused segment (");
974 puts_filtered ("Data (Read/Write, Exp-down");
977 puts_filtered ("Code (Exec-Only, N.Conf");
980 puts_filtered ("Code (Exec/Read, N.Conf");
983 puts_filtered ("Code (Exec-Only, Conf");
986 puts_filtered ("Code (Exec/Read, Conf");
989 printf_filtered ("Unknown type 0x%x",info
.HighWord
.Bits
.Type
);
991 if ((info
.HighWord
.Bits
.Type
& 0x1) == 0)
992 puts_filtered(", N.Acc");
993 puts_filtered (")\n");
994 if ((info
.HighWord
.Bits
.Type
& 0x10) == 0)
995 puts_filtered("System selector ");
996 printf_filtered ("Priviledge level = %d. ", info
.HighWord
.Bits
.Dpl
);
997 if (info
.HighWord
.Bits
.Granularity
)
998 puts_filtered ("Page granular.\n");
1000 puts_filtered ("Byte granular.\n");
1005 printf_filtered ("Invalid selector 0x%lx.\n",sel
);
1011 display_selectors (char * args
, int from_tty
)
1013 if (!current_thread
)
1015 puts_filtered ("Impossible to display selectors now.\n");
1021 puts_filtered ("Selector $cs\n");
1022 display_selector (current_thread
->h
,
1023 current_thread
->context
.SegCs
);
1024 puts_filtered ("Selector $ds\n");
1025 display_selector (current_thread
->h
,
1026 current_thread
->context
.SegDs
);
1027 puts_filtered ("Selector $es\n");
1028 display_selector (current_thread
->h
,
1029 current_thread
->context
.SegEs
);
1030 puts_filtered ("Selector $ss\n");
1031 display_selector (current_thread
->h
,
1032 current_thread
->context
.SegSs
);
1033 puts_filtered ("Selector $fs\n");
1034 display_selector (current_thread
->h
,
1035 current_thread
->context
.SegFs
);
1036 puts_filtered ("Selector $gs\n");
1037 display_selector (current_thread
->h
,
1038 current_thread
->context
.SegGs
);
1043 sel
= parse_and_eval_long (args
);
1044 printf_filtered ("Selector \"%s\"\n",args
);
1045 display_selector (current_thread
->h
, sel
);
1049 static struct cmd_list_element
*info_w32_cmdlist
= NULL
;
1052 info_w32_command (char *args
, int from_tty
)
1054 help_list (info_w32_cmdlist
, "info w32 ", class_info
, gdb_stdout
);
1058 #define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \
1059 printf_unfiltered ("gdb: Target exception %s at 0x%08lx\n", x, \
1060 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress)
1063 handle_exception (struct target_waitstatus
*ourstatus
)
1066 DWORD code
= current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
;
1068 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
1070 /* Record the context of the current thread */
1071 th
= thread_rec (current_event
.dwThreadId
, -1);
1075 case EXCEPTION_ACCESS_VIOLATION
:
1076 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
1077 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
1079 case STATUS_STACK_OVERFLOW
:
1080 DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
1081 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
1083 case STATUS_FLOAT_DENORMAL_OPERAND
:
1084 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
1085 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1087 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED
:
1088 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
1089 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1091 case STATUS_FLOAT_INEXACT_RESULT
:
1092 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
1093 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1095 case STATUS_FLOAT_INVALID_OPERATION
:
1096 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
1097 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1099 case STATUS_FLOAT_OVERFLOW
:
1100 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
1101 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1103 case STATUS_FLOAT_STACK_CHECK
:
1104 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
1105 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1107 case STATUS_FLOAT_UNDERFLOW
:
1108 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
1109 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1111 case STATUS_FLOAT_DIVIDE_BY_ZERO
:
1112 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
1113 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1115 case STATUS_INTEGER_DIVIDE_BY_ZERO
:
1116 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
1117 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1119 case STATUS_INTEGER_OVERFLOW
:
1120 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
1121 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1123 case EXCEPTION_BREAKPOINT
:
1124 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
1125 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
1128 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
1129 ourstatus
->value
.sig
= TARGET_SIGNAL_INT
;
1131 case DBG_CONTROL_BREAK
:
1132 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
1133 ourstatus
->value
.sig
= TARGET_SIGNAL_INT
;
1135 case EXCEPTION_SINGLE_STEP
:
1136 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
1137 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
1139 case EXCEPTION_ILLEGAL_INSTRUCTION
:
1140 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
1141 ourstatus
->value
.sig
= TARGET_SIGNAL_ILL
;
1143 case EXCEPTION_PRIV_INSTRUCTION
:
1144 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
1145 ourstatus
->value
.sig
= TARGET_SIGNAL_ILL
;
1147 case EXCEPTION_NONCONTINUABLE_EXCEPTION
:
1148 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
1149 ourstatus
->value
.sig
= TARGET_SIGNAL_ILL
;
1152 if (current_event
.u
.Exception
.dwFirstChance
)
1154 printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n",
1155 current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
,
1156 (DWORD
) current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
);
1157 ourstatus
->value
.sig
= TARGET_SIGNAL_UNKNOWN
;
1161 last_sig
= ourstatus
->value
.sig
;
1165 /* Resume all artificially suspended threads if we are continuing
1168 child_continue (DWORD continue_status
, int id
)
1174 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, %s);\n",
1175 current_event
.dwProcessId
, current_event
.dwThreadId
,
1176 continue_status
== DBG_CONTINUE
?
1177 "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED"));
1178 res
= ContinueDebugEvent (current_event
.dwProcessId
,
1179 current_event
.dwThreadId
,
1181 continue_status
= 0;
1183 for (th
= &thread_head
; (th
= th
->next
) != NULL
;)
1184 if (((id
== -1) || (id
== (int) th
->id
)) && th
->suspend_count
)
1187 for (i
= 0; i
< th
->suspend_count
; i
++)
1188 (void) ResumeThread (th
->h
);
1189 th
->suspend_count
= 0;
1190 if (debug_registers_changed
)
1192 /* Only change the value of the debug registers */
1193 th
->context
.ContextFlags
= CONTEXT_DEBUG_REGISTERS
;
1194 th
->context
.Dr0
= dr
[0];
1195 th
->context
.Dr1
= dr
[1];
1196 th
->context
.Dr2
= dr
[2];
1197 th
->context
.Dr3
= dr
[3];
1198 /* th->context.Dr6 = dr[6];
1199 FIXME: should we set dr6 also ?? */
1200 th
->context
.Dr7
= dr
[7];
1201 CHECK (SetThreadContext (th
->h
, &th
->context
));
1202 th
->context
.ContextFlags
= 0;
1206 debug_registers_changed
= 0;
1211 fake_create_process ()
1213 current_process_handle
= OpenProcess (PROCESS_ALL_ACCESS
, FALSE
,
1214 current_event
.dwProcessId
);
1215 main_thread_id
= current_event
.dwThreadId
;
1216 current_thread
= child_add_thread (main_thread_id
,
1217 current_event
.u
.CreateThread
.hThread
);
1218 return main_thread_id
;
1221 /* Get the next event from the child. Return 1 if the event requires
1222 handling by WFI (or whatever).
1225 get_child_debug_event (int pid
, struct target_waitstatus
*ourstatus
)
1228 DWORD continue_status
, event_code
;
1230 static thread_info dummy_thread_info
;
1233 last_sig
= TARGET_SIGNAL_0
;
1235 if (!(debug_event
= WaitForDebugEvent (¤t_event
, 1000)))
1239 continue_status
= DBG_CONTINUE
;
1241 event_code
= current_event
.dwDebugEventCode
;
1242 ourstatus
->kind
= TARGET_WAITKIND_SPURIOUS
;
1247 case CREATE_THREAD_DEBUG_EVENT
:
1248 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1249 (unsigned) current_event
.dwProcessId
,
1250 (unsigned) current_event
.dwThreadId
,
1251 "CREATE_THREAD_DEBUG_EVENT"));
1252 if (saw_create
!= 1)
1254 if (!saw_create
&& attach_flag
)
1256 retval
= ourstatus
->value
.related_pid
= fake_create_process ();
1261 /* Record the existence of this thread */
1262 th
= child_add_thread (current_event
.dwThreadId
,
1263 current_event
.u
.CreateThread
.hThread
);
1265 printf_unfiltered ("[New %s]\n",
1267 pid_to_ptid (current_event
.dwThreadId
)));
1268 retval
= current_event
.dwThreadId
;
1271 case EXIT_THREAD_DEBUG_EVENT
:
1272 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1273 (unsigned) current_event
.dwProcessId
,
1274 (unsigned) current_event
.dwThreadId
,
1275 "EXIT_THREAD_DEBUG_EVENT"));
1276 if (current_event
.dwThreadId
!= main_thread_id
)
1278 child_delete_thread (current_event
.dwThreadId
);
1279 th
= &dummy_thread_info
;
1283 case CREATE_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 "CREATE_PROCESS_DEBUG_EVENT"));
1288 CloseHandle (current_event
.u
.CreateProcessInfo
.hFile
);
1289 if (++saw_create
!= 1)
1291 CloseHandle (current_event
.u
.CreateProcessInfo
.hProcess
);
1295 current_process_handle
= current_event
.u
.CreateProcessInfo
.hProcess
;
1297 child_delete_thread (main_thread_id
);
1298 main_thread_id
= current_event
.dwThreadId
;
1299 /* Add the main thread */
1300 th
= child_add_thread (main_thread_id
,
1301 current_event
.u
.CreateProcessInfo
.hThread
);
1302 retval
= ourstatus
->value
.related_pid
= current_event
.dwThreadId
;
1305 case EXIT_PROCESS_DEBUG_EVENT
:
1306 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1307 (unsigned) current_event
.dwProcessId
,
1308 (unsigned) current_event
.dwThreadId
,
1309 "EXIT_PROCESS_DEBUG_EVENT"));
1310 if (saw_create
!= 1)
1312 ourstatus
->kind
= TARGET_WAITKIND_EXITED
;
1313 ourstatus
->value
.integer
= current_event
.u
.ExitProcess
.dwExitCode
;
1314 CloseHandle (current_process_handle
);
1315 retval
= main_thread_id
;
1318 case LOAD_DLL_DEBUG_EVENT
:
1319 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1320 (unsigned) current_event
.dwProcessId
,
1321 (unsigned) current_event
.dwThreadId
,
1322 "LOAD_DLL_DEBUG_EVENT"));
1323 CloseHandle (current_event
.u
.LoadDll
.hFile
);
1324 if (saw_create
!= 1)
1326 catch_errors (handle_load_dll
, NULL
, (char *) "", RETURN_MASK_ALL
);
1327 registers_changed (); /* mark all regs invalid */
1328 ourstatus
->kind
= TARGET_WAITKIND_LOADED
;
1329 ourstatus
->value
.integer
= 0;
1330 retval
= main_thread_id
;
1331 re_enable_breakpoints_in_shlibs ();
1334 case UNLOAD_DLL_DEBUG_EVENT
:
1335 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1336 (unsigned) current_event
.dwProcessId
,
1337 (unsigned) current_event
.dwThreadId
,
1338 "UNLOAD_DLL_DEBUG_EVENT"));
1339 if (saw_create
!= 1)
1341 catch_errors (handle_unload_dll
, NULL
, (char *) "", RETURN_MASK_ALL
);
1342 registers_changed (); /* mark all regs invalid */
1343 /* ourstatus->kind = TARGET_WAITKIND_UNLOADED;
1344 does not exist yet. */
1347 case EXCEPTION_DEBUG_EVENT
:
1348 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1349 (unsigned) current_event
.dwProcessId
,
1350 (unsigned) current_event
.dwThreadId
,
1351 "EXCEPTION_DEBUG_EVENT"));
1352 if (saw_create
!= 1)
1354 if (handle_exception (ourstatus
))
1355 retval
= current_event
.dwThreadId
;
1358 case OUTPUT_DEBUG_STRING_EVENT
: /* message from the kernel */
1359 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1360 (unsigned) current_event
.dwProcessId
,
1361 (unsigned) current_event
.dwThreadId
,
1362 "OUTPUT_DEBUG_STRING_EVENT"));
1363 if (saw_create
!= 1)
1365 if (handle_output_debug_string (ourstatus
))
1366 retval
= main_thread_id
;
1370 if (saw_create
!= 1)
1372 printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
1373 (DWORD
) current_event
.dwProcessId
,
1374 (DWORD
) current_event
.dwThreadId
);
1375 printf_unfiltered (" unknown event code %ld\n",
1376 current_event
.dwDebugEventCode
);
1380 if (!retval
|| saw_create
!= 1)
1381 CHECK (child_continue (continue_status
, -1));
1384 inferior_ptid
= pid_to_ptid (retval
);
1385 current_thread
= th
?: thread_rec (current_event
.dwThreadId
, TRUE
);
1392 /* Wait for interesting events to occur in the target process. */
1394 child_wait (ptid_t ptid
, struct target_waitstatus
*ourstatus
)
1396 int pid
= PIDGET (ptid
);
1398 /* We loop when we get a non-standard exception rather than return
1399 with a SPURIOUS because resume can try and step or modify things,
1400 which needs a current_thread->h. But some of these exceptions mark
1401 the birth or death of threads, which mean that the current thread
1402 isn't necessarily what you think it is. */
1406 int retval
= get_child_debug_event (pid
, ourstatus
);
1408 return pid_to_ptid (retval
);
1413 if (ui_loop_hook
!= NULL
)
1414 detach
= ui_loop_hook (0);
1417 child_kill_inferior ();
1423 do_initial_child_stuff (DWORD pid
)
1425 extern int stop_after_trap
;
1428 last_sig
= TARGET_SIGNAL_0
;
1430 exception_count
= 0;
1431 debug_registers_changed
= 0;
1432 debug_registers_used
= 0;
1433 for (i
= 0; i
< sizeof (dr
) / sizeof (dr
[0]); i
++)
1435 current_event
.dwProcessId
= pid
;
1436 memset (¤t_event
, 0, sizeof (current_event
));
1437 push_target (&child_ops
);
1438 child_init_thread_list ();
1439 disable_breakpoints_in_shlibs (1);
1440 child_clear_solibs ();
1441 clear_proceed_status ();
1442 init_wait_for_inferior ();
1444 target_terminal_init ();
1445 target_terminal_inferior ();
1449 stop_after_trap
= 1;
1450 wait_for_inferior ();
1451 if (stop_signal
!= TARGET_SIGNAL_TRAP
)
1452 resume (0, stop_signal
);
1456 stop_after_trap
= 0;
1460 /* Since Windows XP, detaching from a process is supported by Windows.
1461 The following code tries loading the appropriate functions dynamically.
1462 If loading these functions succeeds use them to actually detach from
1463 the inferior process, otherwise behave as usual, pretending that
1464 detach has worked. */
1465 static BOOL
WINAPI (*DebugSetProcessKillOnExit
)(BOOL
);
1466 static BOOL
WINAPI (*DebugActiveProcessStop
)(DWORD
);
1469 has_detach_ability (void)
1471 static HMODULE kernel32
= NULL
;
1474 kernel32
= LoadLibrary ("kernel32.dll");
1477 if (!DebugSetProcessKillOnExit
)
1478 DebugSetProcessKillOnExit
= GetProcAddress (kernel32
,
1479 "DebugSetProcessKillOnExit");
1480 if (!DebugActiveProcessStop
)
1481 DebugActiveProcessStop
= GetProcAddress (kernel32
,
1482 "DebugActiveProcessStop");
1483 if (DebugSetProcessKillOnExit
&& DebugActiveProcessStop
)
1489 /* Try to set or remove a user privilege to the current process. Return -1
1490 if that fails, the previous setting of that privilege otherwise.
1492 This code is copied from the Cygwin source code and rearranged to allow
1493 dynamically loading of the needed symbols from advapi32 which is only
1494 available on NT/2K/XP. */
1496 set_process_privilege (const char *privilege
, BOOL enable
)
1498 static HMODULE advapi32
= NULL
;
1499 static BOOL
WINAPI (*OpenProcessToken
)(HANDLE
, DWORD
, PHANDLE
);
1500 static BOOL
WINAPI (*LookupPrivilegeValue
)(LPCSTR
, LPCSTR
, PLUID
);
1501 static BOOL
WINAPI (*AdjustTokenPrivileges
)(HANDLE
, BOOL
, PTOKEN_PRIVILEGES
,
1502 DWORD
, PTOKEN_PRIVILEGES
, PDWORD
);
1504 HANDLE token_hdl
= NULL
;
1506 TOKEN_PRIVILEGES new_priv
, orig_priv
;
1510 if (GetVersion () >= 0x80000000) /* No security availbale on 9x/Me */
1515 if (!(advapi32
= LoadLibrary ("advapi32.dll")))
1517 if (!OpenProcessToken
)
1518 OpenProcessToken
= GetProcAddress (advapi32
, "OpenProcessToken");
1519 if (!LookupPrivilegeValue
)
1520 LookupPrivilegeValue
= GetProcAddress (advapi32
,
1521 "LookupPrivilegeValueA");
1522 if (!AdjustTokenPrivileges
)
1523 AdjustTokenPrivileges
= GetProcAddress (advapi32
,
1524 "AdjustTokenPrivileges");
1525 if (!OpenProcessToken
|| !LookupPrivilegeValue
|| !AdjustTokenPrivileges
)
1532 if (!OpenProcessToken (GetCurrentProcess (),
1533 TOKEN_QUERY
| TOKEN_ADJUST_PRIVILEGES
,
1537 if (!LookupPrivilegeValue (NULL
, privilege
, &restore_priv
))
1540 new_priv
.PrivilegeCount
= 1;
1541 new_priv
.Privileges
[0].Luid
= restore_priv
;
1542 new_priv
.Privileges
[0].Attributes
= enable
? SE_PRIVILEGE_ENABLED
: 0;
1544 if (!AdjustTokenPrivileges (token_hdl
, FALSE
, &new_priv
,
1545 sizeof orig_priv
, &orig_priv
, &size
))
1548 /* Disabled, otherwise every `attach' in an unprivileged user session
1549 would raise the "Failed to get SE_DEBUG_NAME privilege" warning in
1551 /* AdjustTokenPrivileges returns TRUE even if the privilege could not
1552 be enabled. GetLastError () returns an correct error code, though. */
1553 if (enable
&& GetLastError () == ERROR_NOT_ALL_ASSIGNED
)
1557 ret
= orig_priv
.Privileges
[0].Attributes
== SE_PRIVILEGE_ENABLED
? 1 : 0;
1561 CloseHandle (token_hdl
);
1566 /* Attach to process PID, then initialize for debugging it. */
1568 child_attach (char *args
, int from_tty
)
1574 error_no_arg ("process-id to attach");
1576 if (set_process_privilege (SE_DEBUG_NAME
, TRUE
) < 0)
1578 printf_unfiltered ("Warning: Failed to get SE_DEBUG_NAME privilege\n");
1579 printf_unfiltered ("This can cause attach to fail on Windows NT/2K/XP\n");
1582 pid
= strtoul (args
, 0, 0); /* Windows pid */
1584 ok
= DebugActiveProcess (pid
);
1589 /* Try fall back to Cygwin pid */
1590 pid
= cygwin_internal (CW_CYGWIN_PID_TO_WINPID
, pid
);
1593 ok
= DebugActiveProcess (pid
);
1596 error ("Can't attach to process.");
1599 if (has_detach_ability ())
1600 DebugSetProcessKillOnExit (FALSE
);
1606 char *exec_file
= (char *) get_exec_file (0);
1609 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file
,
1610 target_pid_to_str (pid_to_ptid (pid
)));
1612 printf_unfiltered ("Attaching to %s\n",
1613 target_pid_to_str (pid_to_ptid (pid
)));
1615 gdb_flush (gdb_stdout
);
1618 do_initial_child_stuff (pid
);
1619 target_terminal_ours ();
1623 child_detach (char *args
, int from_tty
)
1627 if (has_detach_ability ())
1629 delete_command (NULL
, 0);
1630 child_continue (DBG_CONTINUE
, -1);
1631 if (!DebugActiveProcessStop (current_event
.dwProcessId
))
1633 error ("Can't detach process %lu (error %lu)",
1634 current_event
.dwProcessId
, GetLastError ());
1637 DebugSetProcessKillOnExit (FALSE
);
1639 if (detached
&& from_tty
)
1641 char *exec_file
= get_exec_file (0);
1644 printf_unfiltered ("Detaching from program: %s, Pid %lu\n", exec_file
,
1645 current_event
.dwProcessId
);
1646 gdb_flush (gdb_stdout
);
1648 inferior_ptid
= null_ptid
;
1649 unpush_target (&child_ops
);
1652 /* Print status information about what we're accessing. */
1655 child_files_info (struct target_ops
*ignore
)
1657 printf_unfiltered ("\tUsing the running image of %s %s.\n",
1658 attach_flag
? "attached" : "child", target_pid_to_str (inferior_ptid
));
1662 child_open (char *arg
, int from_tty
)
1664 error ("Use the \"run\" command to start a Unix child process.");
1667 /* Start an inferior win32 child process and sets inferior_ptid to its pid.
1668 EXEC_FILE is the file to run.
1669 ALLARGS is a string containing the arguments to the program.
1670 ENV is the environment vector to pass. Errors reported with error(). */
1673 child_create_inferior (char *exec_file
, char *allargs
, char **env
)
1680 PROCESS_INFORMATION pi
;
1684 char real_path
[MAXPATHLEN
];
1686 char shell
[MAX_PATH
+ 1]; /* Path to shell */
1689 int ostdin
, ostdout
, ostderr
;
1692 error ("No executable specified, use `target exec'.\n");
1694 memset (&si
, 0, sizeof (si
));
1695 si
.cb
= sizeof (si
);
1699 flags
= DEBUG_ONLY_THIS_PROCESS
;
1700 cygwin_conv_to_win32_path (exec_file
, real_path
);
1706 sh
= getenv ("SHELL");
1709 cygwin_conv_to_win32_path (sh
, shell
);
1710 newallargs
= alloca (sizeof (" -c 'exec '") + strlen (exec_file
)
1711 + strlen (allargs
) + 2);
1712 sprintf (newallargs
, " -c 'exec %s %s'", exec_file
, allargs
);
1713 allargs
= newallargs
;
1715 flags
= DEBUG_PROCESS
;
1719 flags
|= CREATE_NEW_PROCESS_GROUP
;
1722 flags
|= CREATE_NEW_CONSOLE
;
1726 args
= alloca (strlen (toexec
) + strlen (allargs
) + 2);
1727 strcpy (args
, toexec
);
1729 strcat (args
, allargs
);
1731 /* Prepare the environment vars for CreateProcess. */
1733 /* This code used to assume all env vars were file names and would
1734 translate them all to win32 style. That obviously doesn't work in the
1735 general case. The current rule is that we only translate PATH.
1736 We need to handle PATH because we're about to call CreateProcess and
1737 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
1738 in both posix and win32 environments. cygwin.dll will change it back
1739 to posix style if necessary. */
1741 static const char *conv_path_names
[] =
1747 /* CreateProcess takes the environment list as a null terminated set of
1748 strings (i.e. two nulls terminate the list). */
1750 /* Get total size for env strings. */
1751 for (envlen
= 0, i
= 0; env
[i
] && *env
[i
]; i
++)
1755 for (j
= 0; conv_path_names
[j
]; j
++)
1757 len
= strlen (conv_path_names
[j
]);
1758 if (strncmp (conv_path_names
[j
], env
[i
], len
) == 0)
1760 if (cygwin_posix_path_list_p (env
[i
] + len
))
1762 + cygwin_posix_to_win32_path_list_buf_size (env
[i
] + len
);
1764 envlen
+= strlen (env
[i
]) + 1;
1768 if (conv_path_names
[j
] == NULL
)
1769 envlen
+= strlen (env
[i
]) + 1;
1772 winenv
= alloca (envlen
+ 1);
1774 /* Copy env strings into new buffer. */
1775 for (temp
= winenv
, i
= 0; env
[i
] && *env
[i
]; i
++)
1779 for (j
= 0; conv_path_names
[j
]; j
++)
1781 len
= strlen (conv_path_names
[j
]);
1782 if (strncmp (conv_path_names
[j
], env
[i
], len
) == 0)
1784 if (cygwin_posix_path_list_p (env
[i
] + len
))
1786 memcpy (temp
, env
[i
], len
);
1787 cygwin_posix_to_win32_path_list (env
[i
] + len
, temp
+ len
);
1790 strcpy (temp
, env
[i
]);
1794 if (conv_path_names
[j
] == NULL
)
1795 strcpy (temp
, env
[i
]);
1797 temp
+= strlen (temp
) + 1;
1800 /* Final nil string to terminate new env. */
1804 if (!inferior_io_terminal
)
1805 tty
= ostdin
= ostdout
= ostderr
= -1;
1808 tty
= open (inferior_io_terminal
, O_RDWR
| O_NOCTTY
);
1811 print_sys_errmsg (inferior_io_terminal
, errno
);
1812 ostdin
= ostdout
= ostderr
= -1;
1825 ret
= CreateProcess (0,
1826 args
, /* command line */
1827 NULL
, /* Security */
1829 TRUE
, /* inherit handles */
1830 flags
, /* start flags */
1832 NULL
, /* current directory */
1847 error ("Error creating process %s, (error %d)\n", exec_file
, (unsigned) GetLastError ());
1849 CloseHandle (pi
.hThread
);
1850 CloseHandle (pi
.hProcess
);
1852 if (useshell
&& shell
[0] != '\0')
1857 do_initial_child_stuff (pi
.dwProcessId
);
1859 /* child_continue (DBG_CONTINUE, -1); */
1860 proceed ((CORE_ADDR
) - 1, TARGET_SIGNAL_0
, 0);
1864 child_mourn_inferior (void)
1866 (void) child_continue (DBG_CONTINUE
, -1);
1867 i386_cleanup_dregs();
1868 unpush_target (&child_ops
);
1869 generic_mourn_inferior ();
1872 /* Send a SIGINT to the process group. This acts just like the user typed a
1873 ^C on the controlling terminal. */
1878 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
1879 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT
, current_event
.dwProcessId
));
1880 registers_changed (); /* refresh register state */
1884 child_xfer_memory (CORE_ADDR memaddr
, char *our
, int len
,
1885 int write
, struct mem_attrib
*mem
,
1886 struct target_ops
*target
)
1891 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
1892 len
, (DWORD
) memaddr
));
1893 if (!WriteProcessMemory (current_process_handle
, (LPVOID
) memaddr
, our
,
1896 FlushInstructionCache (current_process_handle
, (LPCVOID
) memaddr
, len
);
1900 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
1901 len
, (DWORD
) memaddr
));
1902 if (!ReadProcessMemory (current_process_handle
, (LPCVOID
) memaddr
, our
,
1910 child_kill_inferior (void)
1912 CHECK (TerminateProcess (current_process_handle
, 0));
1916 if (!child_continue (DBG_CONTINUE
, -1))
1918 if (!WaitForDebugEvent (¤t_event
, INFINITE
))
1920 if (current_event
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
)
1924 CHECK (CloseHandle (current_process_handle
));
1926 /* this may fail in an attached process so don't check. */
1927 if (current_thread
&& current_thread
->h
)
1928 (void) CloseHandle (current_thread
->h
);
1929 target_mourn_inferior (); /* or just child_mourn_inferior? */
1933 child_resume (ptid_t ptid
, int step
, enum target_signal sig
)
1936 DWORD continue_status
= DBG_CONTINUE
;
1938 int pid
= PIDGET (ptid
);
1940 if (sig
!= TARGET_SIGNAL_0
)
1942 if (current_event
.dwDebugEventCode
!= EXCEPTION_DEBUG_EVENT
)
1944 DEBUG_EXCEPT(("Cannot continue with signal %d here.\n",sig
));
1946 else if (sig
== last_sig
)
1947 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
1950 /* This code does not seem to work, because
1951 the kernel does probably not consider changes in the ExceptionRecord
1952 structure when passing the exception to the inferior.
1953 Note that this seems possible in the exception handler itself. */
1956 for (i
= 0; xlate
[i
].them
!= -1; i
++)
1957 if (xlate
[i
].us
== sig
)
1959 current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
=
1961 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
1964 if (continue_status
== DBG_CONTINUE
)
1966 DEBUG_EXCEPT(("Cannot continue with signal %d.\n",sig
));
1970 DEBUG_EXCEPT(("Can only continue with recieved signal %d.\n",
1974 last_sig
= TARGET_SIGNAL_0
;
1976 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1979 /* Get context for currently selected thread */
1980 th
= thread_rec (current_event
.dwThreadId
, FALSE
);
1985 /* Single step by setting t bit */
1986 child_fetch_inferior_registers (PS_REGNUM
);
1987 th
->context
.EFlags
|= FLAG_TRACE_BIT
;
1990 if (th
->context
.ContextFlags
)
1992 if (debug_registers_changed
)
1994 th
->context
.Dr0
= dr
[0];
1995 th
->context
.Dr1
= dr
[1];
1996 th
->context
.Dr2
= dr
[2];
1997 th
->context
.Dr3
= dr
[3];
1998 /* th->context.Dr6 = dr[6];
1999 FIXME: should we set dr6 also ?? */
2000 th
->context
.Dr7
= dr
[7];
2002 CHECK (SetThreadContext (th
->h
, &th
->context
));
2003 th
->context
.ContextFlags
= 0;
2007 /* Allow continuing with the same signal that interrupted us.
2008 Otherwise complain. */
2010 child_continue (continue_status
, pid
);
2014 child_prepare_to_store (void)
2016 /* Do nothing, since we can store individual regs */
2020 child_can_run (void)
2028 DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n",
2029 PIDGET (inferior_ptid
)));
2032 struct target_ops child_ops
;
2035 init_child_ops (void)
2037 child_ops
.to_shortname
= "child";
2038 child_ops
.to_longname
= "Win32 child process";
2039 child_ops
.to_doc
= "Win32 child process (started by the \"run\" command).";
2040 child_ops
.to_open
= child_open
;
2041 child_ops
.to_close
= child_close
;
2042 child_ops
.to_attach
= child_attach
;
2043 child_ops
.to_detach
= child_detach
;
2044 child_ops
.to_resume
= child_resume
;
2045 child_ops
.to_wait
= child_wait
;
2046 child_ops
.to_fetch_registers
= child_fetch_inferior_registers
;
2047 child_ops
.to_store_registers
= child_store_inferior_registers
;
2048 child_ops
.to_prepare_to_store
= child_prepare_to_store
;
2049 child_ops
.to_xfer_memory
= child_xfer_memory
;
2050 child_ops
.to_files_info
= child_files_info
;
2051 child_ops
.to_insert_breakpoint
= memory_insert_breakpoint
;
2052 child_ops
.to_remove_breakpoint
= memory_remove_breakpoint
;
2053 child_ops
.to_terminal_init
= terminal_init_inferior
;
2054 child_ops
.to_terminal_inferior
= terminal_inferior
;
2055 child_ops
.to_terminal_ours_for_output
= terminal_ours_for_output
;
2056 child_ops
.to_terminal_ours
= terminal_ours
;
2057 child_ops
.to_terminal_save_ours
= terminal_save_ours
;
2058 child_ops
.to_terminal_info
= child_terminal_info
;
2059 child_ops
.to_kill
= child_kill_inferior
;
2060 child_ops
.to_create_inferior
= child_create_inferior
;
2061 child_ops
.to_mourn_inferior
= child_mourn_inferior
;
2062 child_ops
.to_can_run
= child_can_run
;
2063 child_ops
.to_thread_alive
= win32_child_thread_alive
;
2064 child_ops
.to_pid_to_str
= cygwin_pid_to_str
;
2065 child_ops
.to_stop
= child_stop
;
2066 child_ops
.to_stratum
= process_stratum
;
2067 child_ops
.to_has_all_memory
= 1;
2068 child_ops
.to_has_memory
= 1;
2069 child_ops
.to_has_stack
= 1;
2070 child_ops
.to_has_registers
= 1;
2071 child_ops
.to_has_execution
= 1;
2072 child_ops
.to_magic
= OPS_MAGIC
;
2076 _initialize_win32_nat (void)
2078 struct cmd_list_element
*c
;
2082 c
= add_com ("dll-symbols", class_files
, dll_symbol_command
,
2083 "Load dll library symbols from FILE.");
2084 set_cmd_completer (c
, filename_completer
);
2086 add_com_alias ("sharedlibrary", "dll-symbols", class_alias
, 1);
2088 add_show_from_set (add_set_cmd ("shell", class_support
, var_boolean
,
2090 "Set use of shell to start subprocess.",
2094 add_show_from_set (add_set_cmd ("new-console", class_support
, var_boolean
,
2095 (char *) &new_console
,
2096 "Set creation of new console when creating child process.",
2100 add_show_from_set (add_set_cmd ("new-group", class_support
, var_boolean
,
2101 (char *) &new_group
,
2102 "Set creation of new group when creating child process.",
2106 add_show_from_set (add_set_cmd ("debugexec", class_support
, var_boolean
,
2107 (char *) &debug_exec
,
2108 "Set whether to display execution in child process.",
2112 add_show_from_set (add_set_cmd ("debugevents", class_support
, var_boolean
,
2113 (char *) &debug_events
,
2114 "Set whether to display kernel events in child process.",
2118 add_show_from_set (add_set_cmd ("debugmemory", class_support
, var_boolean
,
2119 (char *) &debug_memory
,
2120 "Set whether to display memory accesses in child process.",
2124 add_show_from_set (add_set_cmd ("debugexceptions", class_support
, var_boolean
,
2125 (char *) &debug_exceptions
,
2126 "Set whether to display kernel exceptions in child process.",
2130 add_info ("dll", info_dll_command
, "Status of loaded DLLs.");
2131 add_info_alias ("sharedlibrary", "dll", 1);
2133 add_prefix_cmd ("w32", class_info
, info_w32_command
,
2134 "Print information specific to Win32 debugging.",
2135 &info_w32_cmdlist
, "info w32 ", 0, &infolist
);
2137 add_cmd ("selector", class_info
, display_selectors
,
2138 "Display selectors infos.",
2141 add_target (&child_ops
);
2144 /* Hardware watchpoint support, adapted from go32-nat.c code. */
2146 /* Pass the address ADDR to the inferior in the I'th debug register.
2147 Here we just store the address in dr array, the registers will be
2148 actually set up when child_continue is called. */
2150 cygwin_set_dr (int i
, CORE_ADDR addr
)
2153 internal_error (__FILE__
, __LINE__
,
2154 "Invalid register %d in cygwin_set_dr.\n", i
);
2155 dr
[i
] = (unsigned) addr
;
2156 debug_registers_changed
= 1;
2157 debug_registers_used
= 1;
2160 /* Pass the value VAL to the inferior in the DR7 debug control
2161 register. Here we just store the address in D_REGS, the watchpoint
2162 will be actually set up in child_wait. */
2164 cygwin_set_dr7 (unsigned val
)
2167 debug_registers_changed
= 1;
2168 debug_registers_used
= 1;
2171 /* Get the value of the DR6 debug status register from the inferior.
2172 Here we just return the value stored in dr[6]
2173 by the last call to thread_rec for current_event.dwThreadId id. */
2175 cygwin_get_dr6 (void)
2180 /* Determine if the thread referenced by "pid" is alive
2181 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
2182 it means that the pid has died. Otherwise it is assumed to be alive. */
2184 win32_child_thread_alive (ptid_t ptid
)
2186 int pid
= PIDGET (ptid
);
2188 return WaitForSingleObject (thread_rec (pid
, FALSE
)->h
, 0) == WAIT_OBJECT_0
?
2192 /* Convert pid to printable format. */
2194 cygwin_pid_to_str (ptid_t ptid
)
2196 static char buf
[80];
2197 int pid
= PIDGET (ptid
);
2199 if ((DWORD
) pid
== current_event
.dwProcessId
)
2200 sprintf (buf
, "process %d", pid
);
2202 sprintf (buf
, "thread %ld.0x%x", current_event
.dwProcessId
, pid
);
2207 core_dll_symbols_add (char *dll_name
, DWORD base_addr
)
2209 struct objfile
*objfile
;
2210 char *objfile_basename
;
2211 const char *dll_basename
;
2213 if (!(dll_basename
= strrchr (dll_name
, '/')))
2214 dll_basename
= dll_name
;
2218 ALL_OBJFILES (objfile
)
2220 objfile_basename
= strrchr (objfile
->name
, '/');
2222 if (objfile_basename
&&
2223 strcmp (dll_basename
, objfile_basename
+ 1) == 0)
2225 printf_unfiltered ("%08lx:%s (symbols previously loaded)\n",
2226 base_addr
, dll_name
);
2231 register_loaded_dll (dll_name
, base_addr
+ 0x1000);
2232 solib_symbols_add (dll_name
, 0, (CORE_ADDR
) base_addr
+ 0x1000);
2240 struct target_ops
*target
;
2242 } map_code_section_args
;
2245 map_single_dll_code_section (bfd
* abfd
, asection
* sect
, void *obj
)
2249 struct section_table
*new_target_sect_ptr
;
2251 map_code_section_args
*args
= (map_code_section_args
*) obj
;
2252 struct target_ops
*target
= args
->target
;
2253 if (sect
->flags
& SEC_CODE
)
2255 update_coreops
= core_ops
.to_sections
== target
->to_sections
;
2257 if (target
->to_sections
)
2259 old
= target
->to_sections_end
- target
->to_sections
;
2260 target
->to_sections
= (struct section_table
*)
2261 xrealloc ((char *) target
->to_sections
,
2262 (sizeof (struct section_table
)) * (1 + old
));
2267 target
->to_sections
= (struct section_table
*)
2268 xmalloc ((sizeof (struct section_table
)));
2270 target
->to_sections_end
= target
->to_sections
+ (1 + old
);
2272 /* Update the to_sections field in the core_ops structure
2276 core_ops
.to_sections
= target
->to_sections
;
2277 core_ops
.to_sections_end
= target
->to_sections_end
;
2279 new_target_sect_ptr
= target
->to_sections
+ old
;
2280 new_target_sect_ptr
->addr
= args
->addr
+ bfd_section_vma (abfd
, sect
);
2281 new_target_sect_ptr
->endaddr
= args
->addr
+ bfd_section_vma (abfd
, sect
) +
2282 bfd_section_size (abfd
, sect
);;
2283 new_target_sect_ptr
->the_bfd_section
= sect
;
2284 new_target_sect_ptr
->bfd
= abfd
;
2289 dll_code_sections_add (const char *dll_name
, int base_addr
, struct target_ops
*target
)
2292 map_code_section_args map_args
;
2293 asection
*lowest_sect
;
2295 if (dll_name
== NULL
|| target
== NULL
)
2297 name
= xstrdup (dll_name
);
2298 dll_bfd
= bfd_openr (name
, "pei-i386");
2299 if (dll_bfd
== NULL
)
2302 if (bfd_check_format (dll_bfd
, bfd_object
))
2304 lowest_sect
= bfd_get_section_by_name (dll_bfd
, ".text");
2305 if (lowest_sect
== NULL
)
2307 map_args
.target
= target
;
2308 map_args
.addr
= base_addr
- bfd_section_vma (dll_bfd
, lowest_sect
);
2310 bfd_map_over_sections (dll_bfd
, &map_single_dll_code_section
, (void *) (&map_args
));
2317 core_section_load_dll_symbols (bfd
* abfd
, asection
* sect
, void *obj
)
2319 struct target_ops
*target
= (struct target_ops
*) obj
;
2324 char *dll_name
= NULL
;
2326 struct win32_pstatus
*pstatus
;
2329 if (strncmp (sect
->name
, ".module", 7))
2332 buf
= (char *) xmalloc (sect
->_raw_size
+ 1);
2335 printf_unfiltered ("memory allocation failed for %s\n", sect
->name
);
2338 if (!bfd_get_section_contents (abfd
, sect
, buf
, 0, sect
->_raw_size
))
2341 pstatus
= (struct win32_pstatus
*) buf
;
2343 memmove (&base_addr
, &(pstatus
->data
.module_info
.base_address
), sizeof (base_addr
));
2344 dll_name_size
= pstatus
->data
.module_info
.module_name_size
;
2345 if (offsetof (struct win32_pstatus
, data
.module_info
.module_name
) + dll_name_size
> sect
->_raw_size
)
2348 dll_name
= (char *) xmalloc (dll_name_size
+ 1);
2351 printf_unfiltered ("memory allocation failed for %s\n", sect
->name
);
2354 strncpy (dll_name
, pstatus
->data
.module_info
.module_name
, dll_name_size
);
2356 while ((p
= strchr (dll_name
, '\\')))
2359 if (!core_dll_symbols_add (dll_name
, (DWORD
) base_addr
))
2360 printf_unfiltered ("%s: Failed to load dll symbols.\n", dll_name
);
2362 if (!dll_code_sections_add (dll_name
, (DWORD
) base_addr
+ 0x1000, target
))
2363 printf_unfiltered ("%s: Failed to map dll code sections.\n", dll_name
);
2374 child_solib_add (char *filename
, int from_tty
, struct target_ops
*target
,
2381 child_clear_solibs ();
2382 bfd_map_over_sections (core_bfd
, &core_section_load_dll_symbols
, target
);
2386 if (solib_end
&& solib_end
->name
)
2387 solib_end
->objfile
= solib_symbols_add (solib_end
->name
, from_tty
,
2388 solib_end
->load_addr
);
2393 fetch_elf_core_registers (char *core_reg_sect
,
2394 unsigned core_reg_size
,
2399 if (core_reg_size
< sizeof (CONTEXT
))
2401 error ("Core file register section too small (%u bytes).", core_reg_size
);
2404 for (r
= 0; r
< NUM_REGS
; r
++)
2405 supply_register (r
, core_reg_sect
+ mappings
[r
]);
2408 static struct core_fns win32_elf_core_fns
=
2410 bfd_target_elf_flavour
,
2411 default_check_format
,
2412 default_core_sniffer
,
2413 fetch_elf_core_registers
,
2418 _initialize_core_win32 (void)
2420 add_core_fns (&win32_elf_core_fns
);
2424 _initialize_check_for_gdb_ini (void)
2427 if (inhibit_gdbinit
)
2430 homedir
= getenv ("HOME");
2434 char *oldini
= (char *) alloca (strlen (homedir
) +
2435 sizeof ("/gdb.ini"));
2436 strcpy (oldini
, homedir
);
2437 p
= strchr (oldini
, '\0');
2438 if (p
> oldini
&& p
[-1] != '/')
2440 strcpy (p
, "gdb.ini");
2441 if (access (oldini
, 0) == 0)
2443 int len
= strlen (oldini
);
2444 char *newini
= alloca (len
+ 1);
2445 sprintf (newini
, "%.*s.gdbinit",
2446 (int) (len
- (sizeof ("gdb.ini") - 1)), oldini
);
2447 warning ("obsolete '%s' found. Rename to '%s'.", oldini
, newini
);