1 /* Target-vector operations for controlling win32 child processes, for GDB.
3 Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
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
);
303 thread_head
.next
= NULL
;
306 /* Delete a thread from the list of threads */
308 child_delete_thread (DWORD id
)
313 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (pid_to_ptid (id
)));
314 delete_thread (pid_to_ptid (id
));
316 for (th
= &thread_head
;
317 th
->next
!= NULL
&& th
->next
->id
!= id
;
321 if (th
->next
!= NULL
)
323 thread_info
*here
= th
->next
;
324 th
->next
= here
->next
;
325 CloseHandle (here
->h
);
331 do_child_fetch_inferior_registers (int r
)
333 char *context_offset
= ((char *) ¤t_thread
->context
) + mappings
[r
];
337 return; /* Windows sometimes uses a non-existent thread id in its
340 if (current_thread
->reload_context
)
342 thread_info
*th
= current_thread
;
343 th
->context
.ContextFlags
= CONTEXT_DEBUGGER_DR
;
344 GetThreadContext (th
->h
, &th
->context
);
345 /* Copy dr values from that thread. */
346 dr
[0] = th
->context
.Dr0
;
347 dr
[1] = th
->context
.Dr1
;
348 dr
[2] = th
->context
.Dr2
;
349 dr
[3] = th
->context
.Dr3
;
350 dr
[6] = th
->context
.Dr6
;
351 dr
[7] = th
->context
.Dr7
;
352 current_thread
->reload_context
= 0;
355 #define I387_ST0_REGNUM I386_ST0_REGNUM
357 if (r
== I387_FISEG_REGNUM
)
359 l
= *((long *) context_offset
) & 0xffff;
360 regcache_raw_supply (current_regcache
, r
, (char *) &l
);
362 else if (r
== I387_FOP_REGNUM
)
364 l
= (*((long *) context_offset
) >> 16) & ((1 << 11) - 1);
365 regcache_raw_supply (current_regcache
, r
, (char *) &l
);
368 regcache_raw_supply (current_regcache
, r
, context_offset
);
371 for (r
= 0; r
< NUM_REGS
; r
++)
372 do_child_fetch_inferior_registers (r
);
375 #undef I387_ST0_REGNUM
379 child_fetch_inferior_registers (int r
)
381 current_thread
= thread_rec (PIDGET (inferior_ptid
), TRUE
);
382 /* Check if current_thread exists. Windows sometimes uses a non-existent
383 thread id in its events */
385 do_child_fetch_inferior_registers (r
);
389 do_child_store_inferior_registers (int r
)
392 /* Windows sometimes uses a non-existent thread id in its events */;
394 regcache_raw_collect (current_regcache
, r
,
395 ((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."), (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."), (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
;
1082 if (find_pc_partial_function ((CORE_ADDR
) current_event
.u
.Exception
1083 .ExceptionRecord
.ExceptionAddress
,
1085 && strncmp (fn
, "KERNEL32!IsBad", strlen ("KERNEL32!IsBad")) == 0)
1089 case STATUS_STACK_OVERFLOW
:
1090 DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
1091 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
1093 case STATUS_FLOAT_DENORMAL_OPERAND
:
1094 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
1095 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1097 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED
:
1098 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
1099 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1101 case STATUS_FLOAT_INEXACT_RESULT
:
1102 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
1103 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1105 case STATUS_FLOAT_INVALID_OPERATION
:
1106 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
1107 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1109 case STATUS_FLOAT_OVERFLOW
:
1110 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
1111 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1113 case STATUS_FLOAT_STACK_CHECK
:
1114 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
1115 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1117 case STATUS_FLOAT_UNDERFLOW
:
1118 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
1119 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1121 case STATUS_FLOAT_DIVIDE_BY_ZERO
:
1122 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
1123 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1125 case STATUS_INTEGER_DIVIDE_BY_ZERO
:
1126 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
1127 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1129 case STATUS_INTEGER_OVERFLOW
:
1130 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
1131 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
1133 case EXCEPTION_BREAKPOINT
:
1134 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
1135 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
1138 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
1139 ourstatus
->value
.sig
= TARGET_SIGNAL_INT
;
1141 case DBG_CONTROL_BREAK
:
1142 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
1143 ourstatus
->value
.sig
= TARGET_SIGNAL_INT
;
1145 case EXCEPTION_SINGLE_STEP
:
1146 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
1147 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
1149 case EXCEPTION_ILLEGAL_INSTRUCTION
:
1150 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
1151 ourstatus
->value
.sig
= TARGET_SIGNAL_ILL
;
1153 case EXCEPTION_PRIV_INSTRUCTION
:
1154 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
1155 ourstatus
->value
.sig
= TARGET_SIGNAL_ILL
;
1157 case EXCEPTION_NONCONTINUABLE_EXCEPTION
:
1158 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
1159 ourstatus
->value
.sig
= TARGET_SIGNAL_ILL
;
1162 if (current_event
.u
.Exception
.dwFirstChance
)
1164 printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n",
1165 current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
,
1166 (DWORD
) current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
);
1167 ourstatus
->value
.sig
= TARGET_SIGNAL_UNKNOWN
;
1171 last_sig
= ourstatus
->value
.sig
;
1175 /* Resume all artificially suspended threads if we are continuing
1178 child_continue (DWORD continue_status
, int id
)
1184 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, %s);\n",
1185 current_event
.dwProcessId
, current_event
.dwThreadId
,
1186 continue_status
== DBG_CONTINUE
?
1187 "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED"));
1188 res
= ContinueDebugEvent (current_event
.dwProcessId
,
1189 current_event
.dwThreadId
,
1191 continue_status
= 0;
1193 for (th
= &thread_head
; (th
= th
->next
) != NULL
;)
1194 if (((id
== -1) || (id
== (int) th
->id
)) && th
->suspend_count
)
1197 for (i
= 0; i
< th
->suspend_count
; i
++)
1198 (void) ResumeThread (th
->h
);
1199 th
->suspend_count
= 0;
1200 if (debug_registers_changed
)
1202 /* Only change the value of the debug registers */
1203 th
->context
.ContextFlags
= CONTEXT_DEBUG_REGISTERS
;
1204 th
->context
.Dr0
= dr
[0];
1205 th
->context
.Dr1
= dr
[1];
1206 th
->context
.Dr2
= dr
[2];
1207 th
->context
.Dr3
= dr
[3];
1208 /* th->context.Dr6 = dr[6];
1209 FIXME: should we set dr6 also ?? */
1210 th
->context
.Dr7
= dr
[7];
1211 CHECK (SetThreadContext (th
->h
, &th
->context
));
1212 th
->context
.ContextFlags
= 0;
1216 debug_registers_changed
= 0;
1220 /* Called in pathological case where Windows fails to send a
1221 CREATE_PROCESS_DEBUG_EVENT after an attach. */
1223 fake_create_process (void)
1225 current_process_handle
= OpenProcess (PROCESS_ALL_ACCESS
, FALSE
,
1226 current_event
.dwProcessId
);
1227 main_thread_id
= current_event
.dwThreadId
;
1228 current_thread
= child_add_thread (main_thread_id
,
1229 current_event
.u
.CreateThread
.hThread
);
1230 return main_thread_id
;
1233 /* Get the next event from the child. Return 1 if the event requires
1234 handling by WFI (or whatever).
1237 get_child_debug_event (int pid
, struct target_waitstatus
*ourstatus
)
1240 DWORD continue_status
, event_code
;
1242 static thread_info dummy_thread_info
;
1245 last_sig
= TARGET_SIGNAL_0
;
1247 if (!(debug_event
= WaitForDebugEvent (¤t_event
, 1000)))
1251 continue_status
= DBG_CONTINUE
;
1253 event_code
= current_event
.dwDebugEventCode
;
1254 ourstatus
->kind
= TARGET_WAITKIND_SPURIOUS
;
1259 case CREATE_THREAD_DEBUG_EVENT
:
1260 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1261 (unsigned) current_event
.dwProcessId
,
1262 (unsigned) current_event
.dwThreadId
,
1263 "CREATE_THREAD_DEBUG_EVENT"));
1264 if (saw_create
!= 1)
1266 if (!saw_create
&& attach_flag
)
1268 /* Kludge around a Windows bug where first event is a create
1269 thread event. Caused when attached process does not have
1271 retval
= ourstatus
->value
.related_pid
= fake_create_process ();
1276 /* Record the existence of this thread */
1277 th
= child_add_thread (current_event
.dwThreadId
,
1278 current_event
.u
.CreateThread
.hThread
);
1280 printf_unfiltered ("[New %s]\n",
1282 pid_to_ptid (current_event
.dwThreadId
)));
1283 retval
= current_event
.dwThreadId
;
1286 case EXIT_THREAD_DEBUG_EVENT
:
1287 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1288 (unsigned) current_event
.dwProcessId
,
1289 (unsigned) current_event
.dwThreadId
,
1290 "EXIT_THREAD_DEBUG_EVENT"));
1291 if (current_event
.dwThreadId
!= main_thread_id
)
1293 child_delete_thread (current_event
.dwThreadId
);
1294 th
= &dummy_thread_info
;
1298 case CREATE_PROCESS_DEBUG_EVENT
:
1299 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1300 (unsigned) current_event
.dwProcessId
,
1301 (unsigned) current_event
.dwThreadId
,
1302 "CREATE_PROCESS_DEBUG_EVENT"));
1303 CloseHandle (current_event
.u
.CreateProcessInfo
.hFile
);
1304 if (++saw_create
!= 1)
1306 CloseHandle (current_event
.u
.CreateProcessInfo
.hProcess
);
1310 current_process_handle
= current_event
.u
.CreateProcessInfo
.hProcess
;
1312 child_delete_thread (main_thread_id
);
1313 main_thread_id
= current_event
.dwThreadId
;
1314 /* Add the main thread */
1315 th
= child_add_thread (main_thread_id
,
1316 current_event
.u
.CreateProcessInfo
.hThread
);
1317 retval
= ourstatus
->value
.related_pid
= current_event
.dwThreadId
;
1320 case EXIT_PROCESS_DEBUG_EVENT
:
1321 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1322 (unsigned) current_event
.dwProcessId
,
1323 (unsigned) current_event
.dwThreadId
,
1324 "EXIT_PROCESS_DEBUG_EVENT"));
1325 if (saw_create
!= 1)
1327 ourstatus
->kind
= TARGET_WAITKIND_EXITED
;
1328 ourstatus
->value
.integer
= current_event
.u
.ExitProcess
.dwExitCode
;
1329 CloseHandle (current_process_handle
);
1330 retval
= main_thread_id
;
1333 case LOAD_DLL_DEBUG_EVENT
:
1334 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1335 (unsigned) current_event
.dwProcessId
,
1336 (unsigned) current_event
.dwThreadId
,
1337 "LOAD_DLL_DEBUG_EVENT"));
1338 CloseHandle (current_event
.u
.LoadDll
.hFile
);
1339 if (saw_create
!= 1)
1341 catch_errors (handle_load_dll
, NULL
, (char *) "", RETURN_MASK_ALL
);
1342 registers_changed (); /* mark all regs invalid */
1343 ourstatus
->kind
= TARGET_WAITKIND_LOADED
;
1344 ourstatus
->value
.integer
= 0;
1345 retval
= main_thread_id
;
1346 re_enable_breakpoints_in_shlibs ();
1349 case UNLOAD_DLL_DEBUG_EVENT
:
1350 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1351 (unsigned) current_event
.dwProcessId
,
1352 (unsigned) current_event
.dwThreadId
,
1353 "UNLOAD_DLL_DEBUG_EVENT"));
1354 if (saw_create
!= 1)
1356 catch_errors (handle_unload_dll
, NULL
, (char *) "", RETURN_MASK_ALL
);
1357 registers_changed (); /* mark all regs invalid */
1358 /* ourstatus->kind = TARGET_WAITKIND_UNLOADED;
1359 does not exist yet. */
1362 case EXCEPTION_DEBUG_EVENT
:
1363 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1364 (unsigned) current_event
.dwProcessId
,
1365 (unsigned) current_event
.dwThreadId
,
1366 "EXCEPTION_DEBUG_EVENT"));
1367 if (saw_create
!= 1)
1369 if (handle_exception (ourstatus
))
1370 retval
= current_event
.dwThreadId
;
1372 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
1375 case OUTPUT_DEBUG_STRING_EVENT
: /* message from the kernel */
1376 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1377 (unsigned) current_event
.dwProcessId
,
1378 (unsigned) current_event
.dwThreadId
,
1379 "OUTPUT_DEBUG_STRING_EVENT"));
1380 if (saw_create
!= 1)
1382 if (handle_output_debug_string (ourstatus
))
1383 retval
= main_thread_id
;
1387 if (saw_create
!= 1)
1389 printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
1390 (DWORD
) current_event
.dwProcessId
,
1391 (DWORD
) current_event
.dwThreadId
);
1392 printf_unfiltered (" unknown event code %ld\n",
1393 current_event
.dwDebugEventCode
);
1397 if (!retval
|| saw_create
!= 1)
1398 CHECK (child_continue (continue_status
, -1));
1401 inferior_ptid
= pid_to_ptid (retval
);
1402 current_thread
= th
?: thread_rec (current_event
.dwThreadId
, TRUE
);
1409 /* Wait for interesting events to occur in the target process. */
1411 child_wait (ptid_t ptid
, struct target_waitstatus
*ourstatus
)
1413 int pid
= PIDGET (ptid
);
1415 /* We loop when we get a non-standard exception rather than return
1416 with a SPURIOUS because resume can try and step or modify things,
1417 which needs a current_thread->h. But some of these exceptions mark
1418 the birth or death of threads, which mean that the current thread
1419 isn't necessarily what you think it is. */
1423 int retval
= get_child_debug_event (pid
, ourstatus
);
1425 return pid_to_ptid (retval
);
1430 if (deprecated_ui_loop_hook
!= NULL
)
1431 detach
= deprecated_ui_loop_hook (0);
1434 child_kill_inferior ();
1440 do_initial_child_stuff (DWORD pid
)
1442 extern int stop_after_trap
;
1445 last_sig
= TARGET_SIGNAL_0
;
1447 exception_count
= 0;
1448 debug_registers_changed
= 0;
1449 debug_registers_used
= 0;
1450 for (i
= 0; i
< sizeof (dr
) / sizeof (dr
[0]); i
++)
1452 current_event
.dwProcessId
= pid
;
1453 memset (¤t_event
, 0, sizeof (current_event
));
1454 push_target (&deprecated_child_ops
);
1455 disable_breakpoints_in_shlibs (1);
1456 child_clear_solibs ();
1457 clear_proceed_status ();
1458 init_wait_for_inferior ();
1460 target_terminal_init ();
1461 target_terminal_inferior ();
1465 stop_after_trap
= 1;
1466 wait_for_inferior ();
1467 if (stop_signal
!= TARGET_SIGNAL_TRAP
)
1468 resume (0, stop_signal
);
1472 stop_after_trap
= 0;
1476 /* Since Windows XP, detaching from a process is supported by Windows.
1477 The following code tries loading the appropriate functions dynamically.
1478 If loading these functions succeeds use them to actually detach from
1479 the inferior process, otherwise behave as usual, pretending that
1480 detach has worked. */
1481 static BOOL
WINAPI (*DebugSetProcessKillOnExit
)(BOOL
);
1482 static BOOL
WINAPI (*DebugActiveProcessStop
)(DWORD
);
1485 has_detach_ability (void)
1487 static HMODULE kernel32
= NULL
;
1490 kernel32
= LoadLibrary ("kernel32.dll");
1493 if (!DebugSetProcessKillOnExit
)
1494 DebugSetProcessKillOnExit
= GetProcAddress (kernel32
,
1495 "DebugSetProcessKillOnExit");
1496 if (!DebugActiveProcessStop
)
1497 DebugActiveProcessStop
= GetProcAddress (kernel32
,
1498 "DebugActiveProcessStop");
1499 if (DebugSetProcessKillOnExit
&& DebugActiveProcessStop
)
1505 /* Try to set or remove a user privilege to the current process. Return -1
1506 if that fails, the previous setting of that privilege otherwise.
1508 This code is copied from the Cygwin source code and rearranged to allow
1509 dynamically loading of the needed symbols from advapi32 which is only
1510 available on NT/2K/XP. */
1512 set_process_privilege (const char *privilege
, BOOL enable
)
1514 static HMODULE advapi32
= NULL
;
1515 static BOOL
WINAPI (*OpenProcessToken
)(HANDLE
, DWORD
, PHANDLE
);
1516 static BOOL
WINAPI (*LookupPrivilegeValue
)(LPCSTR
, LPCSTR
, PLUID
);
1517 static BOOL
WINAPI (*AdjustTokenPrivileges
)(HANDLE
, BOOL
, PTOKEN_PRIVILEGES
,
1518 DWORD
, PTOKEN_PRIVILEGES
, PDWORD
);
1520 HANDLE token_hdl
= NULL
;
1522 TOKEN_PRIVILEGES new_priv
, orig_priv
;
1526 if (GetVersion () >= 0x80000000) /* No security availbale on 9x/Me */
1531 if (!(advapi32
= LoadLibrary ("advapi32.dll")))
1533 if (!OpenProcessToken
)
1534 OpenProcessToken
= GetProcAddress (advapi32
, "OpenProcessToken");
1535 if (!LookupPrivilegeValue
)
1536 LookupPrivilegeValue
= GetProcAddress (advapi32
,
1537 "LookupPrivilegeValueA");
1538 if (!AdjustTokenPrivileges
)
1539 AdjustTokenPrivileges
= GetProcAddress (advapi32
,
1540 "AdjustTokenPrivileges");
1541 if (!OpenProcessToken
|| !LookupPrivilegeValue
|| !AdjustTokenPrivileges
)
1548 if (!OpenProcessToken (GetCurrentProcess (),
1549 TOKEN_QUERY
| TOKEN_ADJUST_PRIVILEGES
,
1553 if (!LookupPrivilegeValue (NULL
, privilege
, &restore_priv
))
1556 new_priv
.PrivilegeCount
= 1;
1557 new_priv
.Privileges
[0].Luid
= restore_priv
;
1558 new_priv
.Privileges
[0].Attributes
= enable
? SE_PRIVILEGE_ENABLED
: 0;
1560 if (!AdjustTokenPrivileges (token_hdl
, FALSE
, &new_priv
,
1561 sizeof orig_priv
, &orig_priv
, &size
))
1564 /* Disabled, otherwise every `attach' in an unprivileged user session
1565 would raise the "Failed to get SE_DEBUG_NAME privilege" warning in
1567 /* AdjustTokenPrivileges returns TRUE even if the privilege could not
1568 be enabled. GetLastError () returns an correct error code, though. */
1569 if (enable
&& GetLastError () == ERROR_NOT_ALL_ASSIGNED
)
1573 ret
= orig_priv
.Privileges
[0].Attributes
== SE_PRIVILEGE_ENABLED
? 1 : 0;
1577 CloseHandle (token_hdl
);
1582 /* Attach to process PID, then initialize for debugging it. */
1584 child_attach (char *args
, int from_tty
)
1590 error_no_arg (_("process-id to attach"));
1592 if (set_process_privilege (SE_DEBUG_NAME
, TRUE
) < 0)
1594 printf_unfiltered ("Warning: Failed to get SE_DEBUG_NAME privilege\n");
1595 printf_unfiltered ("This can cause attach to fail on Windows NT/2K/XP\n");
1598 pid
= strtoul (args
, 0, 0); /* Windows pid */
1600 child_init_thread_list ();
1601 ok
= DebugActiveProcess (pid
);
1606 /* Try fall back to Cygwin pid */
1607 pid
= cygwin_internal (CW_CYGWIN_PID_TO_WINPID
, pid
);
1610 ok
= DebugActiveProcess (pid
);
1613 error (_("Can't attach to process."));
1616 if (has_detach_ability ())
1617 DebugSetProcessKillOnExit (FALSE
);
1623 char *exec_file
= (char *) get_exec_file (0);
1626 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file
,
1627 target_pid_to_str (pid_to_ptid (pid
)));
1629 printf_unfiltered ("Attaching to %s\n",
1630 target_pid_to_str (pid_to_ptid (pid
)));
1632 gdb_flush (gdb_stdout
);
1635 do_initial_child_stuff (pid
);
1636 target_terminal_ours ();
1640 child_detach (char *args
, int from_tty
)
1644 if (has_detach_ability ())
1646 delete_command (NULL
, 0);
1647 child_continue (DBG_CONTINUE
, -1);
1648 if (!DebugActiveProcessStop (current_event
.dwProcessId
))
1650 error (_("Can't detach process %lu (error %lu)"),
1651 current_event
.dwProcessId
, GetLastError ());
1654 DebugSetProcessKillOnExit (FALSE
);
1656 if (detached
&& from_tty
)
1658 char *exec_file
= get_exec_file (0);
1661 printf_unfiltered ("Detaching from program: %s, Pid %lu\n", exec_file
,
1662 current_event
.dwProcessId
);
1663 gdb_flush (gdb_stdout
);
1665 inferior_ptid
= null_ptid
;
1666 unpush_target (&deprecated_child_ops
);
1670 child_pid_to_exec_file (int pid
)
1672 /* Try to find the process path using the Cygwin internal process list
1673 pid isn't a valid pid, unfortunately. Use current_event.dwProcessId
1675 /* TODO: Also find native Windows processes using CW_GETPINFO_FULL. */
1677 static char path
[MAX_PATH
+ 1];
1678 char *path_ptr
= NULL
;
1680 struct external_pinfo
*pinfo
;
1682 cygwin_internal (CW_LOCK_PINFO
, 1000);
1684 (pinfo
= (struct external_pinfo
*)
1685 cygwin_internal (CW_GETPINFO
, cpid
| CW_NEXTPID
));
1688 if (pinfo
->dwProcessId
== current_event
.dwProcessId
) /* Got it */
1690 cygwin_conv_to_full_posix_path (pinfo
->progname
, path
);
1695 cygwin_internal (CW_UNLOCK_PINFO
);
1699 /* Print status information about what we're accessing. */
1702 child_files_info (struct target_ops
*ignore
)
1704 printf_unfiltered ("\tUsing the running image of %s %s.\n",
1705 attach_flag
? "attached" : "child", target_pid_to_str (inferior_ptid
));
1709 child_open (char *arg
, int from_tty
)
1711 error (_("Use the \"run\" command to start a Unix child process."));
1714 /* Start an inferior win32 child process and sets inferior_ptid to its pid.
1715 EXEC_FILE is the file to run.
1716 ALLARGS is a string containing the arguments to the program.
1717 ENV is the environment vector to pass. Errors reported with error(). */
1720 child_create_inferior (char *exec_file
, char *allargs
, char **env
,
1728 PROCESS_INFORMATION pi
;
1732 char real_path
[MAXPATHLEN
];
1734 char shell
[MAX_PATH
+ 1]; /* Path to shell */
1737 int ostdin
, ostdout
, ostderr
;
1738 const char *inferior_io_terminal
= get_inferior_io_terminal ();
1741 error (_("No executable specified, use `target exec'."));
1743 memset (&si
, 0, sizeof (si
));
1744 si
.cb
= sizeof (si
);
1748 flags
= DEBUG_ONLY_THIS_PROCESS
;
1749 cygwin_conv_to_win32_path (exec_file
, real_path
);
1755 sh
= getenv ("SHELL");
1758 cygwin_conv_to_win32_path (sh
, shell
);
1759 newallargs
= alloca (sizeof (" -c 'exec '") + strlen (exec_file
)
1760 + strlen (allargs
) + 2);
1761 sprintf (newallargs
, " -c 'exec %s %s'", exec_file
, allargs
);
1762 allargs
= newallargs
;
1764 flags
= DEBUG_PROCESS
;
1768 flags
|= CREATE_NEW_PROCESS_GROUP
;
1771 flags
|= CREATE_NEW_CONSOLE
;
1775 args
= alloca (strlen (toexec
) + strlen (allargs
) + 2);
1776 strcpy (args
, toexec
);
1778 strcat (args
, allargs
);
1780 /* Prepare the environment vars for CreateProcess. */
1782 /* This code used to assume all env vars were file names and would
1783 translate them all to win32 style. That obviously doesn't work in the
1784 general case. The current rule is that we only translate PATH.
1785 We need to handle PATH because we're about to call CreateProcess and
1786 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
1787 in both posix and win32 environments. cygwin.dll will change it back
1788 to posix style if necessary. */
1790 static const char *conv_path_names
[] =
1796 /* CreateProcess takes the environment list as a null terminated set of
1797 strings (i.e. two nulls terminate the list). */
1799 /* Get total size for env strings. */
1800 for (envlen
= 0, i
= 0; env
[i
] && *env
[i
]; i
++)
1804 for (j
= 0; conv_path_names
[j
]; j
++)
1806 len
= strlen (conv_path_names
[j
]);
1807 if (strncmp (conv_path_names
[j
], env
[i
], len
) == 0)
1809 if (cygwin_posix_path_list_p (env
[i
] + len
))
1811 + cygwin_posix_to_win32_path_list_buf_size (env
[i
] + len
);
1813 envlen
+= strlen (env
[i
]) + 1;
1817 if (conv_path_names
[j
] == NULL
)
1818 envlen
+= strlen (env
[i
]) + 1;
1821 winenv
= alloca (envlen
+ 1);
1823 /* Copy env strings into new buffer. */
1824 for (temp
= winenv
, i
= 0; env
[i
] && *env
[i
]; i
++)
1828 for (j
= 0; conv_path_names
[j
]; j
++)
1830 len
= strlen (conv_path_names
[j
]);
1831 if (strncmp (conv_path_names
[j
], env
[i
], len
) == 0)
1833 if (cygwin_posix_path_list_p (env
[i
] + len
))
1835 memcpy (temp
, env
[i
], len
);
1836 cygwin_posix_to_win32_path_list (env
[i
] + len
, temp
+ len
);
1839 strcpy (temp
, env
[i
]);
1843 if (conv_path_names
[j
] == NULL
)
1844 strcpy (temp
, env
[i
]);
1846 temp
+= strlen (temp
) + 1;
1849 /* Final nil string to terminate new env. */
1853 if (!inferior_io_terminal
)
1854 tty
= ostdin
= ostdout
= ostderr
= -1;
1857 tty
= open (inferior_io_terminal
, O_RDWR
| O_NOCTTY
);
1860 print_sys_errmsg (inferior_io_terminal
, errno
);
1861 ostdin
= ostdout
= ostderr
= -1;
1874 child_init_thread_list ();
1875 ret
= CreateProcess (0,
1876 args
, /* command line */
1877 NULL
, /* Security */
1879 TRUE
, /* inherit handles */
1880 flags
, /* start flags */
1882 NULL
, /* current directory */
1897 error (_("Error creating process %s, (error %d)."),
1898 exec_file
, (unsigned) GetLastError ());
1900 CloseHandle (pi
.hThread
);
1901 CloseHandle (pi
.hProcess
);
1903 if (useshell
&& shell
[0] != '\0')
1908 do_initial_child_stuff (pi
.dwProcessId
);
1910 /* child_continue (DBG_CONTINUE, -1); */
1911 proceed ((CORE_ADDR
) - 1, TARGET_SIGNAL_0
, 0);
1915 child_mourn_inferior (void)
1917 (void) child_continue (DBG_CONTINUE
, -1);
1918 i386_cleanup_dregs();
1919 unpush_target (&deprecated_child_ops
);
1920 generic_mourn_inferior ();
1923 /* Send a SIGINT to the process group. This acts just like the user typed a
1924 ^C on the controlling terminal. */
1929 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
1930 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT
, current_event
.dwProcessId
));
1931 registers_changed (); /* refresh register state */
1935 child_xfer_memory (CORE_ADDR memaddr
, gdb_byte
*our
, int len
,
1936 int write
, struct mem_attrib
*mem
,
1937 struct target_ops
*target
)
1942 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
1943 len
, (DWORD
) memaddr
));
1944 if (!WriteProcessMemory (current_process_handle
, (LPVOID
) memaddr
, our
,
1947 FlushInstructionCache (current_process_handle
, (LPCVOID
) memaddr
, len
);
1951 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
1952 len
, (DWORD
) memaddr
));
1953 if (!ReadProcessMemory (current_process_handle
, (LPCVOID
) memaddr
, our
,
1961 child_kill_inferior (void)
1963 CHECK (TerminateProcess (current_process_handle
, 0));
1967 if (!child_continue (DBG_CONTINUE
, -1))
1969 if (!WaitForDebugEvent (¤t_event
, INFINITE
))
1971 if (current_event
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
)
1975 CHECK (CloseHandle (current_process_handle
));
1977 /* this may fail in an attached process so don't check. */
1978 if (current_thread
&& current_thread
->h
)
1979 (void) CloseHandle (current_thread
->h
);
1980 target_mourn_inferior (); /* or just child_mourn_inferior? */
1984 child_resume (ptid_t ptid
, int step
, enum target_signal sig
)
1987 DWORD continue_status
= DBG_CONTINUE
;
1989 int pid
= PIDGET (ptid
);
1991 if (sig
!= TARGET_SIGNAL_0
)
1993 if (current_event
.dwDebugEventCode
!= EXCEPTION_DEBUG_EVENT
)
1995 DEBUG_EXCEPT(("Cannot continue with signal %d here.\n",sig
));
1997 else if (sig
== last_sig
)
1998 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
2001 /* This code does not seem to work, because
2002 the kernel does probably not consider changes in the ExceptionRecord
2003 structure when passing the exception to the inferior.
2004 Note that this seems possible in the exception handler itself. */
2007 for (i
= 0; xlate
[i
].them
!= -1; i
++)
2008 if (xlate
[i
].us
== sig
)
2010 current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
=
2012 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
2015 if (continue_status
== DBG_CONTINUE
)
2017 DEBUG_EXCEPT(("Cannot continue with signal %d.\n",sig
));
2021 DEBUG_EXCEPT(("Can only continue with recieved signal %d.\n",
2025 last_sig
= TARGET_SIGNAL_0
;
2027 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
2030 /* Get context for currently selected thread */
2031 th
= thread_rec (current_event
.dwThreadId
, FALSE
);
2036 /* Single step by setting t bit */
2037 child_fetch_inferior_registers (PS_REGNUM
);
2038 th
->context
.EFlags
|= FLAG_TRACE_BIT
;
2041 if (th
->context
.ContextFlags
)
2043 if (debug_registers_changed
)
2045 th
->context
.Dr0
= dr
[0];
2046 th
->context
.Dr1
= dr
[1];
2047 th
->context
.Dr2
= dr
[2];
2048 th
->context
.Dr3
= dr
[3];
2049 /* th->context.Dr6 = dr[6];
2050 FIXME: should we set dr6 also ?? */
2051 th
->context
.Dr7
= dr
[7];
2053 CHECK (SetThreadContext (th
->h
, &th
->context
));
2054 th
->context
.ContextFlags
= 0;
2058 /* Allow continuing with the same signal that interrupted us.
2059 Otherwise complain. */
2061 child_continue (continue_status
, pid
);
2065 child_prepare_to_store (void)
2067 /* Do nothing, since we can store individual regs */
2071 child_can_run (void)
2079 DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n",
2080 PIDGET (inferior_ptid
)));
2084 init_child_ops (void)
2086 deprecated_child_ops
.to_shortname
= "child";
2087 deprecated_child_ops
.to_longname
= "Win32 child process";
2088 deprecated_child_ops
.to_doc
= "Win32 child process (started by the \"run\" command).";
2089 deprecated_child_ops
.to_open
= child_open
;
2090 deprecated_child_ops
.to_close
= child_close
;
2091 deprecated_child_ops
.to_attach
= child_attach
;
2092 deprecated_child_ops
.to_detach
= child_detach
;
2093 deprecated_child_ops
.to_resume
= child_resume
;
2094 deprecated_child_ops
.to_wait
= child_wait
;
2095 deprecated_child_ops
.to_fetch_registers
= child_fetch_inferior_registers
;
2096 deprecated_child_ops
.to_store_registers
= child_store_inferior_registers
;
2097 deprecated_child_ops
.to_prepare_to_store
= child_prepare_to_store
;
2098 deprecated_child_ops
.deprecated_xfer_memory
= child_xfer_memory
;
2099 deprecated_child_ops
.to_files_info
= child_files_info
;
2100 deprecated_child_ops
.to_insert_breakpoint
= memory_insert_breakpoint
;
2101 deprecated_child_ops
.to_remove_breakpoint
= memory_remove_breakpoint
;
2102 deprecated_child_ops
.to_terminal_init
= terminal_init_inferior
;
2103 deprecated_child_ops
.to_terminal_inferior
= terminal_inferior
;
2104 deprecated_child_ops
.to_terminal_ours_for_output
= terminal_ours_for_output
;
2105 deprecated_child_ops
.to_terminal_ours
= terminal_ours
;
2106 deprecated_child_ops
.to_terminal_save_ours
= terminal_save_ours
;
2107 deprecated_child_ops
.to_terminal_info
= child_terminal_info
;
2108 deprecated_child_ops
.to_kill
= child_kill_inferior
;
2109 deprecated_child_ops
.to_create_inferior
= child_create_inferior
;
2110 deprecated_child_ops
.to_mourn_inferior
= child_mourn_inferior
;
2111 deprecated_child_ops
.to_can_run
= child_can_run
;
2112 deprecated_child_ops
.to_thread_alive
= win32_child_thread_alive
;
2113 deprecated_child_ops
.to_pid_to_str
= cygwin_pid_to_str
;
2114 deprecated_child_ops
.to_stop
= child_stop
;
2115 deprecated_child_ops
.to_stratum
= process_stratum
;
2116 deprecated_child_ops
.to_has_all_memory
= 1;
2117 deprecated_child_ops
.to_has_memory
= 1;
2118 deprecated_child_ops
.to_has_stack
= 1;
2119 deprecated_child_ops
.to_has_registers
= 1;
2120 deprecated_child_ops
.to_has_execution
= 1;
2121 deprecated_child_ops
.to_magic
= OPS_MAGIC
;
2122 deprecated_child_ops
.to_pid_to_exec_file
= child_pid_to_exec_file
;
2126 _initialize_win32_nat (void)
2128 struct cmd_list_element
*c
;
2132 c
= add_com ("dll-symbols", class_files
, dll_symbol_command
,
2133 _("Load dll library symbols from FILE."));
2134 set_cmd_completer (c
, filename_completer
);
2136 add_com_alias ("sharedlibrary", "dll-symbols", class_alias
, 1);
2138 add_setshow_boolean_cmd ("shell", class_support
, &useshell
, _("\
2139 Set use of shell to start subprocess."), _("\
2140 Show use of shell to start subprocess."), NULL
,
2142 NULL
, /* FIXME: i18n: */
2143 &setlist
, &showlist
);
2145 add_setshow_boolean_cmd ("new-console", class_support
, &new_console
, _("\
2146 Set creation of new console when creating child process."), _("\
2147 Show creation of new console when creating child process."), NULL
,
2149 NULL
, /* FIXME: i18n: */
2150 &setlist
, &showlist
);
2152 add_setshow_boolean_cmd ("new-group", class_support
, &new_group
, _("\
2153 Set creation of new group when creating child process."), _("\
2154 Show creation of new group when creating child process."), NULL
,
2156 NULL
, /* FIXME: i18n: */
2157 &setlist
, &showlist
);
2159 add_setshow_boolean_cmd ("debugexec", class_support
, &debug_exec
, _("\
2160 Set whether to display execution in child process."), _("\
2161 Show whether to display execution in child process."), NULL
,
2163 NULL
, /* FIXME: i18n: */
2164 &setlist
, &showlist
);
2166 add_setshow_boolean_cmd ("debugevents", class_support
, &debug_events
, _("\
2167 Set whether to display kernel events in child process."), _("\
2168 Show whether to display kernel events in child process."), NULL
,
2170 NULL
, /* FIXME: i18n: */
2171 &setlist
, &showlist
);
2173 add_setshow_boolean_cmd ("debugmemory", class_support
, &debug_memory
, _("\
2174 Set whether to display memory accesses in child process."), _("\
2175 Show whether to display memory accesses in child process."), NULL
,
2177 NULL
, /* FIXME: i18n: */
2178 &setlist
, &showlist
);
2180 add_setshow_boolean_cmd ("debugexceptions", class_support
,
2181 &debug_exceptions
, _("\
2182 Set whether to display kernel exceptions in child process."), _("\
2183 Show whether to display kernel exceptions in child process."), NULL
,
2185 NULL
, /* FIXME: i18n: */
2186 &setlist
, &showlist
);
2188 add_info ("dll", info_dll_command
, _("Status of loaded DLLs."));
2189 add_info_alias ("sharedlibrary", "dll", 1);
2191 add_prefix_cmd ("w32", class_info
, info_w32_command
,
2192 _("Print information specific to Win32 debugging."),
2193 &info_w32_cmdlist
, "info w32 ", 0, &infolist
);
2195 add_cmd ("selector", class_info
, display_selectors
,
2196 _("Display selectors infos."),
2199 add_target (&deprecated_child_ops
);
2202 /* Hardware watchpoint support, adapted from go32-nat.c code. */
2204 /* Pass the address ADDR to the inferior in the I'th debug register.
2205 Here we just store the address in dr array, the registers will be
2206 actually set up when child_continue is called. */
2208 cygwin_set_dr (int i
, CORE_ADDR addr
)
2211 internal_error (__FILE__
, __LINE__
,
2212 _("Invalid register %d in cygwin_set_dr.\n"), i
);
2213 dr
[i
] = (unsigned) addr
;
2214 debug_registers_changed
= 1;
2215 debug_registers_used
= 1;
2218 /* Pass the value VAL to the inferior in the DR7 debug control
2219 register. Here we just store the address in D_REGS, the watchpoint
2220 will be actually set up in child_wait. */
2222 cygwin_set_dr7 (unsigned val
)
2225 debug_registers_changed
= 1;
2226 debug_registers_used
= 1;
2229 /* Get the value of the DR6 debug status register from the inferior.
2230 Here we just return the value stored in dr[6]
2231 by the last call to thread_rec for current_event.dwThreadId id. */
2233 cygwin_get_dr6 (void)
2238 /* Determine if the thread referenced by "pid" is alive
2239 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
2240 it means that the pid has died. Otherwise it is assumed to be alive. */
2242 win32_child_thread_alive (ptid_t ptid
)
2244 int pid
= PIDGET (ptid
);
2246 return WaitForSingleObject (thread_rec (pid
, FALSE
)->h
, 0) == WAIT_OBJECT_0
?
2250 /* Convert pid to printable format. */
2252 cygwin_pid_to_str (ptid_t ptid
)
2254 static char buf
[80];
2255 int pid
= PIDGET (ptid
);
2257 if ((DWORD
) pid
== current_event
.dwProcessId
)
2258 sprintf (buf
, "process %d", pid
);
2260 sprintf (buf
, "thread %ld.0x%x", current_event
.dwProcessId
, pid
);
2265 core_dll_symbols_add (char *dll_name
, DWORD base_addr
)
2267 struct objfile
*objfile
;
2268 char *objfile_basename
;
2269 const char *dll_basename
;
2271 if (!(dll_basename
= strrchr (dll_name
, '/')))
2272 dll_basename
= dll_name
;
2276 ALL_OBJFILES (objfile
)
2278 objfile_basename
= strrchr (objfile
->name
, '/');
2280 if (objfile_basename
&&
2281 strcmp (dll_basename
, objfile_basename
+ 1) == 0)
2283 printf_unfiltered ("%08lx:%s (symbols previously loaded)\n",
2284 base_addr
, dll_name
);
2289 register_loaded_dll (dll_name
, base_addr
+ 0x1000);
2290 solib_symbols_add (dll_name
, 0, (CORE_ADDR
) base_addr
+ 0x1000);
2298 struct target_ops
*target
;
2300 } map_code_section_args
;
2303 map_single_dll_code_section (bfd
* abfd
, asection
* sect
, void *obj
)
2307 struct section_table
*new_target_sect_ptr
;
2309 map_code_section_args
*args
= (map_code_section_args
*) obj
;
2310 struct target_ops
*target
= args
->target
;
2311 if (sect
->flags
& SEC_CODE
)
2313 update_coreops
= core_ops
.to_sections
== target
->to_sections
;
2315 if (target
->to_sections
)
2317 old
= target
->to_sections_end
- target
->to_sections
;
2318 target
->to_sections
= (struct section_table
*)
2319 xrealloc ((char *) target
->to_sections
,
2320 (sizeof (struct section_table
)) * (1 + old
));
2325 target
->to_sections
= (struct section_table
*)
2326 xmalloc ((sizeof (struct section_table
)));
2328 target
->to_sections_end
= target
->to_sections
+ (1 + old
);
2330 /* Update the to_sections field in the core_ops structure
2334 core_ops
.to_sections
= target
->to_sections
;
2335 core_ops
.to_sections_end
= target
->to_sections_end
;
2337 new_target_sect_ptr
= target
->to_sections
+ old
;
2338 new_target_sect_ptr
->addr
= args
->addr
+ bfd_section_vma (abfd
, sect
);
2339 new_target_sect_ptr
->endaddr
= args
->addr
+ bfd_section_vma (abfd
, sect
) +
2340 bfd_section_size (abfd
, sect
);;
2341 new_target_sect_ptr
->the_bfd_section
= sect
;
2342 new_target_sect_ptr
->bfd
= abfd
;
2347 dll_code_sections_add (const char *dll_name
, int base_addr
, struct target_ops
*target
)
2350 map_code_section_args map_args
;
2351 asection
*lowest_sect
;
2353 if (dll_name
== NULL
|| target
== NULL
)
2355 name
= xstrdup (dll_name
);
2356 dll_bfd
= bfd_openr (name
, "pei-i386");
2357 if (dll_bfd
== NULL
)
2360 if (bfd_check_format (dll_bfd
, bfd_object
))
2362 lowest_sect
= bfd_get_section_by_name (dll_bfd
, ".text");
2363 if (lowest_sect
== NULL
)
2365 map_args
.target
= target
;
2366 map_args
.addr
= base_addr
- bfd_section_vma (dll_bfd
, lowest_sect
);
2368 bfd_map_over_sections (dll_bfd
, &map_single_dll_code_section
, (void *) (&map_args
));
2375 core_section_load_dll_symbols (bfd
* abfd
, asection
* sect
, void *obj
)
2377 struct target_ops
*target
= (struct target_ops
*) obj
;
2382 char *dll_name
= NULL
;
2384 struct win32_pstatus
*pstatus
;
2387 if (strncmp (sect
->name
, ".module", 7))
2390 buf
= (char *) xmalloc (bfd_get_section_size (sect
) + 1);
2393 printf_unfiltered ("memory allocation failed for %s\n", sect
->name
);
2396 if (!bfd_get_section_contents (abfd
, sect
, buf
, 0, bfd_get_section_size (sect
)))
2399 pstatus
= (struct win32_pstatus
*) buf
;
2401 memmove (&base_addr
, &(pstatus
->data
.module_info
.base_address
), sizeof (base_addr
));
2402 dll_name_size
= pstatus
->data
.module_info
.module_name_size
;
2403 if (offsetof (struct win32_pstatus
, data
.module_info
.module_name
) + dll_name_size
> bfd_get_section_size (sect
))
2406 dll_name
= (char *) xmalloc (dll_name_size
+ 1);
2409 printf_unfiltered ("memory allocation failed for %s\n", sect
->name
);
2412 strncpy (dll_name
, pstatus
->data
.module_info
.module_name
, dll_name_size
);
2414 while ((p
= strchr (dll_name
, '\\')))
2417 if (!core_dll_symbols_add (dll_name
, (DWORD
) base_addr
))
2418 printf_unfiltered ("%s: Failed to load dll symbols.\n", dll_name
);
2420 if (!dll_code_sections_add (dll_name
, (DWORD
) base_addr
+ 0x1000, target
))
2421 printf_unfiltered ("%s: Failed to map dll code sections.\n", dll_name
);
2432 child_solib_add (char *filename
, int from_tty
, struct target_ops
*target
,
2439 child_clear_solibs ();
2440 bfd_map_over_sections (core_bfd
, &core_section_load_dll_symbols
, target
);
2444 if (solib_end
&& solib_end
->name
)
2445 solib_end
->objfile
= solib_symbols_add (solib_end
->name
, from_tty
,
2446 solib_end
->load_addr
);
2451 fetch_elf_core_registers (char *core_reg_sect
,
2452 unsigned core_reg_size
,
2457 if (core_reg_size
< sizeof (CONTEXT
))
2459 error (_("Core file register section too small (%u bytes)."), core_reg_size
);
2462 for (r
= 0; r
< NUM_REGS
; r
++)
2463 regcache_raw_supply (current_regcache
, r
, core_reg_sect
+ mappings
[r
]);
2466 static struct core_fns win32_elf_core_fns
=
2468 bfd_target_elf_flavour
,
2469 default_check_format
,
2470 default_core_sniffer
,
2471 fetch_elf_core_registers
,
2476 _initialize_core_win32 (void)
2478 deprecated_add_core_fns (&win32_elf_core_fns
);
2482 _initialize_check_for_gdb_ini (void)
2485 if (inhibit_gdbinit
)
2488 homedir
= getenv ("HOME");
2492 char *oldini
= (char *) alloca (strlen (homedir
) +
2493 sizeof ("/gdb.ini"));
2494 strcpy (oldini
, homedir
);
2495 p
= strchr (oldini
, '\0');
2496 if (p
> oldini
&& p
[-1] != '/')
2498 strcpy (p
, "gdb.ini");
2499 if (access (oldini
, 0) == 0)
2501 int len
= strlen (oldini
);
2502 char *newini
= alloca (len
+ 1);
2503 sprintf (newini
, "%.*s.gdbinit",
2504 (int) (len
- (sizeof ("gdb.ini") - 1)), oldini
);
2505 warning (_("obsolete '%s' found. Rename to '%s'."), oldini
, newini
);