/* 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, 2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 1995-2012 Free Software Foundation, Inc.
Contributed by Cygnus Solutions, A Red Hat Company.
static void cygwin_set_dr (int i, CORE_ADDR addr);
static void cygwin_set_dr7 (unsigned long val);
+static CORE_ADDR cygwin_get_dr (int i);
static unsigned long cygwin_get_dr6 (void);
+static unsigned long cygwin_get_dr7 (void);
-static enum target_signal last_sig = TARGET_SIGNAL_0;
+static enum gdb_signal last_sig = TARGET_SIGNAL_0;
/* Set if a signal was received from the debugged process. */
/* Thread information structure used to track information that is
static const int *mappings;
+/* The function to use in order to determine whether a register is
+ a segment register or not. */
+static segment_register_p_ftype *segment_register_p;
+
/* This vector maps the target's idea of an exception (extracted
from the DEBUG_EVENT structure) to GDB's idea. */
struct xlate_exception
{
int them;
- enum target_signal us;
+ enum gdb_signal us;
};
static const struct xlate_exception
mappings = offsets;
}
+/* See windows-nat.h. */
+
+void
+windows_set_segment_register_p (segment_register_p_ftype *fun)
+{
+ segment_register_p = fun;
+}
+
static void
check (BOOL ok, const char *file, int line)
{
l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
regcache_raw_supply (regcache, r, (char *) &l);
}
+ else if (segment_register_p (r))
+ {
+ /* GDB treats segment registers as 32bit registers, but they are
+ in fact only 16 bits long. Make sure we do not read extra
+ bits from our source buffer. */
+ l = *((long *) context_offset) & 0xffff;
+ regcache_raw_supply (regcache, r, (char *) &l);
+ }
else if (r >= 0)
regcache_raw_supply (regcache, r, context_offset);
else
}
/* Load DLL symbol info. */
-void
+static void
dll_symbol_command (char *args, int from_tty)
{
int n;
to treat this like a real signal. */
char *p;
int sig = strtol (s + sizeof (_CYGWIN_SIGNAL_STRING) - 1, &p, 0);
- int gotasig = target_signal_from_host (sig);
+ int gotasig = gdb_signal_from_host (sig);
ourstatus->value.sig = gotasig;
if (gotasig)
{
cygwin later in the process and will be sent as a
cygwin-specific-signal. So, ignore SEGVs if they show up
within the text segment of the DLL itself. */
- char *fn;
+ const char *fn;
CORE_ADDR addr = (CORE_ADDR) (uintptr_t)
current_event.u.Exception.ExceptionRecord.ExceptionAddress;
static void
windows_resume (struct target_ops *ops,
- ptid_t ptid, int step, enum target_signal sig)
+ ptid_t ptid, int step, enum gdb_signal sig)
{
thread_info *th;
DWORD continue_status = DBG_CONTINUE;
handler is in charge of interrupting the inferior using DebugBreakProcess.
Note that this function is not available prior to Windows XP. In this case
we emit a warning. */
-BOOL WINAPI
+static BOOL WINAPI
ctrl_c_handler (DWORD event_type)
{
const int attach_flag = current_inferior ()->attach_flag;
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_addr = cygwin_get_dr;
i386_dr_low.get_status = cygwin_get_dr6;
+ i386_dr_low.get_control = cygwin_get_dr7;
/* i386_dr_low.debug_register_length field is set by
calling i386_set_debug_register_length function
add_info_alias ("dll", "sharedlibrary", 1);
}
+/* -Wmissing-prototypes */
+extern initialize_file_ftype _initialize_windows_nat;
+
void
_initialize_windows_nat (void)
{
debug_registers_used = 1;
}
+/* Get the value of debug register I from the inferior. */
+
+static CORE_ADDR
+cygwin_get_dr (int i)
+{
+ return dr[i];
+}
+
/* 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. */
return (unsigned long) dr[6];
}
+/* Get the value of the DR7 debug status register from the inferior.
+ Here we just return the value stored in dr[7] by the last call to
+ thread_rec for current_event.dwThreadId id. */
+
+static unsigned long
+cygwin_get_dr7 (void)
+{
+ return (unsigned long) dr[7];
+}
+
/* Determine if the thread referenced by "ptid" is alive
by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
it means that the thread has died. Otherwise it is assumed to be alive. */
? FALSE : TRUE;
}
+/* -Wmissing-prototypes */
+extern initialize_file_ftype _initialize_check_for_gdb_ini;
+
void
_initialize_check_for_gdb_ini (void)
{
return size;
}
+/* -Wmissing-prototypes */
+extern initialize_file_ftype _initialize_loadable;
+
/* Load any functions which may not be available in ancient versions
of Windows. */
+
void
_initialize_loadable (void)
{