/* Target-vector operations for controlling windows child processes, for GDB.
- Copyright (C) 1995-2014 Free Software Foundation, Inc.
+ Copyright (C) 1995-2015 Free Software Foundation, Inc.
Contributed by Cygnus Solutions, A Red Hat Company.
#include "defs.h"
#include "frame.h" /* required by inferior.h */
#include "inferior.h"
+#include "infrun.h"
#include "target.h"
-#include "exceptions.h"
#include "gdbcore.h"
#include "command.h"
#include "completer.h"
#include <signal.h>
#include <sys/types.h>
#include <fcntl.h>
-#include <stdlib.h>
#include <windows.h>
#include <imagehlp.h>
#include <psapi.h>
#include "objfiles.h"
#include "gdb_bfd.h"
#include "gdb_obstack.h"
-#include <string.h>
#include "gdbthread.h"
#include "gdbcmd.h"
#include <unistd.h>
#include "windows-tdep.h"
#include "windows-nat.h"
-#include "i386-nat.h"
+#include "x86-nat.h"
#include "complaints.h"
+#include "inf-child.h"
#define AdjustTokenPrivileges dyn_AdjustTokenPrivileges
#define DebugActiveProcessStop dyn_DebugActiveProcessStop
CONSOLE_FONT_INFO *);
static COORD WINAPI (*GetConsoleFontSize) (HANDLE, DWORD);
-static struct target_ops windows_ops;
-
#undef STARTUPINFO
#undef CreateProcess
#undef GetModuleFileNameEx
enum
{
FLAG_TRACE_BIT = 0x100,
- CONTEXT_DEBUGGER = (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
};
#endif
#define CONTEXT_EXTENDED_REGISTERS 0
#endif
-#define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \
- | CONTEXT_EXTENDED_REGISTERS
+#define CONTEXT_DEBUGGER_DR CONTEXT_FULL | CONTEXT_FLOATING_POINT \
+ | CONTEXT_SEGMENTS | CONTEXT_DEBUG_REGISTERS \
+ | CONTEXT_EXTENDED_REGISTERS
static uintptr_t dr[8];
static int debug_registers_changed;
#define DEBUG_MEM(x) if (debug_memory) printf_unfiltered x
#define DEBUG_EXCEPT(x) if (debug_exceptions) printf_unfiltered x
-static void windows_stop (struct target_ops *self, ptid_t);
+static void windows_interrupt (struct target_ops *self, ptid_t);
static int windows_thread_alive (struct target_ops *, ptid_t);
static void windows_kill_inferior (struct target_ops *);
/* Thread information structure used to track information that is
not available in gdb's thread structure. */
-typedef struct thread_info_struct
+typedef struct windows_thread_info_struct
{
- struct thread_info_struct *next;
+ struct windows_thread_info_struct *next;
DWORD id;
HANDLE h;
CORE_ADDR thread_local_base;
CONTEXT context;
STACKFRAME sf;
}
-thread_info;
+windows_thread_info;
-static thread_info thread_head;
+static windows_thread_info thread_head;
/* The process and thread handles for the above context. */
static DEBUG_EVENT current_event; /* The current debug event from
WaitForDebugEvent */
static HANDLE current_process_handle; /* Currently executing process */
-static thread_info *current_thread; /* Info on currently selected thread */
+static windows_thread_info *current_thread; /* Info on currently selected thread */
static DWORD main_thread_id; /* Thread ID of the main thread */
/* Counts of things. */
/* Find a thread record given a thread id. If GET_CONTEXT is not 0,
then also retrieve the context for this thread. If GET_CONTEXT is
negative, then don't suspend the thread. */
-static thread_info *
+static windows_thread_info *
thread_rec (DWORD id, int get_context)
{
- thread_info *th;
+ windows_thread_info *th;
for (th = &thread_head; (th = th->next) != NULL;)
if (th->id == id)
{
DWORD err = GetLastError ();
- warning (_("SuspendThread (tid=0x%x) failed."
- " (winerr %u)"),
- (unsigned) id, (unsigned) err);
- return NULL;
+ /* We get Access Denied (5) when trying to suspend
+ threads that Windows started on behalf of the
+ debuggee, usually when those threads are just
+ about to exit.
+ We can get Invalid Handle (6) if the main thread
+ has exited. */
+ if (err != ERROR_INVALID_HANDLE
+ && err != ERROR_ACCESS_DENIED)
+ warning (_("SuspendThread (tid=0x%x) failed."
+ " (winerr %u)"),
+ (unsigned) id, (unsigned) err);
+ th->suspended = -1;
}
- th->suspended = 1;
+ else
+ th->suspended = 1;
}
else if (get_context < 0)
th->suspended = -1;
}
/* Add a thread to the thread list. */
-static thread_info *
+static windows_thread_info *
windows_add_thread (ptid_t ptid, HANDLE h, void *tlb)
{
- thread_info *th;
+ windows_thread_info *th;
DWORD id;
gdb_assert (ptid_get_tid (ptid) != 0);
if ((th = thread_rec (id, FALSE)))
return th;
- th = XCNEW (thread_info);
+ th = XCNEW (windows_thread_info);
th->id = id;
th->h = h;
th->thread_local_base = (CORE_ADDR) (uintptr_t) tlb;
static void
windows_init_thread_list (void)
{
- thread_info *th = &thread_head;
+ windows_thread_info *th = &thread_head;
DEBUG_EVENTS (("gdb: windows_init_thread_list\n"));
init_thread_list ();
while (th->next != NULL)
{
- thread_info *here = th->next;
+ windows_thread_info *here = th->next;
th->next = here->next;
xfree (here);
}
static void
windows_delete_thread (ptid_t ptid, DWORD exit_code)
{
- thread_info *th;
+ windows_thread_info *th;
DWORD id;
gdb_assert (ptid_get_tid (ptid) != 0);
if (th->next != NULL)
{
- thread_info *here = th->next;
+ windows_thread_info *here = th->next;
th->next = here->next;
xfree (here);
}
if (current_thread->reload_context)
{
-#ifdef __COPY_CONTEXT_SIZE
+#ifdef __CYGWIN__
if (have_saved_context)
{
/* Lie about where the program actually is stopped since
else
#endif
{
- thread_info *th = current_thread;
+ windows_thread_info *th = current_thread;
th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
- GetThreadContext (th->h, &th->context);
+ CHECK (GetThreadContext (th->h, &th->context));
/* Copy dr values from that thread.
But only if there were not modified since last stop.
PR gdb/2388 */
static struct so_list solib_start, *solib_end;
-/* Call symbol_file_add with stderr redirected. We don't care if there
- are errors. */
-static int
-safe_symbol_file_add_stub (void *argv)
-{
-#define p ((struct safe_symbol_file_add_args *) argv)
- 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
-}
-
-/* Restore gdb's stderr after calling symbol_file_add. */
-static void
-safe_symbol_file_add_cleanup (void *p)
-{
-#define sp ((struct safe_symbol_file_add_args *)p)
- gdb_flush (gdb_stderr);
- gdb_flush (gdb_stdout);
- ui_file_delete (gdb_stderr);
- ui_file_delete (gdb_stdout);
- gdb_stderr = sp->err;
- gdb_stdout = sp->out;
-#undef sp
-}
-
-/* symbol_file_add wrapper that prevents errors from being displayed. */
-static struct objfile *
-safe_symbol_file_add (char *name, int from_tty,
- struct section_addr_info *addrs,
- int mainline, int flags)
-{
- struct safe_symbol_file_add_args p;
- struct cleanup *cleanup;
-
- cleanup = make_cleanup (safe_symbol_file_add_cleanup, &p);
-
- p.err = gdb_stderr;
- p.out = gdb_stdout;
- gdb_flush (gdb_stderr);
- gdb_flush (gdb_stdout);
- gdb_stderr = ui_file_new ();
- gdb_stdout = ui_file_new ();
- p.name = name;
- p.from_tty = from_tty;
- p.addrs = addrs;
- p.mainline = mainline;
- p.flags = flags;
- catch_errors (safe_symbol_file_add_stub, &p, "", RETURN_MASK_ERROR);
-
- do_cleanups (cleanup);
- return p.ret;
-}
-
static struct so_list *
windows_make_so (const char *name, LPVOID load_addr)
{
}
#endif
so = XCNEW (struct so_list);
- so->lm_info = (struct lm_info *) xmalloc (sizeof (struct lm_info));
+ so->lm_info = XNEW (struct lm_info);
so->lm_info->load_addr = load_addr;
strcpy (so->so_original_name, name);
#ifndef __CYGWIN__
solib_end = &solib_start;
}
-/* Load DLL symbol info. */
-static void
-dll_symbol_command (char *args, int from_tty)
-{
- int n;
- dont_repeat ();
-
- if (args == NULL)
- error (_("dll-symbols requires a file name"));
-
- n = strlen (args);
- if (n > 4 && strcasecmp (args + n - 4, ".dll") != 0)
- {
- char *newargs = (char *) alloca (n + 4 + 1);
- strcpy (newargs, args);
- strcat (newargs, ".dll");
- args = newargs;
- }
-
- safe_symbol_file_add (args, from_tty, NULL, 0, OBJF_SHARED | OBJF_USERLOADED);
-}
-
/* Handle DEBUG_STRING output from child process.
Cygwin prepends its messages with a "cygwin:". Interpret this as
a Cygwin signal. Otherwise just print the string as a warning. */
&s, 1024, 0)
|| !s || !*s)
/* nothing to do */;
- else if (strncmp (s, _CYGWIN_SIGNAL_STRING,
- sizeof (_CYGWIN_SIGNAL_STRING) - 1) != 0)
+ else if (!startswith (s, _CYGWIN_SIGNAL_STRING))
{
#ifdef __CYGWIN__
- if (strncmp (s, "cYg", 3) != 0)
+ if (!startswith (s, "cYg"))
#endif
- warning (("%s"), s);
+ {
+ char *p = strchr (s, '\0');
+
+ if (p > s && *--p == '\n')
+ *p = '\0';
+ warning (("%s"), s);
+ }
}
-#ifdef __COPY_CONTEXT_SIZE
+#ifdef __CYGWIN__
else
{
/* Got a cygwin signal marker. A cygwin signal is followed by
__COPY_CONTEXT_SIZE, &n)
&& n == __COPY_CONTEXT_SIZE)
have_saved_context = 1;
- current_event.dwThreadId = retval;
}
}
#endif
static int
handle_exception (struct target_waitstatus *ourstatus)
{
- thread_info *th;
+ windows_thread_info *th;
DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
ourstatus->kind = TARGET_WAITKIND_STOPPED;
if ((!cygwin_exceptions && (addr >= cygwin_load_start
&& addr < cygwin_load_end))
|| (find_pc_partial_function (addr, &fn, NULL, NULL)
- && strncmp (fn, "KERNEL32!IsBad",
- strlen ("KERNEL32!IsBad")) == 0))
+ && startswith (fn, "KERNEL32!IsBad")))
return 0;
}
#endif
return 1;
}
-/* Resume all artificially suspended threads if we are continuing
- execution. */
+/* Resume thread specified by ID, or all artificially suspended
+ threads, if we are continuing execution. KILLED non-zero means we
+ have killed the inferior, so we should ignore weird errors due to
+ threads shutting down. */
static BOOL
-windows_continue (DWORD continue_status, int id)
+windows_continue (DWORD continue_status, int id, int killed)
{
int i;
- thread_info *th;
+ windows_thread_info *th;
BOOL res;
DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=0x%x, %s);\n",
}
if (th->context.ContextFlags)
{
- CHECK (SetThreadContext (th->h, &th->context));
+ DWORD ec = 0;
+
+ if (GetExitCodeThread (th->h, &ec)
+ && ec == STILL_ACTIVE)
+ {
+ BOOL status = SetThreadContext (th->h, &th->context);
+
+ if (!killed)
+ CHECK (status);
+ }
th->context.ContextFlags = 0;
}
if (th->suspended > 0)
current_event.dwThreadId,
continue_status);
+ if (!res)
+ error (_("Failed to resume program execution"
+ " (ContinueDebugEvent failed, error %u)"),
+ (unsigned int) GetLastError ());
+
debug_registers_changed = 0;
return res;
}
windows_resume (struct target_ops *ops,
ptid_t ptid, int step, enum gdb_signal sig)
{
- thread_info *th;
+ windows_thread_info *th;
DWORD continue_status = DBG_CONTINUE;
/* A specific PTID means `step only this thread id'. */
}
}
#endif
- DEBUG_EXCEPT(("Can only continue with recieved signal %d.\n",
+ DEBUG_EXCEPT(("Can only continue with received signal %d.\n",
last_sig));
}
Otherwise complain. */
if (resume_all)
- windows_continue (continue_status, -1);
+ windows_continue (continue_status, -1, 0);
else
- windows_continue (continue_status, ptid_get_tid (ptid));
+ windows_continue (continue_status, ptid_get_tid (ptid), 0);
}
/* Ctrl-C handler used when the inferior is not run in the same console. The
return TRUE;
}
-/* Get the next event from the child. Return 1 if the event requires
- handling by WFI (or whatever). */
+/* Get the next event from the child. Returns a non-zero thread id if the event
+ requires handling by WFI (or whatever). */
static int
get_windows_debug_event (struct target_ops *ops,
int pid, struct target_waitstatus *ourstatus)
{
BOOL debug_event;
DWORD continue_status, event_code;
- thread_info *th;
- static thread_info dummy_thread_info;
- int retval = 0;
+ windows_thread_info *th;
+ static windows_thread_info dummy_thread_info;
+ DWORD thread_id = 0;
last_sig = GDB_SIGNAL_0;
/* Kludge around a Windows bug where first event is a create
thread event. Caused when attached process does not have
a main thread. */
- retval = fake_create_process ();
- if (retval)
+ thread_id = fake_create_process ();
+ if (thread_id)
saw_create++;
}
break;
}
/* Record the existence of this thread. */
- retval = current_event.dwThreadId;
+ thread_id = current_event.dwThreadId;
th = windows_add_thread (ptid_build (current_event.dwProcessId, 0,
current_event.dwThreadId),
current_event.u.CreateThread.hThread,
current_event.dwThreadId),
current_event.u.CreateProcessInfo.hThread,
current_event.u.CreateProcessInfo.lpThreadLocalBase);
- retval = current_event.dwThreadId;
+ thread_id = current_event.dwThreadId;
break;
case EXIT_PROCESS_DEBUG_EVENT:
{
ourstatus->kind = TARGET_WAITKIND_EXITED;
ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
- retval = main_thread_id;
+ thread_id = main_thread_id;
}
break;
catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
ourstatus->kind = TARGET_WAITKIND_LOADED;
ourstatus->value.integer = 0;
- retval = main_thread_id;
+ thread_id = main_thread_id;
break;
case UNLOAD_DLL_DEBUG_EVENT:
catch_errors (handle_unload_dll, NULL, (char *) "", RETURN_MASK_ALL);
ourstatus->kind = TARGET_WAITKIND_LOADED;
ourstatus->value.integer = 0;
- retval = main_thread_id;
+ thread_id = main_thread_id;
break;
case EXCEPTION_DEBUG_EVENT:
continue_status = DBG_EXCEPTION_NOT_HANDLED;
break;
case 1:
- retval = current_event.dwThreadId;
+ thread_id = current_event.dwThreadId;
break;
case -1:
last_sig = 1;
"OUTPUT_DEBUG_STRING_EVENT"));
if (saw_create != 1)
break;
- retval = handle_output_debug_string (ourstatus);
+ thread_id = handle_output_debug_string (ourstatus);
break;
default:
break;
}
- if (!retval || saw_create != 1)
+ if (!thread_id || saw_create != 1)
{
if (continue_status == -1)
windows_resume (ops, minus_one_ptid, 0, 1);
else
- CHECK (windows_continue (continue_status, -1));
+ CHECK (windows_continue (continue_status, -1, 0));
}
else
{
inferior_ptid = ptid_build (current_event.dwProcessId, 0,
- retval);
- current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE);
+ thread_id);
+ current_thread = th;
+ if (!current_thread)
+ current_thread = thread_rec (thread_id, TRUE);
}
out:
- return retval;
+ return thread_id;
}
/* Wait for interesting events to occur in the target process. */
#endif
current_event.dwProcessId = pid;
memset (¤t_event, 0, sizeof (current_event));
- push_target (ops);
+ if (!target_is_pushed (ops))
+ push_target (ops);
disable_breakpoints_in_shlibs ();
windows_clear_solib ();
- clear_proceed_status ();
+ clear_proceed_status (0);
init_wait_for_inferior ();
inf = current_inferior ();
current thread until we report an event out of windows_wait. */
inferior_ptid = pid_to_ptid (pid);
- terminal_init_inferior_with_pgrp (pid);
+ target_terminal_init ();
target_terminal_inferior ();
windows_initialization_done = 0;
wait_for_inferior ();
tp = inferior_thread ();
if (tp->suspend.stop_signal != GDB_SIGNAL_TRAP)
- resume (0, tp->suspend.stop_signal);
+ resume (tp->suspend.stop_signal);
else
break;
}
/* Attach to process PID, then initialize for debugging it. */
static void
-windows_attach (struct target_ops *ops, char *args, int from_tty)
+windows_attach (struct target_ops *ops, const char *args, int from_tty)
{
BOOL ok;
DWORD pid;
gdb_flush (gdb_stdout);
}
- i386_cleanup_dregs ();
+ x86_cleanup_dregs ();
inferior_ptid = null_ptid;
detach_inferior (current_event.dwProcessId);
- unpush_target (ops);
+ inf_child_maybe_unpush_target (ops);
}
/* Try to determine the executable filename.
target_pid_to_str (inferior_ptid));
}
-static void
-windows_open (char *arg, int from_tty)
-{
- error (_("Use the \"run\" command to start a Unix child process."));
-}
-
/* Modify CreateProcess parameters for use of a new separate console.
Parameters are:
*FLAGS: DWORD parameter for general process creation flags.
do_initial_windows_stuff (ops, pi.dwProcessId, 0);
- /* windows_continue (DBG_CONTINUE, -1); */
+ /* windows_continue (DBG_CONTINUE, -1, 0); */
}
static void
windows_mourn_inferior (struct target_ops *ops)
{
- (void) windows_continue (DBG_CONTINUE, -1);
- i386_cleanup_dregs();
+ (void) windows_continue (DBG_CONTINUE, -1, 0);
+ x86_cleanup_dregs();
if (open_process_used)
{
CHECK (CloseHandle (current_process_handle));
open_process_used = 0;
}
- unpush_target (ops);
- generic_mourn_inferior ();
+ inf_child_mourn_inferior (ops);
}
/* Send a SIGINT to the process group. This acts just like the user typed a
^C on the controlling terminal. */
static void
-windows_stop (struct target_ops *self, ptid_t ptid)
+windows_interrupt (struct target_ops *self, ptid_t ptid)
{
DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
for (;;)
{
- if (!windows_continue (DBG_CONTINUE, -1))
+ if (!windows_continue (DBG_CONTINUE, -1, 1))
break;
if (!WaitForDebugEvent (¤t_event, INFINITE))
break;
target_mourn_inferior (); /* Or just windows_mourn_inferior? */
}
-static void
-windows_prepare_to_store (struct target_ops *self, struct regcache *regcache)
-{
- /* Do nothing, since we can store individual regs. */
-}
-
-static int
-windows_can_run (struct target_ops *self)
-{
- return 1;
-}
-
static void
windows_close (struct target_ops *self)
{
obstack_free (&obstack, NULL);
*xfered_len = (ULONGEST) len;
- return TARGET_XFER_OK;
+ return len != 0 ? TARGET_XFER_OK : TARGET_XFER_EOF;
}
static enum target_xfer_status
writebuf, offset, len, xfered_len);
default:
- if (ops->beneath != NULL)
- return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
- readbuf, writebuf, offset, len,
- xfered_len);
- return TARGET_XFER_E_IO;
+ return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
+ readbuf, writebuf, offset, len,
+ xfered_len);
}
}
windows_get_tib_address (struct target_ops *self,
ptid_t ptid, CORE_ADDR *addr)
{
- thread_info *th;
+ windows_thread_info *th;
th = thread_rec (ptid_get_tid (ptid), 0);
if (th == NULL)
return ptid_build (ptid_get_pid (inferior_ptid), 0, lwp);
}
-static void
-init_windows_ops (void)
-{
- windows_ops.to_shortname = "child";
- windows_ops.to_longname = "Win32 child process";
- windows_ops.to_doc = "Win32 child process (started by the \"run\" command).";
- windows_ops.to_open = windows_open;
- windows_ops.to_close = windows_close;
- windows_ops.to_attach = windows_attach;
- windows_ops.to_attach_no_wait = 1;
- windows_ops.to_detach = windows_detach;
- windows_ops.to_resume = windows_resume;
- windows_ops.to_wait = windows_wait;
- windows_ops.to_fetch_registers = windows_fetch_inferior_registers;
- windows_ops.to_store_registers = windows_store_inferior_registers;
- windows_ops.to_prepare_to_store = windows_prepare_to_store;
- windows_ops.to_xfer_partial = windows_xfer_partial;
- windows_ops.to_files_info = windows_files_info;
- windows_ops.to_insert_breakpoint = memory_insert_breakpoint;
- windows_ops.to_remove_breakpoint = memory_remove_breakpoint;
- windows_ops.to_terminal_init = terminal_init_inferior;
- windows_ops.to_terminal_inferior = terminal_inferior;
- windows_ops.to_terminal_ours_for_output = terminal_ours_for_output;
- windows_ops.to_terminal_ours = terminal_ours;
- windows_ops.to_terminal_save_ours = terminal_save_ours;
- windows_ops.to_terminal_info = child_terminal_info;
- windows_ops.to_kill = windows_kill_inferior;
- windows_ops.to_create_inferior = windows_create_inferior;
- windows_ops.to_mourn_inferior = windows_mourn_inferior;
- windows_ops.to_can_run = windows_can_run;
- windows_ops.to_thread_alive = windows_thread_alive;
- 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 = 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;
- windows_ops.to_get_tib_address = windows_get_tib_address;
-
- i386_use_watchpoints (&windows_ops);
-
- i386_dr_low.set_control = cygwin_set_dr7;
- i386_dr_low.set_addr = cygwin_set_dr;
- 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
- in processor windows specific native file. */
+static struct target_ops *
+windows_target (void)
+{
+ struct target_ops *t = inf_child_target ();
- windows_ops.to_magic = OPS_MAGIC;
-}
+ t->to_close = windows_close;
+ t->to_attach = windows_attach;
+ t->to_attach_no_wait = 1;
+ t->to_detach = windows_detach;
+ t->to_resume = windows_resume;
+ t->to_wait = windows_wait;
+ t->to_fetch_registers = windows_fetch_inferior_registers;
+ t->to_store_registers = windows_store_inferior_registers;
+ t->to_xfer_partial = windows_xfer_partial;
+ t->to_files_info = windows_files_info;
+ t->to_kill = windows_kill_inferior;
+ t->to_create_inferior = windows_create_inferior;
+ t->to_mourn_inferior = windows_mourn_inferior;
+ t->to_thread_alive = windows_thread_alive;
+ t->to_pid_to_str = windows_pid_to_str;
+ t->to_interrupt = windows_interrupt;
+ t->to_pid_to_exec_file = windows_pid_to_exec_file;
+ t->to_get_ada_task_ptid = windows_get_ada_task_ptid;
+ t->to_get_tib_address = windows_get_tib_address;
-static void
-set_windows_aliases (char *argv0)
-{
- add_info_alias ("dll", "sharedlibrary", 1);
+ return t;
}
/* -Wmissing-prototypes */
void
_initialize_windows_nat (void)
{
- struct cmd_list_element *c;
+ struct target_ops *t;
- init_windows_ops ();
+ t = windows_target ();
-#ifdef __CYGWIN__
- cygwin_internal (CW_SET_DOS_FILE_WARNING, 0);
-#endif
+ x86_use_watchpoints (t);
- c = add_com ("dll-symbols", class_files, dll_symbol_command,
- _("Load dll library symbols from FILE."));
- set_cmd_completer (c, filename_completer);
- deprecate_cmd (c, "sharedlibrary");
+ x86_dr_low.set_control = cygwin_set_dr7;
+ x86_dr_low.set_addr = cygwin_set_dr;
+ x86_dr_low.get_addr = cygwin_get_dr;
+ x86_dr_low.get_status = cygwin_get_dr6;
+ x86_dr_low.get_control = cygwin_get_dr7;
+
+ /* x86_dr_low.debug_register_length field is set by
+ calling x86_set_debug_register_length function
+ in processor windows specific native file. */
- c = add_com ("add-shared-symbol-files", class_files, dll_symbol_command,
- _("Load dll library symbols from FILE."));
- set_cmd_completer (c, filename_completer);
- deprecate_cmd (c, "sharedlibrary");
+ add_target (t);
- c = add_com ("assf", class_files, dll_symbol_command,
- _("Load dll library symbols from FILE."));
- set_cmd_completer (c, filename_completer);
- deprecate_cmd (c, "sharedlibrary");
+#ifdef __CYGWIN__
+ cygwin_internal (CW_SET_DOS_FILE_WARNING, 0);
+#endif
#ifdef __CYGWIN__
add_setshow_boolean_cmd ("shell", class_support, &useshell, _("\
add_cmd ("selector", class_info, display_selectors,
_("Display selectors infos."),
&info_w32_cmdlist);
- add_target (&windows_ops);
- deprecated_init_ui_hook = set_windows_aliases;
}
/* Hardware watchpoint support, adapted from go32-nat.c code. */