/* Target-vector operations for controlling windows child processes, for GDB.
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+ 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
Contributed by Cygnus Solutions, A Red Hat Company.
#include "windows-tdep.h"
#include "windows-nat.h"
+#include "i386-nat.h"
#define AdjustTokenPrivileges dyn_AdjustTokenPrivileges
#define DebugActiveProcessStop dyn_DebugActiveProcessStop
static uintptr_t dr[8];
static int debug_registers_changed;
static int debug_registers_used;
+
+static int windows_initialization_done;
#define DR6_CLEAR_VALUE 0xffff0ff0
/* The string sent by cygwin when it processes a signal.
static int windows_thread_alive (struct target_ops *, ptid_t);
static void windows_kill_inferior (struct target_ops *);
+static void cygwin_set_dr (int i, CORE_ADDR addr);
+static void cygwin_set_dr7 (unsigned long val);
+static unsigned long cygwin_get_dr6 (void);
+
static enum target_signal last_sig = TARGET_SIGNAL_0;
/* Set if a signal was received from the debugged process */
safe_symbol_file_add_stub (void *argv)
{
#define p ((struct safe_symbol_file_add_args *) argv)
- p->ret = symbol_file_add (p->name, p->from_tty, p->addrs, p->mainline, p->flags);
+ const int add_flags = ((p->from_tty ? SYMFILE_VERBOSE : 0)
+ | (p->mainline ? SYMFILE_MAINLINE : 0));
+ p->ret = symbol_file_add (p->name, add_flags, p->addrs, p->flags);
return !!p->ret;
#undef p
}
solib_end->next = windows_make_so (dll_name, event->lpBaseOfDll);
solib_end = solib_end->next;
- DEBUG_EVENTS (("gdb: Loading dll \"%s\" at %p.\n", solib_end->so_name,
- solib_end->lm_info->load_addr));
+ DEBUG_EVENTS (("gdb: Loading dll \"%s\" at %s.\n", solib_end->so_name,
+ host_address_to_string (solib_end->lm_info->load_addr)));
return 1;
}
return 1;
}
- error (_("Error: dll starting at %p not found."), lpBaseOfDll);
+ error (_("Error: dll starting at %s not found."),
+ host_address_to_string (lpBaseOfDll));
return 0;
}
#define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \
- printf_unfiltered ("gdb: Target exception %s at %p\n", x, \
- current_event.u.Exception.ExceptionRecord.ExceptionAddress)
+ printf_unfiltered ("gdb: Target exception %s at %s\n", x, \
+ host_address_to_string (\
+ current_event.u.Exception.ExceptionRecord.ExceptionAddress))
static int
handle_exception (struct target_waitstatus *ourstatus)
/* Treat unhandled first chance exceptions specially. */
if (current_event.u.Exception.dwFirstChance)
return -1;
- printf_unfiltered ("gdb: unknown target exception 0x%08lx at %p\n",
- current_event.u.Exception.ExceptionRecord.ExceptionCode,
- current_event.u.Exception.ExceptionRecord.ExceptionAddress);
+ printf_unfiltered ("gdb: unknown target exception 0x%08lx at %s\n",
+ current_event.u.Exception.ExceptionRecord.ExceptionCode,
+ host_address_to_string (
+ current_event.u.Exception.ExceptionRecord.ExceptionAddress));
ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
break;
}
thread_info *th;
BOOL res;
- DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, %s);\n",
+ DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%lx, %s);\n",
current_event.dwProcessId, current_event.dwThreadId,
continue_status == DBG_CONTINUE ?
"DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED"));
if (step)
{
/* Single step by setting t bit */
- windows_fetch_inferior_registers (ops,
- get_current_regcache (),
- gdbarch_ps_regnum (current_gdbarch));
+ struct regcache *regcache = get_current_regcache ();
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ windows_fetch_inferior_registers (ops, regcache,
+ gdbarch_ps_regnum (gdbarch));
th->context.EFlags |= FLAG_TRACE_BIT;
}
{
const int attach_flag = current_inferior ()->attach_flag;
- /* Only handle Ctrl-C event. Ignore others. */
- if (event_type != CTRL_C_EVENT)
+ /* Only handle Ctrl-C and Ctrl-Break events. Ignore others. */
+ if (event_type != CTRL_C_EVENT && event_type != CTRL_BREAK_EVENT)
return FALSE;
/* If the inferior and the debugger share the same console, do nothing as
break;
case EXIT_THREAD_DEBUG_EVENT:
- DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
+ DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
(unsigned) current_event.dwProcessId,
(unsigned) current_event.dwThreadId,
"EXIT_THREAD_DEBUG_EVENT"));
break;
case CREATE_PROCESS_DEBUG_EVENT:
- DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
+ DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
(unsigned) current_event.dwProcessId,
(unsigned) current_event.dwThreadId,
"CREATE_PROCESS_DEBUG_EVENT"));
break;
case EXIT_PROCESS_DEBUG_EVENT:
- DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
+ DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
(unsigned) current_event.dwProcessId,
(unsigned) current_event.dwThreadId,
"EXIT_PROCESS_DEBUG_EVENT"));
- if (saw_create != 1)
- break;
- ourstatus->kind = TARGET_WAITKIND_EXITED;
- ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
- retval = main_thread_id;
+ if (!windows_initialization_done)
+ {
+ target_terminal_ours ();
+ target_mourn_inferior ();
+ error (_("During startup program exited with code 0x%x."),
+ (unsigned int) current_event.u.ExitProcess.dwExitCode);
+ }
+ else if (saw_create == 1)
+ {
+ ourstatus->kind = TARGET_WAITKIND_EXITED;
+ ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
+ retval = main_thread_id;
+ }
break;
case LOAD_DLL_DEBUG_EVENT:
- DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
+ DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
(unsigned) current_event.dwProcessId,
(unsigned) current_event.dwThreadId,
"LOAD_DLL_DEBUG_EVENT"));
break;
case UNLOAD_DLL_DEBUG_EVENT:
- DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
+ DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
(unsigned) current_event.dwProcessId,
(unsigned) current_event.dwThreadId,
"UNLOAD_DLL_DEBUG_EVENT"));
break;
case EXCEPTION_DEBUG_EVENT:
- DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
+ DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
(unsigned) current_event.dwProcessId,
(unsigned) current_event.dwThreadId,
"EXCEPTION_DEBUG_EVENT"));
break;
case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */
- DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
+ DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
(unsigned) current_event.dwProcessId,
(unsigned) current_event.dwThreadId,
"OUTPUT_DEBUG_STRING_EVENT"));
/* Wait for interesting events to occur in the target process. */
static ptid_t
windows_wait (struct target_ops *ops,
- ptid_t ptid, struct target_waitstatus *ourstatus)
+ ptid_t ptid, struct target_waitstatus *ourstatus, int options)
{
int pid = -1;
clear_proceed_status ();
init_wait_for_inferior ();
- inf = add_inferior (pid);
+ inf = current_inferior ();
+ inferior_appeared (inf, pid);
inf->attach_flag = attaching;
/* Make the new process the current inferior, so terminal handling
terminal_init_inferior_with_pgrp (pid);
target_terminal_inferior ();
+ windows_initialization_done = 0;
inf->stop_soon = STOP_QUIETLY;
while (1)
{
break;
}
+ windows_initialization_done = 1;
inf->stop_soon = NO_STOP_QUIETLY;
stop_after_trap = 0;
return;
obstack_grow_str (&obstack, "<library-list>\n");
for (so = solib_start.next; so; so = so->next)
windows_xfer_shared_library (so->so_name, (CORE_ADDR) (uintptr_t) so->lm_info->load_addr,
- &obstack);
+ target_gdbarch, &obstack);
obstack_grow_str0 (&obstack, "</library-list>\n");
buf = obstack_finish (&obstack);
}
}
+static ptid_t
+windows_get_ada_task_ptid (long lwp, long thread)
+{
+ return ptid_build (ptid_get_pid (inferior_ptid), 0, lwp);
+}
+
static void
init_windows_ops (void)
{
windows_ops.to_pid_to_str = windows_pid_to_str;
windows_ops.to_stop = windows_stop;
windows_ops.to_stratum = process_stratum;
- windows_ops.to_has_all_memory = 1;
- windows_ops.to_has_memory = 1;
- windows_ops.to_has_stack = 1;
- windows_ops.to_has_registers = 1;
- windows_ops.to_has_execution = 1;
+ windows_ops.to_has_all_memory = default_child_has_all_memory;
+ windows_ops.to_has_memory = default_child_has_memory;
+ windows_ops.to_has_stack = default_child_has_stack;
+ windows_ops.to_has_registers = default_child_has_registers;
+ windows_ops.to_has_execution = default_child_has_execution;
windows_ops.to_pid_to_exec_file = windows_pid_to_exec_file;
+ windows_ops.to_get_ada_task_ptid = windows_get_ada_task_ptid;
+
i386_use_watchpoints (&windows_ops);
+ i386_dr_low.set_control = cygwin_set_dr7;
+ i386_dr_low.set_addr = cygwin_set_dr;
+ i386_dr_low.reset_addr = NULL;
+ i386_dr_low.get_status = cygwin_get_dr6;
+
+ /* i386_dr_low.debug_register_length field is set by
+ calling i386_set_debug_register_length function
+ in processor windows specific native file. */
+
windows_ops.to_magic = OPS_MAGIC;
}
add_com_alias ("sharedlibrary", "dll-symbols", class_alias, 1);
+ add_com_alias ("add-shared-symbol-files", "dll-symbols", class_alias, 1);
+
+ add_com_alias ("assf", "dll-symbols", class_alias, 1);
+
#ifdef __CYGWIN__
add_setshow_boolean_cmd ("shell", class_support, &useshell, _("\
Set use of shell to start subprocess."), _("\
/* Pass the address ADDR to the inferior in the I'th debug register.
Here we just store the address in dr array, the registers will be
actually set up when windows_continue is called. */
-void
+static void
cygwin_set_dr (int i, CORE_ADDR addr)
{
if (i < 0 || i > 3)
/* Pass the value VAL to the inferior in the DR7 debug control
register. Here we just store the address in D_REGS, the watchpoint
will be actually set up in windows_wait. */
-void
-cygwin_set_dr7 (unsigned val)
+static void
+cygwin_set_dr7 (unsigned long val)
{
- dr[7] = val;
+ dr[7] = (CORE_ADDR) val;
debug_registers_changed = 1;
debug_registers_used = 1;
}
/* Get the value of the DR6 debug status register from the inferior.
Here we just return the value stored in dr[6]
by the last call to thread_rec for current_event.dwThreadId id. */
-unsigned
+static unsigned long
cygwin_get_dr6 (void)
{
- return dr[6];
+ return (unsigned long) dr[6];
}
/* Determine if the thread referenced by "ptid" is alive