1 /* Target-vector operations for controlling win32 child processes, for GDB.
3 Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
4 Free Software Foundation, Inc.
6 Contributed by Cygnus Solutions, A Red Hat Company.
8 This file is part of GDB.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without eve nthe implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
25 /* Originally by Steve Chamberlain, sac@cygnus.com */
27 /* We assume we're being built with and will be used for cygwin. */
30 #include "frame.h" /* required by inferior.h */
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 /* If we're not using the old Cygwin header file set, define the
60 following which never should have been in the generic Win32 API
61 headers in the first place since they were our own invention... */
62 #ifndef _GNU_H_WINDOWS_H
65 FLAG_TRACE_BIT
= 0x100,
66 CONTEXT_DEBUGGER
= (CONTEXT_FULL
| CONTEXT_FLOATING_POINT
)
69 #include <sys/procfs.h>
72 #define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \
73 | CONTEXT_EXTENDED_REGISTERS
75 static unsigned dr
[8];
76 static int debug_registers_changed
;
77 static int debug_registers_used
;
79 /* The string sent by cygwin when it processes a signal.
80 FIXME: This should be in a cygwin include file. */
81 #define CYGWIN_SIGNAL_STRING "cygwin: signal"
83 #define CHECK(x) check (x, __FILE__,__LINE__)
84 #define DEBUG_EXEC(x) if (debug_exec) printf_unfiltered x
85 #define DEBUG_EVENTS(x) if (debug_events) printf_unfiltered x
86 #define DEBUG_MEM(x) if (debug_memory) printf_unfiltered x
87 #define DEBUG_EXCEPT(x) if (debug_exceptions) printf_unfiltered x
89 /* Forward declaration */
90 extern struct target_ops child_ops
;
92 static void child_stop (void);
93 static int win32_child_thread_alive (ptid_t
);
94 void child_kill_inferior (void);
96 static enum target_signal last_sig
= TARGET_SIGNAL_0
;
97 /* Set if a signal was received from the debugged process */
99 /* Thread information structure used to track information that is
100 not available in gdb's thread structure. */
101 typedef struct thread_info_struct
103 struct thread_info_struct
*next
;
114 static thread_info thread_head
;
116 /* The process and thread handles for the above context. */
118 static DEBUG_EVENT current_event
; /* The current debug event from
120 static HANDLE current_process_handle
; /* Currently executing process */
121 static thread_info
*current_thread
; /* Info on currently selected thread */
122 static DWORD main_thread_id
; /* Thread ID of the main thread */
124 /* Counts of things. */
125 static int exception_count
= 0;
126 static int event_count
= 0;
127 static int saw_create
;
130 static int new_console
= 0;
131 static int new_group
= 1;
132 static int debug_exec
= 0; /* show execution */
133 static int debug_events
= 0; /* show events from kernel */
134 static int debug_memory
= 0; /* show target memory accesses */
135 static int debug_exceptions
= 0; /* show target exceptions */
136 static int useshell
= 0; /* use shell for subprocesses */
138 /* This vector maps GDB's idea of a register's number into an address
139 in the win32 exception context vector.
141 It also contains the bit mask needed to load the register in question.
143 One day we could read a reg, we could inspect the context we
144 already have loaded, if it doesn't have the bit set that we need,
145 we read that set of registers in using GetThreadContext. If the
146 context already contains what we need, we just unpack it. Then to
147 write a register, first we have to ensure that the context contains
148 the other regs of the group, and then we copy the info in and set
151 #define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
152 static const int mappings
[] =
154 context_offset (Eax
),
155 context_offset (Ecx
),
156 context_offset (Edx
),
157 context_offset (Ebx
),
158 context_offset (Esp
),
159 context_offset (Ebp
),
160 context_offset (Esi
),
161 context_offset (Edi
),
162 context_offset (Eip
),
163 context_offset (EFlags
),
164 context_offset (SegCs
),
165 context_offset (SegSs
),
166 context_offset (SegDs
),
167 context_offset (SegEs
),
168 context_offset (SegFs
),
169 context_offset (SegGs
),
170 context_offset (FloatSave
.RegisterArea
[0 * 10]),
171 context_offset (FloatSave
.RegisterArea
[1 * 10]),
172 context_offset (FloatSave
.RegisterArea
[2 * 10]),
173 context_offset (FloatSave
.RegisterArea
[3 * 10]),
174 context_offset (FloatSave
.RegisterArea
[4 * 10]),
175 context_offset (FloatSave
.RegisterArea
[5 * 10]),
176 context_offset (FloatSave
.RegisterArea
[6 * 10]),
177 context_offset (FloatSave
.RegisterArea
[7 * 10]),
178 context_offset (FloatSave
.ControlWord
),
179 context_offset (FloatSave
.StatusWord
),
180 context_offset (FloatSave
.TagWord
),
181 context_offset (FloatSave
.ErrorSelector
),
182 context_offset (FloatSave
.ErrorOffset
),
183 context_offset (FloatSave
.DataSelector
),
184 context_offset (FloatSave
.DataOffset
),
185 context_offset (FloatSave
.ErrorSelector
)
187 context_offset (ExtendedRegisters
[10*16]),
188 context_offset (ExtendedRegisters
[11*16]),
189 context_offset (ExtendedRegisters
[12*16]),
190 context_offset (ExtendedRegisters
[13*16]),
191 context_offset (ExtendedRegisters
[14*16]),
192 context_offset (ExtendedRegisters
[15*16]),
193 context_offset (ExtendedRegisters
[16*16]),
194 context_offset (ExtendedRegisters
[17*16]),
196 context_offset (ExtendedRegisters
[24])
199 #undef context_offset
201 /* This vector maps the target's idea of an exception (extracted
202 from the DEBUG_EVENT structure) to GDB's idea. */
204 struct xlate_exception
207 enum target_signal us
;
210 static const struct xlate_exception
213 {EXCEPTION_ACCESS_VIOLATION
, TARGET_SIGNAL_SEGV
},
214 {STATUS_STACK_OVERFLOW
, TARGET_SIGNAL_SEGV
},
215 {EXCEPTION_BREAKPOINT
, TARGET_SIGNAL_TRAP
},
216 {DBG_CONTROL_C
, TARGET_SIGNAL_INT
},
217 {EXCEPTION_SINGLE_STEP
, TARGET_SIGNAL_TRAP
},
218 {STATUS_FLOAT_DIVIDE_BY_ZERO
, TARGET_SIGNAL_FPE
},
222 check (BOOL ok
, const char *file
, int line
)
225 printf_filtered ("error return %s:%d was %lu\n", file
, line
,
229 /* Find a thread record given a thread id.
230 If get_context then also retrieve the context for this
233 thread_rec (DWORD id
, int get_context
)
237 for (th
= &thread_head
; (th
= th
->next
) != NULL
;)
240 if (!th
->suspend_count
&& get_context
)
242 if (get_context
> 0 && id
!= current_event
.dwThreadId
)
243 th
->suspend_count
= SuspendThread (th
->h
) + 1;
244 else if (get_context
< 0)
245 th
->suspend_count
= -1;
246 th
->reload_context
= 1;
254 /* Add a thread to the thread list */
256 child_add_thread (DWORD id
, HANDLE h
)
260 if ((th
= thread_rec (id
, FALSE
)))
263 th
= (thread_info
*) xmalloc (sizeof (*th
));
264 memset (th
, 0, sizeof (*th
));
267 th
->next
= thread_head
.next
;
268 thread_head
.next
= th
;
269 add_thread (pid_to_ptid (id
));
270 /* Set the debug registers for the new thread in they are used. */
271 if (debug_registers_used
)
273 /* Only change the value of the debug registers. */
274 th
->context
.ContextFlags
= CONTEXT_DEBUG_REGISTERS
;
275 CHECK (GetThreadContext (th
->h
, &th
->context
));
276 th
->context
.Dr0
= dr
[0];
277 th
->context
.Dr1
= dr
[1];
278 th
->context
.Dr2
= dr
[2];
279 th
->context
.Dr3
= dr
[3];
280 /* th->context.Dr6 = dr[6];
281 FIXME: should we set dr6 also ?? */
282 th
->context
.Dr7
= dr
[7];
283 CHECK (SetThreadContext (th
->h
, &th
->context
));
284 th
->context
.ContextFlags
= 0;
289 /* Clear out any old thread list and reintialize it to a
292 child_init_thread_list (void)
294 thread_info
*th
= &thread_head
;
296 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
298 while (th
->next
!= NULL
)
300 thread_info
*here
= th
->next
;
301 th
->next
= here
->next
;
302 (void) CloseHandle (here
->h
);
307 /* Delete a thread from the list of threads */
309 child_delete_thread (DWORD id
)
314 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (pid_to_ptid (id
)));
315 delete_thread (pid_to_ptid (id
));
317 for (th
= &thread_head
;
318 th
->next
!= NULL
&& th
->next
->id
!= id
;
322 if (th
->next
!= NULL
)
324 thread_info
*here
= th
->next
;
325 th
->next
= here
->next
;
326 CloseHandle (here
->h
);
332 do_child_fetch_inferior_registers (int r
)
334 char *context_offset
= ((char *) ¤t_thread
->context
) + mappings
[r
];
338 return; /* Windows sometimes uses a non-existent thread id in its
341 if (current_thread
->reload_context
)
343 thread_info
*th
= current_thread
;
344 th
->context
.ContextFlags
= CONTEXT_DEBUGGER_DR
;
345 GetThreadContext (th
->h
, &th
->context
);
346 /* Copy dr values from that thread. */
347 dr
[0] = th
->context
.Dr0
;
348 dr
[1] = th
->context
.Dr1
;
349 dr
[2] = th
->context
.Dr2
;
350 dr
[3] = th
->context
.Dr3
;
351 dr
[6] = th
->context
.Dr6
;
352 dr
[7] = th
->context
.Dr7
;
353 current_thread
->reload_context
= 0;
356 #define I387_ST0_REGNUM I386_ST0_REGNUM
358 if (r
== I387_FISEG_REGNUM
)
360 l
= *((long *) context_offset
) & 0xffff;
361 supply_register (r
, (char *) &l
);
363 else if (r
== I387_FOP_REGNUM
)
365 l
= (*((long *) context_offset
) >> 16) & ((1 << 11) - 1);
366 supply_register (r
, (char *) &l
);
369 supply_register (r
, context_offset
);
372 for (r
= 0; r
< NUM_REGS
; r
++)
373 do_child_fetch_inferior_registers (r
);
376 #undef I387_ST0_REGNUM
380 child_fetch_inferior_registers (int r
)
382 current_thread
= thread_rec (PIDGET (inferior_ptid
), TRUE
);
383 /* Check if current_thread exists. Windows sometimes uses a non-existent
384 thread id in its events */
386 do_child_fetch_inferior_registers (r
);
390 do_child_store_inferior_registers (int r
)
393 /* Windows sometimes uses a non-existent thread id in its events */;
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
);
408 /* Check if current_thread exists. Windows sometimes uses a non-existent
409 thread id in its events */
411 do_child_store_inferior_registers (r
);
414 static int psapi_loaded
= 0;
415 static HMODULE psapi_module_handle
= NULL
;
416 static BOOL
WINAPI (*psapi_EnumProcessModules
) (HANDLE
, HMODULE
*, DWORD
, LPDWORD
) = NULL
;
417 static BOOL
WINAPI (*psapi_GetModuleInformation
) (HANDLE
, HMODULE
, LPMODULEINFO
, DWORD
) = NULL
;
418 static DWORD
WINAPI (*psapi_GetModuleFileNameExA
) (HANDLE
, HMODULE
, LPSTR
, DWORD
) = NULL
;
421 psapi_get_dll_name (DWORD BaseAddress
, char *dll_name_ret
)
427 HMODULE
*DllHandle
= dh_buf
;
432 psapi_EnumProcessModules
== NULL
||
433 psapi_GetModuleInformation
== NULL
||
434 psapi_GetModuleFileNameExA
== NULL
)
439 psapi_module_handle
= LoadLibrary ("psapi.dll");
440 if (!psapi_module_handle
)
442 /* printf_unfiltered ("error loading psapi.dll: %u", GetLastError ()); */
445 psapi_EnumProcessModules
= GetProcAddress (psapi_module_handle
, "EnumProcessModules");
446 psapi_GetModuleInformation
= GetProcAddress (psapi_module_handle
, "GetModuleInformation");
447 psapi_GetModuleFileNameExA
= (void *) GetProcAddress (psapi_module_handle
,
448 "GetModuleFileNameExA");
449 if (psapi_EnumProcessModules
== NULL
||
450 psapi_GetModuleInformation
== NULL
||
451 psapi_GetModuleFileNameExA
== NULL
)
456 ok
= (*psapi_EnumProcessModules
) (current_process_handle
,
461 if (!ok
|| !cbNeeded
)
464 DllHandle
= (HMODULE
*) alloca (cbNeeded
);
468 ok
= (*psapi_EnumProcessModules
) (current_process_handle
,
475 for (i
= 0; i
< (int) (cbNeeded
/ sizeof (HMODULE
)); i
++)
477 if (!(*psapi_GetModuleInformation
) (current_process_handle
,
481 error ("Can't get module info");
483 len
= (*psapi_GetModuleFileNameExA
) (current_process_handle
,
488 error ("Error getting dll name: %u\n", (unsigned) GetLastError ());
490 if ((DWORD
) (mi
.lpBaseOfDll
) == BaseAddress
)
495 dll_name_ret
[0] = '\0';
499 /* Encapsulate the information required in a call to
500 symbol_file_add_args */
501 struct safe_symbol_file_add_args
505 struct section_addr_info
*addrs
;
508 struct ui_file
*err
, *out
;
512 /* Maintain a linked list of "so" information. */
515 struct so_stuff
*next
;
519 struct objfile
*objfile
;
521 } solib_start
, *solib_end
;
523 /* Call symbol_file_add with stderr redirected. We don't care if there
526 safe_symbol_file_add_stub (void *argv
)
528 #define p ((struct safe_symbol_file_add_args *)argv)
529 struct so_stuff
*so
= &solib_start
;
531 while ((so
= so
->next
))
532 if (so
->loaded
&& strcasecmp (so
->name
, p
->name
) == 0)
534 p
->ret
= symbol_file_add (p
->name
, p
->from_tty
, p
->addrs
, p
->mainline
, p
->flags
);
539 /* Restore gdb's stderr after calling symbol_file_add */
541 safe_symbol_file_add_cleanup (void *p
)
543 #define sp ((struct safe_symbol_file_add_args *)p)
544 gdb_flush (gdb_stderr
);
545 gdb_flush (gdb_stdout
);
546 ui_file_delete (gdb_stderr
);
547 ui_file_delete (gdb_stdout
);
548 gdb_stderr
= sp
->err
;
549 gdb_stdout
= sp
->out
;
553 /* symbol_file_add wrapper that prevents errors from being displayed. */
554 static struct objfile
*
555 safe_symbol_file_add (char *name
, int from_tty
,
556 struct section_addr_info
*addrs
,
557 int mainline
, int flags
)
559 struct safe_symbol_file_add_args p
;
560 struct cleanup
*cleanup
;
562 cleanup
= make_cleanup (safe_symbol_file_add_cleanup
, &p
);
566 gdb_flush (gdb_stderr
);
567 gdb_flush (gdb_stdout
);
568 gdb_stderr
= ui_file_new ();
569 gdb_stdout
= ui_file_new ();
571 p
.from_tty
= from_tty
;
573 p
.mainline
= mainline
;
575 catch_errors (safe_symbol_file_add_stub
, &p
, "", RETURN_MASK_ERROR
);
577 do_cleanups (cleanup
);
581 /* Remember the maximum DLL length for printing in info dll command. */
582 int max_dll_name_len
;
585 register_loaded_dll (const char *name
, DWORD load_addr
)
588 char ppath
[MAX_PATH
+ 1];
589 char buf
[MAX_PATH
+ 1];
590 char cwd
[MAX_PATH
+ 1];
592 WIN32_FIND_DATA w32_fd
;
593 HANDLE h
= FindFirstFile(name
, &w32_fd
);
594 MEMORY_BASIC_INFORMATION m
;
597 if (h
== INVALID_HANDLE_VALUE
)
603 if (GetCurrentDirectory (MAX_PATH
+ 1, cwd
))
605 p
= strrchr (buf
, '\\');
608 SetCurrentDirectory (buf
);
609 GetFullPathName (w32_fd
.cFileName
, MAX_PATH
, buf
, &p
);
610 SetCurrentDirectory (cwd
);
614 cygwin_conv_to_posix_path (buf
, ppath
);
615 so
= (struct so_stuff
*) xmalloc (sizeof (struct so_stuff
) + strlen (ppath
) + 8 + 1);
617 so
->load_addr
= load_addr
;
618 if (VirtualQueryEx (current_process_handle
, (void *) load_addr
, &m
,
620 so
->end_addr
= (DWORD
) m
.AllocationBase
+ m
.RegionSize
;
622 so
->end_addr
= load_addr
+ 0x2000; /* completely arbitrary */
626 strcpy (so
->name
, ppath
);
628 solib_end
->next
= so
;
630 len
= strlen (ppath
);
631 if (len
> max_dll_name_len
)
632 max_dll_name_len
= len
;
636 get_image_name (HANDLE h
, void *address
, int unicode
)
638 static char buf
[(2 * MAX_PATH
) + 1];
639 DWORD size
= unicode
? sizeof (WCHAR
) : sizeof (char);
645 /* Attempt to read the name of the dll that was detected.
646 This is documented to work only when actively debugging
647 a program. It will not work for attached processes. */
651 /* See if we could read the address of a string, and that the
652 address isn't null. */
653 if (!ReadProcessMemory (h
, address
, &address_ptr
, sizeof (address_ptr
), &done
)
654 || done
!= sizeof (address_ptr
) || !address_ptr
)
657 /* Find the length of the string */
658 while (ReadProcessMemory (h
, address_ptr
+ len
++ * size
, &b
, size
, &done
)
659 && (b
[0] != 0 || b
[size
- 1] != 0) && done
== size
)
663 ReadProcessMemory (h
, address_ptr
, buf
, len
, &done
);
666 WCHAR
*unicode_address
= (WCHAR
*) alloca (len
* sizeof (WCHAR
));
667 ReadProcessMemory (h
, address_ptr
, unicode_address
, len
* sizeof (WCHAR
),
670 WideCharToMultiByte (CP_ACP
, 0, unicode_address
, len
, buf
, len
, 0, 0);
676 /* Wait for child to do something. Return pid of child, or -1 in case
677 of error; store status through argument pointer OURSTATUS. */
679 handle_load_dll (void *dummy
)
681 LOAD_DLL_DEBUG_INFO
*event
= ¤t_event
.u
.LoadDll
;
682 char dll_buf
[MAX_PATH
+ 1];
683 char *dll_name
= NULL
;
686 dll_buf
[0] = dll_buf
[sizeof (dll_buf
) - 1] = '\0';
688 if (!psapi_get_dll_name ((DWORD
) (event
->lpBaseOfDll
), dll_buf
))
689 dll_buf
[0] = dll_buf
[sizeof (dll_buf
) - 1] = '\0';
693 if (*dll_name
== '\0')
694 dll_name
= get_image_name (current_process_handle
, event
->lpImageName
, event
->fUnicode
);
698 register_loaded_dll (dll_name
, (DWORD
) event
->lpBaseOfDll
+ 0x1000);
704 handle_unload_dll (void *dummy
)
706 DWORD lpBaseOfDll
= (DWORD
) current_event
.u
.UnloadDll
.lpBaseOfDll
+ 0x1000;
709 for (so
= &solib_start
; so
->next
!= NULL
; so
= so
->next
)
710 if (so
->next
->load_addr
== lpBaseOfDll
)
712 struct so_stuff
*sodel
= so
->next
;
713 so
->next
= sodel
->next
;
717 free_objfile (sodel
->objfile
);
721 error ("Error: dll starting at 0x%lx not found.\n", (DWORD
) lpBaseOfDll
);
727 solib_address (CORE_ADDR address
)
730 for (so
= &solib_start
; so
->next
!= NULL
; so
= so
->next
)
731 if (address
>= so
->load_addr
&& address
<= so
->end_addr
)
736 /* Return name of last loaded DLL. */
738 child_solib_loaded_library_pathname (int pid
)
740 return !solib_end
|| !solib_end
->name
[0] ? NULL
: solib_end
->name
;
743 /* Clear list of loaded DLLs. */
745 child_clear_solibs (void)
747 struct so_stuff
*so
, *so1
= solib_start
.next
;
749 while ((so
= so1
) != NULL
)
755 solib_start
.next
= NULL
;
756 solib_start
.objfile
= NULL
;
757 solib_end
= &solib_start
;
758 max_dll_name_len
= sizeof ("DLL Name") - 1;
761 /* Get the loaded address of all sections, given that .text was loaded
762 at text_load. Assumes that all sections are subject to the same
763 relocation offset. Returns NULL if problems occur or if the
764 sections were not relocated. */
766 static struct section_addr_info
*
767 get_relocated_section_addrs (bfd
*abfd
, CORE_ADDR text_load
)
769 struct section_addr_info
*result
= NULL
;
770 int section_count
= bfd_count_sections (abfd
);
771 asection
*text_section
= bfd_get_section_by_name (abfd
, ".text");
776 /* Couldn't get the .text section. Weird. */
779 else if (text_load
== (text_vma
= bfd_get_section_vma (abfd
, text_section
)))
781 /* DLL wasn't relocated. */
786 /* Figure out all sections' loaded addresses. The offset here is
787 such that taking a bfd_get_section_vma() result and adding
788 offset will give the real load address of the section. */
790 CORE_ADDR offset
= text_load
- text_vma
;
792 struct section_table
*table_start
= NULL
;
793 struct section_table
*table_end
= NULL
;
794 struct section_table
*iter
= NULL
;
796 build_section_table (abfd
, &table_start
, &table_end
);
798 for (iter
= table_start
; iter
< table_end
; ++iter
)
800 /* Relocated addresses. */
801 iter
->addr
+= offset
;
802 iter
->endaddr
+= offset
;
805 result
= build_section_addr_info_from_section_table (table_start
,
814 /* Add DLL symbol information. */
815 static struct objfile
*
816 solib_symbols_add (char *name
, int from_tty
, CORE_ADDR load_addr
)
818 struct section_addr_info
*addrs
= NULL
;
819 static struct objfile
*result
= NULL
;
822 /* The symbols in a dll are offset by 0x1000, which is the
823 the offset from 0 of the first byte in an image - because
824 of the file header and the section alignment. */
826 if (!name
|| !name
[0])
829 abfd
= bfd_openr (name
, "pei-i386");
833 /* pei failed - try pe */
834 abfd
= bfd_openr (name
, "pe-i386");
839 if (bfd_check_format (abfd
, bfd_object
))
841 addrs
= get_relocated_section_addrs (abfd
, load_addr
);
849 result
= safe_symbol_file_add (name
, from_tty
, addrs
, 0, OBJF_SHARED
);
850 free_section_addr_info (addrs
);
854 /* Fallback on handling just the .text section. */
855 struct cleanup
*my_cleanups
;
857 addrs
= alloc_section_addr_info (1);
858 my_cleanups
= make_cleanup (xfree
, addrs
);
859 addrs
->other
[0].name
= ".text";
860 addrs
->other
[0].addr
= load_addr
;
862 result
= safe_symbol_file_add (name
, from_tty
, addrs
, 0, OBJF_SHARED
);
863 do_cleanups (my_cleanups
);
869 /* Load DLL symbol info. */
871 dll_symbol_command (char *args
, int from_tty
)
877 error ("dll-symbols requires a file name");
880 if (n
> 4 && strcasecmp (args
+ n
- 4, ".dll") != 0)
882 char *newargs
= (char *) alloca (n
+ 4 + 1);
883 strcpy (newargs
, args
);
884 strcat (newargs
, ".dll");
888 safe_symbol_file_add (args
, from_tty
, NULL
, 0, OBJF_SHARED
| OBJF_USERLOADED
);
891 /* List currently loaded DLLs. */
893 info_dll_command (char *ignore
, int from_tty
)
895 struct so_stuff
*so
= &solib_start
;
900 printf_filtered ("%*s Load Address\n", -max_dll_name_len
, "DLL Name");
901 while ((so
= so
->next
) != NULL
)
902 printf_filtered ("%*s %08lx\n", -max_dll_name_len
, so
->name
, so
->load_addr
);
907 /* Handle DEBUG_STRING output from child process.
908 Cygwin prepends its messages with a "cygwin:". Interpret this as
909 a Cygwin signal. Otherwise just print the string as a warning. */
911 handle_output_debug_string (struct target_waitstatus
*ourstatus
)
916 if (!target_read_string
917 ((CORE_ADDR
) current_event
.u
.DebugString
.lpDebugStringData
, &s
, 1024, 0)
921 if (strncmp (s
, CYGWIN_SIGNAL_STRING
, sizeof (CYGWIN_SIGNAL_STRING
) - 1) != 0)
923 if (strncmp (s
, "cYg", 3) != 0)
929 int sig
= strtol (s
+ sizeof (CYGWIN_SIGNAL_STRING
) - 1, &p
, 0);
930 gotasig
= target_signal_from_host (sig
);
931 ourstatus
->value
.sig
= gotasig
;
933 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
941 display_selector (HANDLE thread
, DWORD sel
)
944 if (GetThreadSelectorEntry (thread
, sel
, &info
))
947 printf_filtered ("0x%03lx: ", sel
);
948 if (!info
.HighWord
.Bits
.Pres
)
950 puts_filtered ("Segment not present\n");
953 base
= (info
.HighWord
.Bits
.BaseHi
<< 24) +
954 (info
.HighWord
.Bits
.BaseMid
<< 16)
956 limit
= (info
.HighWord
.Bits
.LimitHi
<< 16) + info
.LimitLow
;
957 if (info
.HighWord
.Bits
.Granularity
)
958 limit
= (limit
<< 12) | 0xfff;
959 printf_filtered ("base=0x%08x limit=0x%08x", base
, limit
);
960 if (info
.HighWord
.Bits
.Default_Big
)
961 puts_filtered(" 32-bit ");
963 puts_filtered(" 16-bit ");
964 switch ((info
.HighWord
.Bits
.Type
& 0xf) >> 1)
967 puts_filtered ("Data (Read-Only, Exp-up");
970 puts_filtered ("Data (Read/Write, Exp-up");
973 puts_filtered ("Unused segment (");
976 puts_filtered ("Data (Read/Write, Exp-down");
979 puts_filtered ("Code (Exec-Only, N.Conf");
982 puts_filtered ("Code (Exec/Read, N.Conf");
985 puts_filtered ("Code (Exec-Only, Conf");
988 puts_filtered ("Code (Exec/Read, Conf");
991 printf_filtered ("Unknown type 0x%x",info
.HighWord
.Bits
.Type
);
993 if ((info
.HighWord
.Bits
.Type
& 0x1) == 0)
994 puts_filtered(", N.Acc");
995 puts_filtered (")\n");
996 if ((info
.HighWord
.Bits
.Type
& 0x10) == 0)
997 puts_filtered("System selector ");
998 printf_filtered ("Priviledge level = %d. ", info
.HighWord
.Bits
.Dpl
);
999 if (info
.HighWord
.Bits
.Granularity
)
1000 puts_filtered ("Page granular.\n");
1002 puts_filtered ("Byte granular.\n");
1007 printf_filtered ("Invalid selector 0x%lx.\n",sel
);
1013 display_selectors (char * args
, int from_tty
)
1015 if (!current_thread
)
1017 puts_filtered ("Impossible to display selectors now.\n");
1023 puts_filtered ("Selector $cs\n");
1024 display_selector (current_thread
->h
,
1025 current_thread
->context
.SegCs
);
1026 puts_filtered ("Selector $ds\n");
1027 display_selector (current_thread
->h
,
1028 current_thread
->context
.SegDs
);
1029 puts_filtered ("Selector $es\n");
1030 display_selector (current_thread
->h
,
1031 current_thread
->context
.SegEs
);
1032 puts_filtered ("Selector $ss\n");
1033 display_selector (current_thread
->h
,
1034 current_thread
->context
.SegSs
);
1035 puts_filtered ("Selector $fs\n");
1036 display_selector (current_thread
->h
,
1037 current_thread
->context
.SegFs
);
1038 puts_filtered ("Selector $gs\n");
1039 display_selector (current_thread
->h
,
1040 current_thread
->context
.SegGs
);
1045 sel
= parse_and_eval_long (args
);
1046 printf_filtered ("Selector \"%s\"\n",args
);
1047 display_selector (current_thread
->h
, sel
);
1051 static struct cmd_list_element
*info_w32_cmdlist
= NULL
;
1054 info_w32_command (char *args
, int from_tty
)
1056 help_list (info_w32_cmdlist
, "info w32 ", class_info
, gdb_stdout
);
1060 #define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \
1061 printf_unfiltered ("gdb: Target exception %s at 0x%08lx\n", x, \
1062 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress)
1065 handle_exception (struct target_waitstatus
*ourstatus
)
1068 DWORD code
= current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
;
1070 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
1072 /* Record the context of the current thread */
1073 th
= thread_rec (current_event
.dwThreadId
, -1);
1077 case EXCEPTION_ACCESS_VIOLATION
:
1078 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
1079 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
1081 case STATUS_STACK_OVERFLOW
:
1082 DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
1083 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
1085 case STATUS_FLOAT_DENORMAL_OPERAND
:
1086 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
1087 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1089 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED
:
1090 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
1091 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1093 case STATUS_FLOAT_INEXACT_RESULT
:
1094 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
1095 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1097 case STATUS_FLOAT_INVALID_OPERATION
:
1098 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
1099 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1101 case STATUS_FLOAT_OVERFLOW
:
1102 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
1103 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1105 case STATUS_FLOAT_STACK_CHECK
:
1106 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
1107 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1109 case STATUS_FLOAT_UNDERFLOW
:
1110 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
1111 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1113 case STATUS_FLOAT_DIVIDE_BY_ZERO
:
1114 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
1115 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1117 case STATUS_INTEGER_DIVIDE_BY_ZERO
:
1118 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
1119 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1121 case STATUS_INTEGER_OVERFLOW
:
1122 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
1123 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1125 case EXCEPTION_BREAKPOINT
:
1126 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
1127 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
1130 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
1131 ourstatus
->value
.sig
= TARGET_SIGNAL_INT
;
1133 case DBG_CONTROL_BREAK
:
1134 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
1135 ourstatus
->value
.sig
= TARGET_SIGNAL_INT
;
1137 case EXCEPTION_SINGLE_STEP
:
1138 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
1139 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
1141 case EXCEPTION_ILLEGAL_INSTRUCTION
:
1142 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
1143 ourstatus
->value
.sig
= TARGET_SIGNAL_ILL
;
1145 case EXCEPTION_PRIV_INSTRUCTION
:
1146 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
1147 ourstatus
->value
.sig
= TARGET_SIGNAL_ILL
;
1149 case EXCEPTION_NONCONTINUABLE_EXCEPTION
:
1150 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
1151 ourstatus
->value
.sig
= TARGET_SIGNAL_ILL
;
1154 if (current_event
.u
.Exception
.dwFirstChance
)
1156 printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n",
1157 current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
,
1158 (DWORD
) current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
);
1159 ourstatus
->value
.sig
= TARGET_SIGNAL_UNKNOWN
;
1163 last_sig
= ourstatus
->value
.sig
;
1167 /* Resume all artificially suspended threads if we are continuing
1170 child_continue (DWORD continue_status
, int id
)
1176 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, %s);\n",
1177 current_event
.dwProcessId
, current_event
.dwThreadId
,
1178 continue_status
== DBG_CONTINUE
?
1179 "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED"));
1180 res
= ContinueDebugEvent (current_event
.dwProcessId
,
1181 current_event
.dwThreadId
,
1183 continue_status
= 0;
1185 for (th
= &thread_head
; (th
= th
->next
) != NULL
;)
1186 if (((id
== -1) || (id
== (int) th
->id
)) && th
->suspend_count
)
1189 for (i
= 0; i
< th
->suspend_count
; i
++)
1190 (void) ResumeThread (th
->h
);
1191 th
->suspend_count
= 0;
1192 if (debug_registers_changed
)
1194 /* Only change the value of the debug registers */
1195 th
->context
.ContextFlags
= CONTEXT_DEBUG_REGISTERS
;
1196 th
->context
.Dr0
= dr
[0];
1197 th
->context
.Dr1
= dr
[1];
1198 th
->context
.Dr2
= dr
[2];
1199 th
->context
.Dr3
= dr
[3];
1200 /* th->context.Dr6 = dr[6];
1201 FIXME: should we set dr6 also ?? */
1202 th
->context
.Dr7
= dr
[7];
1203 CHECK (SetThreadContext (th
->h
, &th
->context
));
1204 th
->context
.ContextFlags
= 0;
1208 debug_registers_changed
= 0;
1212 /* Called in pathological case where Windows fails to send a
1213 CREATE_PROCESS_DEBUG_EVENT after an attach. */
1215 fake_create_process (void)
1217 current_process_handle
= OpenProcess (PROCESS_ALL_ACCESS
, FALSE
,
1218 current_event
.dwProcessId
);
1219 main_thread_id
= current_event
.dwThreadId
;
1220 current_thread
= child_add_thread (main_thread_id
,
1221 current_event
.u
.CreateThread
.hThread
);
1222 return main_thread_id
;
1225 /* Get the next event from the child. Return 1 if the event requires
1226 handling by WFI (or whatever).
1229 get_child_debug_event (int pid
, struct target_waitstatus
*ourstatus
)
1232 DWORD continue_status
, event_code
;
1234 static thread_info dummy_thread_info
;
1237 last_sig
= TARGET_SIGNAL_0
;
1239 if (!(debug_event
= WaitForDebugEvent (¤t_event
, 1000)))
1243 continue_status
= DBG_CONTINUE
;
1245 event_code
= current_event
.dwDebugEventCode
;
1246 ourstatus
->kind
= TARGET_WAITKIND_SPURIOUS
;
1251 case CREATE_THREAD_DEBUG_EVENT
:
1252 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1253 (unsigned) current_event
.dwProcessId
,
1254 (unsigned) current_event
.dwThreadId
,
1255 "CREATE_THREAD_DEBUG_EVENT"));
1256 if (saw_create
!= 1)
1258 if (!saw_create
&& attach_flag
)
1260 /* Kludge around a Windows bug where first event is a create
1261 thread event. Caused when attached process does not have
1263 retval
= ourstatus
->value
.related_pid
= fake_create_process ();
1268 /* Record the existence of this thread */
1269 th
= child_add_thread (current_event
.dwThreadId
,
1270 current_event
.u
.CreateThread
.hThread
);
1272 printf_unfiltered ("[New %s]\n",
1274 pid_to_ptid (current_event
.dwThreadId
)));
1275 retval
= current_event
.dwThreadId
;
1278 case EXIT_THREAD_DEBUG_EVENT
:
1279 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1280 (unsigned) current_event
.dwProcessId
,
1281 (unsigned) current_event
.dwThreadId
,
1282 "EXIT_THREAD_DEBUG_EVENT"));
1283 if (current_event
.dwThreadId
!= main_thread_id
)
1285 child_delete_thread (current_event
.dwThreadId
);
1286 th
= &dummy_thread_info
;
1290 case CREATE_PROCESS_DEBUG_EVENT
:
1291 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1292 (unsigned) current_event
.dwProcessId
,
1293 (unsigned) current_event
.dwThreadId
,
1294 "CREATE_PROCESS_DEBUG_EVENT"));
1295 CloseHandle (current_event
.u
.CreateProcessInfo
.hFile
);
1296 if (++saw_create
!= 1)
1298 CloseHandle (current_event
.u
.CreateProcessInfo
.hProcess
);
1302 current_process_handle
= current_event
.u
.CreateProcessInfo
.hProcess
;
1304 child_delete_thread (main_thread_id
);
1305 main_thread_id
= current_event
.dwThreadId
;
1306 /* Add the main thread */
1307 th
= child_add_thread (main_thread_id
,
1308 current_event
.u
.CreateProcessInfo
.hThread
);
1309 retval
= ourstatus
->value
.related_pid
= current_event
.dwThreadId
;
1312 case EXIT_PROCESS_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 "EXIT_PROCESS_DEBUG_EVENT"));
1317 if (saw_create
!= 1)
1319 ourstatus
->kind
= TARGET_WAITKIND_EXITED
;
1320 ourstatus
->value
.integer
= current_event
.u
.ExitProcess
.dwExitCode
;
1321 CloseHandle (current_process_handle
);
1322 retval
= main_thread_id
;
1325 case LOAD_DLL_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 "LOAD_DLL_DEBUG_EVENT"));
1330 CloseHandle (current_event
.u
.LoadDll
.hFile
);
1331 if (saw_create
!= 1)
1333 catch_errors (handle_load_dll
, NULL
, (char *) "", RETURN_MASK_ALL
);
1334 registers_changed (); /* mark all regs invalid */
1335 ourstatus
->kind
= TARGET_WAITKIND_LOADED
;
1336 ourstatus
->value
.integer
= 0;
1337 retval
= main_thread_id
;
1338 re_enable_breakpoints_in_shlibs ();
1341 case UNLOAD_DLL_DEBUG_EVENT
:
1342 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1343 (unsigned) current_event
.dwProcessId
,
1344 (unsigned) current_event
.dwThreadId
,
1345 "UNLOAD_DLL_DEBUG_EVENT"));
1346 if (saw_create
!= 1)
1348 catch_errors (handle_unload_dll
, NULL
, (char *) "", RETURN_MASK_ALL
);
1349 registers_changed (); /* mark all regs invalid */
1350 /* ourstatus->kind = TARGET_WAITKIND_UNLOADED;
1351 does not exist yet. */
1354 case EXCEPTION_DEBUG_EVENT
:
1355 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1356 (unsigned) current_event
.dwProcessId
,
1357 (unsigned) current_event
.dwThreadId
,
1358 "EXCEPTION_DEBUG_EVENT"));
1359 if (saw_create
!= 1)
1361 if (handle_exception (ourstatus
))
1362 retval
= current_event
.dwThreadId
;
1365 case OUTPUT_DEBUG_STRING_EVENT
: /* message from the kernel */
1366 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1367 (unsigned) current_event
.dwProcessId
,
1368 (unsigned) current_event
.dwThreadId
,
1369 "OUTPUT_DEBUG_STRING_EVENT"));
1370 if (saw_create
!= 1)
1372 if (handle_output_debug_string (ourstatus
))
1373 retval
= main_thread_id
;
1377 if (saw_create
!= 1)
1379 printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
1380 (DWORD
) current_event
.dwProcessId
,
1381 (DWORD
) current_event
.dwThreadId
);
1382 printf_unfiltered (" unknown event code %ld\n",
1383 current_event
.dwDebugEventCode
);
1387 if (!retval
|| saw_create
!= 1)
1388 CHECK (child_continue (continue_status
, -1));
1391 inferior_ptid
= pid_to_ptid (retval
);
1392 current_thread
= th
?: thread_rec (current_event
.dwThreadId
, TRUE
);
1399 /* Wait for interesting events to occur in the target process. */
1401 child_wait (ptid_t ptid
, struct target_waitstatus
*ourstatus
)
1403 int pid
= PIDGET (ptid
);
1405 /* We loop when we get a non-standard exception rather than return
1406 with a SPURIOUS because resume can try and step or modify things,
1407 which needs a current_thread->h. But some of these exceptions mark
1408 the birth or death of threads, which mean that the current thread
1409 isn't necessarily what you think it is. */
1413 int retval
= get_child_debug_event (pid
, ourstatus
);
1415 return pid_to_ptid (retval
);
1420 if (ui_loop_hook
!= NULL
)
1421 detach
= ui_loop_hook (0);
1424 child_kill_inferior ();
1430 do_initial_child_stuff (DWORD pid
)
1432 extern int stop_after_trap
;
1435 last_sig
= TARGET_SIGNAL_0
;
1437 exception_count
= 0;
1438 debug_registers_changed
= 0;
1439 debug_registers_used
= 0;
1440 for (i
= 0; i
< sizeof (dr
) / sizeof (dr
[0]); i
++)
1442 current_event
.dwProcessId
= pid
;
1443 memset (¤t_event
, 0, sizeof (current_event
));
1444 push_target (&child_ops
);
1445 child_init_thread_list ();
1446 disable_breakpoints_in_shlibs (1);
1447 child_clear_solibs ();
1448 clear_proceed_status ();
1449 init_wait_for_inferior ();
1451 target_terminal_init ();
1452 target_terminal_inferior ();
1456 stop_after_trap
= 1;
1457 wait_for_inferior ();
1458 if (stop_signal
!= TARGET_SIGNAL_TRAP
)
1459 resume (0, stop_signal
);
1463 stop_after_trap
= 0;
1467 /* Since Windows XP, detaching from a process is supported by Windows.
1468 The following code tries loading the appropriate functions dynamically.
1469 If loading these functions succeeds use them to actually detach from
1470 the inferior process, otherwise behave as usual, pretending that
1471 detach has worked. */
1472 static BOOL
WINAPI (*DebugSetProcessKillOnExit
)(BOOL
);
1473 static BOOL
WINAPI (*DebugActiveProcessStop
)(DWORD
);
1476 has_detach_ability (void)
1478 static HMODULE kernel32
= NULL
;
1481 kernel32
= LoadLibrary ("kernel32.dll");
1484 if (!DebugSetProcessKillOnExit
)
1485 DebugSetProcessKillOnExit
= GetProcAddress (kernel32
,
1486 "DebugSetProcessKillOnExit");
1487 if (!DebugActiveProcessStop
)
1488 DebugActiveProcessStop
= GetProcAddress (kernel32
,
1489 "DebugActiveProcessStop");
1490 if (DebugSetProcessKillOnExit
&& DebugActiveProcessStop
)
1496 /* Try to set or remove a user privilege to the current process. Return -1
1497 if that fails, the previous setting of that privilege otherwise.
1499 This code is copied from the Cygwin source code and rearranged to allow
1500 dynamically loading of the needed symbols from advapi32 which is only
1501 available on NT/2K/XP. */
1503 set_process_privilege (const char *privilege
, BOOL enable
)
1505 static HMODULE advapi32
= NULL
;
1506 static BOOL
WINAPI (*OpenProcessToken
)(HANDLE
, DWORD
, PHANDLE
);
1507 static BOOL
WINAPI (*LookupPrivilegeValue
)(LPCSTR
, LPCSTR
, PLUID
);
1508 static BOOL
WINAPI (*AdjustTokenPrivileges
)(HANDLE
, BOOL
, PTOKEN_PRIVILEGES
,
1509 DWORD
, PTOKEN_PRIVILEGES
, PDWORD
);
1511 HANDLE token_hdl
= NULL
;
1513 TOKEN_PRIVILEGES new_priv
, orig_priv
;
1517 if (GetVersion () >= 0x80000000) /* No security availbale on 9x/Me */
1522 if (!(advapi32
= LoadLibrary ("advapi32.dll")))
1524 if (!OpenProcessToken
)
1525 OpenProcessToken
= GetProcAddress (advapi32
, "OpenProcessToken");
1526 if (!LookupPrivilegeValue
)
1527 LookupPrivilegeValue
= GetProcAddress (advapi32
,
1528 "LookupPrivilegeValueA");
1529 if (!AdjustTokenPrivileges
)
1530 AdjustTokenPrivileges
= GetProcAddress (advapi32
,
1531 "AdjustTokenPrivileges");
1532 if (!OpenProcessToken
|| !LookupPrivilegeValue
|| !AdjustTokenPrivileges
)
1539 if (!OpenProcessToken (GetCurrentProcess (),
1540 TOKEN_QUERY
| TOKEN_ADJUST_PRIVILEGES
,
1544 if (!LookupPrivilegeValue (NULL
, privilege
, &restore_priv
))
1547 new_priv
.PrivilegeCount
= 1;
1548 new_priv
.Privileges
[0].Luid
= restore_priv
;
1549 new_priv
.Privileges
[0].Attributes
= enable
? SE_PRIVILEGE_ENABLED
: 0;
1551 if (!AdjustTokenPrivileges (token_hdl
, FALSE
, &new_priv
,
1552 sizeof orig_priv
, &orig_priv
, &size
))
1555 /* Disabled, otherwise every `attach' in an unprivileged user session
1556 would raise the "Failed to get SE_DEBUG_NAME privilege" warning in
1558 /* AdjustTokenPrivileges returns TRUE even if the privilege could not
1559 be enabled. GetLastError () returns an correct error code, though. */
1560 if (enable
&& GetLastError () == ERROR_NOT_ALL_ASSIGNED
)
1564 ret
= orig_priv
.Privileges
[0].Attributes
== SE_PRIVILEGE_ENABLED
? 1 : 0;
1568 CloseHandle (token_hdl
);
1573 /* Attach to process PID, then initialize for debugging it. */
1575 child_attach (char *args
, int from_tty
)
1581 error_no_arg ("process-id to attach");
1583 if (set_process_privilege (SE_DEBUG_NAME
, TRUE
) < 0)
1585 printf_unfiltered ("Warning: Failed to get SE_DEBUG_NAME privilege\n");
1586 printf_unfiltered ("This can cause attach to fail on Windows NT/2K/XP\n");
1589 pid
= strtoul (args
, 0, 0); /* Windows pid */
1591 ok
= DebugActiveProcess (pid
);
1596 /* Try fall back to Cygwin pid */
1597 pid
= cygwin_internal (CW_CYGWIN_PID_TO_WINPID
, pid
);
1600 ok
= DebugActiveProcess (pid
);
1603 error ("Can't attach to process.");
1606 if (has_detach_ability ())
1607 DebugSetProcessKillOnExit (FALSE
);
1613 char *exec_file
= (char *) get_exec_file (0);
1616 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file
,
1617 target_pid_to_str (pid_to_ptid (pid
)));
1619 printf_unfiltered ("Attaching to %s\n",
1620 target_pid_to_str (pid_to_ptid (pid
)));
1622 gdb_flush (gdb_stdout
);
1625 do_initial_child_stuff (pid
);
1626 target_terminal_ours ();
1630 child_detach (char *args
, int from_tty
)
1634 if (has_detach_ability ())
1636 delete_command (NULL
, 0);
1637 child_continue (DBG_CONTINUE
, -1);
1638 if (!DebugActiveProcessStop (current_event
.dwProcessId
))
1640 error ("Can't detach process %lu (error %lu)",
1641 current_event
.dwProcessId
, GetLastError ());
1644 DebugSetProcessKillOnExit (FALSE
);
1646 if (detached
&& from_tty
)
1648 char *exec_file
= get_exec_file (0);
1651 printf_unfiltered ("Detaching from program: %s, Pid %lu\n", exec_file
,
1652 current_event
.dwProcessId
);
1653 gdb_flush (gdb_stdout
);
1655 inferior_ptid
= null_ptid
;
1656 unpush_target (&child_ops
);
1659 /* Print status information about what we're accessing. */
1662 child_files_info (struct target_ops
*ignore
)
1664 printf_unfiltered ("\tUsing the running image of %s %s.\n",
1665 attach_flag
? "attached" : "child", target_pid_to_str (inferior_ptid
));
1669 child_open (char *arg
, int from_tty
)
1671 error ("Use the \"run\" command to start a Unix child process.");
1674 /* Start an inferior win32 child process and sets inferior_ptid to its pid.
1675 EXEC_FILE is the file to run.
1676 ALLARGS is a string containing the arguments to the program.
1677 ENV is the environment vector to pass. Errors reported with error(). */
1680 child_create_inferior (char *exec_file
, char *allargs
, char **env
,
1688 PROCESS_INFORMATION pi
;
1692 char real_path
[MAXPATHLEN
];
1694 char shell
[MAX_PATH
+ 1]; /* Path to shell */
1697 int ostdin
, ostdout
, ostderr
;
1700 error ("No executable specified, use `target exec'.\n");
1702 memset (&si
, 0, sizeof (si
));
1703 si
.cb
= sizeof (si
);
1707 flags
= DEBUG_ONLY_THIS_PROCESS
;
1708 cygwin_conv_to_win32_path (exec_file
, real_path
);
1714 sh
= getenv ("SHELL");
1717 cygwin_conv_to_win32_path (sh
, shell
);
1718 newallargs
= alloca (sizeof (" -c 'exec '") + strlen (exec_file
)
1719 + strlen (allargs
) + 2);
1720 sprintf (newallargs
, " -c 'exec %s %s'", exec_file
, allargs
);
1721 allargs
= newallargs
;
1723 flags
= DEBUG_PROCESS
;
1727 flags
|= CREATE_NEW_PROCESS_GROUP
;
1730 flags
|= CREATE_NEW_CONSOLE
;
1734 args
= alloca (strlen (toexec
) + strlen (allargs
) + 2);
1735 strcpy (args
, toexec
);
1737 strcat (args
, allargs
);
1739 /* Prepare the environment vars for CreateProcess. */
1741 /* This code used to assume all env vars were file names and would
1742 translate them all to win32 style. That obviously doesn't work in the
1743 general case. The current rule is that we only translate PATH.
1744 We need to handle PATH because we're about to call CreateProcess and
1745 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
1746 in both posix and win32 environments. cygwin.dll will change it back
1747 to posix style if necessary. */
1749 static const char *conv_path_names
[] =
1755 /* CreateProcess takes the environment list as a null terminated set of
1756 strings (i.e. two nulls terminate the list). */
1758 /* Get total size for env strings. */
1759 for (envlen
= 0, i
= 0; env
[i
] && *env
[i
]; i
++)
1763 for (j
= 0; conv_path_names
[j
]; j
++)
1765 len
= strlen (conv_path_names
[j
]);
1766 if (strncmp (conv_path_names
[j
], env
[i
], len
) == 0)
1768 if (cygwin_posix_path_list_p (env
[i
] + len
))
1770 + cygwin_posix_to_win32_path_list_buf_size (env
[i
] + len
);
1772 envlen
+= strlen (env
[i
]) + 1;
1776 if (conv_path_names
[j
] == NULL
)
1777 envlen
+= strlen (env
[i
]) + 1;
1780 winenv
= alloca (envlen
+ 1);
1782 /* Copy env strings into new buffer. */
1783 for (temp
= winenv
, i
= 0; env
[i
] && *env
[i
]; i
++)
1787 for (j
= 0; conv_path_names
[j
]; j
++)
1789 len
= strlen (conv_path_names
[j
]);
1790 if (strncmp (conv_path_names
[j
], env
[i
], len
) == 0)
1792 if (cygwin_posix_path_list_p (env
[i
] + len
))
1794 memcpy (temp
, env
[i
], len
);
1795 cygwin_posix_to_win32_path_list (env
[i
] + len
, temp
+ len
);
1798 strcpy (temp
, env
[i
]);
1802 if (conv_path_names
[j
] == NULL
)
1803 strcpy (temp
, env
[i
]);
1805 temp
+= strlen (temp
) + 1;
1808 /* Final nil string to terminate new env. */
1812 if (!inferior_io_terminal
)
1813 tty
= ostdin
= ostdout
= ostderr
= -1;
1816 tty
= open (inferior_io_terminal
, O_RDWR
| O_NOCTTY
);
1819 print_sys_errmsg (inferior_io_terminal
, errno
);
1820 ostdin
= ostdout
= ostderr
= -1;
1833 ret
= CreateProcess (0,
1834 args
, /* command line */
1835 NULL
, /* Security */
1837 TRUE
, /* inherit handles */
1838 flags
, /* start flags */
1840 NULL
, /* current directory */
1855 error ("Error creating process %s, (error %d)\n", exec_file
, (unsigned) GetLastError ());
1857 CloseHandle (pi
.hThread
);
1858 CloseHandle (pi
.hProcess
);
1860 if (useshell
&& shell
[0] != '\0')
1865 do_initial_child_stuff (pi
.dwProcessId
);
1867 /* child_continue (DBG_CONTINUE, -1); */
1868 proceed ((CORE_ADDR
) - 1, TARGET_SIGNAL_0
, 0);
1872 child_mourn_inferior (void)
1874 (void) child_continue (DBG_CONTINUE
, -1);
1875 i386_cleanup_dregs();
1876 unpush_target (&child_ops
);
1877 generic_mourn_inferior ();
1880 /* Send a SIGINT to the process group. This acts just like the user typed a
1881 ^C on the controlling terminal. */
1886 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
1887 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT
, current_event
.dwProcessId
));
1888 registers_changed (); /* refresh register state */
1892 child_xfer_memory (CORE_ADDR memaddr
, char *our
, int len
,
1893 int write
, struct mem_attrib
*mem
,
1894 struct target_ops
*target
)
1899 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
1900 len
, (DWORD
) memaddr
));
1901 if (!WriteProcessMemory (current_process_handle
, (LPVOID
) memaddr
, our
,
1904 FlushInstructionCache (current_process_handle
, (LPCVOID
) memaddr
, len
);
1908 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
1909 len
, (DWORD
) memaddr
));
1910 if (!ReadProcessMemory (current_process_handle
, (LPCVOID
) memaddr
, our
,
1918 child_kill_inferior (void)
1920 CHECK (TerminateProcess (current_process_handle
, 0));
1924 if (!child_continue (DBG_CONTINUE
, -1))
1926 if (!WaitForDebugEvent (¤t_event
, INFINITE
))
1928 if (current_event
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
)
1932 CHECK (CloseHandle (current_process_handle
));
1934 /* this may fail in an attached process so don't check. */
1935 if (current_thread
&& current_thread
->h
)
1936 (void) CloseHandle (current_thread
->h
);
1937 target_mourn_inferior (); /* or just child_mourn_inferior? */
1941 child_resume (ptid_t ptid
, int step
, enum target_signal sig
)
1944 DWORD continue_status
= DBG_CONTINUE
;
1946 int pid
= PIDGET (ptid
);
1948 if (sig
!= TARGET_SIGNAL_0
)
1950 if (current_event
.dwDebugEventCode
!= EXCEPTION_DEBUG_EVENT
)
1952 DEBUG_EXCEPT(("Cannot continue with signal %d here.\n",sig
));
1954 else if (sig
== last_sig
)
1955 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
1958 /* This code does not seem to work, because
1959 the kernel does probably not consider changes in the ExceptionRecord
1960 structure when passing the exception to the inferior.
1961 Note that this seems possible in the exception handler itself. */
1964 for (i
= 0; xlate
[i
].them
!= -1; i
++)
1965 if (xlate
[i
].us
== sig
)
1967 current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
=
1969 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
1972 if (continue_status
== DBG_CONTINUE
)
1974 DEBUG_EXCEPT(("Cannot continue with signal %d.\n",sig
));
1978 DEBUG_EXCEPT(("Can only continue with recieved signal %d.\n",
1982 last_sig
= TARGET_SIGNAL_0
;
1984 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1987 /* Get context for currently selected thread */
1988 th
= thread_rec (current_event
.dwThreadId
, FALSE
);
1993 /* Single step by setting t bit */
1994 child_fetch_inferior_registers (PS_REGNUM
);
1995 th
->context
.EFlags
|= FLAG_TRACE_BIT
;
1998 if (th
->context
.ContextFlags
)
2000 if (debug_registers_changed
)
2002 th
->context
.Dr0
= dr
[0];
2003 th
->context
.Dr1
= dr
[1];
2004 th
->context
.Dr2
= dr
[2];
2005 th
->context
.Dr3
= dr
[3];
2006 /* th->context.Dr6 = dr[6];
2007 FIXME: should we set dr6 also ?? */
2008 th
->context
.Dr7
= dr
[7];
2010 CHECK (SetThreadContext (th
->h
, &th
->context
));
2011 th
->context
.ContextFlags
= 0;
2015 /* Allow continuing with the same signal that interrupted us.
2016 Otherwise complain. */
2018 child_continue (continue_status
, pid
);
2022 child_prepare_to_store (void)
2024 /* Do nothing, since we can store individual regs */
2028 child_can_run (void)
2036 DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n",
2037 PIDGET (inferior_ptid
)));
2040 struct target_ops child_ops
;
2043 init_child_ops (void)
2045 child_ops
.to_shortname
= "child";
2046 child_ops
.to_longname
= "Win32 child process";
2047 child_ops
.to_doc
= "Win32 child process (started by the \"run\" command).";
2048 child_ops
.to_open
= child_open
;
2049 child_ops
.to_close
= child_close
;
2050 child_ops
.to_attach
= child_attach
;
2051 child_ops
.to_detach
= child_detach
;
2052 child_ops
.to_resume
= child_resume
;
2053 child_ops
.to_wait
= child_wait
;
2054 child_ops
.to_fetch_registers
= child_fetch_inferior_registers
;
2055 child_ops
.to_store_registers
= child_store_inferior_registers
;
2056 child_ops
.to_prepare_to_store
= child_prepare_to_store
;
2057 child_ops
.to_xfer_memory
= child_xfer_memory
;
2058 child_ops
.to_files_info
= child_files_info
;
2059 child_ops
.to_insert_breakpoint
= memory_insert_breakpoint
;
2060 child_ops
.to_remove_breakpoint
= memory_remove_breakpoint
;
2061 child_ops
.to_terminal_init
= terminal_init_inferior
;
2062 child_ops
.to_terminal_inferior
= terminal_inferior
;
2063 child_ops
.to_terminal_ours_for_output
= terminal_ours_for_output
;
2064 child_ops
.to_terminal_ours
= terminal_ours
;
2065 child_ops
.to_terminal_save_ours
= terminal_save_ours
;
2066 child_ops
.to_terminal_info
= child_terminal_info
;
2067 child_ops
.to_kill
= child_kill_inferior
;
2068 child_ops
.to_create_inferior
= child_create_inferior
;
2069 child_ops
.to_mourn_inferior
= child_mourn_inferior
;
2070 child_ops
.to_can_run
= child_can_run
;
2071 child_ops
.to_thread_alive
= win32_child_thread_alive
;
2072 child_ops
.to_pid_to_str
= cygwin_pid_to_str
;
2073 child_ops
.to_stop
= child_stop
;
2074 child_ops
.to_stratum
= process_stratum
;
2075 child_ops
.to_has_all_memory
= 1;
2076 child_ops
.to_has_memory
= 1;
2077 child_ops
.to_has_stack
= 1;
2078 child_ops
.to_has_registers
= 1;
2079 child_ops
.to_has_execution
= 1;
2080 child_ops
.to_magic
= OPS_MAGIC
;
2084 _initialize_win32_nat (void)
2086 struct cmd_list_element
*c
;
2090 c
= add_com ("dll-symbols", class_files
, dll_symbol_command
,
2091 "Load dll library symbols from FILE.");
2092 set_cmd_completer (c
, filename_completer
);
2094 add_com_alias ("sharedlibrary", "dll-symbols", class_alias
, 1);
2096 add_show_from_set (add_set_cmd ("shell", class_support
, var_boolean
,
2098 "Set use of shell to start subprocess.",
2102 add_show_from_set (add_set_cmd ("new-console", class_support
, var_boolean
,
2103 (char *) &new_console
,
2104 "Set creation of new console when creating child process.",
2108 add_show_from_set (add_set_cmd ("new-group", class_support
, var_boolean
,
2109 (char *) &new_group
,
2110 "Set creation of new group when creating child process.",
2114 add_show_from_set (add_set_cmd ("debugexec", class_support
, var_boolean
,
2115 (char *) &debug_exec
,
2116 "Set whether to display execution in child process.",
2120 add_show_from_set (add_set_cmd ("debugevents", class_support
, var_boolean
,
2121 (char *) &debug_events
,
2122 "Set whether to display kernel events in child process.",
2126 add_show_from_set (add_set_cmd ("debugmemory", class_support
, var_boolean
,
2127 (char *) &debug_memory
,
2128 "Set whether to display memory accesses in child process.",
2132 add_show_from_set (add_set_cmd ("debugexceptions", class_support
, var_boolean
,
2133 (char *) &debug_exceptions
,
2134 "Set whether to display kernel exceptions in child process.",
2138 add_info ("dll", info_dll_command
, "Status of loaded DLLs.");
2139 add_info_alias ("sharedlibrary", "dll", 1);
2141 add_prefix_cmd ("w32", class_info
, info_w32_command
,
2142 "Print information specific to Win32 debugging.",
2143 &info_w32_cmdlist
, "info w32 ", 0, &infolist
);
2145 add_cmd ("selector", class_info
, display_selectors
,
2146 "Display selectors infos.",
2149 add_target (&child_ops
);
2152 /* Hardware watchpoint support, adapted from go32-nat.c code. */
2154 /* Pass the address ADDR to the inferior in the I'th debug register.
2155 Here we just store the address in dr array, the registers will be
2156 actually set up when child_continue is called. */
2158 cygwin_set_dr (int i
, CORE_ADDR addr
)
2161 internal_error (__FILE__
, __LINE__
,
2162 "Invalid register %d in cygwin_set_dr.\n", i
);
2163 dr
[i
] = (unsigned) addr
;
2164 debug_registers_changed
= 1;
2165 debug_registers_used
= 1;
2168 /* Pass the value VAL to the inferior in the DR7 debug control
2169 register. Here we just store the address in D_REGS, the watchpoint
2170 will be actually set up in child_wait. */
2172 cygwin_set_dr7 (unsigned val
)
2175 debug_registers_changed
= 1;
2176 debug_registers_used
= 1;
2179 /* Get the value of the DR6 debug status register from the inferior.
2180 Here we just return the value stored in dr[6]
2181 by the last call to thread_rec for current_event.dwThreadId id. */
2183 cygwin_get_dr6 (void)
2188 /* Determine if the thread referenced by "pid" is alive
2189 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
2190 it means that the pid has died. Otherwise it is assumed to be alive. */
2192 win32_child_thread_alive (ptid_t ptid
)
2194 int pid
= PIDGET (ptid
);
2196 return WaitForSingleObject (thread_rec (pid
, FALSE
)->h
, 0) == WAIT_OBJECT_0
?
2200 /* Convert pid to printable format. */
2202 cygwin_pid_to_str (ptid_t ptid
)
2204 static char buf
[80];
2205 int pid
= PIDGET (ptid
);
2207 if ((DWORD
) pid
== current_event
.dwProcessId
)
2208 sprintf (buf
, "process %d", pid
);
2210 sprintf (buf
, "thread %ld.0x%x", current_event
.dwProcessId
, pid
);
2215 core_dll_symbols_add (char *dll_name
, DWORD base_addr
)
2217 struct objfile
*objfile
;
2218 char *objfile_basename
;
2219 const char *dll_basename
;
2221 if (!(dll_basename
= strrchr (dll_name
, '/')))
2222 dll_basename
= dll_name
;
2226 ALL_OBJFILES (objfile
)
2228 objfile_basename
= strrchr (objfile
->name
, '/');
2230 if (objfile_basename
&&
2231 strcmp (dll_basename
, objfile_basename
+ 1) == 0)
2233 printf_unfiltered ("%08lx:%s (symbols previously loaded)\n",
2234 base_addr
, dll_name
);
2239 register_loaded_dll (dll_name
, base_addr
+ 0x1000);
2240 solib_symbols_add (dll_name
, 0, (CORE_ADDR
) base_addr
+ 0x1000);
2248 struct target_ops
*target
;
2250 } map_code_section_args
;
2253 map_single_dll_code_section (bfd
* abfd
, asection
* sect
, void *obj
)
2257 struct section_table
*new_target_sect_ptr
;
2259 map_code_section_args
*args
= (map_code_section_args
*) obj
;
2260 struct target_ops
*target
= args
->target
;
2261 if (sect
->flags
& SEC_CODE
)
2263 update_coreops
= core_ops
.to_sections
== target
->to_sections
;
2265 if (target
->to_sections
)
2267 old
= target
->to_sections_end
- target
->to_sections
;
2268 target
->to_sections
= (struct section_table
*)
2269 xrealloc ((char *) target
->to_sections
,
2270 (sizeof (struct section_table
)) * (1 + old
));
2275 target
->to_sections
= (struct section_table
*)
2276 xmalloc ((sizeof (struct section_table
)));
2278 target
->to_sections_end
= target
->to_sections
+ (1 + old
);
2280 /* Update the to_sections field in the core_ops structure
2284 core_ops
.to_sections
= target
->to_sections
;
2285 core_ops
.to_sections_end
= target
->to_sections_end
;
2287 new_target_sect_ptr
= target
->to_sections
+ old
;
2288 new_target_sect_ptr
->addr
= args
->addr
+ bfd_section_vma (abfd
, sect
);
2289 new_target_sect_ptr
->endaddr
= args
->addr
+ bfd_section_vma (abfd
, sect
) +
2290 bfd_section_size (abfd
, sect
);;
2291 new_target_sect_ptr
->the_bfd_section
= sect
;
2292 new_target_sect_ptr
->bfd
= abfd
;
2297 dll_code_sections_add (const char *dll_name
, int base_addr
, struct target_ops
*target
)
2300 map_code_section_args map_args
;
2301 asection
*lowest_sect
;
2303 if (dll_name
== NULL
|| target
== NULL
)
2305 name
= xstrdup (dll_name
);
2306 dll_bfd
= bfd_openr (name
, "pei-i386");
2307 if (dll_bfd
== NULL
)
2310 if (bfd_check_format (dll_bfd
, bfd_object
))
2312 lowest_sect
= bfd_get_section_by_name (dll_bfd
, ".text");
2313 if (lowest_sect
== NULL
)
2315 map_args
.target
= target
;
2316 map_args
.addr
= base_addr
- bfd_section_vma (dll_bfd
, lowest_sect
);
2318 bfd_map_over_sections (dll_bfd
, &map_single_dll_code_section
, (void *) (&map_args
));
2325 core_section_load_dll_symbols (bfd
* abfd
, asection
* sect
, void *obj
)
2327 struct target_ops
*target
= (struct target_ops
*) obj
;
2332 char *dll_name
= NULL
;
2334 struct win32_pstatus
*pstatus
;
2337 if (strncmp (sect
->name
, ".module", 7))
2340 buf
= (char *) xmalloc (bfd_get_section_size (sect
) + 1);
2343 printf_unfiltered ("memory allocation failed for %s\n", sect
->name
);
2346 if (!bfd_get_section_contents (abfd
, sect
, buf
, 0, bfd_get_section_size (sect
)))
2349 pstatus
= (struct win32_pstatus
*) buf
;
2351 memmove (&base_addr
, &(pstatus
->data
.module_info
.base_address
), sizeof (base_addr
));
2352 dll_name_size
= pstatus
->data
.module_info
.module_name_size
;
2353 if (offsetof (struct win32_pstatus
, data
.module_info
.module_name
) + dll_name_size
> bfd_get_section_size (sect
))
2356 dll_name
= (char *) xmalloc (dll_name_size
+ 1);
2359 printf_unfiltered ("memory allocation failed for %s\n", sect
->name
);
2362 strncpy (dll_name
, pstatus
->data
.module_info
.module_name
, dll_name_size
);
2364 while ((p
= strchr (dll_name
, '\\')))
2367 if (!core_dll_symbols_add (dll_name
, (DWORD
) base_addr
))
2368 printf_unfiltered ("%s: Failed to load dll symbols.\n", dll_name
);
2370 if (!dll_code_sections_add (dll_name
, (DWORD
) base_addr
+ 0x1000, target
))
2371 printf_unfiltered ("%s: Failed to map dll code sections.\n", dll_name
);
2382 child_solib_add (char *filename
, int from_tty
, struct target_ops
*target
,
2389 child_clear_solibs ();
2390 bfd_map_over_sections (core_bfd
, &core_section_load_dll_symbols
, target
);
2394 if (solib_end
&& solib_end
->name
)
2395 solib_end
->objfile
= solib_symbols_add (solib_end
->name
, from_tty
,
2396 solib_end
->load_addr
);
2401 fetch_elf_core_registers (char *core_reg_sect
,
2402 unsigned core_reg_size
,
2407 if (core_reg_size
< sizeof (CONTEXT
))
2409 error ("Core file register section too small (%u bytes).", core_reg_size
);
2412 for (r
= 0; r
< NUM_REGS
; r
++)
2413 supply_register (r
, core_reg_sect
+ mappings
[r
]);
2416 static struct core_fns win32_elf_core_fns
=
2418 bfd_target_elf_flavour
,
2419 default_check_format
,
2420 default_core_sniffer
,
2421 fetch_elf_core_registers
,
2426 _initialize_core_win32 (void)
2428 deprecated_add_core_fns (&win32_elf_core_fns
);
2432 _initialize_check_for_gdb_ini (void)
2435 if (inhibit_gdbinit
)
2438 homedir
= getenv ("HOME");
2442 char *oldini
= (char *) alloca (strlen (homedir
) +
2443 sizeof ("/gdb.ini"));
2444 strcpy (oldini
, homedir
);
2445 p
= strchr (oldini
, '\0');
2446 if (p
> oldini
&& p
[-1] != '/')
2448 strcpy (p
, "gdb.ini");
2449 if (access (oldini
, 0) == 0)
2451 int len
= strlen (oldini
);
2452 char *newini
= alloca (len
+ 1);
2453 sprintf (newini
, "%.*s.gdbinit",
2454 (int) (len
- (sizeof ("gdb.ini") - 1)), oldini
);
2455 warning ("obsolete '%s' found. Rename to '%s'.", oldini
, newini
);