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. */
25 /* We assume we're being built with and will be used for cygwin. */
28 #include "tm.h" /* required for SSE registers */
29 #include "frame.h" /* required by inferior.h */
34 #include "completer.h"
37 #include "i386-tdep.h"
39 #include <sys/types.h>
44 #include <sys/cygwin.h>
49 #include "gdb_string.h"
50 #include "gdbthread.h"
52 #include <sys/param.h>
55 /* The ui's event loop. */
56 extern int (*ui_loop_hook) (int signo);
58 /* If we're not using the old Cygwin header file set, define the
59 following which never should have been in the generic Win32 API
60 headers in the first place since they were our own invention... */
61 #ifndef _GNU_H_WINDOWS_H
64 FLAG_TRACE_BIT = 0x100,
65 CONTEXT_DEBUGGER = (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
68 #include <sys/procfs.h>
72 #define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_EXTENDED_REGISTERS
74 #define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER
78 /* The string sent by cygwin when it processes a signal.
79 FIXME: This should be in a cygwin include file. */
80 #define CYGWIN_SIGNAL_STRING "cygwin: signal"
82 #define CHECK(x) check (x, __FILE__,__LINE__)
83 #define DEBUG_EXEC(x) if (debug_exec) printf x
84 #define DEBUG_EVENTS(x) if (debug_events) printf x
85 #define DEBUG_MEM(x) if (debug_memory) printf x
86 #define DEBUG_EXCEPT(x) if (debug_exceptions) printf x
88 /* Forward declaration */
89 extern struct target_ops child_ops;
91 static void child_stop (void);
92 static int win32_child_thread_alive (ptid_t);
93 void child_kill_inferior (void);
95 static int last_sig = 0; /* Set if a signal was received from the
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;
111 static thread_info thread_head;
113 /* The process and thread handles for the above context. */
115 static DEBUG_EVENT current_event; /* The current debug event from
117 static HANDLE current_process_handle; /* Currently executing process */
118 static thread_info *current_thread; /* Info on currently selected thread */
119 static DWORD main_thread_id; /* Thread ID of the main thread */
121 /* Counts of things. */
122 static int exception_count = 0;
123 static int event_count = 0;
126 static int new_console = 0;
127 static int new_group = 1;
128 static int debug_exec = 0; /* show execution */
129 static int debug_events = 0; /* show events from kernel */
130 static int debug_memory = 0; /* show target memory accesses */
131 static int debug_exceptions = 0; /* show target exceptions */
133 /* This vector maps GDB's idea of a register's number into an address
134 in the win32 exception context vector.
136 It also contains the bit mask needed to load the register in question.
138 One day we could read a reg, we could inspect the context we
139 already have loaded, if it doesn't have the bit set that we need,
140 we read that set of registers in using GetThreadContext. If the
141 context already contains what we need, we just unpack it. Then to
142 write a register, first we have to ensure that the context contains
143 the other regs of the group, and then we copy the info in and set
146 #define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
147 static const int mappings[] =
149 context_offset (Eax),
150 context_offset (Ecx),
151 context_offset (Edx),
152 context_offset (Ebx),
153 context_offset (Esp),
154 context_offset (Ebp),
155 context_offset (Esi),
156 context_offset (Edi),
157 context_offset (Eip),
158 context_offset (EFlags),
159 context_offset (SegCs),
160 context_offset (SegSs),
161 context_offset (SegDs),
162 context_offset (SegEs),
163 context_offset (SegFs),
164 context_offset (SegGs),
165 context_offset (FloatSave.RegisterArea[0 * 10]),
166 context_offset (FloatSave.RegisterArea[1 * 10]),
167 context_offset (FloatSave.RegisterArea[2 * 10]),
168 context_offset (FloatSave.RegisterArea[3 * 10]),
169 context_offset (FloatSave.RegisterArea[4 * 10]),
170 context_offset (FloatSave.RegisterArea[5 * 10]),
171 context_offset (FloatSave.RegisterArea[6 * 10]),
172 context_offset (FloatSave.RegisterArea[7 * 10]),
173 context_offset (FloatSave.ControlWord),
174 context_offset (FloatSave.StatusWord),
175 context_offset (FloatSave.TagWord),
176 context_offset (FloatSave.ErrorSelector),
177 context_offset (FloatSave.ErrorOffset),
178 context_offset (FloatSave.DataSelector),
179 context_offset (FloatSave.DataOffset),
180 context_offset (FloatSave.ErrorSelector)
183 context_offset (ExtendedRegisters[10*16]),
184 context_offset (ExtendedRegisters[11*16]),
185 context_offset (ExtendedRegisters[12*16]),
186 context_offset (ExtendedRegisters[13*16]),
187 context_offset (ExtendedRegisters[14*16]),
188 context_offset (ExtendedRegisters[15*16]),
189 context_offset (ExtendedRegisters[16*16]),
190 context_offset (ExtendedRegisters[17*16]),
192 context_offset (ExtendedRegisters[24])
196 #undef context_offset
198 /* This vector maps the target's idea of an exception (extracted
199 from the DEBUG_EVENT structure) to GDB's idea. */
201 struct xlate_exception
204 enum target_signal us;
207 static const struct xlate_exception
210 {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV},
211 {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV},
212 {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP},
213 {DBG_CONTROL_C, TARGET_SIGNAL_INT},
214 {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP},
217 /* Find a thread record given a thread id.
218 If get_context then also retrieve the context for this
221 thread_rec (DWORD id, int get_context)
225 for (th = &thread_head; (th = th->next) != NULL;)
228 if (!th->suspend_count && get_context)
230 if (get_context > 0 && id != current_event.dwThreadId)
231 th->suspend_count = SuspendThread (th->h) + 1;
232 else if (get_context < 0)
233 th->suspend_count = -1;
235 th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
236 GetThreadContext (th->h, &th->context);
244 /* Add a thread to the thread list */
246 child_add_thread (DWORD id, HANDLE h)
250 if ((th = thread_rec (id, FALSE)))
253 th = (thread_info *) xmalloc (sizeof (*th));
254 memset (th, 0, sizeof (*th));
257 th->next = thread_head.next;
258 thread_head.next = th;
259 add_thread (pid_to_ptid (id));
263 /* Clear out any old thread list and reintialize it to a
266 child_init_thread_list (void)
268 thread_info *th = &thread_head;
270 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
272 while (th->next != NULL)
274 thread_info *here = th->next;
275 th->next = here->next;
276 (void) CloseHandle (here->h);
281 /* Delete a thread from the list of threads */
283 child_delete_thread (DWORD id)
288 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (pid_to_ptid (id)));
289 delete_thread (pid_to_ptid (id));
291 for (th = &thread_head;
292 th->next != NULL && th->next->id != id;
296 if (th->next != NULL)
298 thread_info *here = th->next;
299 th->next = here->next;
300 CloseHandle (here->h);
306 check (BOOL ok, const char *file, int line)
309 printf_filtered ("error return %s:%d was %lu\n", file, line, GetLastError ());
313 do_child_fetch_inferior_registers (int r)
315 char *context_offset = ((char *) ¤t_thread->context) + mappings[r];
319 l = *((long *) context_offset) & 0xffff;
320 supply_register (r, (char *) &l);
322 else if (r == FOP_REGNUM)
324 l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
325 supply_register (r, (char *) &l);
328 supply_register (r, context_offset);
331 for (r = 0; r < NUM_REGS; r++)
332 do_child_fetch_inferior_registers (r);
337 child_fetch_inferior_registers (int r)
339 current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
340 do_child_fetch_inferior_registers (r);
344 do_child_store_inferior_registers (int r)
347 read_register_gen (r, ((char *) ¤t_thread->context) + mappings[r]);
350 for (r = 0; r < NUM_REGS; r++)
351 do_child_store_inferior_registers (r);
355 /* Store a new register value into the current thread context */
357 child_store_inferior_registers (int r)
359 current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
360 do_child_store_inferior_registers (r);
363 static int psapi_loaded = 0;
364 static HMODULE psapi_module_handle = NULL;
365 static BOOL WINAPI (*psapi_EnumProcessModules) (HANDLE, HMODULE *, DWORD, LPDWORD) = NULL;
366 static BOOL WINAPI (*psapi_GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO, DWORD) = NULL;
367 static DWORD WINAPI (*psapi_GetModuleFileNameExA) (HANDLE, HMODULE, LPSTR, DWORD) = NULL;
370 psapi_get_dll_name (DWORD BaseAddress, char *dll_name_ret)
376 HMODULE *DllHandle = dh_buf;
381 psapi_EnumProcessModules == NULL ||
382 psapi_GetModuleInformation == NULL ||
383 psapi_GetModuleFileNameExA == NULL)
388 psapi_module_handle = LoadLibrary ("psapi.dll");
389 if (!psapi_module_handle)
391 /* printf_unfiltered ("error loading psapi.dll: %u", GetLastError ()); */
394 psapi_EnumProcessModules = GetProcAddress (psapi_module_handle, "EnumProcessModules");
395 psapi_GetModuleInformation = GetProcAddress (psapi_module_handle, "GetModuleInformation");
396 psapi_GetModuleFileNameExA = (void *) GetProcAddress (psapi_module_handle,
397 "GetModuleFileNameExA");
398 if (psapi_EnumProcessModules == NULL ||
399 psapi_GetModuleInformation == NULL ||
400 psapi_GetModuleFileNameExA == NULL)
405 ok = (*psapi_EnumProcessModules) (current_process_handle,
410 if (!ok || !cbNeeded)
413 DllHandle = (HMODULE *) alloca (cbNeeded);
417 ok = (*psapi_EnumProcessModules) (current_process_handle,
424 for (i = 0; i < (int) (cbNeeded / sizeof (HMODULE)); i++)
426 if (!(*psapi_GetModuleInformation) (current_process_handle,
430 error ("Can't get module info");
432 len = (*psapi_GetModuleFileNameExA) (current_process_handle,
437 error ("Error getting dll name: %u\n", GetLastError ());
439 if ((DWORD) (mi.lpBaseOfDll) == BaseAddress)
444 dll_name_ret[0] = '\0';
448 /* Encapsulate the information required in a call to
449 symbol_file_add_args */
450 struct safe_symbol_file_add_args
454 struct section_addr_info *addrs;
457 struct ui_file *err, *out;
461 /* Maintain a linked list of "so" information. */
464 struct so_stuff *next;
467 struct objfile *objfile;
469 } solib_start, *solib_end;
471 /* Call symbol_file_add with stderr redirected. We don't care if there
474 safe_symbol_file_add_stub (void *argv)
476 #define p ((struct safe_symbol_file_add_args *)argv)
477 struct so_stuff *so = &solib_start;
479 while ((so = so->next))
480 if (so->loaded && strcasecmp (so->name, p->name) == 0)
482 p->ret = symbol_file_add (p->name, p->from_tty, p->addrs, p->mainline, p->flags);
487 /* Restore gdb's stderr after calling symbol_file_add */
489 safe_symbol_file_add_cleanup (void *p)
491 #define sp ((struct safe_symbol_file_add_args *)p)
492 gdb_flush (gdb_stderr);
493 gdb_flush (gdb_stdout);
494 ui_file_delete (gdb_stderr);
495 ui_file_delete (gdb_stdout);
496 gdb_stderr = sp->err;
497 gdb_stdout = sp->out;
501 /* symbol_file_add wrapper that prevents errors from being displayed. */
502 static struct objfile *
503 safe_symbol_file_add (char *name, int from_tty,
504 struct section_addr_info *addrs,
505 int mainline, int flags)
507 struct safe_symbol_file_add_args p;
508 struct cleanup *cleanup;
510 cleanup = make_cleanup (safe_symbol_file_add_cleanup, &p);
514 gdb_flush (gdb_stderr);
515 gdb_flush (gdb_stdout);
516 gdb_stderr = ui_file_new ();
517 gdb_stdout = ui_file_new ();
519 p.from_tty = from_tty;
521 p.mainline = mainline;
523 catch_errors (safe_symbol_file_add_stub, &p, "", RETURN_MASK_ERROR);
525 do_cleanups (cleanup);
529 /* Remember the maximum DLL length for printing in info dll command. */
530 int max_dll_name_len;
533 register_loaded_dll (const char *name, DWORD load_addr)
536 char ppath[MAX_PATH + 1];
537 char buf[MAX_PATH + 1];
538 char cwd[MAX_PATH + 1];
540 WIN32_FIND_DATA w32_fd;
541 HANDLE h = FindFirstFile(name, &w32_fd);
546 if (GetCurrentDirectory (MAX_PATH + 1, cwd))
548 p = strrchr (buf, '\\');
551 SetCurrentDirectory (buf);
552 GetFullPathName (w32_fd.cFileName, MAX_PATH, buf, &p);
553 SetCurrentDirectory (cwd);
556 cygwin_conv_to_posix_path (buf, ppath);
557 so = (struct so_stuff *) xmalloc (sizeof (struct so_stuff) + strlen (ppath) + 8 + 1);
559 so->load_addr = load_addr;
562 strcpy (so->name, ppath);
564 solib_end->next = so;
566 len = strlen (ppath);
567 if (len > max_dll_name_len)
568 max_dll_name_len = len;
571 /* Wait for child to do something. Return pid of child, or -1 in case
572 of error; store status through argument pointer OURSTATUS. */
574 handle_load_dll (void *dummy ATTRIBUTE_UNUSED)
576 LOAD_DLL_DEBUG_INFO *event = ¤t_event.u.LoadDll;
579 char dll_buf[MAX_PATH + 1];
580 char *dll_name = NULL;
583 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
585 if (!psapi_get_dll_name ((DWORD) (event->lpBaseOfDll), dll_buf))
586 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
590 /* Attempt to read the name of the dll that was detected.
591 This is documented to work only when actively debugging
592 a program. It will not work for attached processes. */
593 if (dll_name == NULL || *dll_name == '\0')
595 DWORD size = event->fUnicode ? sizeof (WCHAR) : sizeof (char);
599 ReadProcessMemory (current_process_handle,
600 (LPCVOID) event->lpImageName,
601 (char *) &dll_name_ptr,
602 sizeof (dll_name_ptr), &done);
604 /* See if we could read the address of a string, and that the
605 address isn't null. */
607 if (done != sizeof (dll_name_ptr) || !dll_name_ptr)
612 ReadProcessMemory (current_process_handle,
613 (LPCVOID) (dll_name_ptr + len * size),
619 while ((b[0] != 0 || b[size - 1] != 0) && done == size);
621 dll_name = alloca (len);
625 WCHAR *unicode_dll_name = (WCHAR *) alloca (len * sizeof (WCHAR));
626 ReadProcessMemory (current_process_handle,
627 (LPCVOID) dll_name_ptr,
629 len * sizeof (WCHAR),
632 WideCharToMultiByte (CP_ACP, 0,
633 unicode_dll_name, len,
634 dll_name, len, 0, 0);
638 ReadProcessMemory (current_process_handle,
639 (LPCVOID) dll_name_ptr,
649 register_loaded_dll (dll_name, (DWORD) event->lpBaseOfDll + 0x1000);
655 handle_unload_dll (void *dummy ATTRIBUTE_UNUSED)
657 DWORD lpBaseOfDll = (DWORD) current_event.u.UnloadDll.lpBaseOfDll + 0x1000;
660 for (so = &solib_start; so->next != NULL; so = so->next)
661 if (so->next->load_addr == lpBaseOfDll)
663 struct so_stuff *sodel = so->next;
664 so->next = sodel->next;
668 free_objfile (sodel->objfile);
672 error ("Error: dll starting at 0x%lx not found.\n", (DWORD) lpBaseOfDll);
677 /* Return name of last loaded DLL. */
679 child_solib_loaded_library_pathname (int pid ATTRIBUTE_UNUSED)
681 return !solib_end || !solib_end->name[0] ? NULL : solib_end->name;
684 /* Clear list of loaded DLLs. */
686 child_clear_solibs (void)
688 struct so_stuff *so, *so1 = solib_start.next;
690 while ((so = so1) != NULL)
696 solib_start.next = NULL;
697 solib_start.objfile = NULL;
698 solib_end = &solib_start;
699 max_dll_name_len = sizeof ("DLL Name") - 1;
702 /* Add DLL symbol information. */
703 static struct objfile *
704 solib_symbols_add (char *name, int from_tty, CORE_ADDR load_addr)
706 struct section_addr_info section_addrs;
708 /* The symbols in a dll are offset by 0x1000, which is the
709 the offset from 0 of the first byte in an image - because
710 of the file header and the section alignment. */
712 if (!name || !name[0])
715 memset (§ion_addrs, 0, sizeof (section_addrs));
716 section_addrs.other[0].name = ".text";
717 section_addrs.other[0].addr = load_addr;
718 return safe_symbol_file_add (name, from_tty, NULL, 0, OBJF_SHARED);
721 /* Load DLL symbol info. */
723 dll_symbol_command (char *args, int from_tty)
729 error ("dll-symbols requires a file name");
732 if (n > 4 && strcasecmp (args + n - 4, ".dll") != 0)
734 char *newargs = (char *) alloca (n + 4 + 1);
735 strcpy (newargs, args);
736 strcat (newargs, ".dll");
740 safe_symbol_file_add (args, from_tty, NULL, 0, OBJF_SHARED | OBJF_USERLOADED);
743 /* List currently loaded DLLs. */
745 info_dll_command (char *ignore ATTRIBUTE_UNUSED, int from_tty ATTRIBUTE_UNUSED)
747 struct so_stuff *so = &solib_start;
752 printf ("%*s Load Address\n", -max_dll_name_len, "DLL Name");
753 while ((so = so->next) != NULL)
754 printf_filtered ("%*s %08lx\n", -max_dll_name_len, so->name, so->load_addr);
759 /* Handle DEBUG_STRING output from child process.
760 Cygwin prepends its messages with a "cygwin:". Interpret this as
761 a Cygwin signal. Otherwise just print the string as a warning. */
763 handle_output_debug_string (struct target_waitstatus *ourstatus)
768 if (!target_read_string
769 ((CORE_ADDR) current_event.u.DebugString.lpDebugStringData, &s, 1024, 0)
773 if (strncmp (s, CYGWIN_SIGNAL_STRING, sizeof (CYGWIN_SIGNAL_STRING) - 1) != 0)
775 if (strncmp (s, "cYg", 3) != 0)
781 int sig = strtol (s + sizeof (CYGWIN_SIGNAL_STRING) - 1, &p, 0);
782 gotasig = target_signal_from_host (sig);
783 ourstatus->value.sig = gotasig;
785 ourstatus->kind = TARGET_WAITKIND_STOPPED;
793 handle_exception (struct target_waitstatus *ourstatus)
796 DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
798 ourstatus->kind = TARGET_WAITKIND_STOPPED;
800 /* Record the context of the current thread */
801 th = thread_rec (current_event.dwThreadId, -1);
805 case EXCEPTION_ACCESS_VIOLATION:
806 DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08lx\n",
807 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
808 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
811 case STATUS_FLOAT_UNDERFLOW:
812 case STATUS_FLOAT_DIVIDE_BY_ZERO:
813 case STATUS_FLOAT_OVERFLOW:
814 case STATUS_INTEGER_DIVIDE_BY_ZERO:
815 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08lx\n",
816 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
817 ourstatus->value.sig = TARGET_SIGNAL_FPE;
820 case STATUS_STACK_OVERFLOW:
821 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08lx\n",
822 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
823 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
825 case EXCEPTION_BREAKPOINT:
826 DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08lx\n",
827 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
828 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
831 DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08lx\n",
832 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
833 ourstatus->value.sig = TARGET_SIGNAL_INT;
834 last_sig = SIGINT; /* FIXME - should check pass state */
836 case EXCEPTION_SINGLE_STEP:
837 DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08lx\n",
838 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
839 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
841 case EXCEPTION_ILLEGAL_INSTRUCTION:
842 DEBUG_EXCEPT (("gdb: Target exception SINGLE_ILL at 0x%08lx\n",
843 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
844 ourstatus->value.sig = TARGET_SIGNAL_ILL;
848 if (current_event.u.Exception.dwFirstChance)
850 printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n",
851 current_event.u.Exception.ExceptionRecord.ExceptionCode,
852 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress);
853 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
860 /* Resume all artificially suspended threads if we are continuing
863 child_continue (DWORD continue_status, int id)
869 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, DBG_CONTINUE);\n",
870 current_event.dwProcessId, current_event.dwThreadId));
871 res = ContinueDebugEvent (current_event.dwProcessId,
872 current_event.dwThreadId,
876 for (th = &thread_head; (th = th->next) != NULL;)
877 if (((id == -1) || (id == (int) th->id)) && th->suspend_count)
879 for (i = 0; i < th->suspend_count; i++)
880 (void) ResumeThread (th->h);
881 th->suspend_count = 0;
887 /* Get the next event from the child. Return 1 if the event requires
888 handling by WFI (or whatever).
891 get_child_debug_event (int pid ATTRIBUTE_UNUSED, struct target_waitstatus *ourstatus)
894 DWORD continue_status, event_code;
895 thread_info *th = NULL;
896 static thread_info dummy_thread_info;
901 if (!(debug_event = WaitForDebugEvent (¤t_event, 1000)))
905 continue_status = DBG_CONTINUE;
907 event_code = current_event.dwDebugEventCode;
908 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
912 case CREATE_THREAD_DEBUG_EVENT:
913 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
914 (unsigned) current_event.dwProcessId,
915 (unsigned) current_event.dwThreadId,
916 "CREATE_THREAD_DEBUG_EVENT"));
917 /* Record the existence of this thread */
918 th = child_add_thread (current_event.dwThreadId,
919 current_event.u.CreateThread.hThread);
921 printf_unfiltered ("[New %s]\n",
923 pid_to_ptid (current_event.dwThreadId)));
924 retval = current_event.dwThreadId;
927 case EXIT_THREAD_DEBUG_EVENT:
928 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
929 (unsigned) current_event.dwProcessId,
930 (unsigned) current_event.dwThreadId,
931 "EXIT_THREAD_DEBUG_EVENT"));
932 child_delete_thread (current_event.dwThreadId);
933 th = &dummy_thread_info;
936 case CREATE_PROCESS_DEBUG_EVENT:
937 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
938 (unsigned) current_event.dwProcessId,
939 (unsigned) current_event.dwThreadId,
940 "CREATE_PROCESS_DEBUG_EVENT"));
941 CloseHandle (current_event.u.CreateProcessInfo.hFile);
942 current_process_handle = current_event.u.CreateProcessInfo.hProcess;
944 main_thread_id = current_event.dwThreadId;
945 /* Add the main thread */
947 th = child_add_thread (current_event.dwProcessId,
948 current_event.u.CreateProcessInfo.hProcess);
950 th = child_add_thread (main_thread_id,
951 current_event.u.CreateProcessInfo.hThread);
952 retval = ourstatus->value.related_pid = current_event.dwThreadId;
955 case EXIT_PROCESS_DEBUG_EVENT:
956 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
957 (unsigned) current_event.dwProcessId,
958 (unsigned) current_event.dwThreadId,
959 "EXIT_PROCESS_DEBUG_EVENT"));
960 ourstatus->kind = TARGET_WAITKIND_EXITED;
961 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
962 CloseHandle (current_process_handle);
963 retval = main_thread_id;
966 case LOAD_DLL_DEBUG_EVENT:
967 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
968 (unsigned) current_event.dwProcessId,
969 (unsigned) current_event.dwThreadId,
970 "LOAD_DLL_DEBUG_EVENT"));
971 CloseHandle (current_event.u.LoadDll.hFile);
972 catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
973 registers_changed (); /* mark all regs invalid */
974 ourstatus->kind = TARGET_WAITKIND_LOADED;
975 ourstatus->value.integer = 0;
976 retval = main_thread_id;
979 case UNLOAD_DLL_DEBUG_EVENT:
980 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
981 (unsigned) current_event.dwProcessId,
982 (unsigned) current_event.dwThreadId,
983 "UNLOAD_DLL_DEBUG_EVENT"));
984 catch_errors (handle_unload_dll, NULL, (char *) "", RETURN_MASK_ALL);
985 registers_changed (); /* mark all regs invalid */
986 /* ourstatus->kind = TARGET_WAITKIND_UNLOADED;
987 does not exist yet. */
990 case EXCEPTION_DEBUG_EVENT:
991 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
992 (unsigned) current_event.dwProcessId,
993 (unsigned) current_event.dwThreadId,
994 "EXCEPTION_DEBUG_EVENT"));
995 if (handle_exception (ourstatus))
996 retval = current_event.dwThreadId;
999 case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */
1000 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1001 (unsigned) current_event.dwProcessId,
1002 (unsigned) current_event.dwThreadId,
1003 "OUTPUT_DEBUG_STRING_EVENT"));
1004 if (handle_output_debug_string (ourstatus))
1005 retval = main_thread_id;
1009 printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
1010 (DWORD) current_event.dwProcessId,
1011 (DWORD) current_event.dwThreadId);
1012 printf_unfiltered (" unknown event code %ld\n",
1013 current_event.dwDebugEventCode);
1018 CHECK (child_continue (continue_status, -1));
1021 current_thread = th ? : thread_rec (current_event.dwThreadId, TRUE);
1022 inferior_ptid = pid_to_ptid (retval);
1029 /* Wait for interesting events to occur in the target process. */
1031 child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
1033 int pid = PIDGET (ptid);
1035 /* We loop when we get a non-standard exception rather than return
1036 with a SPURIOUS because resume can try and step or modify things,
1037 which needs a current_thread->h. But some of these exceptions mark
1038 the birth or death of threads, which mean that the current thread
1039 isn't necessarily what you think it is. */
1043 int retval = get_child_debug_event (pid, ourstatus);
1045 return pid_to_ptid (retval);
1050 if (ui_loop_hook != NULL)
1051 detach = ui_loop_hook (0);
1054 child_kill_inferior ();
1060 do_initial_child_stuff (DWORD pid)
1062 extern int stop_after_trap;
1066 exception_count = 0;
1067 current_event.dwProcessId = pid;
1068 memset (¤t_event, 0, sizeof (current_event));
1069 push_target (&child_ops);
1070 child_init_thread_list ();
1071 child_clear_solibs ();
1072 clear_proceed_status ();
1073 init_wait_for_inferior ();
1075 target_terminal_init ();
1076 target_terminal_inferior ();
1080 stop_after_trap = 1;
1081 wait_for_inferior ();
1082 if (stop_signal != TARGET_SIGNAL_TRAP)
1083 resume (0, stop_signal);
1087 stop_after_trap = 0;
1091 /* Since Windows XP, detaching from a process is supported by Windows.
1092 The following code tries loading the appropriate functions dynamically.
1093 If loading these functions succeeds use them to actually detach from
1094 the inferior process, otherwise behave as usual, pretending that
1095 detach has worked. */
1096 static BOOL WINAPI (*DebugSetProcessKillOnExit)(BOOL);
1097 static BOOL WINAPI (*DebugActiveProcessStop)(DWORD);
1100 has_detach_ability ()
1102 static HMODULE kernel32 = NULL;
1105 kernel32 = LoadLibrary ("kernel32.dll");
1108 if (!DebugSetProcessKillOnExit)
1109 DebugSetProcessKillOnExit = GetProcAddress (kernel32,
1110 "DebugSetProcessKillOnExit");
1111 if (!DebugActiveProcessStop)
1112 DebugActiveProcessStop = GetProcAddress (kernel32,
1113 "DebugActiveProcessStop");
1114 if (DebugSetProcessKillOnExit && DebugActiveProcessStop)
1120 /* Attach to process PID, then initialize for debugging it. */
1122 child_attach (char *args, int from_tty)
1128 error_no_arg ("process-id to attach");
1130 pid = strtoul (args, 0, 0);
1131 ok = DebugActiveProcess (pid);
1134 error ("Can't attach to process.");
1136 if (has_detach_ability ())
1139 DebugSetProcessKillOnExit (FALSE);
1144 char *exec_file = (char *) get_exec_file (0);
1147 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
1148 target_pid_to_str (pid_to_ptid (pid)));
1150 printf_unfiltered ("Attaching to %s\n",
1151 target_pid_to_str (pid_to_ptid (pid)));
1153 gdb_flush (gdb_stdout);
1156 do_initial_child_stuff (pid);
1157 target_terminal_ours ();
1161 child_detach (char *args ATTRIBUTE_UNUSED, int from_tty)
1165 if (has_detach_ability ())
1167 delete_command (NULL, 0);
1168 child_continue (DBG_CONTINUE, -1);
1169 if (!DebugActiveProcessStop (current_event.dwProcessId))
1171 error ("Can't detach process %lu (error %lu)",
1172 current_event.dwProcessId, GetLastError ());
1175 DebugSetProcessKillOnExit (FALSE);
1177 if (detached && from_tty)
1179 char *exec_file = get_exec_file (0);
1182 printf_unfiltered ("Detaching from program: %s, Pid %lu\n", exec_file,
1183 current_event.dwProcessId);
1184 gdb_flush (gdb_stdout);
1186 inferior_ptid = null_ptid;
1187 unpush_target (&child_ops);
1190 /* Print status information about what we're accessing. */
1193 child_files_info (struct target_ops *ignore ATTRIBUTE_UNUSED)
1195 printf_unfiltered ("\tUsing the running image of %s %s.\n",
1196 attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid));
1201 child_open (char *arg ATTRIBUTE_UNUSED, int from_tty ATTRIBUTE_UNUSED)
1203 error ("Use the \"run\" command to start a Unix child process.");
1206 /* Start an inferior win32 child process and sets inferior_ptid to its pid.
1207 EXEC_FILE is the file to run.
1208 ALLARGS is a string containing the arguments to the program.
1209 ENV is the environment vector to pass. Errors reported with error(). */
1212 child_create_inferior (char *exec_file, char *allargs, char **env)
1214 char real_path[MAXPATHLEN];
1220 PROCESS_INFORMATION pi;
1226 error ("No executable specified, use `target exec'.\n");
1228 memset (&si, 0, sizeof (si));
1229 si.cb = sizeof (si);
1231 cygwin_conv_to_win32_path (exec_file, real_path);
1233 flags = DEBUG_ONLY_THIS_PROCESS;
1236 flags |= CREATE_NEW_PROCESS_GROUP;
1239 flags |= CREATE_NEW_CONSOLE;
1241 args = alloca (strlen (real_path) + strlen (allargs) + 2);
1243 strcpy (args, real_path);
1246 strcat (args, allargs);
1248 /* Prepare the environment vars for CreateProcess. */
1250 /* This code use to assume all env vars were file names and would
1251 translate them all to win32 style. That obviously doesn't work in the
1252 general case. The current rule is that we only translate PATH.
1253 We need to handle PATH because we're about to call CreateProcess and
1254 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
1255 in both posix and win32 environments. cygwin.dll will change it back
1256 to posix style if necessary. */
1258 static const char *conv_path_names[] =
1264 /* CreateProcess takes the environment list as a null terminated set of
1265 strings (i.e. two nulls terminate the list). */
1267 /* Get total size for env strings. */
1268 for (envlen = 0, i = 0; env[i] && *env[i]; i++)
1272 for (j = 0; conv_path_names[j]; j++)
1274 len = strlen (conv_path_names[j]);
1275 if (strncmp (conv_path_names[j], env[i], len) == 0)
1277 if (cygwin_posix_path_list_p (env[i] + len))
1279 + cygwin_posix_to_win32_path_list_buf_size (env[i] + len);
1281 envlen += strlen (env[i]) + 1;
1285 if (conv_path_names[j] == NULL)
1286 envlen += strlen (env[i]) + 1;
1289 winenv = alloca (envlen + 1);
1291 /* Copy env strings into new buffer. */
1292 for (temp = winenv, i = 0; env[i] && *env[i]; i++)
1296 for (j = 0; conv_path_names[j]; j++)
1298 len = strlen (conv_path_names[j]);
1299 if (strncmp (conv_path_names[j], env[i], len) == 0)
1301 if (cygwin_posix_path_list_p (env[i] + len))
1303 memcpy (temp, env[i], len);
1304 cygwin_posix_to_win32_path_list (env[i] + len, temp + len);
1307 strcpy (temp, env[i]);
1311 if (conv_path_names[j] == NULL)
1312 strcpy (temp, env[i]);
1314 temp += strlen (temp) + 1;
1317 /* Final nil string to terminate new env. */
1321 ret = CreateProcess (0,
1322 args, /* command line */
1323 NULL, /* Security */
1325 TRUE, /* inherit handles */
1326 flags, /* start flags */
1328 NULL, /* current directory */
1332 error ("Error creating process %s, (error %d)\n", exec_file, GetLastError ());
1334 CloseHandle (pi.hThread);
1335 CloseHandle (pi.hProcess);
1336 do_initial_child_stuff (pi.dwProcessId);
1338 /* child_continue (DBG_CONTINUE, -1); */
1339 proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
1343 child_mourn_inferior (void)
1345 (void) child_continue (DBG_CONTINUE, -1);
1346 unpush_target (&child_ops);
1347 generic_mourn_inferior ();
1350 /* Send a SIGINT to the process group. This acts just like the user typed a
1351 ^C on the controlling terminal. */
1356 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
1357 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
1358 registers_changed (); /* refresh register state */
1362 child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
1363 int write, struct mem_attrib *mem ATTRIBUTE_UNUSED,
1364 struct target_ops *target ATTRIBUTE_UNUSED)
1369 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
1370 len, (DWORD) memaddr));
1371 WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our,
1373 FlushInstructionCache (current_process_handle, (LPCVOID) memaddr, len);
1377 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
1378 len, (DWORD) memaddr));
1379 ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our, len,
1386 child_kill_inferior (void)
1388 CHECK (TerminateProcess (current_process_handle, 0));
1392 if (!child_continue (DBG_CONTINUE, -1))
1394 if (!WaitForDebugEvent (¤t_event, INFINITE))
1396 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
1400 CHECK (CloseHandle (current_process_handle));
1402 /* this may fail in an attached process so don't check. */
1403 (void) CloseHandle (current_thread->h);
1404 target_mourn_inferior (); /* or just child_mourn_inferior? */
1408 child_resume (ptid_t ptid, int step, enum target_signal sig)
1411 DWORD continue_status = last_sig > 0 && last_sig < NSIG ?
1412 DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE;
1413 int pid = PIDGET (ptid);
1417 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1420 /* Get context for currently selected thread */
1421 th = thread_rec (current_event.dwThreadId, FALSE);
1426 /* Single step by setting t bit */
1427 child_fetch_inferior_registers (PS_REGNUM);
1428 th->context.EFlags |= FLAG_TRACE_BIT;
1431 if (th->context.ContextFlags)
1433 CHECK (SetThreadContext (th->h, &th->context));
1434 th->context.ContextFlags = 0;
1438 /* Allow continuing with the same signal that interrupted us.
1439 Otherwise complain. */
1441 child_continue (continue_status, pid);
1445 child_prepare_to_store (void)
1447 /* Do nothing, since we can store individual regs */
1451 child_can_run (void)
1457 child_close (int x ATTRIBUTE_UNUSED)
1459 DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n",
1460 PIDGET (inferior_ptid)));
1463 struct target_ops child_ops;
1466 init_child_ops (void)
1468 child_ops.to_shortname = "child";
1469 child_ops.to_longname = "Win32 child process";
1470 child_ops.to_doc = "Win32 child process (started by the \"run\" command).";
1471 child_ops.to_open = child_open;
1472 child_ops.to_close = child_close;
1473 child_ops.to_attach = child_attach;
1474 child_ops.to_detach = child_detach;
1475 child_ops.to_resume = child_resume;
1476 child_ops.to_wait = child_wait;
1477 child_ops.to_fetch_registers = child_fetch_inferior_registers;
1478 child_ops.to_store_registers = child_store_inferior_registers;
1479 child_ops.to_prepare_to_store = child_prepare_to_store;
1480 child_ops.to_xfer_memory = child_xfer_memory;
1481 child_ops.to_files_info = child_files_info;
1482 child_ops.to_insert_breakpoint = memory_insert_breakpoint;
1483 child_ops.to_remove_breakpoint = memory_remove_breakpoint;
1484 child_ops.to_terminal_init = terminal_init_inferior;
1485 child_ops.to_terminal_inferior = terminal_inferior;
1486 child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1487 child_ops.to_terminal_ours = terminal_ours;
1488 child_ops.to_terminal_info = child_terminal_info;
1489 child_ops.to_kill = child_kill_inferior;
1490 child_ops.to_load = 0;
1491 child_ops.to_lookup_symbol = 0;
1492 child_ops.to_create_inferior = child_create_inferior;
1493 child_ops.to_mourn_inferior = child_mourn_inferior;
1494 child_ops.to_can_run = child_can_run;
1495 child_ops.to_notice_signals = 0;
1496 child_ops.to_thread_alive = win32_child_thread_alive;
1497 child_ops.to_pid_to_str = cygwin_pid_to_str;
1498 child_ops.to_stop = child_stop;
1499 child_ops.to_stratum = process_stratum;
1500 child_ops.DONT_USE = 0;
1501 child_ops.to_has_all_memory = 1;
1502 child_ops.to_has_memory = 1;
1503 child_ops.to_has_stack = 1;
1504 child_ops.to_has_registers = 1;
1505 child_ops.to_has_execution = 1;
1506 child_ops.to_sections = 0;
1507 child_ops.to_sections_end = 0;
1508 child_ops.to_magic = OPS_MAGIC;
1512 _initialize_inftarg (void)
1514 struct cmd_list_element *c;
1518 c = add_com ("dll-symbols", class_files, dll_symbol_command,
1519 "Load dll library symbols from FILE.");
1520 c->completer = filename_completer;
1522 add_com_alias ("sharedlibrary", "dll-symbols", class_alias, 1);
1524 add_show_from_set (add_set_cmd ("new-console", class_support, var_boolean,
1525 (char *) &new_console,
1526 "Set creation of new console when creating child process.",
1530 add_show_from_set (add_set_cmd ("new-group", class_support, var_boolean,
1531 (char *) &new_group,
1532 "Set creation of new group when creating child process.",
1536 add_show_from_set (add_set_cmd ("debugexec", class_support, var_boolean,
1537 (char *) &debug_exec,
1538 "Set whether to display execution in child process.",
1542 add_show_from_set (add_set_cmd ("debugevents", class_support, var_boolean,
1543 (char *) &debug_events,
1544 "Set whether to display kernel events in child process.",
1548 add_show_from_set (add_set_cmd ("debugmemory", class_support, var_boolean,
1549 (char *) &debug_memory,
1550 "Set whether to display memory accesses in child process.",
1554 add_show_from_set (add_set_cmd ("debugexceptions", class_support, var_boolean,
1555 (char *) &debug_exceptions,
1556 "Set whether to display kernel exceptions in child process.",
1560 add_info ("dll", info_dll_command, "Status of loaded DLLs.");
1561 add_info_alias ("sharedlibrary", "dll", 1);
1563 add_target (&child_ops);
1566 /* Determine if the thread referenced by "pid" is alive
1567 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
1568 it means that the pid has died. Otherwise it is assumed to be alive. */
1570 win32_child_thread_alive (ptid_t ptid)
1572 int pid = PIDGET (ptid);
1574 return WaitForSingleObject (thread_rec (pid, FALSE)->h, 0) == WAIT_OBJECT_0 ?
1578 /* Convert pid to printable format. */
1580 cygwin_pid_to_str (ptid_t ptid)
1582 static char buf[80];
1583 int pid = PIDGET (ptid);
1585 if ((DWORD) pid == current_event.dwProcessId)
1586 sprintf (buf, "process %d", pid);
1588 sprintf (buf, "thread %ld.0x%x", current_event.dwProcessId, pid);
1593 core_dll_symbols_add (char *dll_name, DWORD base_addr)
1595 struct objfile *objfile;
1596 char *objfile_basename;
1597 const char *dll_basename;
1599 if (!(dll_basename = strrchr (dll_name, '/')))
1600 dll_basename = dll_name;
1604 ALL_OBJFILES (objfile)
1606 objfile_basename = strrchr (objfile->name, '/');
1608 if (objfile_basename &&
1609 strcmp (dll_basename, objfile_basename + 1) == 0)
1611 printf_unfiltered ("%08lx:%s (symbols previously loaded)\n",
1612 base_addr, dll_name);
1617 register_loaded_dll (dll_name, base_addr + 0x1000);
1618 solib_symbols_add (dll_name, 0, (CORE_ADDR) base_addr + 0x1000);
1626 struct target_ops *target;
1629 map_code_section_args;
1632 map_single_dll_code_section (bfd * abfd, asection * sect, void *obj)
1636 struct section_table *new_target_sect_ptr;
1638 map_code_section_args *args = (map_code_section_args *) obj;
1639 struct target_ops *target = args->target;
1640 if (sect->flags & SEC_CODE)
1642 update_coreops = core_ops.to_sections == target->to_sections;
1644 if (target->to_sections)
1646 old = target->to_sections_end - target->to_sections;
1647 target->to_sections = (struct section_table *)
1648 xrealloc ((char *) target->to_sections,
1649 (sizeof (struct section_table)) * (1 + old));
1654 target->to_sections = (struct section_table *)
1655 xmalloc ((sizeof (struct section_table)));
1657 target->to_sections_end = target->to_sections + (1 + old);
1659 /* Update the to_sections field in the core_ops structure
1663 core_ops.to_sections = target->to_sections;
1664 core_ops.to_sections_end = target->to_sections_end;
1666 new_target_sect_ptr = target->to_sections + old;
1667 new_target_sect_ptr->addr = args->addr + bfd_section_vma (abfd, sect);
1668 new_target_sect_ptr->endaddr = args->addr + bfd_section_vma (abfd, sect) +
1669 bfd_section_size (abfd, sect);;
1670 new_target_sect_ptr->the_bfd_section = sect;
1671 new_target_sect_ptr->bfd = abfd;
1676 dll_code_sections_add (const char *dll_name, int base_addr, struct target_ops *target)
1679 map_code_section_args map_args;
1680 asection *lowest_sect;
1682 if (dll_name == NULL || target == NULL)
1684 name = xstrdup (dll_name);
1685 dll_bfd = bfd_openr (name, "pei-i386");
1686 if (dll_bfd == NULL)
1689 if (bfd_check_format (dll_bfd, bfd_object))
1691 lowest_sect = bfd_get_section_by_name (dll_bfd, ".text");
1692 if (lowest_sect == NULL)
1694 map_args.target = target;
1695 map_args.addr = base_addr - bfd_section_vma (dll_bfd, lowest_sect);
1697 bfd_map_over_sections (dll_bfd, &map_single_dll_code_section, (void *) (&map_args));
1704 core_section_load_dll_symbols (bfd * abfd, asection * sect, void *obj)
1706 struct target_ops *target = (struct target_ops *) obj;
1711 char *dll_name = NULL;
1713 struct win32_pstatus *pstatus;
1716 if (strncmp (sect->name, ".module", 7))
1719 buf = (char *) xmalloc (sect->_raw_size + 1);
1722 printf_unfiltered ("memory allocation failed for %s\n", sect->name);
1725 if (!bfd_get_section_contents (abfd, sect, buf, 0, sect->_raw_size))
1728 pstatus = (struct win32_pstatus *) buf;
1730 memmove (&base_addr, &(pstatus->data.module_info.base_address), sizeof (base_addr));
1731 dll_name_size = pstatus->data.module_info.module_name_size;
1732 if (offsetof (struct win32_pstatus, data.module_info.module_name) + dll_name_size > sect->_raw_size)
1735 dll_name = (char *) xmalloc (dll_name_size + 1);
1738 printf_unfiltered ("memory allocation failed for %s\n", sect->name);
1741 strncpy (dll_name, pstatus->data.module_info.module_name, dll_name_size);
1743 while ((p = strchr (dll_name, '\\')))
1746 if (!core_dll_symbols_add (dll_name, (DWORD) base_addr))
1747 printf_unfiltered ("%s: Failed to load dll symbols.\n", dll_name);
1749 if (!dll_code_sections_add (dll_name, (DWORD) base_addr + 0x1000, target))
1750 printf_unfiltered ("%s: Failed to map dll code sections.\n", dll_name);
1761 child_solib_add (char *filename ATTRIBUTE_UNUSED, int from_tty, struct target_ops *target, int readsyms)
1767 child_clear_solibs ();
1768 bfd_map_over_sections (core_bfd, &core_section_load_dll_symbols, target);
1772 if (solib_end && solib_end->name)
1773 solib_end->objfile = solib_symbols_add (solib_end->name, from_tty,
1774 solib_end->load_addr);
1779 fetch_elf_core_registers (char *core_reg_sect,
1780 unsigned core_reg_size,
1785 if (core_reg_size < sizeof (CONTEXT))
1787 error ("Core file register section too small (%u bytes).", core_reg_size);
1790 for (r = 0; r < NUM_REGS; r++)
1791 supply_register (r, core_reg_sect + mappings[r]);
1794 static struct core_fns win32_elf_core_fns =
1796 bfd_target_elf_flavour,
1797 default_check_format,
1798 default_core_sniffer,
1799 fetch_elf_core_registers,
1804 _initialize_core_win32 (void)
1806 add_core_fns (&win32_elf_core_fns);
1810 _initialize_check_for_gdb_ini (void)
1813 if (inhibit_gdbinit)
1816 homedir = getenv ("HOME");
1820 char *oldini = (char *) alloca (strlen (homedir) +
1821 sizeof ("/gdb.ini"));
1822 strcpy (oldini, homedir);
1823 p = strchr (oldini, '\0');
1824 if (p > oldini && p[-1] != '/')
1826 strcpy (p, "gdb.ini");
1827 if (access (oldini, 0) == 0)
1829 int len = strlen (oldini);
1830 char *newini = alloca (len + 1);
1831 sprintf (newini, "%.*s.gdbinit", len - (sizeof ("gdb.ini") - 1), oldini);
1832 warning ("obsolete '%s' found. Rename to '%s'.", oldini, newini);