-/* Clear out any old thread list and reintialize it to a pristine
- state. */
-static void
-child_init_thread_list (void)
-{
- for_each_inferior (&all_threads, delete_thread_info);
-}
-
-static void
-do_initial_child_stuff (DWORD pid)
-{
- int i;
-
- last_sig = TARGET_SIGNAL_0;
-
- debug_registers_changed = 0;
- debug_registers_used = 0;
- for (i = 0; i < sizeof (dr) / sizeof (dr[0]); i++)
- dr[i] = 0;
- memset (¤t_event, 0, sizeof (current_event));
-
- child_init_thread_list ();
-}
-
-/* Resume all artificially suspended threads if we are continuing
- execution. */
-static int
-continue_one_thread (struct inferior_list_entry *this_thread, void *id_ptr)
-{
- struct thread_info *thread = (struct thread_info *) this_thread;
- int thread_id = * (int *) id_ptr;
- thread_info *th = inferior_target_data (thread);
- int i;
-
- if ((thread_id == -1 || thread_id == th->tid)
- && th->suspend_count)
- {
- for (i = 0; i < th->suspend_count; i++)
- (void) ResumeThread (th->h);
- th->suspend_count = 0;
- if (debug_registers_changed)
- {
- /* Only change the value of the debug registers. */
- th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
- th->context.Dr0 = dr[0];
- th->context.Dr1 = dr[1];
- th->context.Dr2 = dr[2];
- th->context.Dr3 = dr[3];
- /* th->context.Dr6 = dr[6];
- FIXME: should we set dr6 also ?? */
- th->context.Dr7 = dr[7];
- SetThreadContext (th->h, &th->context);
- th->context.ContextFlags = 0;
- }
- }
-
- return 0;
-}
-
-static BOOL
-child_continue (DWORD continue_status, int thread_id)
-{
- BOOL res;
-
- res = ContinueDebugEvent (current_event.dwProcessId,
- current_event.dwThreadId, continue_status);
- continue_status = 0;
- if (res)
- find_inferior (&all_threads, continue_one_thread, &thread_id);
-
- debug_registers_changed = 0;
- return res;
-}
-
-/* Fetch register(s) from gdbserver regcache data. */
-static void
-do_child_fetch_inferior_registers (thread_info *th, int r)
-{
- char *context_offset = ((char *) &th->context) + mappings[r];
- long l;
- if (r == FCS_REGNUM)
- {
- l = *((long *) context_offset) & 0xffff;
- supply_register (r, (char *) &l);
- }
- else if (r == FOP_REGNUM)
- {
- l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
- supply_register (r, (char *) &l);
- }
- else
- supply_register (r, context_offset);
-}
-
-/* Fetch register(s) from the current thread context. */
-static void
-child_fetch_inferior_registers (int r)
-{
- int regno;
- thread_info *th = thread_rec (current_inferior_tid (), TRUE);
- if (r == -1 || r == 0 || r > NUM_REGS)
- child_fetch_inferior_registers (NUM_REGS);
- else
- for (regno = 0; regno < r; regno++)
- do_child_fetch_inferior_registers (th, regno);
-}
-
-/* Get register from gdbserver regcache data. */
-static void
-do_child_store_inferior_registers (thread_info *th, int r)
-{
- collect_register (r, ((char *) &th->context) + mappings[r]);
-}
-
-/* Store a new register value into the current thread context. We don't
- change the program's context until later, when we resume it. */
-static void
-child_store_inferior_registers (int r)
-{
- int regno;
- thread_info *th = thread_rec (current_inferior_tid (), TRUE);
- if (r == -1 || r == 0 || r > NUM_REGS)
- child_store_inferior_registers (NUM_REGS);
- else
- for (regno = 0; regno < r; regno++)
- do_child_store_inferior_registers (th, regno);
-}
-
-/* Start a new process.
- PROGRAM is a path to the program to execute.
- ARGS is a standard NULL-terminated array of arguments,
- to be passed to the inferior as ``argv''.
- Returns the new PID on success, -1 on failure. Registers the new
- process with the process list. */
-static int
-win32_create_inferior (char *program, char **program_args)
-{
-#ifndef USE_WIN32API
- char real_path[MAXPATHLEN];
- char *orig_path, *new_path, *path_ptr;
-#endif
- char *winenv = NULL;
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
- BOOL ret;
- DWORD flags;
- char *args;
- int argslen;
- int argc;
-
- if (!program)
- error ("No executable specified, specify executable to debug.\n");
-
- memset (&si, 0, sizeof (si));
- si.cb = sizeof (si);
-
- flags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS;
-
-#ifndef USE_WIN32API
- orig_path = NULL;
- path_ptr = getenv ("PATH");
- if (path_ptr)
- {
- orig_path = alloca (strlen (path_ptr) + 1);
- new_path = alloca (cygwin_posix_to_win32_path_list_buf_size (path_ptr));
- strcpy (orig_path, path_ptr);
- cygwin_posix_to_win32_path_list (path_ptr, new_path);
- setenv ("PATH", new_path, 1);
- }
- cygwin_conv_to_win32_path (program, real_path);
- program = real_path;
-#endif
-
- argslen = strlen (program) + 1;
- for (argc = 1; program_args[argc]; argc++)
- argslen += strlen (program_args[argc]) + 1;
- args = alloca (argslen);
- strcpy (args, program);
- for (argc = 1; program_args[argc]; argc++)
- {
- /* FIXME: Can we do better about quoting? How does Cygwin
- handle this? */
- strcat (args, " ");
- strcat (args, program_args[argc]);
- }
- OUTMSG2 (("Command line is %s\n", args));
-
- flags |= CREATE_NEW_PROCESS_GROUP;
-
- ret = CreateProcess (0, args, /* command line */
- NULL, /* Security */
- NULL, /* thread */
- TRUE, /* inherit handles */
- flags, /* start flags */
- winenv, NULL, /* current directory */
- &si, &pi);
-
-#ifndef USE_WIN32API
- if (orig_path)
- setenv ("PATH", orig_path, 1);
-#endif
-
- if (!ret)
- {
- error ("Error creating process %s, (error %d): %s\n", args,
- (int) GetLastError (), strerror (GetLastError ()));
- }
- else
- {
- OUTMSG2 (("Process created: %s\n", (char *) args));
- }
-
- CloseHandle (pi.hThread);
-
- current_process_handle = pi.hProcess;
- current_process_id = pi.dwProcessId;
-
- do_initial_child_stuff (current_process_id);
-
- return current_process_id;
-}
-
-/* Attach to a running process.
- PID is the process ID to attach to, specified by the user
- or a higher layer. */
-static int
-win32_attach (unsigned long pid)
-{
- int res = 0;
- HMODULE kernel32 = LoadLibrary ("KERNEL32.DLL");
- winapi_DebugActiveProcessStop *DebugActiveProcessStop = NULL;
- winapi_DebugSetProcessKillOnExit *DebugSetProcessKillOnExit = NULL;
-
- DebugActiveProcessStop =
- (winapi_DebugActiveProcessStop *) GetProcAddress (kernel32,
- "DebugActiveProcessStop");
- DebugSetProcessKillOnExit =
- (winapi_DebugSetProcessKillOnExit *) GetProcAddress (kernel32,
- "DebugSetProcessKillOnExit");
-
- res = DebugActiveProcess (pid) ? 1 : 0;
-
- if (!res)
- error ("Attach to process failed.");
-
- if (DebugSetProcessKillOnExit != NULL)
- DebugSetProcessKillOnExit (FALSE);
-
- current_process_id = pid;
- current_process_handle = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid);
-
- if (current_process_handle == NULL)
- {
- res = 0;
- if (DebugActiveProcessStop != NULL)
- DebugActiveProcessStop (current_process_id);
- }
-
- if (res)
- do_initial_child_stuff (pid);
-
- FreeLibrary (kernel32);
-
- return res;
-}
-
-/* Kill all inferiors. */
-static void
-win32_kill (void)
-{
- if (current_process_handle == NULL)
- return;
-
- TerminateProcess (current_process_handle, 0);
- for (;;)
- {
- if (!child_continue (DBG_CONTINUE, -1))
- break;
- if (!WaitForDebugEvent (¤t_event, INFINITE))
- break;
- if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
- break;
- }
-}
-
-/* Detach from all inferiors. */
-static void
-win32_detach (void)
-{
- HMODULE kernel32 = LoadLibrary ("KERNEL32.DLL");
- winapi_DebugActiveProcessStop *DebugActiveProcessStop = NULL;
- winapi_DebugSetProcessKillOnExit *DebugSetProcessKillOnExit = NULL;
-
- DebugActiveProcessStop =
- (winapi_DebugActiveProcessStop *) GetProcAddress (kernel32,
- "DebugActiveProcessStop");
- DebugSetProcessKillOnExit =
- (winapi_DebugSetProcessKillOnExit *) GetProcAddress (kernel32,
- "DebugSetProcessKillOnExit");
-
- if (DebugSetProcessKillOnExit != NULL)
- DebugSetProcessKillOnExit (FALSE);
-
- if (DebugActiveProcessStop != NULL)
- DebugActiveProcessStop (current_process_id);
- else
- win32_kill ();
-
- FreeLibrary (kernel32);
-}
-
-/* Return 1 iff the thread with thread ID TID is alive. */
-static int
-win32_thread_alive (unsigned long tid)
-{
- int res;
-
- /* Our thread list is reliable; don't bother to poll target
- threads. */
- if (find_inferior_id (&all_threads, tid) != NULL)
- res = 1;
- else
- res = 0;
- return res;
-}
-
-/* Resume the inferior process. RESUME_INFO describes how we want
- to resume. */
-static void
-win32_resume (struct thread_resume *resume_info)
-{
- DWORD tid;
- enum target_signal sig;
- int step;
- thread_info *th;
- DWORD continue_status = DBG_CONTINUE;
-
- /* This handles the very limited set of resume packets that GDB can
- currently produce. */
-
- if (resume_info[0].thread == -1)
- tid = -1;
- else if (resume_info[1].thread == -1 && !resume_info[1].leave_stopped)
- tid = -1;
- else
- /* Yes, we're ignoring resume_info[0].thread. It'd be tricky to make
- the Windows resume code do the right thing for thread switching. */
- tid = current_event.dwThreadId;
-
- if (resume_info[0].thread != -1)
- {
- sig = resume_info[0].sig;
- step = resume_info[0].step;
- }
- else
- {
- sig = 0;
- step = 0;
- }
-
- if (sig != TARGET_SIGNAL_0)
- {
- if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
- {
- OUTMSG (("Cannot continue with signal %d here.\n", sig));
- }
- else if (sig == last_sig)
- continue_status = DBG_EXCEPTION_NOT_HANDLED;
- else
- OUTMSG (("Can only continue with recieved signal %d.\n", last_sig));
- }
-
- last_sig = TARGET_SIGNAL_0;
-
- /* Get context for the currently selected thread. */
- th = thread_rec (current_event.dwThreadId, FALSE);
- if (th)
- {
- if (th->context.ContextFlags)
- {
- if (debug_registers_changed)
- {
- th->context.Dr0 = dr[0];
- th->context.Dr1 = dr[1];
- th->context.Dr2 = dr[2];
- th->context.Dr3 = dr[3];
- /* th->context.Dr6 = dr[6];
- FIXME: should we set dr6 also ?? */
- th->context.Dr7 = dr[7];
- }
-
- /* Move register values from the inferior into the thread
- context structure. */
- regcache_invalidate ();
-
- if (step)
- th->context.EFlags |= FLAG_TRACE_BIT;
-
- SetThreadContext (th->h, &th->context);
- th->context.ContextFlags = 0;
- }
- }
-
- /* Allow continuing with the same signal that interrupted us.
- Otherwise complain. */
-
- child_continue (continue_status, tid);
-}
-
-static int
-handle_exception (struct target_waitstatus *ourstatus)
-{
- thread_info *th;
- DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
-
- ourstatus->kind = TARGET_WAITKIND_STOPPED;
-
- /* Record the context of the current thread. */
- th = thread_rec (current_event.dwThreadId, -1);
-
- switch (code)
- {
- case EXCEPTION_ACCESS_VIOLATION:
- OUTMSG2 (("EXCEPTION_ACCESS_VIOLATION"));
- ourstatus->value.sig = TARGET_SIGNAL_SEGV;
- break;
- case STATUS_STACK_OVERFLOW:
- OUTMSG2 (("STATUS_STACK_OVERFLOW"));
- ourstatus->value.sig = TARGET_SIGNAL_SEGV;
- break;
- case STATUS_FLOAT_DENORMAL_OPERAND:
- OUTMSG2 (("STATUS_FLOAT_DENORMAL_OPERAND"));
- ourstatus->value.sig = TARGET_SIGNAL_FPE;
- break;
- case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
- OUTMSG2 (("EXCEPTION_ARRAY_BOUNDS_EXCEEDED"));
- ourstatus->value.sig = TARGET_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_INEXACT_RESULT:
- OUTMSG2 (("STATUS_FLOAT_INEXACT_RESULT"));
- ourstatus->value.sig = TARGET_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_INVALID_OPERATION:
- OUTMSG2 (("STATUS_FLOAT_INVALID_OPERATION"));
- ourstatus->value.sig = TARGET_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_OVERFLOW:
- OUTMSG2 (("STATUS_FLOAT_OVERFLOW"));
- ourstatus->value.sig = TARGET_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_STACK_CHECK:
- OUTMSG2 (("STATUS_FLOAT_STACK_CHECK"));
- ourstatus->value.sig = TARGET_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_UNDERFLOW:
- OUTMSG2 (("STATUS_FLOAT_UNDERFLOW"));
- ourstatus->value.sig = TARGET_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_DIVIDE_BY_ZERO:
- OUTMSG2 (("STATUS_FLOAT_DIVIDE_BY_ZERO"));
- ourstatus->value.sig = TARGET_SIGNAL_FPE;
- break;
- case STATUS_INTEGER_DIVIDE_BY_ZERO:
- OUTMSG2 (("STATUS_INTEGER_DIVIDE_BY_ZERO"));
- ourstatus->value.sig = TARGET_SIGNAL_FPE;
- break;
- case STATUS_INTEGER_OVERFLOW:
- OUTMSG2 (("STATUS_INTEGER_OVERFLOW"));
- ourstatus->value.sig = TARGET_SIGNAL_FPE;
- break;
- case EXCEPTION_BREAKPOINT:
- OUTMSG2 (("EXCEPTION_BREAKPOINT"));
- ourstatus->value.sig = TARGET_SIGNAL_TRAP;
- break;
- case DBG_CONTROL_C:
- OUTMSG2 (("DBG_CONTROL_C"));
- ourstatus->value.sig = TARGET_SIGNAL_INT;
- break;
- case DBG_CONTROL_BREAK:
- OUTMSG2 (("DBG_CONTROL_BREAK"));
- ourstatus->value.sig = TARGET_SIGNAL_INT;
- break;
- case EXCEPTION_SINGLE_STEP:
- OUTMSG2 (("EXCEPTION_SINGLE_STEP"));
- ourstatus->value.sig = TARGET_SIGNAL_TRAP;
- break;
- case EXCEPTION_ILLEGAL_INSTRUCTION:
- OUTMSG2 (("EXCEPTION_ILLEGAL_INSTRUCTION"));
- ourstatus->value.sig = TARGET_SIGNAL_ILL;
- break;
- case EXCEPTION_PRIV_INSTRUCTION:
- OUTMSG2 (("EXCEPTION_PRIV_INSTRUCTION"));
- ourstatus->value.sig = TARGET_SIGNAL_ILL;
- break;
- case EXCEPTION_NONCONTINUABLE_EXCEPTION:
- OUTMSG2 (("EXCEPTION_NONCONTINUABLE_EXCEPTION"));
- ourstatus->value.sig = TARGET_SIGNAL_ILL;
- break;
- default:
- if (current_event.u.Exception.dwFirstChance)
- return 0;
- OUTMSG2 (("gdbserver: unknown target exception 0x%08lx at 0x%08lx",
- current_event.u.Exception.ExceptionRecord.ExceptionCode,
- (DWORD) current_event.u.Exception.ExceptionRecord.
- ExceptionAddress));
- ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
- break;
- }
- OUTMSG2 (("\n"));
- last_sig = ourstatus->value.sig;
- return 1;
-}
-
-/* Get the next event from the child. Return 1 if the event requires
- handling. */
-static int
-get_child_debug_event (struct target_waitstatus *ourstatus)
-{
- BOOL debug_event;
- DWORD continue_status, event_code;
- thread_info *th = NULL;
- static thread_info dummy_thread_info;
- int retval = 0;
-
-in:
-
- last_sig = TARGET_SIGNAL_0;
- ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
-
- if (!(debug_event = WaitForDebugEvent (¤t_event, 1000)))
- goto out;
-
- current_inferior =
- (struct thread_info *) find_inferior_id (&all_threads,
- current_event.dwThreadId);
-
- continue_status = DBG_CONTINUE;
- event_code = current_event.dwDebugEventCode;
-
- switch (event_code)
- {
- case CREATE_THREAD_DEBUG_EVENT:
- OUTMSG2 (("gdbserver: kernel event CREATE_THREAD_DEBUG_EVENT "
- "for pid=%d tid=%x)\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId));
-
- /* Record the existence of this thread. */
- th = child_add_thread (current_event.dwThreadId,
- current_event.u.CreateThread.hThread);
-
- retval = current_event.dwThreadId;
- break;
-
- case EXIT_THREAD_DEBUG_EVENT:
- OUTMSG2 (("gdbserver: kernel event EXIT_THREAD_DEBUG_EVENT "
- "for pid=%d tid=%x\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId));
- child_delete_thread (current_event.dwThreadId);
- th = &dummy_thread_info;
- break;
-
- case CREATE_PROCESS_DEBUG_EVENT:
- OUTMSG2 (("gdbserver: kernel event CREATE_PROCESS_DEBUG_EVENT "
- "for pid=%d tid=%x\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId));
- CloseHandle (current_event.u.CreateProcessInfo.hFile);
-
- current_process_handle = current_event.u.CreateProcessInfo.hProcess;
- main_thread_id = current_event.dwThreadId;
-
- ourstatus->kind = TARGET_WAITKIND_EXECD;
- ourstatus->value.execd_pathname = "Main executable";
-
- /* Add the main thread. */
- th =
- child_add_thread (main_thread_id,
- current_event.u.CreateProcessInfo.hThread);
-
- retval = ourstatus->value.related_pid = current_event.dwThreadId;
- break;
-
- case EXIT_PROCESS_DEBUG_EVENT:
- OUTMSG2 (("gdbserver: kernel event EXIT_PROCESS_DEBUG_EVENT "
- "for pid=%d tid=%x\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId));
- ourstatus->kind = TARGET_WAITKIND_EXITED;
- ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
- CloseHandle (current_process_handle);
- current_process_handle = NULL;
- retval = main_thread_id;
- break;
-
- case LOAD_DLL_DEBUG_EVENT:
- OUTMSG2 (("gdbserver: kernel event LOAD_DLL_DEBUG_EVENT "
- "for pid=%d tid=%x\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId));
- CloseHandle (current_event.u.LoadDll.hFile);
-
- ourstatus->kind = TARGET_WAITKIND_LOADED;
- ourstatus->value.integer = 0;
- retval = main_thread_id;
- break;
-
- case UNLOAD_DLL_DEBUG_EVENT:
- OUTMSG2 (("gdbserver: kernel event UNLOAD_DLL_DEBUG_EVENT "
- "for pid=%d tid=%x\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId));
- break;
-
- case EXCEPTION_DEBUG_EVENT:
- OUTMSG2 (("gdbserver: kernel event EXCEPTION_DEBUG_EVENT "
- "for pid=%d tid=%x\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId));
- retval = handle_exception (ourstatus);
- break;
-
- case OUTPUT_DEBUG_STRING_EVENT:
- /* A message from the kernel (or Cygwin). */
- OUTMSG2 (("gdbserver: kernel event OUTPUT_DEBUG_STRING_EVENT "
- "for pid=%d tid=%x\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId));
- break;
-
- default:
- OUTMSG2 (("gdbserver: kernel event unknown "
- "for pid=%d tid=%x code=%ld\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId,
- current_event.dwDebugEventCode));
- break;
- }
-
- current_inferior =
- (struct thread_info *) find_inferior_id (&all_threads,
- current_event.dwThreadId);
-
- if (!retval || (event_code != EXCEPTION_DEBUG_EVENT && event_code != EXIT_PROCESS_DEBUG_EVENT))
- {
- child_continue (continue_status, -1);
- goto in;
- }
-
- if (th == NULL)
- thread_rec (current_event.dwThreadId, TRUE);
-
-out:
- return retval;
-}
-
-/* Wait for the inferior process to change state.
- STATUS will be filled in with a response code to send to GDB.
- Returns the signal which caused the process to stop. */
-static unsigned char
-win32_wait (char *status)
-{
- struct target_waitstatus our_status;
-
- *status = 'T';
-
- while (1)
- {
- get_child_debug_event (&our_status);
-
- if (our_status.kind == TARGET_WAITKIND_EXITED)
- {
- OUTMSG2 (("Child exited with retcode = %x\n",
- our_status.value.integer));
-
- *status = 'W';
-
- child_fetch_inferior_registers (-1);
-
- return our_status.value.integer;
- }
- else if (our_status.kind == TARGET_WAITKIND_STOPPED)
- {
- OUTMSG2 (("Child Stopped with signal = %x \n",
- WSTOPSIG (our_status.value.sig)));
-
- *status = 'T';
-
- child_fetch_inferior_registers (-1);
-
- return our_status.value.sig;
- }
- else
- OUTMSG (("Ignoring unknown internal event, %d\n", our_status.kind));
-
- {
- struct thread_resume resume;
- resume.thread = -1;
- resume.step = 0;
- resume.sig = 0;
- resume.leave_stopped = 0;
- win32_resume (&resume);
- }
- }
-}
-
-/* Fetch registers from the inferior process.
- If REGNO is -1, fetch all registers; otherwise, fetch at least REGNO. */
-static void
-win32_fetch_inferior_registers (int regno)
-{
- child_fetch_inferior_registers (regno);
-}
-
-/* Store registers to the inferior process.
- If REGNO is -1, store all registers; otherwise, store at least REGNO. */
-static void
-win32_store_inferior_registers (int regno)
-{
- child_store_inferior_registers (regno);
-}
-
-/* Read memory from the inferior process. This should generally be
- called through read_inferior_memory, which handles breakpoint shadowing.
- Read LEN bytes at MEMADDR into a buffer at MYADDR. */
-static int
-win32_read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
-{
- return child_xfer_memory (memaddr, myaddr, len, 0, 0) != len;
-}
-
-/* Write memory to the inferior process. This should generally be
- called through write_inferior_memory, which handles breakpoint shadowing.
- Write LEN bytes from the buffer at MYADDR to MEMADDR.
- Returns 0 on success and errno on failure. */
-static int
-win32_write_inferior_memory (CORE_ADDR memaddr, const unsigned char *myaddr,
- int len)
-{
- return child_xfer_memory (memaddr, (char *) myaddr, len, 1, 0) != len;
-}
-
-static struct target_ops win32_target_ops = {
- win32_create_inferior,
- win32_attach,
- win32_kill,
- win32_detach,
- win32_thread_alive,
- win32_resume,
- win32_wait,
- win32_fetch_inferior_registers,
- win32_store_inferior_registers,
- win32_read_inferior_memory,
- win32_write_inferior_memory,
- 0,
- 0