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 */
33 #include "exceptions.h"
36 #include "completer.h"
40 #include <sys/types.h>
45 #include <sys/cygwin.h>
50 #include "gdb_string.h"
51 #include "gdbthread.h"
53 #include <sys/param.h>
57 #include "i386-tdep.h"
58 #include "i387-tdep.h"
60 /* If we're not using the old Cygwin header file set, define the
61 following which never should have been in the generic Win32 API
62 headers in the first place since they were our own invention... */
63 #ifndef _GNU_H_WINDOWS_H
66 FLAG_TRACE_BIT
= 0x100,
67 CONTEXT_DEBUGGER
= (CONTEXT_FULL
| CONTEXT_FLOATING_POINT
)
70 #include <sys/procfs.h>
73 #define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \
74 | CONTEXT_EXTENDED_REGISTERS
76 static unsigned dr
[8];
77 static int debug_registers_changed
;
78 static int debug_registers_used
;
80 /* The string sent by cygwin when it processes a signal.
81 FIXME: This should be in a cygwin include file. */
82 #define CYGWIN_SIGNAL_STRING "cygwin: signal"
84 #define CHECK(x) check (x, __FILE__,__LINE__)
85 #define DEBUG_EXEC(x) if (debug_exec) printf_unfiltered x
86 #define DEBUG_EVENTS(x) if (debug_events) printf_unfiltered x
87 #define DEBUG_MEM(x) if (debug_memory) printf_unfiltered x
88 #define DEBUG_EXCEPT(x) if (debug_exceptions) printf_unfiltered x
90 static void child_stop (void);
91 static int win32_child_thread_alive (ptid_t
);
92 void child_kill_inferior (void);
94 static enum target_signal last_sig
= TARGET_SIGNAL_0
;
95 /* Set if a signal was received from the debugged process */
97 /* Thread information structure used to track information that is
98 not available in gdb's thread structure. */
99 typedef struct thread_info_struct
101 struct thread_info_struct
*next
;
112 static thread_info thread_head
;
114 /* The process and thread handles for the above context. */
116 static DEBUG_EVENT current_event
; /* The current debug event from
118 static HANDLE current_process_handle
; /* Currently executing process */
119 static thread_info
*current_thread
; /* Info on currently selected thread */
120 static DWORD main_thread_id
; /* Thread ID of the main thread */
122 /* Counts of things. */
123 static int exception_count
= 0;
124 static int event_count
= 0;
125 static int saw_create
;
128 static int new_console
= 0;
129 static int new_group
= 1;
130 static int debug_exec
= 0; /* show execution */
131 static int debug_events
= 0; /* show events from kernel */
132 static int debug_memory
= 0; /* show target memory accesses */
133 static int debug_exceptions
= 0; /* show target exceptions */
134 static int useshell
= 0; /* use shell for subprocesses */
136 /* This vector maps GDB's idea of a register's number into an address
137 in the win32 exception context vector.
139 It also contains the bit mask needed to load the register in question.
141 One day we could read a reg, we could inspect the context we
142 already have loaded, if it doesn't have the bit set that we need,
143 we read that set of registers in using GetThreadContext. If the
144 context already contains what we need, we just unpack it. Then to
145 write a register, first we have to ensure that the context contains
146 the other regs of the group, and then we copy the info in and set
149 #define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
150 static const int mappings
[] =
152 context_offset (Eax
),
153 context_offset (Ecx
),
154 context_offset (Edx
),
155 context_offset (Ebx
),
156 context_offset (Esp
),
157 context_offset (Ebp
),
158 context_offset (Esi
),
159 context_offset (Edi
),
160 context_offset (Eip
),
161 context_offset (EFlags
),
162 context_offset (SegCs
),
163 context_offset (SegSs
),
164 context_offset (SegDs
),
165 context_offset (SegEs
),
166 context_offset (SegFs
),
167 context_offset (SegGs
),
168 context_offset (FloatSave
.RegisterArea
[0 * 10]),
169 context_offset (FloatSave
.RegisterArea
[1 * 10]),
170 context_offset (FloatSave
.RegisterArea
[2 * 10]),
171 context_offset (FloatSave
.RegisterArea
[3 * 10]),
172 context_offset (FloatSave
.RegisterArea
[4 * 10]),
173 context_offset (FloatSave
.RegisterArea
[5 * 10]),
174 context_offset (FloatSave
.RegisterArea
[6 * 10]),
175 context_offset (FloatSave
.RegisterArea
[7 * 10]),
176 context_offset (FloatSave
.ControlWord
),
177 context_offset (FloatSave
.StatusWord
),
178 context_offset (FloatSave
.TagWord
),
179 context_offset (FloatSave
.ErrorSelector
),
180 context_offset (FloatSave
.ErrorOffset
),
181 context_offset (FloatSave
.DataSelector
),
182 context_offset (FloatSave
.DataOffset
),
183 context_offset (FloatSave
.ErrorSelector
)
185 context_offset (ExtendedRegisters
[10*16]),
186 context_offset (ExtendedRegisters
[11*16]),
187 context_offset (ExtendedRegisters
[12*16]),
188 context_offset (ExtendedRegisters
[13*16]),
189 context_offset (ExtendedRegisters
[14*16]),
190 context_offset (ExtendedRegisters
[15*16]),
191 context_offset (ExtendedRegisters
[16*16]),
192 context_offset (ExtendedRegisters
[17*16]),
194 context_offset (ExtendedRegisters
[24])
197 #undef context_offset
199 /* This vector maps the target's idea of an exception (extracted
200 from the DEBUG_EVENT structure) to GDB's idea. */
202 struct xlate_exception
205 enum target_signal us
;
208 static const struct xlate_exception
211 {EXCEPTION_ACCESS_VIOLATION
, TARGET_SIGNAL_SEGV
},
212 {STATUS_STACK_OVERFLOW
, TARGET_SIGNAL_SEGV
},
213 {EXCEPTION_BREAKPOINT
, TARGET_SIGNAL_TRAP
},
214 {DBG_CONTROL_C
, TARGET_SIGNAL_INT
},
215 {EXCEPTION_SINGLE_STEP
, TARGET_SIGNAL_TRAP
},
216 {STATUS_FLOAT_DIVIDE_BY_ZERO
, TARGET_SIGNAL_FPE
},
220 check (BOOL ok
, const char *file
, int line
)
223 printf_filtered ("error return %s:%d was %lu\n", file
, line
,
227 /* Find a thread record given a thread id.
228 If get_context then also retrieve the context for this
231 thread_rec (DWORD id
, int get_context
)
235 for (th
= &thread_head
; (th
= th
->next
) != NULL
;)
238 if (!th
->suspend_count
&& get_context
)
240 if (get_context
> 0 && id
!= current_event
.dwThreadId
)
241 th
->suspend_count
= SuspendThread (th
->h
) + 1;
242 else if (get_context
< 0)
243 th
->suspend_count
= -1;
244 th
->reload_context
= 1;
252 /* Add a thread to the thread list */
254 child_add_thread (DWORD id
, HANDLE h
)
258 if ((th
= thread_rec (id
, FALSE
)))
261 th
= (thread_info
*) xmalloc (sizeof (*th
));
262 memset (th
, 0, sizeof (*th
));
265 th
->next
= thread_head
.next
;
266 thread_head
.next
= th
;
267 add_thread (pid_to_ptid (id
));
268 /* Set the debug registers for the new thread in they are used. */
269 if (debug_registers_used
)
271 /* Only change the value of the debug registers. */
272 th
->context
.ContextFlags
= CONTEXT_DEBUG_REGISTERS
;
273 CHECK (GetThreadContext (th
->h
, &th
->context
));
274 th
->context
.Dr0
= dr
[0];
275 th
->context
.Dr1
= dr
[1];
276 th
->context
.Dr2
= dr
[2];
277 th
->context
.Dr3
= dr
[3];
278 /* th->context.Dr6 = dr[6];
279 FIXME: should we set dr6 also ?? */
280 th
->context
.Dr7
= dr
[7];
281 CHECK (SetThreadContext (th
->h
, &th
->context
));
282 th
->context
.ContextFlags
= 0;
287 /* Clear out any old thread list and reintialize it to a
290 child_init_thread_list (void)
292 thread_info
*th
= &thread_head
;
294 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
296 while (th
->next
!= NULL
)
298 thread_info
*here
= th
->next
;
299 th
->next
= here
->next
;
300 (void) CloseHandle (here
->h
);
305 /* Delete a thread from the list of threads */
307 child_delete_thread (DWORD id
)
312 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (pid_to_ptid (id
)));
313 delete_thread (pid_to_ptid (id
));
315 for (th
= &thread_head
;
316 th
->next
!= NULL
&& th
->next
->id
!= id
;
320 if (th
->next
!= NULL
)
322 thread_info
*here
= th
->next
;
323 th
->next
= here
->next
;
324 CloseHandle (here
->h
);
330 do_child_fetch_inferior_registers (int r
)
332 char *context_offset
= ((char *) ¤t_thread
->context
) + mappings
[r
];
336 return; /* Windows sometimes uses a non-existent thread id in its
339 if (current_thread
->reload_context
)
341 thread_info
*th
= current_thread
;
342 th
->context
.ContextFlags
= CONTEXT_DEBUGGER_DR
;
343 GetThreadContext (th
->h
, &th
->context
);
344 /* Copy dr values from that thread. */
345 dr
[0] = th
->context
.Dr0
;
346 dr
[1] = th
->context
.Dr1
;
347 dr
[2] = th
->context
.Dr2
;
348 dr
[3] = th
->context
.Dr3
;
349 dr
[6] = th
->context
.Dr6
;
350 dr
[7] = th
->context
.Dr7
;
351 current_thread
->reload_context
= 0;
354 #define I387_ST0_REGNUM I386_ST0_REGNUM
356 if (r
== I387_FISEG_REGNUM
)
358 l
= *((long *) context_offset
) & 0xffff;
359 regcache_raw_supply (current_regcache
, r
, (char *) &l
);
361 else if (r
== I387_FOP_REGNUM
)
363 l
= (*((long *) context_offset
) >> 16) & ((1 << 11) - 1);
364 regcache_raw_supply (current_regcache
, r
, (char *) &l
);
367 regcache_raw_supply (current_regcache
, r
, context_offset
);
370 for (r
= 0; r
< NUM_REGS
; r
++)
371 do_child_fetch_inferior_registers (r
);
374 #undef I387_ST0_REGNUM
378 child_fetch_inferior_registers (int r
)
380 current_thread
= thread_rec (PIDGET (inferior_ptid
), TRUE
);
381 /* Check if current_thread exists. Windows sometimes uses a non-existent
382 thread id in its events */
384 do_child_fetch_inferior_registers (r
);
388 do_child_store_inferior_registers (int r
)
391 /* Windows sometimes uses a non-existent thread id in its events */;
393 regcache_raw_collect (current_regcache
, r
,
394 ((char *) ¤t_thread
->context
) + mappings
[r
]);
397 for (r
= 0; r
< NUM_REGS
; r
++)
398 do_child_store_inferior_registers (r
);
402 /* Store a new register value into the current thread context */
404 child_store_inferior_registers (int r
)
406 current_thread
= thread_rec (PIDGET (inferior_ptid
), TRUE
);
407 /* Check if current_thread exists. Windows sometimes uses a non-existent
408 thread id in its events */
410 do_child_store_inferior_registers (r
);
413 static int psapi_loaded
= 0;
414 static HMODULE psapi_module_handle
= NULL
;
415 static BOOL
WINAPI (*psapi_EnumProcessModules
) (HANDLE
, HMODULE
*, DWORD
, LPDWORD
) = NULL
;
416 static BOOL
WINAPI (*psapi_GetModuleInformation
) (HANDLE
, HMODULE
, LPMODULEINFO
, DWORD
) = NULL
;
417 static DWORD
WINAPI (*psapi_GetModuleFileNameExA
) (HANDLE
, HMODULE
, LPSTR
, DWORD
) = NULL
;
420 psapi_get_dll_name (DWORD BaseAddress
, char *dll_name_ret
)
426 HMODULE
*DllHandle
= dh_buf
;
431 psapi_EnumProcessModules
== NULL
||
432 psapi_GetModuleInformation
== NULL
||
433 psapi_GetModuleFileNameExA
== NULL
)
438 psapi_module_handle
= LoadLibrary ("psapi.dll");
439 if (!psapi_module_handle
)
441 /* printf_unfiltered ("error loading psapi.dll: %u", GetLastError ()); */
444 psapi_EnumProcessModules
= GetProcAddress (psapi_module_handle
, "EnumProcessModules");
445 psapi_GetModuleInformation
= GetProcAddress (psapi_module_handle
, "GetModuleInformation");
446 psapi_GetModuleFileNameExA
= (void *) GetProcAddress (psapi_module_handle
,
447 "GetModuleFileNameExA");
448 if (psapi_EnumProcessModules
== NULL
||
449 psapi_GetModuleInformation
== NULL
||
450 psapi_GetModuleFileNameExA
== NULL
)
455 ok
= (*psapi_EnumProcessModules
) (current_process_handle
,
460 if (!ok
|| !cbNeeded
)
463 DllHandle
= (HMODULE
*) alloca (cbNeeded
);
467 ok
= (*psapi_EnumProcessModules
) (current_process_handle
,
474 for (i
= 0; i
< (int) (cbNeeded
/ sizeof (HMODULE
)); i
++)
476 if (!(*psapi_GetModuleInformation
) (current_process_handle
,
480 error ("Can't get module info");
482 len
= (*psapi_GetModuleFileNameExA
) (current_process_handle
,
487 error ("Error getting dll name: %u\n", (unsigned) GetLastError ());
489 if ((DWORD
) (mi
.lpBaseOfDll
) == BaseAddress
)
494 dll_name_ret
[0] = '\0';
498 /* Encapsulate the information required in a call to
499 symbol_file_add_args */
500 struct safe_symbol_file_add_args
504 struct section_addr_info
*addrs
;
507 struct ui_file
*err
, *out
;
511 /* Maintain a linked list of "so" information. */
514 struct so_stuff
*next
;
518 struct objfile
*objfile
;
520 } solib_start
, *solib_end
;
522 /* Call symbol_file_add with stderr redirected. We don't care if there
525 safe_symbol_file_add_stub (void *argv
)
527 #define p ((struct safe_symbol_file_add_args *)argv)
528 struct so_stuff
*so
= &solib_start
;
530 while ((so
= so
->next
))
531 if (so
->loaded
&& strcasecmp (so
->name
, p
->name
) == 0)
533 p
->ret
= symbol_file_add (p
->name
, p
->from_tty
, p
->addrs
, p
->mainline
, p
->flags
);
538 /* Restore gdb's stderr after calling symbol_file_add */
540 safe_symbol_file_add_cleanup (void *p
)
542 #define sp ((struct safe_symbol_file_add_args *)p)
543 gdb_flush (gdb_stderr
);
544 gdb_flush (gdb_stdout
);
545 ui_file_delete (gdb_stderr
);
546 ui_file_delete (gdb_stdout
);
547 gdb_stderr
= sp
->err
;
548 gdb_stdout
= sp
->out
;
552 /* symbol_file_add wrapper that prevents errors from being displayed. */
553 static struct objfile
*
554 safe_symbol_file_add (char *name
, int from_tty
,
555 struct section_addr_info
*addrs
,
556 int mainline
, int flags
)
558 struct safe_symbol_file_add_args p
;
559 struct cleanup
*cleanup
;
561 cleanup
= make_cleanup (safe_symbol_file_add_cleanup
, &p
);
565 gdb_flush (gdb_stderr
);
566 gdb_flush (gdb_stdout
);
567 gdb_stderr
= ui_file_new ();
568 gdb_stdout
= ui_file_new ();
570 p
.from_tty
= from_tty
;
572 p
.mainline
= mainline
;
574 catch_errors (safe_symbol_file_add_stub
, &p
, "", RETURN_MASK_ERROR
);
576 do_cleanups (cleanup
);
580 /* Remember the maximum DLL length for printing in info dll command. */
581 int max_dll_name_len
;
584 register_loaded_dll (const char *name
, DWORD load_addr
)
587 char ppath
[MAX_PATH
+ 1];
588 char buf
[MAX_PATH
+ 1];
589 char cwd
[MAX_PATH
+ 1];
591 WIN32_FIND_DATA w32_fd
;
592 HANDLE h
= FindFirstFile(name
, &w32_fd
);
593 MEMORY_BASIC_INFORMATION m
;
596 if (h
== INVALID_HANDLE_VALUE
)
602 if (GetCurrentDirectory (MAX_PATH
+ 1, cwd
))
604 p
= strrchr (buf
, '\\');
607 SetCurrentDirectory (buf
);
608 GetFullPathName (w32_fd
.cFileName
, MAX_PATH
, buf
, &p
);
609 SetCurrentDirectory (cwd
);
613 cygwin_conv_to_posix_path (buf
, ppath
);
614 so
= (struct so_stuff
*) xmalloc (sizeof (struct so_stuff
) + strlen (ppath
) + 8 + 1);
616 so
->load_addr
= load_addr
;
617 if (VirtualQueryEx (current_process_handle
, (void *) load_addr
, &m
,
619 so
->end_addr
= (DWORD
) m
.AllocationBase
+ m
.RegionSize
;
621 so
->end_addr
= load_addr
+ 0x2000; /* completely arbitrary */
625 strcpy (so
->name
, ppath
);
627 solib_end
->next
= so
;
629 len
= strlen (ppath
);
630 if (len
> max_dll_name_len
)
631 max_dll_name_len
= len
;
635 get_image_name (HANDLE h
, void *address
, int unicode
)
637 static char buf
[(2 * MAX_PATH
) + 1];
638 DWORD size
= unicode
? sizeof (WCHAR
) : sizeof (char);
644 /* Attempt to read the name of the dll that was detected.
645 This is documented to work only when actively debugging
646 a program. It will not work for attached processes. */
650 /* See if we could read the address of a string, and that the
651 address isn't null. */
652 if (!ReadProcessMemory (h
, address
, &address_ptr
, sizeof (address_ptr
), &done
)
653 || done
!= sizeof (address_ptr
) || !address_ptr
)
656 /* Find the length of the string */
657 while (ReadProcessMemory (h
, address_ptr
+ len
++ * size
, &b
, size
, &done
)
658 && (b
[0] != 0 || b
[size
- 1] != 0) && done
== size
)
662 ReadProcessMemory (h
, address_ptr
, buf
, len
, &done
);
665 WCHAR
*unicode_address
= (WCHAR
*) alloca (len
* sizeof (WCHAR
));
666 ReadProcessMemory (h
, address_ptr
, unicode_address
, len
* sizeof (WCHAR
),
669 WideCharToMultiByte (CP_ACP
, 0, unicode_address
, len
, buf
, len
, 0, 0);
675 /* Wait for child to do something. Return pid of child, or -1 in case
676 of error; store status through argument pointer OURSTATUS. */
678 handle_load_dll (void *dummy
)
680 LOAD_DLL_DEBUG_INFO
*event
= ¤t_event
.u
.LoadDll
;
681 char dll_buf
[MAX_PATH
+ 1];
682 char *dll_name
= NULL
;
685 dll_buf
[0] = dll_buf
[sizeof (dll_buf
) - 1] = '\0';
687 if (!psapi_get_dll_name ((DWORD
) (event
->lpBaseOfDll
), dll_buf
))
688 dll_buf
[0] = dll_buf
[sizeof (dll_buf
) - 1] = '\0';
692 if (*dll_name
== '\0')
693 dll_name
= get_image_name (current_process_handle
, event
->lpImageName
, event
->fUnicode
);
697 register_loaded_dll (dll_name
, (DWORD
) event
->lpBaseOfDll
+ 0x1000);
703 handle_unload_dll (void *dummy
)
705 DWORD lpBaseOfDll
= (DWORD
) current_event
.u
.UnloadDll
.lpBaseOfDll
+ 0x1000;
708 for (so
= &solib_start
; so
->next
!= NULL
; so
= so
->next
)
709 if (so
->next
->load_addr
== lpBaseOfDll
)
711 struct so_stuff
*sodel
= so
->next
;
712 so
->next
= sodel
->next
;
716 free_objfile (sodel
->objfile
);
720 error ("Error: dll starting at 0x%lx not found.\n", (DWORD
) lpBaseOfDll
);
726 solib_address (CORE_ADDR address
)
729 for (so
= &solib_start
; so
->next
!= NULL
; so
= so
->next
)
730 if (address
>= so
->load_addr
&& address
<= so
->end_addr
)
735 /* Return name of last loaded DLL. */
737 child_solib_loaded_library_pathname (int pid
)
739 return !solib_end
|| !solib_end
->name
[0] ? NULL
: solib_end
->name
;
742 /* Clear list of loaded DLLs. */
744 child_clear_solibs (void)
746 struct so_stuff
*so
, *so1
= solib_start
.next
;
748 while ((so
= so1
) != NULL
)
754 solib_start
.next
= NULL
;
755 solib_start
.objfile
= NULL
;
756 solib_end
= &solib_start
;
757 max_dll_name_len
= sizeof ("DLL Name") - 1;
760 /* Get the loaded address of all sections, given that .text was loaded
761 at text_load. Assumes that all sections are subject to the same
762 relocation offset. Returns NULL if problems occur or if the
763 sections were not relocated. */
765 static struct section_addr_info
*
766 get_relocated_section_addrs (bfd
*abfd
, CORE_ADDR text_load
)
768 struct section_addr_info
*result
= NULL
;
769 int section_count
= bfd_count_sections (abfd
);
770 asection
*text_section
= bfd_get_section_by_name (abfd
, ".text");
775 /* Couldn't get the .text section. Weird. */
778 else if (text_load
== (text_vma
= bfd_get_section_vma (abfd
, text_section
)))
780 /* DLL wasn't relocated. */
785 /* Figure out all sections' loaded addresses. The offset here is
786 such that taking a bfd_get_section_vma() result and adding
787 offset will give the real load address of the section. */
789 CORE_ADDR offset
= text_load
- text_vma
;
791 struct section_table
*table_start
= NULL
;
792 struct section_table
*table_end
= NULL
;
793 struct section_table
*iter
= NULL
;
795 build_section_table (abfd
, &table_start
, &table_end
);
797 for (iter
= table_start
; iter
< table_end
; ++iter
)
799 /* Relocated addresses. */
800 iter
->addr
+= offset
;
801 iter
->endaddr
+= offset
;
804 result
= build_section_addr_info_from_section_table (table_start
,
813 /* Add DLL symbol information. */
814 static struct objfile
*
815 solib_symbols_add (char *name
, int from_tty
, CORE_ADDR load_addr
)
817 struct section_addr_info
*addrs
= NULL
;
818 static struct objfile
*result
= NULL
;
821 /* The symbols in a dll are offset by 0x1000, which is the
822 the offset from 0 of the first byte in an image - because
823 of the file header and the section alignment. */
825 if (!name
|| !name
[0])
828 abfd
= bfd_openr (name
, "pei-i386");
832 /* pei failed - try pe */
833 abfd
= bfd_openr (name
, "pe-i386");
838 if (bfd_check_format (abfd
, bfd_object
))
840 addrs
= get_relocated_section_addrs (abfd
, load_addr
);
848 result
= safe_symbol_file_add (name
, from_tty
, addrs
, 0, OBJF_SHARED
);
849 free_section_addr_info (addrs
);
853 /* Fallback on handling just the .text section. */
854 struct cleanup
*my_cleanups
;
856 addrs
= alloc_section_addr_info (1);
857 my_cleanups
= make_cleanup (xfree
, addrs
);
858 addrs
->other
[0].name
= ".text";
859 addrs
->other
[0].addr
= load_addr
;
861 result
= safe_symbol_file_add (name
, from_tty
, addrs
, 0, OBJF_SHARED
);
862 do_cleanups (my_cleanups
);
868 /* Load DLL symbol info. */
870 dll_symbol_command (char *args
, int from_tty
)
876 error ("dll-symbols requires a file name");
879 if (n
> 4 && strcasecmp (args
+ n
- 4, ".dll") != 0)
881 char *newargs
= (char *) alloca (n
+ 4 + 1);
882 strcpy (newargs
, args
);
883 strcat (newargs
, ".dll");
887 safe_symbol_file_add (args
, from_tty
, NULL
, 0, OBJF_SHARED
| OBJF_USERLOADED
);
890 /* List currently loaded DLLs. */
892 info_dll_command (char *ignore
, int from_tty
)
894 struct so_stuff
*so
= &solib_start
;
899 printf_filtered ("%*s Load Address\n", -max_dll_name_len
, "DLL Name");
900 while ((so
= so
->next
) != NULL
)
901 printf_filtered ("%*s %08lx\n", -max_dll_name_len
, so
->name
, so
->load_addr
);
906 /* Handle DEBUG_STRING output from child process.
907 Cygwin prepends its messages with a "cygwin:". Interpret this as
908 a Cygwin signal. Otherwise just print the string as a warning. */
910 handle_output_debug_string (struct target_waitstatus
*ourstatus
)
915 if (!target_read_string
916 ((CORE_ADDR
) current_event
.u
.DebugString
.lpDebugStringData
, &s
, 1024, 0)
920 if (strncmp (s
, CYGWIN_SIGNAL_STRING
, sizeof (CYGWIN_SIGNAL_STRING
) - 1) != 0)
922 if (strncmp (s
, "cYg", 3) != 0)
928 int sig
= strtol (s
+ sizeof (CYGWIN_SIGNAL_STRING
) - 1, &p
, 0);
929 gotasig
= target_signal_from_host (sig
);
930 ourstatus
->value
.sig
= gotasig
;
932 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
940 display_selector (HANDLE thread
, DWORD sel
)
943 if (GetThreadSelectorEntry (thread
, sel
, &info
))
946 printf_filtered ("0x%03lx: ", sel
);
947 if (!info
.HighWord
.Bits
.Pres
)
949 puts_filtered ("Segment not present\n");
952 base
= (info
.HighWord
.Bits
.BaseHi
<< 24) +
953 (info
.HighWord
.Bits
.BaseMid
<< 16)
955 limit
= (info
.HighWord
.Bits
.LimitHi
<< 16) + info
.LimitLow
;
956 if (info
.HighWord
.Bits
.Granularity
)
957 limit
= (limit
<< 12) | 0xfff;
958 printf_filtered ("base=0x%08x limit=0x%08x", base
, limit
);
959 if (info
.HighWord
.Bits
.Default_Big
)
960 puts_filtered(" 32-bit ");
962 puts_filtered(" 16-bit ");
963 switch ((info
.HighWord
.Bits
.Type
& 0xf) >> 1)
966 puts_filtered ("Data (Read-Only, Exp-up");
969 puts_filtered ("Data (Read/Write, Exp-up");
972 puts_filtered ("Unused segment (");
975 puts_filtered ("Data (Read/Write, Exp-down");
978 puts_filtered ("Code (Exec-Only, N.Conf");
981 puts_filtered ("Code (Exec/Read, N.Conf");
984 puts_filtered ("Code (Exec-Only, Conf");
987 puts_filtered ("Code (Exec/Read, Conf");
990 printf_filtered ("Unknown type 0x%x",info
.HighWord
.Bits
.Type
);
992 if ((info
.HighWord
.Bits
.Type
& 0x1) == 0)
993 puts_filtered(", N.Acc");
994 puts_filtered (")\n");
995 if ((info
.HighWord
.Bits
.Type
& 0x10) == 0)
996 puts_filtered("System selector ");
997 printf_filtered ("Priviledge level = %d. ", info
.HighWord
.Bits
.Dpl
);
998 if (info
.HighWord
.Bits
.Granularity
)
999 puts_filtered ("Page granular.\n");
1001 puts_filtered ("Byte granular.\n");
1006 printf_filtered ("Invalid selector 0x%lx.\n",sel
);
1012 display_selectors (char * args
, int from_tty
)
1014 if (!current_thread
)
1016 puts_filtered ("Impossible to display selectors now.\n");
1022 puts_filtered ("Selector $cs\n");
1023 display_selector (current_thread
->h
,
1024 current_thread
->context
.SegCs
);
1025 puts_filtered ("Selector $ds\n");
1026 display_selector (current_thread
->h
,
1027 current_thread
->context
.SegDs
);
1028 puts_filtered ("Selector $es\n");
1029 display_selector (current_thread
->h
,
1030 current_thread
->context
.SegEs
);
1031 puts_filtered ("Selector $ss\n");
1032 display_selector (current_thread
->h
,
1033 current_thread
->context
.SegSs
);
1034 puts_filtered ("Selector $fs\n");
1035 display_selector (current_thread
->h
,
1036 current_thread
->context
.SegFs
);
1037 puts_filtered ("Selector $gs\n");
1038 display_selector (current_thread
->h
,
1039 current_thread
->context
.SegGs
);
1044 sel
= parse_and_eval_long (args
);
1045 printf_filtered ("Selector \"%s\"\n",args
);
1046 display_selector (current_thread
->h
, sel
);
1050 static struct cmd_list_element
*info_w32_cmdlist
= NULL
;
1053 info_w32_command (char *args
, int from_tty
)
1055 help_list (info_w32_cmdlist
, "info w32 ", class_info
, gdb_stdout
);
1059 #define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \
1060 printf_unfiltered ("gdb: Target exception %s at 0x%08lx\n", x, \
1061 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress)
1064 handle_exception (struct target_waitstatus
*ourstatus
)
1067 DWORD code
= current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
;
1069 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
1071 /* Record the context of the current thread */
1072 th
= thread_rec (current_event
.dwThreadId
, -1);
1076 case EXCEPTION_ACCESS_VIOLATION
:
1077 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
1078 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
1080 case STATUS_STACK_OVERFLOW
:
1081 DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
1082 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
1084 case STATUS_FLOAT_DENORMAL_OPERAND
:
1085 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
1086 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1088 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED
:
1089 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
1090 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1092 case STATUS_FLOAT_INEXACT_RESULT
:
1093 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
1094 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1096 case STATUS_FLOAT_INVALID_OPERATION
:
1097 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
1098 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1100 case STATUS_FLOAT_OVERFLOW
:
1101 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
1102 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1104 case STATUS_FLOAT_STACK_CHECK
:
1105 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
1106 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1108 case STATUS_FLOAT_UNDERFLOW
:
1109 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
1110 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1112 case STATUS_FLOAT_DIVIDE_BY_ZERO
:
1113 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
1114 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1116 case STATUS_INTEGER_DIVIDE_BY_ZERO
:
1117 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
1118 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1120 case STATUS_INTEGER_OVERFLOW
:
1121 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
1122 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1124 case EXCEPTION_BREAKPOINT
:
1125 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
1126 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
1129 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
1130 ourstatus
->value
.sig
= TARGET_SIGNAL_INT
;
1132 case DBG_CONTROL_BREAK
:
1133 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
1134 ourstatus
->value
.sig
= TARGET_SIGNAL_INT
;
1136 case EXCEPTION_SINGLE_STEP
:
1137 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
1138 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
1140 case EXCEPTION_ILLEGAL_INSTRUCTION
:
1141 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
1142 ourstatus
->value
.sig
= TARGET_SIGNAL_ILL
;
1144 case EXCEPTION_PRIV_INSTRUCTION
:
1145 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
1146 ourstatus
->value
.sig
= TARGET_SIGNAL_ILL
;
1148 case EXCEPTION_NONCONTINUABLE_EXCEPTION
:
1149 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
1150 ourstatus
->value
.sig
= TARGET_SIGNAL_ILL
;
1153 if (current_event
.u
.Exception
.dwFirstChance
)
1155 printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n",
1156 current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
,
1157 (DWORD
) current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
);
1158 ourstatus
->value
.sig
= TARGET_SIGNAL_UNKNOWN
;
1162 last_sig
= ourstatus
->value
.sig
;
1166 /* Resume all artificially suspended threads if we are continuing
1169 child_continue (DWORD continue_status
, int id
)
1175 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, %s);\n",
1176 current_event
.dwProcessId
, current_event
.dwThreadId
,
1177 continue_status
== DBG_CONTINUE
?
1178 "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED"));
1179 res
= ContinueDebugEvent (current_event
.dwProcessId
,
1180 current_event
.dwThreadId
,
1182 continue_status
= 0;
1184 for (th
= &thread_head
; (th
= th
->next
) != NULL
;)
1185 if (((id
== -1) || (id
== (int) th
->id
)) && th
->suspend_count
)
1188 for (i
= 0; i
< th
->suspend_count
; i
++)
1189 (void) ResumeThread (th
->h
);
1190 th
->suspend_count
= 0;
1191 if (debug_registers_changed
)
1193 /* Only change the value of the debug registers */
1194 th
->context
.ContextFlags
= CONTEXT_DEBUG_REGISTERS
;
1195 th
->context
.Dr0
= dr
[0];
1196 th
->context
.Dr1
= dr
[1];
1197 th
->context
.Dr2
= dr
[2];
1198 th
->context
.Dr3
= dr
[3];
1199 /* th->context.Dr6 = dr[6];
1200 FIXME: should we set dr6 also ?? */
1201 th
->context
.Dr7
= dr
[7];
1202 CHECK (SetThreadContext (th
->h
, &th
->context
));
1203 th
->context
.ContextFlags
= 0;
1207 debug_registers_changed
= 0;
1211 /* Called in pathological case where Windows fails to send a
1212 CREATE_PROCESS_DEBUG_EVENT after an attach. */
1214 fake_create_process (void)
1216 current_process_handle
= OpenProcess (PROCESS_ALL_ACCESS
, FALSE
,
1217 current_event
.dwProcessId
);
1218 main_thread_id
= current_event
.dwThreadId
;
1219 current_thread
= child_add_thread (main_thread_id
,
1220 current_event
.u
.CreateThread
.hThread
);
1221 return main_thread_id
;
1224 /* Get the next event from the child. Return 1 if the event requires
1225 handling by WFI (or whatever).
1228 get_child_debug_event (int pid
, struct target_waitstatus
*ourstatus
)
1231 DWORD continue_status
, event_code
;
1233 static thread_info dummy_thread_info
;
1236 last_sig
= TARGET_SIGNAL_0
;
1238 if (!(debug_event
= WaitForDebugEvent (¤t_event
, 1000)))
1242 continue_status
= DBG_CONTINUE
;
1244 event_code
= current_event
.dwDebugEventCode
;
1245 ourstatus
->kind
= TARGET_WAITKIND_SPURIOUS
;
1250 case CREATE_THREAD_DEBUG_EVENT
:
1251 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1252 (unsigned) current_event
.dwProcessId
,
1253 (unsigned) current_event
.dwThreadId
,
1254 "CREATE_THREAD_DEBUG_EVENT"));
1255 if (saw_create
!= 1)
1257 if (!saw_create
&& attach_flag
)
1259 /* Kludge around a Windows bug where first event is a create
1260 thread event. Caused when attached process does not have
1262 retval
= ourstatus
->value
.related_pid
= fake_create_process ();
1267 /* Record the existence of this thread */
1268 th
= child_add_thread (current_event
.dwThreadId
,
1269 current_event
.u
.CreateThread
.hThread
);
1271 printf_unfiltered ("[New %s]\n",
1273 pid_to_ptid (current_event
.dwThreadId
)));
1274 retval
= current_event
.dwThreadId
;
1277 case EXIT_THREAD_DEBUG_EVENT
:
1278 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1279 (unsigned) current_event
.dwProcessId
,
1280 (unsigned) current_event
.dwThreadId
,
1281 "EXIT_THREAD_DEBUG_EVENT"));
1282 if (current_event
.dwThreadId
!= main_thread_id
)
1284 child_delete_thread (current_event
.dwThreadId
);
1285 th
= &dummy_thread_info
;
1289 case CREATE_PROCESS_DEBUG_EVENT
:
1290 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1291 (unsigned) current_event
.dwProcessId
,
1292 (unsigned) current_event
.dwThreadId
,
1293 "CREATE_PROCESS_DEBUG_EVENT"));
1294 CloseHandle (current_event
.u
.CreateProcessInfo
.hFile
);
1295 if (++saw_create
!= 1)
1297 CloseHandle (current_event
.u
.CreateProcessInfo
.hProcess
);
1301 current_process_handle
= current_event
.u
.CreateProcessInfo
.hProcess
;
1303 child_delete_thread (main_thread_id
);
1304 main_thread_id
= current_event
.dwThreadId
;
1305 /* Add the main thread */
1306 th
= child_add_thread (main_thread_id
,
1307 current_event
.u
.CreateProcessInfo
.hThread
);
1308 retval
= ourstatus
->value
.related_pid
= current_event
.dwThreadId
;
1311 case EXIT_PROCESS_DEBUG_EVENT
:
1312 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1313 (unsigned) current_event
.dwProcessId
,
1314 (unsigned) current_event
.dwThreadId
,
1315 "EXIT_PROCESS_DEBUG_EVENT"));
1316 if (saw_create
!= 1)
1318 ourstatus
->kind
= TARGET_WAITKIND_EXITED
;
1319 ourstatus
->value
.integer
= current_event
.u
.ExitProcess
.dwExitCode
;
1320 CloseHandle (current_process_handle
);
1321 retval
= main_thread_id
;
1324 case LOAD_DLL_DEBUG_EVENT
:
1325 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1326 (unsigned) current_event
.dwProcessId
,
1327 (unsigned) current_event
.dwThreadId
,
1328 "LOAD_DLL_DEBUG_EVENT"));
1329 CloseHandle (current_event
.u
.LoadDll
.hFile
);
1330 if (saw_create
!= 1)
1332 catch_errors (handle_load_dll
, NULL
, (char *) "", RETURN_MASK_ALL
);
1333 registers_changed (); /* mark all regs invalid */
1334 ourstatus
->kind
= TARGET_WAITKIND_LOADED
;
1335 ourstatus
->value
.integer
= 0;
1336 retval
= main_thread_id
;
1337 re_enable_breakpoints_in_shlibs ();
1340 case UNLOAD_DLL_DEBUG_EVENT
:
1341 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1342 (unsigned) current_event
.dwProcessId
,
1343 (unsigned) current_event
.dwThreadId
,
1344 "UNLOAD_DLL_DEBUG_EVENT"));
1345 if (saw_create
!= 1)
1347 catch_errors (handle_unload_dll
, NULL
, (char *) "", RETURN_MASK_ALL
);
1348 registers_changed (); /* mark all regs invalid */
1349 /* ourstatus->kind = TARGET_WAITKIND_UNLOADED;
1350 does not exist yet. */
1353 case EXCEPTION_DEBUG_EVENT
:
1354 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1355 (unsigned) current_event
.dwProcessId
,
1356 (unsigned) current_event
.dwThreadId
,
1357 "EXCEPTION_DEBUG_EVENT"));
1358 if (saw_create
!= 1)
1360 if (handle_exception (ourstatus
))
1361 retval
= current_event
.dwThreadId
;
1364 case OUTPUT_DEBUG_STRING_EVENT
: /* message from the kernel */
1365 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1366 (unsigned) current_event
.dwProcessId
,
1367 (unsigned) current_event
.dwThreadId
,
1368 "OUTPUT_DEBUG_STRING_EVENT"));
1369 if (saw_create
!= 1)
1371 if (handle_output_debug_string (ourstatus
))
1372 retval
= main_thread_id
;
1376 if (saw_create
!= 1)
1378 printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
1379 (DWORD
) current_event
.dwProcessId
,
1380 (DWORD
) current_event
.dwThreadId
);
1381 printf_unfiltered (" unknown event code %ld\n",
1382 current_event
.dwDebugEventCode
);
1386 if (!retval
|| saw_create
!= 1)
1387 CHECK (child_continue (continue_status
, -1));
1390 inferior_ptid
= pid_to_ptid (retval
);
1391 current_thread
= th
?: thread_rec (current_event
.dwThreadId
, TRUE
);
1398 /* Wait for interesting events to occur in the target process. */
1400 child_wait (ptid_t ptid
, struct target_waitstatus
*ourstatus
)
1402 int pid
= PIDGET (ptid
);
1404 /* We loop when we get a non-standard exception rather than return
1405 with a SPURIOUS because resume can try and step or modify things,
1406 which needs a current_thread->h. But some of these exceptions mark
1407 the birth or death of threads, which mean that the current thread
1408 isn't necessarily what you think it is. */
1412 int retval
= get_child_debug_event (pid
, ourstatus
);
1414 return pid_to_ptid (retval
);
1419 if (deprecated_ui_loop_hook
!= NULL
)
1420 detach
= deprecated_ui_loop_hook (0);
1423 child_kill_inferior ();
1429 do_initial_child_stuff (DWORD pid
)
1431 extern int stop_after_trap
;
1434 last_sig
= TARGET_SIGNAL_0
;
1436 exception_count
= 0;
1437 debug_registers_changed
= 0;
1438 debug_registers_used
= 0;
1439 for (i
= 0; i
< sizeof (dr
) / sizeof (dr
[0]); i
++)
1441 current_event
.dwProcessId
= pid
;
1442 memset (¤t_event
, 0, sizeof (current_event
));
1443 push_target (&deprecated_child_ops
);
1444 child_init_thread_list ();
1445 disable_breakpoints_in_shlibs (1);
1446 child_clear_solibs ();
1447 clear_proceed_status ();
1448 init_wait_for_inferior ();
1450 target_terminal_init ();
1451 target_terminal_inferior ();
1455 stop_after_trap
= 1;
1456 wait_for_inferior ();
1457 if (stop_signal
!= TARGET_SIGNAL_TRAP
)
1458 resume (0, stop_signal
);
1462 stop_after_trap
= 0;
1466 /* Since Windows XP, detaching from a process is supported by Windows.
1467 The following code tries loading the appropriate functions dynamically.
1468 If loading these functions succeeds use them to actually detach from
1469 the inferior process, otherwise behave as usual, pretending that
1470 detach has worked. */
1471 static BOOL
WINAPI (*DebugSetProcessKillOnExit
)(BOOL
);
1472 static BOOL
WINAPI (*DebugActiveProcessStop
)(DWORD
);
1475 has_detach_ability (void)
1477 static HMODULE kernel32
= NULL
;
1480 kernel32
= LoadLibrary ("kernel32.dll");
1483 if (!DebugSetProcessKillOnExit
)
1484 DebugSetProcessKillOnExit
= GetProcAddress (kernel32
,
1485 "DebugSetProcessKillOnExit");
1486 if (!DebugActiveProcessStop
)
1487 DebugActiveProcessStop
= GetProcAddress (kernel32
,
1488 "DebugActiveProcessStop");
1489 if (DebugSetProcessKillOnExit
&& DebugActiveProcessStop
)
1495 /* Try to set or remove a user privilege to the current process. Return -1
1496 if that fails, the previous setting of that privilege otherwise.
1498 This code is copied from the Cygwin source code and rearranged to allow
1499 dynamically loading of the needed symbols from advapi32 which is only
1500 available on NT/2K/XP. */
1502 set_process_privilege (const char *privilege
, BOOL enable
)
1504 static HMODULE advapi32
= NULL
;
1505 static BOOL
WINAPI (*OpenProcessToken
)(HANDLE
, DWORD
, PHANDLE
);
1506 static BOOL
WINAPI (*LookupPrivilegeValue
)(LPCSTR
, LPCSTR
, PLUID
);
1507 static BOOL
WINAPI (*AdjustTokenPrivileges
)(HANDLE
, BOOL
, PTOKEN_PRIVILEGES
,
1508 DWORD
, PTOKEN_PRIVILEGES
, PDWORD
);
1510 HANDLE token_hdl
= NULL
;
1512 TOKEN_PRIVILEGES new_priv
, orig_priv
;
1516 if (GetVersion () >= 0x80000000) /* No security availbale on 9x/Me */
1521 if (!(advapi32
= LoadLibrary ("advapi32.dll")))
1523 if (!OpenProcessToken
)
1524 OpenProcessToken
= GetProcAddress (advapi32
, "OpenProcessToken");
1525 if (!LookupPrivilegeValue
)
1526 LookupPrivilegeValue
= GetProcAddress (advapi32
,
1527 "LookupPrivilegeValueA");
1528 if (!AdjustTokenPrivileges
)
1529 AdjustTokenPrivileges
= GetProcAddress (advapi32
,
1530 "AdjustTokenPrivileges");
1531 if (!OpenProcessToken
|| !LookupPrivilegeValue
|| !AdjustTokenPrivileges
)
1538 if (!OpenProcessToken (GetCurrentProcess (),
1539 TOKEN_QUERY
| TOKEN_ADJUST_PRIVILEGES
,
1543 if (!LookupPrivilegeValue (NULL
, privilege
, &restore_priv
))
1546 new_priv
.PrivilegeCount
= 1;
1547 new_priv
.Privileges
[0].Luid
= restore_priv
;
1548 new_priv
.Privileges
[0].Attributes
= enable
? SE_PRIVILEGE_ENABLED
: 0;
1550 if (!AdjustTokenPrivileges (token_hdl
, FALSE
, &new_priv
,
1551 sizeof orig_priv
, &orig_priv
, &size
))
1554 /* Disabled, otherwise every `attach' in an unprivileged user session
1555 would raise the "Failed to get SE_DEBUG_NAME privilege" warning in
1557 /* AdjustTokenPrivileges returns TRUE even if the privilege could not
1558 be enabled. GetLastError () returns an correct error code, though. */
1559 if (enable
&& GetLastError () == ERROR_NOT_ALL_ASSIGNED
)
1563 ret
= orig_priv
.Privileges
[0].Attributes
== SE_PRIVILEGE_ENABLED
? 1 : 0;
1567 CloseHandle (token_hdl
);
1572 /* Attach to process PID, then initialize for debugging it. */
1574 child_attach (char *args
, int from_tty
)
1580 error_no_arg ("process-id to attach");
1582 if (set_process_privilege (SE_DEBUG_NAME
, TRUE
) < 0)
1584 printf_unfiltered ("Warning: Failed to get SE_DEBUG_NAME privilege\n");
1585 printf_unfiltered ("This can cause attach to fail on Windows NT/2K/XP\n");
1588 pid
= strtoul (args
, 0, 0); /* Windows pid */
1590 ok
= DebugActiveProcess (pid
);
1595 /* Try fall back to Cygwin pid */
1596 pid
= cygwin_internal (CW_CYGWIN_PID_TO_WINPID
, pid
);
1599 ok
= DebugActiveProcess (pid
);
1602 error ("Can't attach to process.");
1605 if (has_detach_ability ())
1606 DebugSetProcessKillOnExit (FALSE
);
1612 char *exec_file
= (char *) get_exec_file (0);
1615 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file
,
1616 target_pid_to_str (pid_to_ptid (pid
)));
1618 printf_unfiltered ("Attaching to %s\n",
1619 target_pid_to_str (pid_to_ptid (pid
)));
1621 gdb_flush (gdb_stdout
);
1624 do_initial_child_stuff (pid
);
1625 target_terminal_ours ();
1629 child_detach (char *args
, int from_tty
)
1633 if (has_detach_ability ())
1635 delete_command (NULL
, 0);
1636 child_continue (DBG_CONTINUE
, -1);
1637 if (!DebugActiveProcessStop (current_event
.dwProcessId
))
1639 error ("Can't detach process %lu (error %lu)",
1640 current_event
.dwProcessId
, GetLastError ());
1643 DebugSetProcessKillOnExit (FALSE
);
1645 if (detached
&& from_tty
)
1647 char *exec_file
= get_exec_file (0);
1650 printf_unfiltered ("Detaching from program: %s, Pid %lu\n", exec_file
,
1651 current_event
.dwProcessId
);
1652 gdb_flush (gdb_stdout
);
1654 inferior_ptid
= null_ptid
;
1655 unpush_target (&deprecated_child_ops
);
1659 child_pid_to_exec_file (int pid
)
1661 /* Try to find the process path using the Cygwin internal process list
1662 pid isn't a valid pid, unfortunately. Use current_event.dwProcessId
1664 /* TODO: Also find native Windows processes using CW_GETPINFO_FULL. */
1666 static char path
[MAX_PATH
+ 1];
1667 char *path_ptr
= NULL
;
1669 struct external_pinfo
*pinfo
;
1671 cygwin_internal (CW_LOCK_PINFO
, 1000);
1673 (pinfo
= (struct external_pinfo
*)
1674 cygwin_internal (CW_GETPINFO
, cpid
| CW_NEXTPID
));
1677 if (pinfo
->dwProcessId
== current_event
.dwProcessId
) /* Got it */
1679 cygwin_conv_to_full_posix_path (pinfo
->progname
, path
);
1684 cygwin_internal (CW_UNLOCK_PINFO
);
1688 /* Print status information about what we're accessing. */
1691 child_files_info (struct target_ops
*ignore
)
1693 printf_unfiltered ("\tUsing the running image of %s %s.\n",
1694 attach_flag
? "attached" : "child", target_pid_to_str (inferior_ptid
));
1698 child_open (char *arg
, int from_tty
)
1700 error ("Use the \"run\" command to start a Unix child process.");
1703 /* Start an inferior win32 child process and sets inferior_ptid to its pid.
1704 EXEC_FILE is the file to run.
1705 ALLARGS is a string containing the arguments to the program.
1706 ENV is the environment vector to pass. Errors reported with error(). */
1709 child_create_inferior (char *exec_file
, char *allargs
, char **env
,
1717 PROCESS_INFORMATION pi
;
1721 char real_path
[MAXPATHLEN
];
1723 char shell
[MAX_PATH
+ 1]; /* Path to shell */
1726 int ostdin
, ostdout
, ostderr
;
1729 error ("No executable specified, use `target exec'.\n");
1731 memset (&si
, 0, sizeof (si
));
1732 si
.cb
= sizeof (si
);
1736 flags
= DEBUG_ONLY_THIS_PROCESS
;
1737 cygwin_conv_to_win32_path (exec_file
, real_path
);
1743 sh
= getenv ("SHELL");
1746 cygwin_conv_to_win32_path (sh
, shell
);
1747 newallargs
= alloca (sizeof (" -c 'exec '") + strlen (exec_file
)
1748 + strlen (allargs
) + 2);
1749 sprintf (newallargs
, " -c 'exec %s %s'", exec_file
, allargs
);
1750 allargs
= newallargs
;
1752 flags
= DEBUG_PROCESS
;
1756 flags
|= CREATE_NEW_PROCESS_GROUP
;
1759 flags
|= CREATE_NEW_CONSOLE
;
1763 args
= alloca (strlen (toexec
) + strlen (allargs
) + 2);
1764 strcpy (args
, toexec
);
1766 strcat (args
, allargs
);
1768 /* Prepare the environment vars for CreateProcess. */
1770 /* This code used to assume all env vars were file names and would
1771 translate them all to win32 style. That obviously doesn't work in the
1772 general case. The current rule is that we only translate PATH.
1773 We need to handle PATH because we're about to call CreateProcess and
1774 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
1775 in both posix and win32 environments. cygwin.dll will change it back
1776 to posix style if necessary. */
1778 static const char *conv_path_names
[] =
1784 /* CreateProcess takes the environment list as a null terminated set of
1785 strings (i.e. two nulls terminate the list). */
1787 /* Get total size for env strings. */
1788 for (envlen
= 0, i
= 0; env
[i
] && *env
[i
]; i
++)
1792 for (j
= 0; conv_path_names
[j
]; j
++)
1794 len
= strlen (conv_path_names
[j
]);
1795 if (strncmp (conv_path_names
[j
], env
[i
], len
) == 0)
1797 if (cygwin_posix_path_list_p (env
[i
] + len
))
1799 + cygwin_posix_to_win32_path_list_buf_size (env
[i
] + len
);
1801 envlen
+= strlen (env
[i
]) + 1;
1805 if (conv_path_names
[j
] == NULL
)
1806 envlen
+= strlen (env
[i
]) + 1;
1809 winenv
= alloca (envlen
+ 1);
1811 /* Copy env strings into new buffer. */
1812 for (temp
= winenv
, i
= 0; env
[i
] && *env
[i
]; i
++)
1816 for (j
= 0; conv_path_names
[j
]; j
++)
1818 len
= strlen (conv_path_names
[j
]);
1819 if (strncmp (conv_path_names
[j
], env
[i
], len
) == 0)
1821 if (cygwin_posix_path_list_p (env
[i
] + len
))
1823 memcpy (temp
, env
[i
], len
);
1824 cygwin_posix_to_win32_path_list (env
[i
] + len
, temp
+ len
);
1827 strcpy (temp
, env
[i
]);
1831 if (conv_path_names
[j
] == NULL
)
1832 strcpy (temp
, env
[i
]);
1834 temp
+= strlen (temp
) + 1;
1837 /* Final nil string to terminate new env. */
1841 if (!inferior_io_terminal
)
1842 tty
= ostdin
= ostdout
= ostderr
= -1;
1845 tty
= open (inferior_io_terminal
, O_RDWR
| O_NOCTTY
);
1848 print_sys_errmsg (inferior_io_terminal
, errno
);
1849 ostdin
= ostdout
= ostderr
= -1;
1862 ret
= CreateProcess (0,
1863 args
, /* command line */
1864 NULL
, /* Security */
1866 TRUE
, /* inherit handles */
1867 flags
, /* start flags */
1869 NULL
, /* current directory */
1884 error ("Error creating process %s, (error %d)\n", exec_file
, (unsigned) GetLastError ());
1886 CloseHandle (pi
.hThread
);
1887 CloseHandle (pi
.hProcess
);
1889 if (useshell
&& shell
[0] != '\0')
1894 do_initial_child_stuff (pi
.dwProcessId
);
1896 /* child_continue (DBG_CONTINUE, -1); */
1897 proceed ((CORE_ADDR
) - 1, TARGET_SIGNAL_0
, 0);
1901 child_mourn_inferior (void)
1903 (void) child_continue (DBG_CONTINUE
, -1);
1904 i386_cleanup_dregs();
1905 unpush_target (&deprecated_child_ops
);
1906 generic_mourn_inferior ();
1909 /* Send a SIGINT to the process group. This acts just like the user typed a
1910 ^C on the controlling terminal. */
1915 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
1916 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT
, current_event
.dwProcessId
));
1917 registers_changed (); /* refresh register state */
1921 child_xfer_memory (CORE_ADDR memaddr
, char *our
, int len
,
1922 int write
, struct mem_attrib
*mem
,
1923 struct target_ops
*target
)
1928 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
1929 len
, (DWORD
) memaddr
));
1930 if (!WriteProcessMemory (current_process_handle
, (LPVOID
) memaddr
, our
,
1933 FlushInstructionCache (current_process_handle
, (LPCVOID
) memaddr
, len
);
1937 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
1938 len
, (DWORD
) memaddr
));
1939 if (!ReadProcessMemory (current_process_handle
, (LPCVOID
) memaddr
, our
,
1947 child_kill_inferior (void)
1949 CHECK (TerminateProcess (current_process_handle
, 0));
1953 if (!child_continue (DBG_CONTINUE
, -1))
1955 if (!WaitForDebugEvent (¤t_event
, INFINITE
))
1957 if (current_event
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
)
1961 CHECK (CloseHandle (current_process_handle
));
1963 /* this may fail in an attached process so don't check. */
1964 if (current_thread
&& current_thread
->h
)
1965 (void) CloseHandle (current_thread
->h
);
1966 target_mourn_inferior (); /* or just child_mourn_inferior? */
1970 child_resume (ptid_t ptid
, int step
, enum target_signal sig
)
1973 DWORD continue_status
= DBG_CONTINUE
;
1975 int pid
= PIDGET (ptid
);
1977 if (sig
!= TARGET_SIGNAL_0
)
1979 if (current_event
.dwDebugEventCode
!= EXCEPTION_DEBUG_EVENT
)
1981 DEBUG_EXCEPT(("Cannot continue with signal %d here.\n",sig
));
1983 else if (sig
== last_sig
)
1984 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
1987 /* This code does not seem to work, because
1988 the kernel does probably not consider changes in the ExceptionRecord
1989 structure when passing the exception to the inferior.
1990 Note that this seems possible in the exception handler itself. */
1993 for (i
= 0; xlate
[i
].them
!= -1; i
++)
1994 if (xlate
[i
].us
== sig
)
1996 current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
=
1998 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
2001 if (continue_status
== DBG_CONTINUE
)
2003 DEBUG_EXCEPT(("Cannot continue with signal %d.\n",sig
));
2007 DEBUG_EXCEPT(("Can only continue with recieved signal %d.\n",
2011 last_sig
= TARGET_SIGNAL_0
;
2013 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
2016 /* Get context for currently selected thread */
2017 th
= thread_rec (current_event
.dwThreadId
, FALSE
);
2022 /* Single step by setting t bit */
2023 child_fetch_inferior_registers (PS_REGNUM
);
2024 th
->context
.EFlags
|= FLAG_TRACE_BIT
;
2027 if (th
->context
.ContextFlags
)
2029 if (debug_registers_changed
)
2031 th
->context
.Dr0
= dr
[0];
2032 th
->context
.Dr1
= dr
[1];
2033 th
->context
.Dr2
= dr
[2];
2034 th
->context
.Dr3
= dr
[3];
2035 /* th->context.Dr6 = dr[6];
2036 FIXME: should we set dr6 also ?? */
2037 th
->context
.Dr7
= dr
[7];
2039 CHECK (SetThreadContext (th
->h
, &th
->context
));
2040 th
->context
.ContextFlags
= 0;
2044 /* Allow continuing with the same signal that interrupted us.
2045 Otherwise complain. */
2047 child_continue (continue_status
, pid
);
2051 child_prepare_to_store (void)
2053 /* Do nothing, since we can store individual regs */
2057 child_can_run (void)
2065 DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n",
2066 PIDGET (inferior_ptid
)));
2070 init_child_ops (void)
2072 deprecated_child_ops
.to_shortname
= "child";
2073 deprecated_child_ops
.to_longname
= "Win32 child process";
2074 deprecated_child_ops
.to_doc
= "Win32 child process (started by the \"run\" command).";
2075 deprecated_child_ops
.to_open
= child_open
;
2076 deprecated_child_ops
.to_close
= child_close
;
2077 deprecated_child_ops
.to_attach
= child_attach
;
2078 deprecated_child_ops
.to_detach
= child_detach
;
2079 deprecated_child_ops
.to_resume
= child_resume
;
2080 deprecated_child_ops
.to_wait
= child_wait
;
2081 deprecated_child_ops
.to_fetch_registers
= child_fetch_inferior_registers
;
2082 deprecated_child_ops
.to_store_registers
= child_store_inferior_registers
;
2083 deprecated_child_ops
.to_prepare_to_store
= child_prepare_to_store
;
2084 deprecated_child_ops
.deprecated_xfer_memory
= child_xfer_memory
;
2085 deprecated_child_ops
.to_files_info
= child_files_info
;
2086 deprecated_child_ops
.to_insert_breakpoint
= memory_insert_breakpoint
;
2087 deprecated_child_ops
.to_remove_breakpoint
= memory_remove_breakpoint
;
2088 deprecated_child_ops
.to_terminal_init
= terminal_init_inferior
;
2089 deprecated_child_ops
.to_terminal_inferior
= terminal_inferior
;
2090 deprecated_child_ops
.to_terminal_ours_for_output
= terminal_ours_for_output
;
2091 deprecated_child_ops
.to_terminal_ours
= terminal_ours
;
2092 deprecated_child_ops
.to_terminal_save_ours
= terminal_save_ours
;
2093 deprecated_child_ops
.to_terminal_info
= child_terminal_info
;
2094 deprecated_child_ops
.to_kill
= child_kill_inferior
;
2095 deprecated_child_ops
.to_create_inferior
= child_create_inferior
;
2096 deprecated_child_ops
.to_mourn_inferior
= child_mourn_inferior
;
2097 deprecated_child_ops
.to_can_run
= child_can_run
;
2098 deprecated_child_ops
.to_thread_alive
= win32_child_thread_alive
;
2099 deprecated_child_ops
.to_pid_to_str
= cygwin_pid_to_str
;
2100 deprecated_child_ops
.to_stop
= child_stop
;
2101 deprecated_child_ops
.to_stratum
= process_stratum
;
2102 deprecated_child_ops
.to_has_all_memory
= 1;
2103 deprecated_child_ops
.to_has_memory
= 1;
2104 deprecated_child_ops
.to_has_stack
= 1;
2105 deprecated_child_ops
.to_has_registers
= 1;
2106 deprecated_child_ops
.to_has_execution
= 1;
2107 deprecated_child_ops
.to_magic
= OPS_MAGIC
;
2108 deprecated_child_ops
.to_pid_to_exec_file
= child_pid_to_exec_file
;
2112 _initialize_win32_nat (void)
2114 struct cmd_list_element
*c
;
2118 c
= add_com ("dll-symbols", class_files
, dll_symbol_command
,
2119 "Load dll library symbols from FILE.");
2120 set_cmd_completer (c
, filename_completer
);
2122 add_com_alias ("sharedlibrary", "dll-symbols", class_alias
, 1);
2124 deprecated_add_show_from_set
2125 (add_set_cmd ("shell", class_support
, var_boolean
,
2127 "Set use of shell to start subprocess.",
2131 deprecated_add_show_from_set
2132 (add_set_cmd ("new-console", class_support
, var_boolean
,
2133 (char *) &new_console
,
2134 "Set creation of new console when creating child process.",
2138 deprecated_add_show_from_set
2139 (add_set_cmd ("new-group", class_support
, var_boolean
,
2140 (char *) &new_group
,
2141 "Set creation of new group when creating child process.",
2145 deprecated_add_show_from_set
2146 (add_set_cmd ("debugexec", class_support
, var_boolean
,
2147 (char *) &debug_exec
,
2148 "Set whether to display execution in child process.",
2152 deprecated_add_show_from_set
2153 (add_set_cmd ("debugevents", class_support
, var_boolean
,
2154 (char *) &debug_events
,
2155 "Set whether to display kernel events in child process.",
2159 deprecated_add_show_from_set
2160 (add_set_cmd ("debugmemory", class_support
, var_boolean
,
2161 (char *) &debug_memory
,
2162 "Set whether to display memory accesses in child process.",
2166 deprecated_add_show_from_set
2167 (add_set_cmd ("debugexceptions", class_support
, var_boolean
,
2168 (char *) &debug_exceptions
,
2169 "Set whether to display kernel exceptions in child process.",
2173 add_info ("dll", info_dll_command
, "Status of loaded DLLs.");
2174 add_info_alias ("sharedlibrary", "dll", 1);
2176 add_prefix_cmd ("w32", class_info
, info_w32_command
,
2177 "Print information specific to Win32 debugging.",
2178 &info_w32_cmdlist
, "info w32 ", 0, &infolist
);
2180 add_cmd ("selector", class_info
, display_selectors
,
2181 "Display selectors infos.",
2184 add_target (&deprecated_child_ops
);
2187 /* Hardware watchpoint support, adapted from go32-nat.c code. */
2189 /* Pass the address ADDR to the inferior in the I'th debug register.
2190 Here we just store the address in dr array, the registers will be
2191 actually set up when child_continue is called. */
2193 cygwin_set_dr (int i
, CORE_ADDR addr
)
2196 internal_error (__FILE__
, __LINE__
,
2197 "Invalid register %d in cygwin_set_dr.\n", i
);
2198 dr
[i
] = (unsigned) addr
;
2199 debug_registers_changed
= 1;
2200 debug_registers_used
= 1;
2203 /* Pass the value VAL to the inferior in the DR7 debug control
2204 register. Here we just store the address in D_REGS, the watchpoint
2205 will be actually set up in child_wait. */
2207 cygwin_set_dr7 (unsigned val
)
2210 debug_registers_changed
= 1;
2211 debug_registers_used
= 1;
2214 /* Get the value of the DR6 debug status register from the inferior.
2215 Here we just return the value stored in dr[6]
2216 by the last call to thread_rec for current_event.dwThreadId id. */
2218 cygwin_get_dr6 (void)
2223 /* Determine if the thread referenced by "pid" is alive
2224 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
2225 it means that the pid has died. Otherwise it is assumed to be alive. */
2227 win32_child_thread_alive (ptid_t ptid
)
2229 int pid
= PIDGET (ptid
);
2231 return WaitForSingleObject (thread_rec (pid
, FALSE
)->h
, 0) == WAIT_OBJECT_0
?
2235 /* Convert pid to printable format. */
2237 cygwin_pid_to_str (ptid_t ptid
)
2239 static char buf
[80];
2240 int pid
= PIDGET (ptid
);
2242 if ((DWORD
) pid
== current_event
.dwProcessId
)
2243 sprintf (buf
, "process %d", pid
);
2245 sprintf (buf
, "thread %ld.0x%x", current_event
.dwProcessId
, pid
);
2250 core_dll_symbols_add (char *dll_name
, DWORD base_addr
)
2252 struct objfile
*objfile
;
2253 char *objfile_basename
;
2254 const char *dll_basename
;
2256 if (!(dll_basename
= strrchr (dll_name
, '/')))
2257 dll_basename
= dll_name
;
2261 ALL_OBJFILES (objfile
)
2263 objfile_basename
= strrchr (objfile
->name
, '/');
2265 if (objfile_basename
&&
2266 strcmp (dll_basename
, objfile_basename
+ 1) == 0)
2268 printf_unfiltered ("%08lx:%s (symbols previously loaded)\n",
2269 base_addr
, dll_name
);
2274 register_loaded_dll (dll_name
, base_addr
+ 0x1000);
2275 solib_symbols_add (dll_name
, 0, (CORE_ADDR
) base_addr
+ 0x1000);
2283 struct target_ops
*target
;
2285 } map_code_section_args
;
2288 map_single_dll_code_section (bfd
* abfd
, asection
* sect
, void *obj
)
2292 struct section_table
*new_target_sect_ptr
;
2294 map_code_section_args
*args
= (map_code_section_args
*) obj
;
2295 struct target_ops
*target
= args
->target
;
2296 if (sect
->flags
& SEC_CODE
)
2298 update_coreops
= core_ops
.to_sections
== target
->to_sections
;
2300 if (target
->to_sections
)
2302 old
= target
->to_sections_end
- target
->to_sections
;
2303 target
->to_sections
= (struct section_table
*)
2304 xrealloc ((char *) target
->to_sections
,
2305 (sizeof (struct section_table
)) * (1 + old
));
2310 target
->to_sections
= (struct section_table
*)
2311 xmalloc ((sizeof (struct section_table
)));
2313 target
->to_sections_end
= target
->to_sections
+ (1 + old
);
2315 /* Update the to_sections field in the core_ops structure
2319 core_ops
.to_sections
= target
->to_sections
;
2320 core_ops
.to_sections_end
= target
->to_sections_end
;
2322 new_target_sect_ptr
= target
->to_sections
+ old
;
2323 new_target_sect_ptr
->addr
= args
->addr
+ bfd_section_vma (abfd
, sect
);
2324 new_target_sect_ptr
->endaddr
= args
->addr
+ bfd_section_vma (abfd
, sect
) +
2325 bfd_section_size (abfd
, sect
);;
2326 new_target_sect_ptr
->the_bfd_section
= sect
;
2327 new_target_sect_ptr
->bfd
= abfd
;
2332 dll_code_sections_add (const char *dll_name
, int base_addr
, struct target_ops
*target
)
2335 map_code_section_args map_args
;
2336 asection
*lowest_sect
;
2338 if (dll_name
== NULL
|| target
== NULL
)
2340 name
= xstrdup (dll_name
);
2341 dll_bfd
= bfd_openr (name
, "pei-i386");
2342 if (dll_bfd
== NULL
)
2345 if (bfd_check_format (dll_bfd
, bfd_object
))
2347 lowest_sect
= bfd_get_section_by_name (dll_bfd
, ".text");
2348 if (lowest_sect
== NULL
)
2350 map_args
.target
= target
;
2351 map_args
.addr
= base_addr
- bfd_section_vma (dll_bfd
, lowest_sect
);
2353 bfd_map_over_sections (dll_bfd
, &map_single_dll_code_section
, (void *) (&map_args
));
2360 core_section_load_dll_symbols (bfd
* abfd
, asection
* sect
, void *obj
)
2362 struct target_ops
*target
= (struct target_ops
*) obj
;
2367 char *dll_name
= NULL
;
2369 struct win32_pstatus
*pstatus
;
2372 if (strncmp (sect
->name
, ".module", 7))
2375 buf
= (char *) xmalloc (bfd_get_section_size (sect
) + 1);
2378 printf_unfiltered ("memory allocation failed for %s\n", sect
->name
);
2381 if (!bfd_get_section_contents (abfd
, sect
, buf
, 0, bfd_get_section_size (sect
)))
2384 pstatus
= (struct win32_pstatus
*) buf
;
2386 memmove (&base_addr
, &(pstatus
->data
.module_info
.base_address
), sizeof (base_addr
));
2387 dll_name_size
= pstatus
->data
.module_info
.module_name_size
;
2388 if (offsetof (struct win32_pstatus
, data
.module_info
.module_name
) + dll_name_size
> bfd_get_section_size (sect
))
2391 dll_name
= (char *) xmalloc (dll_name_size
+ 1);
2394 printf_unfiltered ("memory allocation failed for %s\n", sect
->name
);
2397 strncpy (dll_name
, pstatus
->data
.module_info
.module_name
, dll_name_size
);
2399 while ((p
= strchr (dll_name
, '\\')))
2402 if (!core_dll_symbols_add (dll_name
, (DWORD
) base_addr
))
2403 printf_unfiltered ("%s: Failed to load dll symbols.\n", dll_name
);
2405 if (!dll_code_sections_add (dll_name
, (DWORD
) base_addr
+ 0x1000, target
))
2406 printf_unfiltered ("%s: Failed to map dll code sections.\n", dll_name
);
2417 child_solib_add (char *filename
, int from_tty
, struct target_ops
*target
,
2424 child_clear_solibs ();
2425 bfd_map_over_sections (core_bfd
, &core_section_load_dll_symbols
, target
);
2429 if (solib_end
&& solib_end
->name
)
2430 solib_end
->objfile
= solib_symbols_add (solib_end
->name
, from_tty
,
2431 solib_end
->load_addr
);
2436 fetch_elf_core_registers (char *core_reg_sect
,
2437 unsigned core_reg_size
,
2442 if (core_reg_size
< sizeof (CONTEXT
))
2444 error ("Core file register section too small (%u bytes).", core_reg_size
);
2447 for (r
= 0; r
< NUM_REGS
; r
++)
2448 regcache_raw_supply (current_regcache
, r
, core_reg_sect
+ mappings
[r
]);
2451 static struct core_fns win32_elf_core_fns
=
2453 bfd_target_elf_flavour
,
2454 default_check_format
,
2455 default_core_sniffer
,
2456 fetch_elf_core_registers
,
2461 _initialize_core_win32 (void)
2463 deprecated_add_core_fns (&win32_elf_core_fns
);
2467 _initialize_check_for_gdb_ini (void)
2470 if (inhibit_gdbinit
)
2473 homedir
= getenv ("HOME");
2477 char *oldini
= (char *) alloca (strlen (homedir
) +
2478 sizeof ("/gdb.ini"));
2479 strcpy (oldini
, homedir
);
2480 p
= strchr (oldini
, '\0');
2481 if (p
> oldini
&& p
[-1] != '/')
2483 strcpy (p
, "gdb.ini");
2484 if (access (oldini
, 0) == 0)
2486 int len
= strlen (oldini
);
2487 char *newini
= alloca (len
+ 1);
2488 sprintf (newini
, "%.*s.gdbinit",
2489 (int) (len
- (sizeof ("gdb.ini") - 1)), oldini
);
2490 warning ("obsolete '%s' found. Rename to '%s'.", oldini
, newini
);