1 /* Target-vector operations for controlling win32 child processes, for GDB.
2 Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
4 Contributed by Cygnus Solutions, A Red Hat Company.
6 This file is part of GDB.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without eve nthe implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* by Steve Chamberlain, sac@cygnus.com */
25 /* We assume we're being built with and will be used for cygwin. */
28 #include "frame.h" /* required by inferior.h */
33 #include "completer.h"
36 #include <sys/types.h>
41 #include <sys/cygwin.h>
46 #include "gdb_string.h"
47 #include "gdbthread.h"
49 #include <sys/param.h>
52 /* The ui's event loop. */
53 extern int (*ui_loop_hook
) (int signo
);
55 /* If we're not using the old Cygwin header file set, define the
56 following which never should have been in the generic Win32 API
57 headers in the first place since they were our own invention... */
58 #ifndef _GNU_H_WINDOWS_H
61 FLAG_TRACE_BIT
= 0x100,
62 CONTEXT_DEBUGGER
= (CONTEXT_FULL
| CONTEXT_FLOATING_POINT
)
65 #include <sys/procfs.h>
68 /* The string sent by cygwin when it processes a signal.
69 FIXME: This should be in a cygwin include file. */
70 #define CYGWIN_SIGNAL_STRING "cygwin: signal"
72 #define CHECK(x) check (x, __FILE__,__LINE__)
73 #define DEBUG_EXEC(x) if (debug_exec) printf x
74 #define DEBUG_EVENTS(x) if (debug_events) printf x
75 #define DEBUG_MEM(x) if (debug_memory) printf x
76 #define DEBUG_EXCEPT(x) if (debug_exceptions) printf x
78 /* Forward declaration */
79 extern struct target_ops child_ops
;
81 static void child_stop (void);
82 static int win32_child_thread_alive (int);
83 void child_kill_inferior (void);
85 static int last_sig
= 0; /* Set if a signal was received from the
87 /* Thread information structure used to track information that is
88 not available in gdb's thread structure. */
89 typedef struct thread_info_struct
91 struct thread_info_struct
*next
;
101 static thread_info thread_head
;
103 /* The process and thread handles for the above context. */
105 static DEBUG_EVENT current_event
; /* The current debug event from
107 static HANDLE current_process_handle
; /* Currently executing process */
108 static thread_info
*current_thread
; /* Info on currently selected thread */
109 static DWORD main_thread_id
; /* Thread ID of the main thread */
111 /* Counts of things. */
112 static int exception_count
= 0;
113 static int event_count
= 0;
116 static int new_console
= 0;
117 static int new_group
= 1;
118 static int debug_exec
= 0; /* show execution */
119 static int debug_events
= 0; /* show events from kernel */
120 static int debug_memory
= 0; /* show target memory accesses */
121 static int debug_exceptions
= 0; /* show target exceptions */
123 /* This vector maps GDB's idea of a register's number into an address
124 in the win32 exception context vector.
126 It also contains the bit mask needed to load the register in question.
128 One day we could read a reg, we could inspect the context we
129 already have loaded, if it doesn't have the bit set that we need,
130 we read that set of registers in using GetThreadContext. If the
131 context already contains what we need, we just unpack it. Then to
132 write a register, first we have to ensure that the context contains
133 the other regs of the group, and then we copy the info in and set
136 #define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
137 static const int mappings
[] =
139 context_offset (Eax
),
140 context_offset (Ecx
),
141 context_offset (Edx
),
142 context_offset (Ebx
),
143 context_offset (Esp
),
144 context_offset (Ebp
),
145 context_offset (Esi
),
146 context_offset (Edi
),
147 context_offset (Eip
),
148 context_offset (EFlags
),
149 context_offset (SegCs
),
150 context_offset (SegSs
),
151 context_offset (SegDs
),
152 context_offset (SegEs
),
153 context_offset (SegFs
),
154 context_offset (SegGs
),
155 context_offset (FloatSave
.RegisterArea
[0 * 10]),
156 context_offset (FloatSave
.RegisterArea
[1 * 10]),
157 context_offset (FloatSave
.RegisterArea
[2 * 10]),
158 context_offset (FloatSave
.RegisterArea
[3 * 10]),
159 context_offset (FloatSave
.RegisterArea
[4 * 10]),
160 context_offset (FloatSave
.RegisterArea
[5 * 10]),
161 context_offset (FloatSave
.RegisterArea
[6 * 10]),
162 context_offset (FloatSave
.RegisterArea
[7 * 10]),
163 context_offset (FloatSave
.ControlWord
),
164 context_offset (FloatSave
.StatusWord
),
165 context_offset (FloatSave
.TagWord
),
166 context_offset (FloatSave
.ErrorSelector
),
167 context_offset (FloatSave
.ErrorOffset
),
168 context_offset (FloatSave
.DataSelector
),
169 context_offset (FloatSave
.DataOffset
),
170 context_offset (FloatSave
.ErrorSelector
)
173 #undef context_offset
175 /* This vector maps the target's idea of an exception (extracted
176 from the DEBUG_EVENT structure) to GDB's idea. */
178 struct xlate_exception
181 enum target_signal us
;
184 static const struct xlate_exception
187 {EXCEPTION_ACCESS_VIOLATION
, TARGET_SIGNAL_SEGV
},
188 {STATUS_STACK_OVERFLOW
, TARGET_SIGNAL_SEGV
},
189 {EXCEPTION_BREAKPOINT
, TARGET_SIGNAL_TRAP
},
190 {DBG_CONTROL_C
, TARGET_SIGNAL_INT
},
191 {EXCEPTION_SINGLE_STEP
, TARGET_SIGNAL_TRAP
},
194 /* Find a thread record given a thread id.
195 If get_context then also retrieve the context for this
198 thread_rec (DWORD id
, int get_context
)
202 for (th
= &thread_head
; (th
= th
->next
) != NULL
;)
205 if (!th
->suspend_count
&& get_context
)
207 if (get_context
> 0 && id
!= current_event
.dwThreadId
)
208 th
->suspend_count
= SuspendThread (th
->h
) + 1;
209 else if (get_context
< 0)
210 th
->suspend_count
= -1;
212 th
->context
.ContextFlags
= CONTEXT_DEBUGGER
;
213 GetThreadContext (th
->h
, &th
->context
);
221 /* Add a thread to the thread list */
223 child_add_thread (DWORD id
, HANDLE h
)
227 if ((th
= thread_rec (id
, FALSE
)))
230 th
= (thread_info
*) xmalloc (sizeof (*th
));
231 memset (th
, 0, sizeof (*th
));
234 th
->next
= thread_head
.next
;
235 thread_head
.next
= th
;
240 /* Clear out any old thread list and reintialize it to a
243 child_init_thread_list (void)
245 thread_info
*th
= &thread_head
;
247 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
249 while (th
->next
!= NULL
)
251 thread_info
*here
= th
->next
;
252 th
->next
= here
->next
;
253 (void) CloseHandle (here
->h
);
258 /* Delete a thread from the list of threads */
260 child_delete_thread (DWORD id
)
265 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (id
));
268 for (th
= &thread_head
;
269 th
->next
!= NULL
&& th
->next
->id
!= id
;
273 if (th
->next
!= NULL
)
275 thread_info
*here
= th
->next
;
276 th
->next
= here
->next
;
277 CloseHandle (here
->h
);
283 check (BOOL ok
, const char *file
, int line
)
286 printf_filtered ("error return %s:%d was %lu\n", file
, line
, GetLastError ());
290 do_child_fetch_inferior_registers (int r
)
292 char *context_offset
= ((char *) ¤t_thread
->context
) + mappings
[r
];
296 l
= *((long *) context_offset
) & 0xffff;
297 supply_register (r
, (char *) &l
);
299 else if (r
== FOP_REGNUM
)
301 l
= (*((long *) context_offset
) >> 16) & ((1 << 11) - 1);
302 supply_register (r
, (char *) &l
);
305 supply_register (r
, context_offset
);
308 for (r
= 0; r
< NUM_REGS
; r
++)
309 do_child_fetch_inferior_registers (r
);
314 child_fetch_inferior_registers (int r
)
316 current_thread
= thread_rec (inferior_pid
, TRUE
);
317 do_child_fetch_inferior_registers (r
);
321 do_child_store_inferior_registers (int r
)
324 read_register_gen (r
, ((char *) ¤t_thread
->context
) + mappings
[r
]);
327 for (r
= 0; r
< NUM_REGS
; r
++)
328 do_child_store_inferior_registers (r
);
332 /* Store a new register value into the current thread context */
334 child_store_inferior_registers (int r
)
336 current_thread
= thread_rec (inferior_pid
, TRUE
);
337 do_child_store_inferior_registers (r
);
340 static int psapi_loaded
= 0;
341 static HMODULE psapi_module_handle
= NULL
;
342 static BOOL
WINAPI (*psapi_EnumProcessModules
) (HANDLE
, HMODULE
*, DWORD
, LPDWORD
) = NULL
;
343 static BOOL
WINAPI (*psapi_GetModuleInformation
) (HANDLE
, HMODULE
, LPMODULEINFO
, DWORD
) = NULL
;
344 static DWORD
WINAPI (*psapi_GetModuleFileNameExA
) (HANDLE
, HMODULE
, LPSTR
, DWORD
) = NULL
;
347 psapi_get_dll_name (DWORD BaseAddress
, char *dll_name_ret
)
353 HMODULE
*DllHandle
= dh_buf
;
358 psapi_EnumProcessModules
== NULL
||
359 psapi_GetModuleInformation
== NULL
||
360 psapi_GetModuleFileNameExA
== NULL
)
365 psapi_module_handle
= LoadLibrary ("psapi.dll");
366 if (!psapi_module_handle
)
368 /* printf_unfiltered ("error loading psapi.dll: %u", GetLastError ()); */
371 psapi_EnumProcessModules
= GetProcAddress (psapi_module_handle
, "EnumProcessModules");
372 psapi_GetModuleInformation
= GetProcAddress (psapi_module_handle
, "GetModuleInformation");
373 psapi_GetModuleFileNameExA
= (void *) GetProcAddress (psapi_module_handle
,
374 "GetModuleFileNameExA");
375 if (psapi_EnumProcessModules
== NULL
||
376 psapi_GetModuleInformation
== NULL
||
377 psapi_GetModuleFileNameExA
== NULL
)
382 ok
= (*psapi_EnumProcessModules
) (current_process_handle
,
387 if (!ok
|| !cbNeeded
)
390 DllHandle
= (HMODULE
*) alloca (cbNeeded
);
394 ok
= (*psapi_EnumProcessModules
) (current_process_handle
,
401 for (i
= 0; i
< (int) (cbNeeded
/ sizeof (HMODULE
)); i
++)
403 if (!(*psapi_GetModuleInformation
) (current_process_handle
,
407 error ("Can't get module info");
409 len
= (*psapi_GetModuleFileNameExA
) (current_process_handle
,
414 error ("Error getting dll name: %u\n", GetLastError ());
416 if ((DWORD
) (mi
.lpBaseOfDll
) == BaseAddress
)
421 dll_name_ret
[0] = '\0';
425 /* Encapsulate the information required in a call to
426 symbol_file_add_args */
427 struct safe_symbol_file_add_args
431 struct section_addr_info
*addrs
;
434 struct ui_file
*err
, *out
;
438 /* Call symbol_file_add with stderr redirected. We don't care if there
441 safe_symbol_file_add_stub (void *argv
)
443 #define p ((struct safe_symbol_file_add_args *)argv)
444 p
->ret
= symbol_file_add (p
->name
, p
->from_tty
, p
->addrs
, p
->mainline
, p
->flags
);
449 /* Restore gdb's stderr after calling symbol_file_add */
451 safe_symbol_file_add_cleanup (void *p
)
453 #define sp ((struct safe_symbol_file_add_args *)p)
454 gdb_flush (gdb_stderr
);
455 gdb_flush (gdb_stdout
);
456 ui_file_delete (gdb_stderr
);
457 ui_file_delete (gdb_stdout
);
458 gdb_stderr
= sp
->err
;
459 gdb_stdout
= sp
->out
;
463 /* symbol_file_add wrapper that prevents errors from being displayed. */
464 static struct objfile
*
465 safe_symbol_file_add (char *name
, int from_tty
,
466 struct section_addr_info
*addrs
,
467 int mainline
, int flags
)
469 struct safe_symbol_file_add_args p
;
470 struct cleanup
*cleanup
;
472 cleanup
= make_cleanup (safe_symbol_file_add_cleanup
, &p
);
476 gdb_flush (gdb_stderr
);
477 gdb_flush (gdb_stdout
);
478 gdb_stderr
= ui_file_new ();
479 gdb_stdout
= ui_file_new ();
481 p
.from_tty
= from_tty
;
483 p
.mainline
= mainline
;
485 catch_errors (safe_symbol_file_add_stub
, &p
, "", RETURN_MASK_ERROR
);
487 do_cleanups (cleanup
);
491 /* Maintain a linked list of "so" information. */
494 struct so_stuff
*next
, **last
;
498 solib_start
, *solib_end
;
500 /* Remember the maximum DLL length for printing in info dll command. */
501 int max_dll_name_len
;
504 register_loaded_dll (const char *name
, DWORD load_addr
)
507 so
= (struct so_stuff
*) xmalloc (sizeof (struct so_stuff
) + strlen (name
) + 8 + 2);
508 so
->load_addr
= load_addr
;
509 strcpy (so
->name
, name
);
511 solib_end
->next
= so
;
516 /* Wait for child to do something. Return pid of child, or -1 in case
517 of error; store status through argument pointer OURSTATUS. */
519 handle_load_dll (void *dummy ATTRIBUTE_UNUSED
)
521 LOAD_DLL_DEBUG_INFO
*event
= ¤t_event
.u
.LoadDll
;
524 char dll_buf
[MAX_PATH
+ 1];
525 char *dll_name
= NULL
;
529 dll_buf
[0] = dll_buf
[sizeof (dll_buf
) - 1] = '\0';
531 if (!psapi_get_dll_name ((DWORD
) (event
->lpBaseOfDll
), dll_buf
))
532 dll_buf
[0] = dll_buf
[sizeof (dll_buf
) - 1] = '\0';
536 /* Attempt to read the name of the dll that was detected.
537 This is documented to work only when actively debugging
538 a program. It will not work for attached processes. */
539 if (dll_name
== NULL
|| *dll_name
== '\0')
541 DWORD size
= event
->fUnicode
? sizeof (WCHAR
) : sizeof (char);
545 ReadProcessMemory (current_process_handle
,
546 (LPCVOID
) event
->lpImageName
,
547 (char *) &dll_name_ptr
,
548 sizeof (dll_name_ptr
), &done
);
550 /* See if we could read the address of a string, and that the
551 address isn't null. */
553 if (done
!= sizeof (dll_name_ptr
) || !dll_name_ptr
)
558 ReadProcessMemory (current_process_handle
,
559 (LPCVOID
) (dll_name_ptr
+ len
* size
),
565 while ((b
[0] != 0 || b
[size
- 1] != 0) && done
== size
);
567 dll_name
= alloca (len
);
571 WCHAR
*unicode_dll_name
= (WCHAR
*) alloca (len
* sizeof (WCHAR
));
572 ReadProcessMemory (current_process_handle
,
573 (LPCVOID
) dll_name_ptr
,
575 len
* sizeof (WCHAR
),
578 WideCharToMultiByte (CP_ACP
, 0,
579 unicode_dll_name
, len
,
580 dll_name
, len
, 0, 0);
584 ReadProcessMemory (current_process_handle
,
585 (LPCVOID
) dll_name_ptr
,
595 (void) strlwr (dll_name
);
597 while ((p
= strchr (dll_name
, '\\')))
600 register_loaded_dll (dll_name
, (DWORD
) event
->lpBaseOfDll
+ 0x1000);
601 len
= strlen (dll_name
);
602 if (len
> max_dll_name_len
)
603 max_dll_name_len
= len
;
608 /* Return name of last loaded DLL. */
610 child_solib_loaded_library_pathname (int pid ATTRIBUTE_UNUSED
)
612 return !solib_end
|| !solib_end
->name
[0] ? NULL
: solib_end
->name
;
615 /* Clear list of loaded DLLs. */
617 child_clear_solibs (void)
619 struct so_stuff
*so
, *so1
= solib_start
.next
;
621 while ((so
= so1
) != NULL
)
627 solib_start
.next
= NULL
;
628 solib_end
= &solib_start
;
629 max_dll_name_len
= sizeof ("DLL Name") - 1;
632 /* Add DLL symbol information. */
634 solib_symbols_add (char *name
, CORE_ADDR load_addr
)
636 struct section_addr_info section_addrs
;
638 /* The symbols in a dll are offset by 0x1000, which is the
639 the offset from 0 of the first byte in an image - because
640 of the file header and the section alignment. */
642 if (!name
|| !name
[0])
645 memset (§ion_addrs
, 0, sizeof (section_addrs
));
646 section_addrs
.other
[0].name
= ".text";
647 section_addrs
.other
[0].addr
= load_addr
;
648 safe_symbol_file_add (name
, 0, §ion_addrs
, 0, OBJF_SHARED
);
653 /* Load DLL symbol info. */
655 dll_symbol_command (char *args
, int from_tty ATTRIBUTE_UNUSED
)
661 error ("dll-symbols requires a file name");
664 if (n
> 4 && strcasecmp (args
+ n
- 4, ".dll") != 0)
666 char *newargs
= (char *) alloca (n
+ 4 + 1);
667 strcpy (newargs
, args
);
668 strcat (newargs
, ".dll");
672 safe_symbol_file_add (args
, 0, NULL
, 0, OBJF_SHARED
| OBJF_USERLOADED
);
675 /* List currently loaded DLLs. */
677 info_dll_command (char *ignore ATTRIBUTE_UNUSED
, int from_tty ATTRIBUTE_UNUSED
)
679 struct so_stuff
*so
= &solib_start
;
684 printf ("%*s Load Address\n", -max_dll_name_len
, "DLL Name");
685 while ((so
= so
->next
) != NULL
)
686 printf_filtered ("%*s %08lx\n", -max_dll_name_len
, so
->name
, so
->load_addr
);
691 /* Handle DEBUG_STRING output from child process.
692 Cygwin prepends its messages with a "cygwin:". Interpret this as
693 a Cygwin signal. Otherwise just print the string as a warning. */
695 handle_output_debug_string (struct target_waitstatus
*ourstatus
)
700 if (!target_read_string
701 ((CORE_ADDR
) current_event
.u
.DebugString
.lpDebugStringData
, &s
, 1024, 0)
705 if (strncmp (s
, CYGWIN_SIGNAL_STRING
, sizeof (CYGWIN_SIGNAL_STRING
) - 1) != 0)
707 if (strncmp (s
, "cYg", 3) != 0)
713 int sig
= strtol (s
+ sizeof (CYGWIN_SIGNAL_STRING
) - 1, &p
, 0);
714 gotasig
= target_signal_from_host (sig
);
715 ourstatus
->value
.sig
= gotasig
;
717 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
725 handle_exception (struct target_waitstatus
*ourstatus
)
728 DWORD code
= current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
;
730 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
732 /* Record the context of the current thread */
733 th
= thread_rec (current_event
.dwThreadId
, -1);
737 case EXCEPTION_ACCESS_VIOLATION
:
738 DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08lx\n",
739 (DWORD
) current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
740 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
743 case STATUS_FLOAT_UNDERFLOW
:
744 case STATUS_FLOAT_DIVIDE_BY_ZERO
:
745 case STATUS_FLOAT_OVERFLOW
:
746 case STATUS_INTEGER_DIVIDE_BY_ZERO
:
747 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08lx\n",
748 (DWORD
) current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
749 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
752 case STATUS_STACK_OVERFLOW
:
753 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08lx\n",
754 (DWORD
) current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
755 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
757 case EXCEPTION_BREAKPOINT
:
758 DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08lx\n",
759 (DWORD
) current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
760 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
763 DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08lx\n",
764 (DWORD
) current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
765 ourstatus
->value
.sig
= TARGET_SIGNAL_INT
;
766 last_sig
= SIGINT
; /* FIXME - should check pass state */
768 case EXCEPTION_SINGLE_STEP
:
769 DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08lx\n",
770 (DWORD
) current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
771 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
773 case EXCEPTION_ILLEGAL_INSTRUCTION
:
774 DEBUG_EXCEPT (("gdb: Target exception SINGLE_ILL at 0x%08lx\n",
775 (DWORD
) current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
776 ourstatus
->value
.sig
= TARGET_SIGNAL_ILL
;
780 printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n",
781 current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
,
782 (DWORD
) current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
);
783 ourstatus
->value
.sig
= TARGET_SIGNAL_UNKNOWN
;
790 /* Resume all artificially suspended threads if we are continuing
793 child_continue (DWORD continue_status
, int id
)
799 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, DBG_CONTINUE);\n",
800 current_event
.dwProcessId
, current_event
.dwThreadId
));
801 res
= ContinueDebugEvent (current_event
.dwProcessId
,
802 current_event
.dwThreadId
,
806 for (th
= &thread_head
; (th
= th
->next
) != NULL
;)
807 if (((id
== -1) || (id
== (int) th
->id
)) && th
->suspend_count
)
809 for (i
= 0; i
< th
->suspend_count
; i
++)
810 (void) ResumeThread (th
->h
);
811 th
->suspend_count
= 0;
817 /* Get the next event from the child. Return 1 if the event requires
818 handling by WFI (or whatever).
821 get_child_debug_event (int pid ATTRIBUTE_UNUSED
, struct target_waitstatus
*ourstatus
)
824 DWORD continue_status
, event_code
;
825 thread_info
*th
= NULL
;
826 static thread_info dummy_thread_info
;
831 if (!(debug_event
= WaitForDebugEvent (¤t_event
, 1000)))
835 continue_status
= DBG_CONTINUE
;
837 event_code
= current_event
.dwDebugEventCode
;
838 ourstatus
->kind
= TARGET_WAITKIND_SPURIOUS
;
842 case CREATE_THREAD_DEBUG_EVENT
:
843 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
844 (unsigned) current_event
.dwProcessId
,
845 (unsigned) current_event
.dwThreadId
,
846 "CREATE_THREAD_DEBUG_EVENT"));
847 /* Record the existence of this thread */
848 th
= child_add_thread (current_event
.dwThreadId
,
849 current_event
.u
.CreateThread
.hThread
);
851 printf_unfiltered ("[New %s]\n",
852 target_pid_to_str (current_event
.dwThreadId
));
853 retval
= current_event
.dwThreadId
;
856 case EXIT_THREAD_DEBUG_EVENT
:
857 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
858 (unsigned) current_event
.dwProcessId
,
859 (unsigned) current_event
.dwThreadId
,
860 "EXIT_THREAD_DEBUG_EVENT"));
861 child_delete_thread (current_event
.dwThreadId
);
862 th
= &dummy_thread_info
;
865 case CREATE_PROCESS_DEBUG_EVENT
:
866 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
867 (unsigned) current_event
.dwProcessId
,
868 (unsigned) current_event
.dwThreadId
,
869 "CREATE_PROCESS_DEBUG_EVENT"));
870 current_process_handle
= current_event
.u
.CreateProcessInfo
.hProcess
;
872 main_thread_id
= current_event
.dwThreadId
;
873 /* Add the main thread */
875 th
= child_add_thread (current_event
.dwProcessId
,
876 current_event
.u
.CreateProcessInfo
.hProcess
);
878 th
= child_add_thread (main_thread_id
,
879 current_event
.u
.CreateProcessInfo
.hThread
);
880 retval
= ourstatus
->value
.related_pid
= current_event
.dwThreadId
;
883 case EXIT_PROCESS_DEBUG_EVENT
:
884 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
885 (unsigned) current_event
.dwProcessId
,
886 (unsigned) current_event
.dwThreadId
,
887 "EXIT_PROCESS_DEBUG_EVENT"));
888 ourstatus
->kind
= TARGET_WAITKIND_EXITED
;
889 ourstatus
->value
.integer
= current_event
.u
.ExitProcess
.dwExitCode
;
890 CloseHandle (current_process_handle
);
891 retval
= main_thread_id
;
894 case LOAD_DLL_DEBUG_EVENT
:
895 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
896 (unsigned) current_event
.dwProcessId
,
897 (unsigned) current_event
.dwThreadId
,
898 "LOAD_DLL_DEBUG_EVENT"));
899 catch_errors (handle_load_dll
, NULL
, (char *) "", RETURN_MASK_ALL
);
900 registers_changed (); /* mark all regs invalid */
901 ourstatus
->kind
= TARGET_WAITKIND_LOADED
;
902 ourstatus
->value
.integer
= 0;
903 retval
= main_thread_id
;
906 case UNLOAD_DLL_DEBUG_EVENT
:
907 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
908 (unsigned) current_event
.dwProcessId
,
909 (unsigned) current_event
.dwThreadId
,
910 "UNLOAD_DLL_DEBUG_EVENT"));
911 break; /* FIXME: don't know what to do here */
913 case EXCEPTION_DEBUG_EVENT
:
914 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
915 (unsigned) current_event
.dwProcessId
,
916 (unsigned) current_event
.dwThreadId
,
917 "EXCEPTION_DEBUG_EVENT"));
918 handle_exception (ourstatus
);
919 retval
= current_event
.dwThreadId
;
922 case OUTPUT_DEBUG_STRING_EVENT
: /* message from the kernel */
923 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
924 (unsigned) current_event
.dwProcessId
,
925 (unsigned) current_event
.dwThreadId
,
926 "OUTPUT_DEBUG_STRING_EVENT"));
927 if (handle_output_debug_string (ourstatus
))
928 retval
= main_thread_id
;
932 printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
933 (DWORD
) current_event
.dwProcessId
,
934 (DWORD
) current_event
.dwThreadId
);
935 printf_unfiltered (" unknown event code %ld\n",
936 current_event
.dwDebugEventCode
);
941 CHECK (child_continue (continue_status
, -1));
944 current_thread
= th
? : thread_rec (current_event
.dwThreadId
, TRUE
);
945 inferior_pid
= retval
;
952 /* Wait for interesting events to occur in the target process. */
954 child_wait (int pid
, struct target_waitstatus
*ourstatus
)
956 /* We loop when we get a non-standard exception rather than return
957 with a SPURIOUS because resume can try and step or modify things,
958 which needs a current_thread->h. But some of these exceptions mark
959 the birth or death of threads, which mean that the current thread
960 isn't necessarily what you think it is. */
964 int retval
= get_child_debug_event (pid
, ourstatus
);
971 if (ui_loop_hook
!= NULL
)
972 detach
= ui_loop_hook (0);
975 child_kill_inferior ();
981 do_initial_child_stuff (DWORD pid
)
983 extern int stop_after_trap
;
988 current_event
.dwProcessId
= pid
;
989 memset (¤t_event
, 0, sizeof (current_event
));
990 push_target (&child_ops
);
991 child_init_thread_list ();
992 child_clear_solibs ();
993 clear_proceed_status ();
994 init_wait_for_inferior ();
996 target_terminal_init ();
997 target_terminal_inferior ();
1001 stop_after_trap
= 1;
1002 wait_for_inferior ();
1003 if (stop_signal
!= TARGET_SIGNAL_TRAP
)
1004 resume (0, stop_signal
);
1008 stop_after_trap
= 0;
1012 /* Attach to process PID, then initialize for debugging it. */
1015 child_attach (char *args
, int from_tty
)
1018 DWORD pid
= strtoul (args
, 0, 0);
1021 error_no_arg ("process-id to attach");
1023 ok
= DebugActiveProcess (pid
);
1026 error ("Can't attach to process.");
1030 char *exec_file
= (char *) get_exec_file (0);
1033 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file
,
1034 target_pid_to_str (pid
));
1036 printf_unfiltered ("Attaching to %s\n",
1037 target_pid_to_str (pid
));
1039 gdb_flush (gdb_stdout
);
1042 do_initial_child_stuff (pid
);
1043 target_terminal_ours ();
1047 child_detach (char *args ATTRIBUTE_UNUSED
, int from_tty
)
1051 char *exec_file
= get_exec_file (0);
1054 printf_unfiltered ("Detaching from program: %s %s\n", exec_file
,
1055 target_pid_to_str (inferior_pid
));
1056 gdb_flush (gdb_stdout
);
1059 unpush_target (&child_ops
);
1062 /* Print status information about what we're accessing. */
1065 child_files_info (struct target_ops
*ignore ATTRIBUTE_UNUSED
)
1067 printf_unfiltered ("\tUsing the running image of %s %s.\n",
1068 attach_flag
? "attached" : "child", target_pid_to_str (inferior_pid
));
1073 child_open (char *arg ATTRIBUTE_UNUSED
, int from_tty ATTRIBUTE_UNUSED
)
1075 error ("Use the \"run\" command to start a Unix child process.");
1078 /* Start an inferior win32 child process and sets inferior_pid to its pid.
1079 EXEC_FILE is the file to run.
1080 ALLARGS is a string containing the arguments to the program.
1081 ENV is the environment vector to pass. Errors reported with error(). */
1084 child_create_inferior (char *exec_file
, char *allargs
, char **env
)
1086 char real_path
[MAXPATHLEN
];
1092 PROCESS_INFORMATION pi
;
1098 error ("No executable specified, use `target exec'.\n");
1100 memset (&si
, 0, sizeof (si
));
1101 si
.cb
= sizeof (si
);
1103 cygwin_conv_to_win32_path (exec_file
, real_path
);
1105 flags
= DEBUG_ONLY_THIS_PROCESS
;
1108 flags
|= CREATE_NEW_PROCESS_GROUP
;
1111 flags
|= CREATE_NEW_CONSOLE
;
1113 args
= alloca (strlen (real_path
) + strlen (allargs
) + 2);
1115 strcpy (args
, real_path
);
1118 strcat (args
, allargs
);
1120 /* Prepare the environment vars for CreateProcess. */
1122 /* This code use to assume all env vars were file names and would
1123 translate them all to win32 style. That obviously doesn't work in the
1124 general case. The current rule is that we only translate PATH.
1125 We need to handle PATH because we're about to call CreateProcess and
1126 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
1127 in both posix and win32 environments. cygwin.dll will change it back
1128 to posix style if necessary. */
1130 static const char *conv_path_names
[] =
1136 /* CreateProcess takes the environment list as a null terminated set of
1137 strings (i.e. two nulls terminate the list). */
1139 /* Get total size for env strings. */
1140 for (envlen
= 0, i
= 0; env
[i
] && *env
[i
]; i
++)
1144 for (j
= 0; conv_path_names
[j
]; j
++)
1146 len
= strlen (conv_path_names
[j
]);
1147 if (strncmp (conv_path_names
[j
], env
[i
], len
) == 0)
1149 if (cygwin_posix_path_list_p (env
[i
] + len
))
1151 + cygwin_posix_to_win32_path_list_buf_size (env
[i
] + len
);
1153 envlen
+= strlen (env
[i
]) + 1;
1157 if (conv_path_names
[j
] == NULL
)
1158 envlen
+= strlen (env
[i
]) + 1;
1161 winenv
= alloca (envlen
+ 1);
1163 /* Copy env strings into new buffer. */
1164 for (temp
= winenv
, i
= 0; env
[i
] && *env
[i
]; i
++)
1168 for (j
= 0; conv_path_names
[j
]; j
++)
1170 len
= strlen (conv_path_names
[j
]);
1171 if (strncmp (conv_path_names
[j
], env
[i
], len
) == 0)
1173 if (cygwin_posix_path_list_p (env
[i
] + len
))
1175 memcpy (temp
, env
[i
], len
);
1176 cygwin_posix_to_win32_path_list (env
[i
] + len
, temp
+ len
);
1179 strcpy (temp
, env
[i
]);
1183 if (conv_path_names
[j
] == NULL
)
1184 strcpy (temp
, env
[i
]);
1186 temp
+= strlen (temp
) + 1;
1189 /* Final nil string to terminate new env. */
1193 ret
= CreateProcess (0,
1194 args
, /* command line */
1195 NULL
, /* Security */
1197 TRUE
, /* inherit handles */
1198 flags
, /* start flags */
1200 NULL
, /* current directory */
1204 error ("Error creating process %s, (error %d)\n", exec_file
, GetLastError ());
1206 do_initial_child_stuff (pi
.dwProcessId
);
1208 /* child_continue (DBG_CONTINUE, -1); */
1209 proceed ((CORE_ADDR
) - 1, TARGET_SIGNAL_0
, 0);
1213 child_mourn_inferior (void)
1215 (void) child_continue (DBG_CONTINUE
, -1);
1216 unpush_target (&child_ops
);
1217 generic_mourn_inferior ();
1220 /* Send a SIGINT to the process group. This acts just like the user typed a
1221 ^C on the controlling terminal. */
1226 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
1227 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT
, current_event
.dwProcessId
));
1228 registers_changed (); /* refresh register state */
1232 child_xfer_memory (CORE_ADDR memaddr
, char *our
, int len
,
1233 int write
, struct mem_attrib
*mem ATTRIBUTE_UNUSED
,
1234 struct target_ops
*target ATTRIBUTE_UNUSED
)
1239 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
1240 len
, (DWORD
) memaddr
));
1241 WriteProcessMemory (current_process_handle
, (LPVOID
) memaddr
, our
,
1243 FlushInstructionCache (current_process_handle
, (LPCVOID
) memaddr
, len
);
1247 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
1248 len
, (DWORD
) memaddr
));
1249 ReadProcessMemory (current_process_handle
, (LPCVOID
) memaddr
, our
, len
,
1256 child_kill_inferior (void)
1258 CHECK (TerminateProcess (current_process_handle
, 0));
1262 if (!child_continue (DBG_CONTINUE
, -1))
1264 if (!WaitForDebugEvent (¤t_event
, INFINITE
))
1266 if (current_event
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
)
1270 CHECK (CloseHandle (current_process_handle
));
1272 /* this may fail in an attached process so don't check. */
1273 (void) CloseHandle (current_thread
->h
);
1274 target_mourn_inferior (); /* or just child_mourn_inferior? */
1278 child_resume (int pid
, int step
, enum target_signal sig
)
1281 DWORD continue_status
= last_sig
> 0 && last_sig
< NSIG
?
1282 DBG_EXCEPTION_NOT_HANDLED
: DBG_CONTINUE
;
1286 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1289 /* Get context for currently selected thread */
1290 th
= thread_rec (current_event
.dwThreadId
, FALSE
);
1295 /* Single step by setting t bit */
1296 child_fetch_inferior_registers (PS_REGNUM
);
1297 th
->context
.EFlags
|= FLAG_TRACE_BIT
;
1300 if (th
->context
.ContextFlags
)
1302 CHECK (SetThreadContext (th
->h
, &th
->context
));
1303 th
->context
.ContextFlags
= 0;
1307 /* Allow continuing with the same signal that interrupted us.
1308 Otherwise complain. */
1310 child_continue (continue_status
, pid
);
1314 child_prepare_to_store (void)
1316 /* Do nothing, since we can store individual regs */
1320 child_can_run (void)
1326 child_close (int x ATTRIBUTE_UNUSED
)
1328 DEBUG_EVENTS (("gdb: child_close, inferior_pid=%d\n", inferior_pid
));
1331 struct target_ops child_ops
;
1334 init_child_ops (void)
1336 child_ops
.to_shortname
= "child";
1337 child_ops
.to_longname
= "Win32 child process";
1338 child_ops
.to_doc
= "Win32 child process (started by the \"run\" command).";
1339 child_ops
.to_open
= child_open
;
1340 child_ops
.to_close
= child_close
;
1341 child_ops
.to_attach
= child_attach
;
1342 child_ops
.to_detach
= child_detach
;
1343 child_ops
.to_resume
= child_resume
;
1344 child_ops
.to_wait
= child_wait
;
1345 child_ops
.to_fetch_registers
= child_fetch_inferior_registers
;
1346 child_ops
.to_store_registers
= child_store_inferior_registers
;
1347 child_ops
.to_prepare_to_store
= child_prepare_to_store
;
1348 child_ops
.to_xfer_memory
= child_xfer_memory
;
1349 child_ops
.to_files_info
= child_files_info
;
1350 child_ops
.to_insert_breakpoint
= memory_insert_breakpoint
;
1351 child_ops
.to_remove_breakpoint
= memory_remove_breakpoint
;
1352 child_ops
.to_terminal_init
= terminal_init_inferior
;
1353 child_ops
.to_terminal_inferior
= terminal_inferior
;
1354 child_ops
.to_terminal_ours_for_output
= terminal_ours_for_output
;
1355 child_ops
.to_terminal_ours
= terminal_ours
;
1356 child_ops
.to_terminal_info
= child_terminal_info
;
1357 child_ops
.to_kill
= child_kill_inferior
;
1358 child_ops
.to_load
= 0;
1359 child_ops
.to_lookup_symbol
= 0;
1360 child_ops
.to_create_inferior
= child_create_inferior
;
1361 child_ops
.to_mourn_inferior
= child_mourn_inferior
;
1362 child_ops
.to_can_run
= child_can_run
;
1363 child_ops
.to_notice_signals
= 0;
1364 child_ops
.to_thread_alive
= win32_child_thread_alive
;
1365 child_ops
.to_pid_to_str
= cygwin_pid_to_str
;
1366 child_ops
.to_stop
= child_stop
;
1367 child_ops
.to_stratum
= process_stratum
;
1368 child_ops
.DONT_USE
= 0;
1369 child_ops
.to_has_all_memory
= 1;
1370 child_ops
.to_has_memory
= 1;
1371 child_ops
.to_has_stack
= 1;
1372 child_ops
.to_has_registers
= 1;
1373 child_ops
.to_has_execution
= 1;
1374 child_ops
.to_sections
= 0;
1375 child_ops
.to_sections_end
= 0;
1376 child_ops
.to_magic
= OPS_MAGIC
;
1380 _initialize_inftarg (void)
1382 struct cmd_list_element
*c
;
1386 c
= add_com ("dll-symbols", class_files
, dll_symbol_command
,
1387 "Load dll library symbols from FILE.");
1388 c
->completer
= filename_completer
;
1391 add_com_alias ("sharedlibrary", "dll-symbols", class_alias
, 1);
1393 add_show_from_set (add_set_cmd ("new-console", class_support
, var_boolean
,
1394 (char *) &new_console
,
1395 "Set creation of new console when creating child process.",
1399 add_show_from_set (add_set_cmd ("new-group", class_support
, var_boolean
,
1400 (char *) &new_group
,
1401 "Set creation of new group when creating child process.",
1405 add_show_from_set (add_set_cmd ("debugexec", class_support
, var_boolean
,
1406 (char *) &debug_exec
,
1407 "Set whether to display execution in child process.",
1411 add_show_from_set (add_set_cmd ("debugevents", class_support
, var_boolean
,
1412 (char *) &debug_events
,
1413 "Set whether to display kernel events in child process.",
1417 add_show_from_set (add_set_cmd ("debugmemory", class_support
, var_boolean
,
1418 (char *) &debug_memory
,
1419 "Set whether to display memory accesses in child process.",
1423 add_show_from_set (add_set_cmd ("debugexceptions", class_support
, var_boolean
,
1424 (char *) &debug_exceptions
,
1425 "Set whether to display kernel exceptions in child process.",
1429 add_info ("dll", info_dll_command
, "Status of loaded DLLs.");
1430 add_info_alias ("sharedlibrary", "dll", 1);
1432 add_target (&child_ops
);
1435 /* Determine if the thread referenced by "pid" is alive
1436 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
1437 it means that the pid has died. Otherwise it is assumed to be alive. */
1439 win32_child_thread_alive (int pid
)
1441 return WaitForSingleObject (thread_rec (pid
, FALSE
)->h
, 0) == WAIT_OBJECT_0
?
1445 /* Convert pid to printable format. */
1447 cygwin_pid_to_str (int pid
)
1449 static char buf
[80];
1450 if ((DWORD
) pid
== current_event
.dwProcessId
)
1451 sprintf (buf
, "process %d", pid
);
1453 sprintf (buf
, "thread %ld.0x%x", current_event
.dwProcessId
, pid
);
1458 core_dll_symbols_add (char *dll_name
, DWORD base_addr
)
1460 struct objfile
*objfile
;
1461 char *objfile_basename
;
1462 const char *dll_basename
;
1464 if (!(dll_basename
= strrchr (dll_name
, '/')))
1465 dll_basename
= dll_name
;
1469 ALL_OBJFILES (objfile
)
1471 objfile_basename
= strrchr (objfile
->name
, '/');
1473 if (objfile_basename
&&
1474 strcmp (dll_basename
, objfile_basename
+ 1) == 0)
1476 printf_unfiltered ("%08lx:%s (symbols previously loaded)\n",
1477 base_addr
, dll_name
);
1482 register_loaded_dll (dll_name
, base_addr
+ 0x1000);
1483 solib_symbols_add (dll_name
, (CORE_ADDR
) base_addr
+ 0x1000);
1491 struct target_ops
*target
;
1494 map_code_section_args
;
1497 map_single_dll_code_section (bfd
* abfd
, asection
* sect
, void *obj
)
1501 struct section_table
*new_target_sect_ptr
;
1503 map_code_section_args
*args
= (map_code_section_args
*) obj
;
1504 struct target_ops
*target
= args
->target
;
1505 if (sect
->flags
& SEC_CODE
)
1507 update_coreops
= core_ops
.to_sections
== target
->to_sections
;
1509 if (target
->to_sections
)
1511 old
= target
->to_sections_end
- target
->to_sections
;
1512 target
->to_sections
= (struct section_table
*)
1513 xrealloc ((char *) target
->to_sections
,
1514 (sizeof (struct section_table
)) * (1 + old
));
1519 target
->to_sections
= (struct section_table
*)
1520 xmalloc ((sizeof (struct section_table
)));
1522 target
->to_sections_end
= target
->to_sections
+ (1 + old
);
1524 /* Update the to_sections field in the core_ops structure
1528 core_ops
.to_sections
= target
->to_sections
;
1529 core_ops
.to_sections_end
= target
->to_sections_end
;
1531 new_target_sect_ptr
= target
->to_sections
+ old
;
1532 new_target_sect_ptr
->addr
= args
->addr
+ bfd_section_vma (abfd
, sect
);
1533 new_target_sect_ptr
->endaddr
= args
->addr
+ bfd_section_vma (abfd
, sect
) +
1534 bfd_section_size (abfd
, sect
);;
1535 new_target_sect_ptr
->the_bfd_section
= sect
;
1536 new_target_sect_ptr
->bfd
= abfd
;
1541 dll_code_sections_add (const char *dll_name
, int base_addr
, struct target_ops
*target
)
1544 map_code_section_args map_args
;
1545 asection
*lowest_sect
;
1547 if (dll_name
== NULL
|| target
== NULL
)
1549 name
= xstrdup (dll_name
);
1550 dll_bfd
= bfd_openr (name
, "pei-i386");
1551 if (dll_bfd
== NULL
)
1554 if (bfd_check_format (dll_bfd
, bfd_object
))
1556 lowest_sect
= bfd_get_section_by_name (dll_bfd
, ".text");
1557 if (lowest_sect
== NULL
)
1559 map_args
.target
= target
;
1560 map_args
.addr
= base_addr
- bfd_section_vma (dll_bfd
, lowest_sect
);
1562 bfd_map_over_sections (dll_bfd
, &map_single_dll_code_section
, (void *) (&map_args
));
1569 core_section_load_dll_symbols (bfd
* abfd
, asection
* sect
, void *obj
)
1571 struct target_ops
*target
= (struct target_ops
*) obj
;
1576 char *dll_name
= NULL
;
1578 struct win32_pstatus
*pstatus
;
1581 if (strncmp (sect
->name
, ".module", 7))
1584 buf
= (char *) xmalloc (sect
->_raw_size
+ 1);
1587 printf_unfiltered ("memory allocation failed for %s\n", sect
->name
);
1590 if (!bfd_get_section_contents (abfd
, sect
, buf
, 0, sect
->_raw_size
))
1593 pstatus
= (struct win32_pstatus
*) buf
;
1595 memmove (&base_addr
, &(pstatus
->data
.module_info
.base_address
), sizeof (base_addr
));
1596 dll_name_size
= pstatus
->data
.module_info
.module_name_size
;
1597 if (offsetof (struct win32_pstatus
, data
.module_info
.module_name
) + dll_name_size
> sect
->_raw_size
)
1600 dll_name
= (char *) xmalloc (dll_name_size
+ 1);
1603 printf_unfiltered ("memory allocation failed for %s\n", sect
->name
);
1606 strncpy (dll_name
, pstatus
->data
.module_info
.module_name
, dll_name_size
);
1608 while ((p
= strchr (dll_name
, '\\')))
1611 if (!core_dll_symbols_add (dll_name
, (DWORD
) base_addr
))
1612 printf_unfiltered ("%s: Failed to load dll symbols.\n", dll_name
);
1614 if (!dll_code_sections_add (dll_name
, (DWORD
) base_addr
+ 0x1000, target
))
1615 printf_unfiltered ("%s: Failed to map dll code sections.\n", dll_name
);
1626 child_solib_add (char *filename ATTRIBUTE_UNUSED
, int from_tty ATTRIBUTE_UNUSED
, struct target_ops
*target
)
1630 child_clear_solibs ();
1631 bfd_map_over_sections (core_bfd
, &core_section_load_dll_symbols
, target
);
1635 if (solib_end
&& solib_end
->name
)
1636 solib_symbols_add (solib_end
->name
, solib_end
->load_addr
);
1641 fetch_elf_core_registers (char *core_reg_sect
,
1642 unsigned core_reg_size
,
1647 if (core_reg_size
< sizeof (CONTEXT
))
1649 error ("Core file register section too small (%u bytes).", core_reg_size
);
1652 for (r
= 0; r
< NUM_REGS
; r
++)
1653 supply_register (r
, core_reg_sect
+ mappings
[r
]);
1656 static struct core_fns win32_elf_core_fns
=
1658 bfd_target_elf_flavour
,
1659 default_check_format
,
1660 default_core_sniffer
,
1661 fetch_elf_core_registers
,
1666 _initialize_core_win32 (void)
1668 add_core_fns (&win32_elf_core_fns
);