/* Target-vector operations for controlling Windows CE child processes, for GDB.
   Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
   Contributed by Cygnus Solutions, A Red Hat Company.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.
 */

/* by Christopher Faylor (cgf@cygnus.com) */

/* We assume we're being built with and will be used for cygwin.  */

#ifdef SHx
#undef SH4
#define SH4			/* Just to get all of the CONTEXT defines. */
#endif

#include "defs.h"
#include "frame.h"		/* required by inferior.h */
#include "inferior.h"
#include "target.h"
#include "gdbcore.h"
#include "command.h"
#include <signal.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdlib.h>

#include <windows.h>
#include <rapi.h>
#include <netdb.h>
#include <cygwin/in.h>
#include <cygwin/socket.h>

#include "buildsym.h"
#include "symfile.h"
#include "objfiles.h"
#include "gdb_string.h"
#include "gdbthread.h"
#include "gdbcmd.h"
#include <sys/param.h>
#include "wince-stub.h"
#include <time.h>
#include "regcache.h"

/* The ui's event loop. */
extern int (*ui_loop_hook) (int signo);

/* If we're not using the old Cygwin header file set, define the
   following which never should have been in the generic Win32 API
   headers in the first place since they were our own invention... */
#ifndef _GNU_H_WINDOWS_H
#define FLAG_TRACE_BIT 0x100
#ifdef CONTEXT_FLOATING_POINT
#define CONTEXT_DEBUGGER0 (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
#else
#define CONTEXT_DEBUGGER0 (CONTEXT_FULL)
#endif
#endif

#ifdef SH4
#define CONTEXT_DEBUGGER ((CONTEXT_DEBUGGER0 & ~(CONTEXT_SH4 | CONTEXT_FLOATING_POINT)) | CONTEXT_SH3)
#else
#define CONTEXT_DEBUGGER CONTEXT_DEBUGGER0
#endif
/* The string sent by cygwin when it processes a signal.
   FIXME: This should be in a cygwin include file. */
#define CYGWIN_SIGNAL_STRING "cygwin: signal"

#define CHECK(x)	check (x, __FILE__,__LINE__)
#define DEBUG_EXEC(x)	if (debug_exec)		printf x
#define DEBUG_EVENTS(x)	if (debug_events)	printf x
#define DEBUG_MEM(x)	if (debug_memory)	printf x
#define DEBUG_EXCEPT(x)	if (debug_exceptions)	printf x

static int connection_initialized = 0;	/* True if we've initialized a RAPI session. */

/* The directory where the stub and executable files are uploaded. */
static const char *remote_directory = "\\gdb";

/* The types automatic upload available. */
static enum
  {
    UPLOAD_ALWAYS = 0,
    UPLOAD_NEWER = 1,
    UPLOAD_NEVER = 2
  }
upload_when = UPLOAD_NEWER;

/* Valid options for 'set remoteupload'.  Note that options
   must track upload_when enum. */
static struct opts
  {
    const char *name;
    int abbrev;
  }
upload_options[3] =
{
  {
    "always", 1
  }
  ,
  {
    "newer", 3
  }
  ,
  {
    "never", 3
  }
};

static char *remote_upload = NULL;	/* Set by set remoteupload */
static int remote_add_host = 0;

/* Forward declaration */
extern struct target_ops child_ops;

static int win32_child_thread_alive (ptid_t);
void child_kill_inferior (void);

static int last_sig = 0;	/* Set if a signal was received from the
				   debugged process */

/* Thread information structure used to track information that is
   not available in gdb's thread structure. */
typedef struct thread_info_struct
  {
    struct thread_info_struct *next;
    DWORD id;
    HANDLE h;
    char *name;
    int suspend_count;
    int stepped;		/* True if stepped. */
    CORE_ADDR step_pc;
    unsigned long step_prev;
    CONTEXT context;
  }
thread_info;

static thread_info thread_head =
{NULL};
static thread_info * thread_rec (DWORD id, int get_context);

/* 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 thread_info *this_thread;	/* Info on thread returned by wait_for_debug_event */
static DWORD main_thread_id;	/* Thread ID of the main thread */

/* Counts of things. */
static int exception_count = 0;
static int event_count = 0;

/* User options. */
static int debug_exec = 0;	/* show execution */
static int debug_events = 0;	/* show events from kernel */
static int debug_memory = 0;	/* show target memory accesses */
static int debug_exceptions = 0;	/* show target exceptions */

/* An array of offset mappings into a Win32 Context structure.
   This is a one-to-one mapping which is indexed by gdb's register
   numbers.  It retrieves an offset into the context structure where
   the 4 byte register is located.
   An offset value of -1 indicates that Win32 does not provide this
   register in it's CONTEXT structure.  regptr will return zero for this
   register.

   This is used by the regptr function. */
#define context_offset(x) ((int)&(((PCONTEXT)NULL)->x))
static const int mappings[NUM_REGS + 1] =
{
#ifdef __i386__
  context_offset (Eax),
  context_offset (Ecx),
  context_offset (Edx),
  context_offset (Ebx),
  context_offset (Esp),
  context_offset (Ebp),
  context_offset (Esi),
  context_offset (Edi),
  context_offset (Eip),
  context_offset (EFlags),
  context_offset (SegCs),
  context_offset (SegSs),
  context_offset (SegDs),
  context_offset (SegEs),
  context_offset (SegFs),
  context_offset (SegGs),
  context_offset (FloatSave.RegisterArea[0 * 10]),
  context_offset (FloatSave.RegisterArea[1 * 10]),
  context_offset (FloatSave.RegisterArea[2 * 10]),
  context_offset (FloatSave.RegisterArea[3 * 10]),
  context_offset (FloatSave.RegisterArea[4 * 10]),
  context_offset (FloatSave.RegisterArea[5 * 10]),
  context_offset (FloatSave.RegisterArea[6 * 10]),
  context_offset (FloatSave.RegisterArea[7 * 10]),
#elif defined(SHx)
  context_offset (R0),
  context_offset (R1),
  context_offset (R2),
  context_offset (R3),
  context_offset (R4),
  context_offset (R5),
  context_offset (R6),
  context_offset (R7),
  context_offset (R8),
  context_offset (R9),
  context_offset (R10),
  context_offset (R11),
  context_offset (R12),
  context_offset (R13),
  context_offset (R14),
  context_offset (R15),
  context_offset (Fir),
  context_offset (PR),		/* Procedure Register */
  context_offset (GBR),		/* Global Base Register */
  context_offset (MACH),	/* Accumulate */
  context_offset (MACL),	/* Multiply */
  context_offset (Psr),
  context_offset (Fpul),
  context_offset (Fpscr),
  context_offset (FRegs[0]),
  context_offset (FRegs[1]),
  context_offset (FRegs[2]),
  context_offset (FRegs[3]),
  context_offset (FRegs[4]),
  context_offset (FRegs[5]),
  context_offset (FRegs[6]),
  context_offset (FRegs[7]),
  context_offset (FRegs[8]),
  context_offset (FRegs[9]),
  context_offset (FRegs[10]),
  context_offset (FRegs[11]),
  context_offset (FRegs[12]),
  context_offset (FRegs[13]),
  context_offset (FRegs[14]),
  context_offset (FRegs[15]),
  context_offset (xFRegs[0]),
  context_offset (xFRegs[1]),
  context_offset (xFRegs[2]),
  context_offset (xFRegs[3]),
  context_offset (xFRegs[4]),
  context_offset (xFRegs[5]),
  context_offset (xFRegs[6]),
  context_offset (xFRegs[7]),
  context_offset (xFRegs[8]),
  context_offset (xFRegs[9]),
  context_offset (xFRegs[10]),
  context_offset (xFRegs[11]),
  context_offset (xFRegs[12]),
  context_offset (xFRegs[13]),
  context_offset (xFRegs[14]),
  context_offset (xFRegs[15]),
#elif defined(MIPS)
  context_offset (IntZero),
  context_offset (IntAt),
  context_offset (IntV0),
  context_offset (IntV1),
  context_offset (IntA0),
  context_offset (IntA1),
  context_offset (IntA2),
  context_offset (IntA3),
  context_offset (IntT0),
  context_offset (IntT1),
  context_offset (IntT2),
  context_offset (IntT3),
  context_offset (IntT4),
  context_offset (IntT5),
  context_offset (IntT6),
  context_offset (IntT7),
  context_offset (IntS0),
  context_offset (IntS1),
  context_offset (IntS2),
  context_offset (IntS3),
  context_offset (IntS4),
  context_offset (IntS5),
  context_offset (IntS6),
  context_offset (IntS7),
  context_offset (IntT8),
  context_offset (IntT9),
  context_offset (IntK0),
  context_offset (IntK1),
  context_offset (IntGp),
  context_offset (IntSp),
  context_offset (IntS8),
  context_offset (IntRa),
  context_offset (Psr),
  context_offset (IntLo),
  context_offset (IntHi),
  -1,				/* bad */
  -1,				/* cause */
  context_offset (Fir),
  context_offset (FltF0),
  context_offset (FltF1),
  context_offset (FltF2),
  context_offset (FltF3),
  context_offset (FltF4),
  context_offset (FltF5),
  context_offset (FltF6),
  context_offset (FltF7),
  context_offset (FltF8),
  context_offset (FltF9),
  context_offset (FltF10),
  context_offset (FltF11),
  context_offset (FltF12),
  context_offset (FltF13),
  context_offset (FltF14),
  context_offset (FltF15),
  context_offset (FltF16),
  context_offset (FltF17),
  context_offset (FltF18),
  context_offset (FltF19),
  context_offset (FltF20),
  context_offset (FltF21),
  context_offset (FltF22),
  context_offset (FltF23),
  context_offset (FltF24),
  context_offset (FltF25),
  context_offset (FltF26),
  context_offset (FltF27),
  context_offset (FltF28),
  context_offset (FltF29),
  context_offset (FltF30),
  context_offset (FltF31),
  context_offset (Fsr),
  context_offset (Fir),
  -1,				/* fp */
#elif defined(ARM)
  context_offset (R0),
  context_offset (R1),
  context_offset (R2),
  context_offset (R3),
  context_offset (R4),
  context_offset (R5),
  context_offset (R6),
  context_offset (R7),
  context_offset (R8),
  context_offset (R9),
  context_offset (R10),
  context_offset (R11),
  context_offset (R12),
  context_offset (Sp),
  context_offset (Lr),
  context_offset (Pc),
  -1,
  -1,
  -1,
  -1,
  -1,
  -1,
  -1,
  -1,
  -1,
  context_offset (Psr),
#endif
  -1
};

/* Return a pointer into a CONTEXT field indexed by gdb register number.
   Return a pointer to an address pointing to zero if there is no
   corresponding CONTEXT field for the given register number.
 */
static ULONG *
regptr (LPCONTEXT c, int r)
{
  static ULONG zero = 0;
  ULONG *p;
  if (mappings[r] < 0)
    p = &zero;
  else
    p = (ULONG *) (((char *) c) + mappings[r]);
  return p;
}

/******************** Beginning of stub interface ********************/

/* Stub interface description:

   The Windows CE stub implements a crude RPC.  The hand-held device
   connects to gdb using port 7000.  gdb and the stub then communicate
   using packets where:

   byte 0:              command id (e.g. Create Process)

   byte 1-4:    DWORD

   byte 1-2:    WORD

   byte 1-2:    length
   byte 3-n:    arbitrary memory.

   The interface is deterministic, i.e., if the stub expects a DWORD then
   the gdb server should send a DWORD.
 */

/* Note:  In the functions below, the `huh' parameter is a string passed from the
   function containing a descriptive string concerning the current operation.
   This is used for error reporting.

   The 'what' parameter is a command id as found in wince-stub.h.

   Hopefully, the rest of the parameters are self-explanatory.
 */

static int s;			/* communication socket */

/* v-style interface for handling varying argyment list error messages.
   Displays the error message in a dialog box and exits when user clicks
   on OK. */
static void
vstub_error (LPCSTR fmt, va_list * args)
{
  char buf[4096];
  vsprintf (buf, fmt, args);
  s = -1;
  error ("%s", buf);
}

/* The standard way to display an error message and exit. */
static void
stub_error (LPCSTR fmt,...)
{
  va_list args;
  va_start (args, fmt);
  vstub_error (fmt, args);
}

/* Standard "oh well" can't communicate error.  Someday this might attempt
   synchronization. */
static void
attempt_resync (LPCSTR huh, int s)
{
  stub_error ("lost synchronization with target attempting %s", huh);
}

/* Read arbitrary stuff from a socket. */
static int
sockread (LPCSTR huh, int s, void *str, size_t n)
{
  for (;;)
    {
      if (recv (s, str, n, 0) == n)
	return n;
      attempt_resync (huh, s);
    }
}

/* Write arbitrary stuff to a socket. */
static int
sockwrite (LPCSTR huh, const void *str, size_t n)
{
  for (;;)
    {
      if (send (s, str, n, 0) == n)
	return n;
      attempt_resync (huh, s);
    }
}

/* Output an id/dword to the host */
static void
putdword (LPCSTR huh, gdb_wince_id what, DWORD n)
{
  if (sockwrite (huh, &what, sizeof (what)) != sizeof (what))
    stub_error ("error writing record id to host for %s", huh);
  if (sockwrite (huh, &n, sizeof (n)) != sizeof (n))
    stub_error ("error writing %s to host.", huh);
}

/* Output an id/word to the host */
static void
putword (LPCSTR huh, gdb_wince_id what, WORD n)
{
  if (sockwrite (huh, &what, sizeof (what)) != sizeof (what))
    stub_error ("error writing record id to host for %s", huh);
  if (sockwrite (huh, &n, sizeof (n)) != sizeof (n))
    stub_error ("error writing %s host.", huh);
}

/* Convenience define for outputting a "gdb_wince_len" type. */
#define putlen(huh, what, n) putword((huh), (what), (gdb_wince_len) (n))

/* Put an arbitrary block of memory to the gdb host.  This comes in
   two chunks an id/dword representing the length and the stream of memory
   itself. */
static void
putmemory (LPCSTR huh, gdb_wince_id what, const void *mem, gdb_wince_len len)
{
  putlen (huh, what, len);
  if (((short) len > 0) && sockwrite (huh, mem, len) != len)
    stub_error ("error writing %s to host.", huh);
}

/* Output the result of an operation to the host.  If res != 0, sends a block of
   memory starting at mem of len bytes.  If res == 0, sends -GetLastError () and
   avoids sending the mem. */
static DWORD
getdword (LPCSTR huh, gdb_wince_id what_this)
{
  DWORD n;
  gdb_wince_id what;
  do
    if (sockread (huh, s, &what, sizeof (what)) != sizeof (what))
      stub_error ("error getting record type from host - %s.", huh);
  while (what_this != what);

  if (sockread (huh, s, &n, sizeof (n)) != sizeof (n))
    stub_error ("error getting %s from host.", huh);

  return n;
}

/* Get a an ID (possibly) and a WORD from the host gdb.
   Don't bother with the id if the main loop has already
   read it. */
static WORD
getword (LPCSTR huh, gdb_wince_id what_this)
{
  WORD n;
  gdb_wince_id what;
  do
    if (sockread (huh, s, &what, sizeof (what)) != sizeof (what))
      stub_error ("error getting record type from host - %s.", huh);
  while (what_this != what);

  if (sockread (huh, s, &n, sizeof (n)) != sizeof (n))
    stub_error ("error getting %s from host.", huh);

  return n;
}

/* Handy defines for getting/putting various types of values. */
#define gethandle(huh, what) (HANDLE) getdword ((huh), (what))
#define getpvoid(huh, what) (LPVOID) getdword ((huh), (what))
#define getlen(huh, what) (gdb_wince_len) getword ((huh), (what))
#define puthandle(huh, what, h) putdword ((huh), (what), (DWORD) (h))
#define putpvoid(huh, what, p) putdword ((huh), (what), (DWORD) (p))

/* Retrieve the result of an operation from the stub.  If nbytes < 0) then nbytes
   is actually an error and nothing else follows.  Use SetLastError to remember this.
   if nbytes > 0, retrieve a block of *nbytes into buf.
 */
int
getresult (LPCSTR huh, gdb_wince_id what, LPVOID buf, gdb_wince_len * nbytes)
{
  gdb_wince_len dummy;
  if (nbytes == NULL)
    nbytes = &dummy;

  *nbytes = getlen (huh, what);

  if ((short) *nbytes < 0)
    {
      SetLastError (-(short) *nbytes);
      return 0;
    }

  if ((gdb_wince_len) sockread (huh, s, buf, *nbytes) != *nbytes)
    stub_error ("couldn't read information from wince stub - %s", huh);

  return 1;
}

/* Convert "narrow" string to "wide".  Manipulates a buffer ring of 8
   buffers which hold the translated string.  This is an arbitrary limit
   but it is approximately double the current needs of this module.
 */
LPWSTR
towide (const char *s, gdb_wince_len * out_len)
{
  static int n = -1;
  static LPWSTR outs[8] =
  {NULL /*, NULL, etc. */ };
  gdb_wince_len dummy;

  if (!out_len)
    out_len = &dummy;

  /* First determine the length required to hold the converted string. */
  *out_len = sizeof (WCHAR) * MultiByteToWideChar (CP_ACP, 0, s, -1, NULL, 0);
  if (!*out_len)
    return NULL;		/* The conversion failed */

  if (++n >= (sizeof (outs) / sizeof (outs[0])))
    n = 0;			/* wrap */

  /* Allocate space for the converted string, reusing any previously allocated
     space, if applicable. Note that if outs[n] is NULL, xrealloc will act as
     a malloc (under cygwin, at least).
   */
  outs[n] = (LPWSTR) xrealloc (outs[n], *out_len);
  memset (outs[n], 0, *out_len);
  (void) MultiByteToWideChar (CP_ACP, 0, s, -1, outs[n], *out_len);
  return outs[n];
}

/******************** Emulation routines start here. ********************

  The functions below are modelled after their Win32 counterparts.  They are named
  similarly to Win32 and take exactly the same arguments except where otherwise noted.
  They communicate with the stub on the hand-held device by sending their arguments
  over the socket and waiting for results from the socket.

  There is one universal change.  In cases where a length is expected to be returned
  in a DWORD, we use a gdb_wince_len type instead.  Currently this is an unsigned short
  which is smaller than the standard Win32 DWORD.  This is done to minimize unnecessary
  traffic since the connection to Windows CE can be slow.  To change this, modify the
  typedef in wince-stub.h and change the putlen/getlen macros in this file and in
  the stub.
*/

static int
create_process (LPSTR exec_file, LPSTR args, DWORD flags, PROCESS_INFORMATION * pi)
{
  gdb_wince_len len;
  LPWSTR buf;

  buf = towide (exec_file, &len);
  putmemory ("CreateProcess exec_file", GDB_CREATEPROCESS, buf, len);
  buf = towide (args, &len);
  putmemory ("CreateProcess args", GDB_CREATEPROCESS, buf, len);
  putdword ("CreateProcess flags", GDB_CREATEPROCESS, flags);
  return getresult ("CreateProcess result", GDB_CREATEPROCESS, pi, NULL);
}

/* Emulate TerminateProcess.  Don't bother with the second argument since CE
   ignores it.
 */
static int
terminate_process (HANDLE h)
{
  gdb_wince_result res;
  if (s < 0)
    return 1;
  puthandle ("TerminateProcess handle", GDB_TERMINATEPROCESS, h);
  return getresult ("TerminateProcess result", GDB_TERMINATEPROCESS, &res, NULL);
}

static int
wait_for_debug_event (DEBUG_EVENT * ev, DWORD ms)
{
  if (s < 0)
    return 1;
  putdword ("WaitForDebugEvent ms", GDB_WAITFORDEBUGEVENT, ms);
  return getresult ("WaitForDebugEvent event", GDB_WAITFORDEBUGEVENT, ev, NULL);
}

static int
get_thread_context (HANDLE h, CONTEXT * c)
{
  if (s < 0)
    return 1;
  puthandle ("GetThreadContext handle", GDB_GETTHREADCONTEXT, h);
  putdword ("GetThreadContext flags", GDB_GETTHREADCONTEXT, c->ContextFlags);
  return getresult ("GetThreadContext context", GDB_GETTHREADCONTEXT, c, NULL);
}

static int
set_thread_context (HANDLE h, CONTEXT * c)
{
  gdb_wince_result res;
  if (s < 0)
    return 1;
  puthandle ("SetThreadContext handle", GDB_SETTHREADCONTEXT, h);
  putmemory ("SetThreadContext context", GDB_SETTHREADCONTEXT, c, sizeof (*c));
  return getresult ("SetThreadContext context", GDB_SETTHREADCONTEXT, &res, NULL);
}

static int
read_process_memory (HANDLE h, LPCVOID where, LPVOID buf, gdb_wince_len len, gdb_wince_len * nbytes)
{
  if (s < 0)
    return 1;
  puthandle ("ReadProcessMemory handle", GDB_READPROCESSMEMORY, h);
  putpvoid ("ReadProcessMemory location", GDB_READPROCESSMEMORY, where);
  putlen ("ReadProcessMemory size", GDB_READPROCESSMEMORY, len);

  return getresult ("ReadProcessMemory buf", GDB_READPROCESSMEMORY, buf, nbytes);
}

static int
write_process_memory (HANDLE h, LPCVOID where, LPCVOID buf, gdb_wince_len len, gdb_wince_len * nbytes)
{
  if (s < 0)
    return 1;
  puthandle ("WriteProcessMemory handle", GDB_WRITEPROCESSMEMORY, h);
  putpvoid ("WriteProcessMemory location", GDB_WRITEPROCESSMEMORY, where);
  putmemory ("WriteProcProcessMemory buf", GDB_WRITEPROCESSMEMORY, buf, len);

  return getresult ("WriteProcessMemory result", GDB_WRITEPROCESSMEMORY, nbytes, NULL);
}

static int
remote_read_bytes (CORE_ADDR memaddr, char *myaddr, int len)
{
  gdb_wince_len nbytes;
  if (!read_process_memory (current_process_handle, (LPCVOID) memaddr,
			    (LPVOID) myaddr, len, &nbytes))
    return -1;
  return nbytes;
}

static int
remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
{
  gdb_wince_len nbytes;
  if (!write_process_memory (current_process_handle, (LPCVOID) memaddr,
			     (LPCVOID) myaddr, len, &nbytes))
    return -1;
  return nbytes;
}

/* This is not a standard Win32 function.  It instructs the stub to return TRUE
   if the thread referenced by HANDLE h is alive.
 */
static int
thread_alive (HANDLE h)
{
  gdb_wince_result res;
  if (s < 0)
    return 1;
  puthandle ("ThreadAlive handle", GDB_THREADALIVE, h);
  return getresult ("ThreadAlive result", GDB_THREADALIVE, &res, NULL);
}

static int
suspend_thread (HANDLE h)
{
  if (s < 0)
    return 1;
  puthandle ("SuspendThread handle", GDB_SUSPENDTHREAD, h);
  return (int) getdword ("SuspendThread result", GDB_SUSPENDTHREAD);
}

static int
resume_thread (HANDLE h)
{
  if (s < 0)
    return 1;
  puthandle ("ResumeThread handle", GDB_RESUMETHREAD, h);
  return (int) getdword ("SuspendThread result", GDB_RESUMETHREAD);
}

static int
continue_debug_event (DWORD pid, DWORD tid, DWORD status)
{
  gdb_wince_result res;
  if (s < 0)
    return 0;
  putdword ("ContinueDebugEvent pid", GDB_CONTINUEDEBUGEVENT, pid);
  putdword ("ContinueDebugEvent tid", GDB_CONTINUEDEBUGEVENT, tid);
  putdword ("ContinueDebugEvent status", GDB_CONTINUEDEBUGEVENT, status);
  return getresult ("ContinueDebugEvent result", GDB_CONTINUEDEBUGEVENT, &res, NULL);
}

static int
close_handle (HANDLE h)
{
  gdb_wince_result res;
  if (s < 0)
    return 1;
  puthandle ("CloseHandle handle", GDB_CLOSEHANDLE, h);
  return (int) getresult ("CloseHandle result", GDB_CLOSEHANDLE, &res, NULL);
}

/* This is not a standard Win32 interface.  This function tells the stub
   to terminate.
 */
static void
stop_stub (void)
{
  if (s < 0)
    return;
  (void) putdword ("Stopping gdb stub", GDB_STOPSTUB, 0);
  s = -1;
}

/******************** End of emulation routines. ********************/
/******************** End of stub interface ********************/

#define check_for_step(a, x) (x)

#ifdef MIPS
static void
undoSStep (thread_info * th)
{
  if (th->stepped)
    {
      memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev);
      th->stepped = 0;
    }
}

void
wince_software_single_step (enum target_signal ignore,
			    int insert_breakpoints_p)
{
  unsigned long pc;
  thread_info *th = current_thread;	/* Info on currently selected thread */
  CORE_ADDR mips_next_pc (CORE_ADDR pc);

  if (!insert_breakpoints_p)
    {
      undoSStep (th);
      return;
    }

  th->stepped = 1;
  pc = read_register (PC_REGNUM);
  th->step_pc = mips_next_pc (pc);
  th->step_prev = 0;
  memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev);
  return;
}
#elif SHx
/* Hitachi SH architecture instruction encoding masks */

#define COND_BR_MASK   0xff00
#define UCOND_DBR_MASK 0xe000
#define UCOND_RBR_MASK 0xf0df
#define TRAPA_MASK     0xff00

#define COND_DISP      0x00ff
#define UCOND_DISP     0x0fff
#define UCOND_REG      0x0f00

/* Hitachi SH instruction opcodes */

#define BF_INSTR       0x8b00
#define BT_INSTR       0x8900
#define BRA_INSTR      0xa000
#define BSR_INSTR      0xb000
#define JMP_INSTR      0x402b
#define JSR_INSTR      0x400b
#define RTS_INSTR      0x000b
#define RTE_INSTR      0x002b
#define TRAPA_INSTR    0xc300
#define SSTEP_INSTR    0xc3ff


#define T_BIT_MASK     0x0001

static CORE_ADDR
sh_get_next_pc (CONTEXT *c)
{
  short *instrMem;
  int displacement;
  int reg;
  unsigned short opcode;

  instrMem = (short *) c->Fir;

  opcode = read_memory_integer ((CORE_ADDR) c->Fir, sizeof (opcode));

  if ((opcode & COND_BR_MASK) == BT_INSTR)
    {
      if (c->Psr & T_BIT_MASK)
	{
	  displacement = (opcode & COND_DISP) << 1;
	  if (displacement & 0x80)
	    displacement |= 0xffffff00;
	  /*
	     * Remember PC points to second instr.
	     * after PC of branch ... so add 4
	   */
	  instrMem = (short *) (c->Fir + displacement + 4);
	}
      else
	instrMem += 1;
    }
  else if ((opcode & COND_BR_MASK) == BF_INSTR)
    {
      if (c->Psr & T_BIT_MASK)
	instrMem += 1;
      else
	{
	  displacement = (opcode & COND_DISP) << 1;
	  if (displacement & 0x80)
	    displacement |= 0xffffff00;
	  /*
	     * Remember PC points to second instr.
	     * after PC of branch ... so add 4
	   */
	  instrMem = (short *) (c->Fir + displacement + 4);
	}
    }
  else if ((opcode & UCOND_DBR_MASK) == BRA_INSTR)
    {
      displacement = (opcode & UCOND_DISP) << 1;
      if (displacement & 0x0800)
	displacement |= 0xfffff000;

      /*
	 * Remember PC points to second instr.
	 * after PC of branch ... so add 4
       */
      instrMem = (short *) (c->Fir + displacement + 4);
    }
  else if ((opcode & UCOND_RBR_MASK) == JSR_INSTR)
    {
      reg = (char) ((opcode & UCOND_REG) >> 8);

      instrMem = (short *) *regptr (c, reg);
    }
  else if (opcode == RTS_INSTR)
    instrMem = (short *) c->PR;
  else if (opcode == RTE_INSTR)
    instrMem = (short *) *regptr (c, 15);
  else if ((opcode & TRAPA_MASK) == TRAPA_INSTR)
    instrMem = (short *) ((opcode & ~TRAPA_MASK) << 2);
  else
    instrMem += 1;

  return (CORE_ADDR) instrMem;
}
/* Single step (in a painstaking fashion) by inspecting the current
   instruction and setting a breakpoint on the "next" instruction
   which would be executed.  This code hails from sh-stub.c.
 */
static void
undoSStep (thread_info * th)
{
  if (th->stepped)
    {
      memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev);
      th->stepped = 0;
    }
  return;
}

/* Single step (in a painstaking fashion) by inspecting the current
   instruction and setting a breakpoint on the "next" instruction
   which would be executed.  This code hails from sh-stub.c.
 */
void
wince_software_single_step (enum target_signal ignore,
			    int insert_breakpoints_p)
{
  thread_info *th = current_thread;	/* Info on currently selected thread */

  if (!insert_breakpoints_p)
    {
      undoSStep (th);
      return;
    }

  th->stepped = 1;
  th->step_pc = sh_get_next_pc (&th->context);
  th->step_prev = 0;
  memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev);
  return;
}
#elif defined (ARM)
#undef check_for_step

static enum target_signal
check_for_step (DEBUG_EVENT *ev, enum target_signal x)
{
  thread_info *th = thread_rec (ev->dwThreadId, 1);

  if (th->stepped &&
      th->step_pc == (CORE_ADDR) ev->u.Exception.ExceptionRecord.ExceptionAddress)
    return TARGET_SIGNAL_TRAP;
  else
    return x;
}

/* Single step (in a painstaking fashion) by inspecting the current
   instruction and setting a breakpoint on the "next" instruction
   which would be executed.  This code hails from sh-stub.c.
 */
static void
undoSStep (thread_info * th)
{
  if (th->stepped)
    {
      memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev);
      th->stepped = 0;
    }
}

void
wince_software_single_step (enum target_signal ignore,
			    int insert_breakpoints_p)
{
  unsigned long pc;
  thread_info *th = current_thread;	/* Info on currently selected thread */
  CORE_ADDR mips_next_pc (CORE_ADDR pc);

  if (!insert_breakpoints_p)
    {
      undoSStep (th);
      return;
    }

  th->stepped = 1;
  pc = read_register (PC_REGNUM);
  th->step_pc = arm_get_next_pc (pc);
  th->step_prev = 0;
  memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev);
  return;
}
#endif

/* Find a thread record given a thread id.
   If get_context then also retrieve the context for this
   thread. */
static thread_info *
thread_rec (DWORD id, int get_context)
{
  thread_info *th;

  for (th = &thread_head; (th = th->next) != NULL;)
    if (th->id == id)
      {
	if (!th->suspend_count && get_context)
	  {
	    if (get_context > 0 && th != this_thread)
	      th->suspend_count = suspend_thread (th->h) + 1;
	    else if (get_context < 0)
	      th->suspend_count = -1;

	    th->context.ContextFlags = CONTEXT_DEBUGGER;
	    get_thread_context (th->h, &th->context);
	  }
	return th;
      }

  return NULL;
}

/* Add a thread to the thread list */
static thread_info *
child_add_thread (DWORD id, HANDLE h)
{
  thread_info *th;

  if ((th = thread_rec (id, FALSE)))
    return th;

  th = (thread_info *) xmalloc (sizeof (*th));
  memset (th, 0, sizeof (*th));
  th->id = id;
  th->h = h;
  th->next = thread_head.next;
  thread_head.next = th;
  add_thread (id);
  return th;
}

/* Clear out any old thread list and reintialize it to a
   pristine state. */
static void
child_init_thread_list (void)
{
  thread_info *th = &thread_head;

  DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
  init_thread_list ();
  while (th->next != NULL)
    {
      thread_info *here = th->next;
      th->next = here->next;
      (void) close_handle (here->h);
      xfree (here);
    }
}

/* Delete a thread from the list of threads */
static void
child_delete_thread (DWORD id)
{
  thread_info *th;

  if (info_verbose)
    printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (id));
  delete_thread (id);

  for (th = &thread_head;
       th->next != NULL && th->next->id != id;
       th = th->next)
    continue;

  if (th->next != NULL)
    {
      thread_info *here = th->next;
      th->next = here->next;
      close_handle (here->h);
      xfree (here);
    }
}

static void
check (BOOL ok, const char *file, int line)
{
  if (!ok)
    printf_filtered ("error return %s:%d was %d\n", file, line, GetLastError ());
}

static void
do_child_fetch_inferior_registers (int r)
{
  if (r >= 0)
    {
      supply_register (r, (char *) regptr (&current_thread->context, r));
    }
  else
    {
      for (r = 0; r < NUM_REGS; r++)
	do_child_fetch_inferior_registers (r);
    }
}

static void
child_fetch_inferior_registers (int r)
{
  current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
  do_child_fetch_inferior_registers (r);
}

static void
do_child_store_inferior_registers (int r)
{
  if (r >= 0)
    read_register_gen (r, ((char *) &current_thread->context) + mappings[r]);
  else
    {
      for (r = 0; r < NUM_REGS; r++)
	do_child_store_inferior_registers (r);
    }
}

/* Store a new register value into the current thread context */
static void
child_store_inferior_registers (int r)
{
  current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
  do_child_store_inferior_registers (r);
}

/* Wait for child to do something.  Return pid of child, or -1 in case
   of error; store status through argument pointer OURSTATUS.  */

static int
handle_load_dll (void *dummy)
{
  LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
  char dll_buf[MAX_PATH + 1];
  char *p, *bufp, *imgp, *dll_name, *dll_basename;
  int len;

  dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
  if (!event->lpImageName)
    return 1;

  len = 0;
  for (bufp = dll_buf, imgp = event->lpImageName;
       bufp < dll_buf + sizeof (dll_buf);
       bufp += 16, imgp += 16)
    {
      gdb_wince_len nbytes = 0;
      (void) read_process_memory (current_process_handle,
				  imgp, bufp, 16, &nbytes);

      if (!nbytes && bufp == dll_buf)
	return 1;		/* couldn't read it */
      for (p = bufp; p < bufp + nbytes; p++)
	{
	  len++;
	  if (*p == '\0')
	    goto out;
	  if (event->fUnicode)
	    p++;
	}
      if (!nbytes)
	break;
    }

out:
  if (!len)
    return 1;
#if 0
  dll_buf[len] = '\0';
#endif
  dll_name = alloca (len);

  if (!dll_name)
    return 1;

  if (!event->fUnicode)
    memcpy (dll_name, dll_buf, len);
  else
    WideCharToMultiByte (CP_ACP, 0, (LPCWSTR) dll_buf, len,
			 dll_name, len, 0, 0);

  while ((p = strchr (dll_name, '\\')))
    *p = '/';

  /* FIXME!! It would be nice to define one symbol which pointed to the
     front of the dll if we can't find any symbols. */

  if (!(dll_basename = strrchr (dll_name, '/')))
    dll_basename = dll_name;
  else
    dll_basename++;

  /* The symbols in a dll are offset by 0x1000, which is the
     the offset from 0 of the first byte in an image - because
     of the file header and the section alignment.

     FIXME: Is this the real reason that we need the 0x1000 ? */

  printf_unfiltered ("%x:%s", event->lpBaseOfDll, dll_name);
  printf_unfiltered ("\n");

  return 1;
}

/* Handle DEBUG_STRING output from child process. */
static void
handle_output_debug_string (struct target_waitstatus *ourstatus)
{
  char p[256];
  char s[255];
  char *q;
  gdb_wince_len nbytes_read;
  gdb_wince_len nbytes = current_event.u.DebugString.nDebugStringLength;

  if (nbytes > 255)
    nbytes = 255;

  memset (p, 0, sizeof (p));
  if (!read_process_memory (current_process_handle,
			    current_event.u.DebugString.lpDebugStringData,
			    &p, nbytes, &nbytes_read)
      || !*p)
    return;

  memset (s, 0, sizeof (s));
  WideCharToMultiByte (CP_ACP, 0, (LPCWSTR) p, (int) nbytes_read, s,
		       sizeof (s) - 1, NULL, NULL);
  q = strchr (s, '\n');
  if (q != NULL)
    {
      *q = '\0';
      if (*--q = '\r')
	*q = '\0';
    }

  warning (s);

  return;
}

/* Handle target exceptions. */
static int
handle_exception (struct target_waitstatus *ourstatus)
{
#if 0
  if (current_event.u.Exception.dwFirstChance)
    return 0;
#endif

  ourstatus->kind = TARGET_WAITKIND_STOPPED;

  switch (current_event.u.Exception.ExceptionRecord.ExceptionCode)
    {
    case EXCEPTION_ACCESS_VIOLATION:
      DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08x\n",
		     (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
      ourstatus->value.sig = TARGET_SIGNAL_SEGV;
      break;
    case STATUS_STACK_OVERFLOW:
      DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08x\n",
		     (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
      ourstatus->value.sig = TARGET_SIGNAL_SEGV;
      break;
    case EXCEPTION_BREAKPOINT:
      DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08x\n",
		     (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
      ourstatus->value.sig = TARGET_SIGNAL_TRAP;
      break;
    case DBG_CONTROL_C:
      DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08x\n",
		     (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
      ourstatus->value.sig = TARGET_SIGNAL_INT;
      /* User typed CTRL-C.  Continue with this status */
      last_sig = SIGINT;	/* FIXME - should check pass state */
      break;
    case EXCEPTION_SINGLE_STEP:
      DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08x\n",
		     (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
      ourstatus->value.sig = TARGET_SIGNAL_TRAP;
      break;
    case EXCEPTION_ILLEGAL_INSTRUCTION:
      DEBUG_EXCEPT (("gdb: Target exception SINGLE_ILL at 0x%08x\n",
	       current_event.u.Exception.ExceptionRecord.ExceptionAddress));
      ourstatus->value.sig = check_for_step (&current_event, TARGET_SIGNAL_ILL);
      break;
    default:
      /* This may be a structured exception handling exception.  In
	 that case, we want to let the program try to handle it, and
	 only break if we see the exception a second time.  */

      printf_unfiltered ("gdb: unknown target exception 0x%08x at 0x%08x\n",
		    current_event.u.Exception.ExceptionRecord.ExceptionCode,
		current_event.u.Exception.ExceptionRecord.ExceptionAddress);
      ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
      break;
    }
  exception_count++;
  return 1;
}

/* Resume all artificially suspended threads if we are continuing
   execution */
static BOOL
child_continue (DWORD continue_status, int id)
{
  int i;
  thread_info *th;
  BOOL res;

  DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=%d, DBG_CONTINUE);\n",
		 (unsigned) current_event.dwProcessId, (unsigned) current_event.dwThreadId));
  res = continue_debug_event (current_event.dwProcessId,
			      current_event.dwThreadId,
			      continue_status);
  if (res)
    for (th = &thread_head; (th = th->next) != NULL;)
      if (((id == -1) || (id == th->id)) && th->suspend_count)
	{
	  for (i = 0; i < th->suspend_count; i++)
	    (void) resume_thread (th->h);
	  th->suspend_count = 0;
	}

  return res;
}

/* Get the next event from the child.  Return 1 if the event requires
   handling by WFI (or whatever).
 */
static int
get_child_debug_event (int pid, struct target_waitstatus *ourstatus,
		       DWORD target_event_code, int *retval)
{
  int breakout = 0;
  BOOL debug_event;
  DWORD continue_status, event_code;
  thread_info *th = NULL;
  static thread_info dummy_thread_info;

  if (!(debug_event = wait_for_debug_event (&current_event, 1000)))
    {
      *retval = 0;
      goto out;
    }

  event_count++;
  continue_status = DBG_CONTINUE;
  *retval = 0;

  event_code = current_event.dwDebugEventCode;
  breakout = event_code == target_event_code;

  switch (event_code)
    {
    case CREATE_THREAD_DEBUG_EVENT:
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
		     (unsigned) current_event.dwProcessId,
		     (unsigned) current_event.dwThreadId,
		     "CREATE_THREAD_DEBUG_EVENT"));
      /* Record the existence of this thread */
      th = child_add_thread (current_event.dwThreadId,
			     current_event.u.CreateThread.hThread);
      if (info_verbose)
	printf_unfiltered ("[New %s]\n",
			   target_pid_to_str (current_event.dwThreadId));
      break;

    case EXIT_THREAD_DEBUG_EVENT:
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
		     (unsigned) current_event.dwProcessId,
		     (unsigned) current_event.dwThreadId,
		     "EXIT_THREAD_DEBUG_EVENT"));
      child_delete_thread (current_event.dwThreadId);
      th = &dummy_thread_info;
      break;

    case CREATE_PROCESS_DEBUG_EVENT:
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
		     (unsigned) current_event.dwProcessId,
		     (unsigned) current_event.dwThreadId,
		     "CREATE_PROCESS_DEBUG_EVENT"));
      current_process_handle = current_event.u.CreateProcessInfo.hProcess;

      main_thread_id = current_event.dwThreadId;
      inferior_ptid = pid_to_ptid (main_thread_id);
      /* Add the main thread */
      th = child_add_thread (PIDGET (inferior_ptid),
			     current_event.u.CreateProcessInfo.hThread);
      break;

    case EXIT_PROCESS_DEBUG_EVENT:
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
		     (unsigned) current_event.dwProcessId,
		     (unsigned) current_event.dwThreadId,
		     "EXIT_PROCESS_DEBUG_EVENT"));
      ourstatus->kind = TARGET_WAITKIND_EXITED;
      ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
      close_handle (current_process_handle);
      *retval = current_event.dwProcessId;
      breakout = 1;
      break;

    case LOAD_DLL_DEBUG_EVENT:
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
		     (unsigned) current_event.dwProcessId,
		     (unsigned) current_event.dwThreadId,
		     "LOAD_DLL_DEBUG_EVENT"));
      catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
      registers_changed ();	/* mark all regs invalid */
      break;

    case UNLOAD_DLL_DEBUG_EVENT:
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
		     (unsigned) current_event.dwProcessId,
		     (unsigned) current_event.dwThreadId,
		     "UNLOAD_DLL_DEBUG_EVENT"));
      break;			/* FIXME: don't know what to do here */

    case EXCEPTION_DEBUG_EVENT:
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
		     (unsigned) current_event.dwProcessId,
		     (unsigned) current_event.dwThreadId,
		     "EXCEPTION_DEBUG_EVENT"));
      if (handle_exception (ourstatus))
	*retval = current_event.dwThreadId;
      else
	{
	  continue_status = DBG_EXCEPTION_NOT_HANDLED;
	  breakout = 0;
	}
      break;

    case OUTPUT_DEBUG_STRING_EVENT:	/* message from the kernel */
      DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
		     (unsigned) current_event.dwProcessId,
		     (unsigned) current_event.dwThreadId,
		     "OUTPUT_DEBUG_STRING_EVENT"));
      handle_output_debug_string ( ourstatus);
      break;
    default:
      printf_unfiltered ("gdb: kernel event for pid=%d tid=%d\n",
			 current_event.dwProcessId,
			 current_event.dwThreadId);
      printf_unfiltered ("                 unknown event code %d\n",
			 current_event.dwDebugEventCode);
      break;
    }

  if (breakout)
    this_thread = current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE);
  else
    CHECK (child_continue (continue_status, -1));

out:
  return breakout;
}

/* Wait for interesting events to occur in the target process. */
static ptid_t
child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
{
  DWORD event_code;
  int retval;
  int pid = PIDGET (ptid);

  /* We loop when we get a non-standard exception rather than return
     with a SPURIOUS because resume can try and step or modify things,
     which needs a current_thread->h.  But some of these exceptions mark
     the birth or death of threads, which mean that the current thread
     isn't necessarily what you think it is. */

  while (1)
    if (get_child_debug_event (pid, ourstatus, EXCEPTION_DEBUG_EVENT, &retval))
      return pid_to_ptid (retval);
    else
      {
	int detach = 0;

	if (ui_loop_hook != NULL)
	  detach = ui_loop_hook (0);

	if (detach)
	  child_kill_inferior ();
      }
}

/* Print status information about what we're accessing.  */

static void
child_files_info (struct target_ops *ignore)
{
  printf_unfiltered ("\tUsing the running image of child %s.\n",
		     target_pid_to_str (inferior_ptid));
}

/* ARGSUSED */
static void
child_open (char *arg, int from_tty)
{
  error ("Use the \"run\" command to start a child process.");
}

#define FACTOR (0x19db1ded53ea710LL)
#define NSPERSEC 10000000

/* Convert a Win32 time to "UNIX" format. */
long
to_time_t (FILETIME * ptr)
{
  /* A file time is the number of 100ns since jan 1 1601
     stuffed into two long words.
     A time_t is the number of seconds since jan 1 1970.  */

  long rem;
  long long x = ((long long) ptr->dwHighDateTime << 32) + ((unsigned) ptr->dwLowDateTime);
  x -= FACTOR;			/* number of 100ns between 1601 and 1970 */
  rem = x % ((long long) NSPERSEC);
  rem += (NSPERSEC / 2);
  x /= (long long) NSPERSEC;	/* number of 100ns in a second */
  x += (long long) (rem / NSPERSEC);
  return x;
}

/* Upload a file to the remote device depending on the user's
   'set remoteupload' specification. */
char *
upload_to_device (const char *to, const char *from)
{
  HANDLE h;
  const char *dir = remote_directory ?: "\\gdb";
  int len;
  static char *remotefile = NULL;
  LPWSTR wstr;
  char *p;
  DWORD err;
  const char *in_to = to;
  FILETIME crtime, actime, wrtime;
  time_t utime;
  struct stat st;
  int fd;

  /* Look for a path separator and only use trailing part. */
  while ((p = strpbrk (to, "/\\")) != NULL)
    to = p + 1;

  if (!*to)
    error ("no filename found to upload - %s.", in_to);

  len = strlen (dir) + strlen (to) + 2;
  remotefile = (char *) xrealloc (remotefile, len);
  strcpy (remotefile, dir);
  strcat (remotefile, "\\");
  strcat (remotefile, to);

  if (upload_when == UPLOAD_NEVER)
    return remotefile;		/* Don't bother uploading. */

  /* Open the source. */
  if ((fd = openp (getenv ("PATH"), TRUE, (char *) from, O_RDONLY, 0, NULL)) < 0)
    error ("couldn't open %s", from);

  /* Get the time for later comparison. */
  if (fstat (fd, &st))
    st.st_mtime = (time_t) - 1;

  /* Always attempt to create the directory on the remote system. */
  wstr = towide (dir, NULL);
  (void) CeCreateDirectory (wstr, NULL);

  /* Attempt to open the remote file, creating it if it doesn't exist. */
  wstr = towide (remotefile, NULL);
  h = CeCreateFile (wstr, GENERIC_READ | GENERIC_WRITE, 0, NULL,
		    OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

  /* Some kind of problem? */
  err = CeGetLastError ();
  if (h == NULL || h == INVALID_HANDLE_VALUE)
    error ("error opening file \"%s\".  Windows error %d.",
	   remotefile, err);

  CeGetFileTime (h, &crtime, &actime, &wrtime);
  utime = to_time_t (&wrtime);
#if 0
  if (utime < st.st_mtime)
    {
      char buf[80];
      strcpy (buf, ctime(&utime));
      printf ("%s < %s\n", buf, ctime(&st.st_mtime));
    }
#endif
  /* See if we need to upload the file. */
  if (upload_when == UPLOAD_ALWAYS ||
      err != ERROR_ALREADY_EXISTS ||
      !CeGetFileTime (h, &crtime, &actime, &wrtime) ||
      to_time_t (&wrtime) < st.st_mtime)
    {
      DWORD nbytes;
      char buf[4096];
      int n;

      /* Upload the file. */
      while ((n = read (fd, buf, sizeof (buf))) > 0)
	if (!CeWriteFile (h, buf, (DWORD) n, &nbytes, NULL))
	  error ("error writing to remote device - %d.",
		 CeGetLastError ());
    }

  close (fd);
  if (!CeCloseHandle (h))
    error ("error closing remote file - %d.", CeGetLastError ());

  return remotefile;
}

/* Initialize the connection to the remote device. */
static void
wince_initialize (void)
{
  int tmp;
  char args[256];
  char *hostname;
  struct sockaddr_in sin;
  char *stub_file_name;
  int s0;
  PROCESS_INFORMATION pi;

  if (!connection_initialized)
    switch (CeRapiInit ())
      {
      case 0:
	connection_initialized = 1;
	break;
      default:
	CeRapiUninit ();
	error ("Can't initialize connection to remote device.\n");
	break;
      }

  /* Upload the stub to the handheld device. */
  stub_file_name = upload_to_device ("wince-stub.exe", WINCE_STUB);
  strcpy (args, stub_file_name);

  if (remote_add_host)
    {
      strcat (args, " ");
      hostname = strchr (args, '\0');
      if (gethostname (hostname, sizeof (args) - strlen (args)))
	error ("couldn't get hostname of this system.");
    }

  /* Get a socket. */
  if ((s0 = socket (AF_INET, SOCK_STREAM, 0)) < 0)
    stub_error ("Couldn't connect to host system.");

  /* Allow rapid reuse of the port. */
  tmp = 1;
  (void) setsockopt (s0, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp, sizeof (tmp));


  /* Set up the information for connecting to the host gdb process. */
  memset (&sin, 0, sizeof (sin));
  sin.sin_family = AF_INET;
  sin.sin_port = htons (7000);	/* FIXME: This should be configurable */

  if (bind (s0, (struct sockaddr *) &sin, sizeof (sin)))
    error ("couldn't bind socket");

  if (listen (s0, 1))
    error ("Couldn't open socket for listening.\n");

  /* Start up the stub on the remote device. */
  if (!CeCreateProcess (towide (stub_file_name, NULL), towide (args, NULL),
			NULL, NULL, 0, 0, NULL, NULL, NULL, &pi))
    error ("Unable to start remote stub '%s'.  Windows CE error %d.",
	   stub_file_name, CeGetLastError ());

  /* Wait for a connection */

  if ((s = accept (s0, NULL, NULL)) < 0)
    error ("couldn't set up server for connection.");

  close (s0);
}

/* Start an inferior win32 child process and sets inferior_ptid to its pid.
   EXEC_FILE is the file to run.
   ALLARGS is a string containing the arguments to the program.
   ENV is the environment vector to pass.  Errors reported with error().  */
static void
child_create_inferior (char *exec_file, char *args, char **env)
{
  PROCESS_INFORMATION pi;
  struct target_waitstatus dummy;
  int ret;
  DWORD flags, event_code;
  char *exec_and_args;

  if (!exec_file)
    error ("No executable specified, use `target exec'.\n");

  flags = DEBUG_PROCESS;

  wince_initialize ();		/* Make sure we've got a connection. */

  exec_file = upload_to_device (exec_file, exec_file);

  while (*args == ' ')
    args++;

  /* Allocate space for "command<sp>args" */
  if (*args == '\0')
    {
      exec_and_args = alloca (strlen (exec_file) + 1);
      strcpy (exec_and_args, exec_file);
    }
  else
    {
      exec_and_args = alloca (strlen (exec_file + strlen (args) + 2));
      sprintf (exec_and_args, "%s %s", exec_file, args);
    }

  memset (&pi, 0, sizeof (pi));
  /* Execute the process */
  if (!create_process (exec_file, exec_and_args, flags, &pi))
    error ("Error creating process %s, (error %d)\n", exec_file, GetLastError ());

  exception_count = 0;
  event_count = 0;

  current_process_handle = pi.hProcess;
  current_event.dwProcessId = pi.dwProcessId;
  memset (&current_event, 0, sizeof (current_event));
  current_event.dwThreadId = pi.dwThreadId;
  inferior_ptid = pid_to_ptid (current_event.dwThreadId);
  push_target (&child_ops);
  child_init_thread_list ();
  child_add_thread (pi.dwThreadId, pi.hThread);
  init_wait_for_inferior ();
  clear_proceed_status ();
  target_terminal_init ();
  target_terminal_inferior ();

  /* Run until process and threads are loaded */
  while (!get_child_debug_event (PIDGET (inferior_ptid), &dummy,
				 CREATE_PROCESS_DEBUG_EVENT, &ret))
    continue;

  proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
}

/* Chile has gone bye-bye. */
static void
child_mourn_inferior (void)
{
  (void) child_continue (DBG_CONTINUE, -1);
  unpush_target (&child_ops);
  stop_stub ();
  CeRapiUninit ();
  connection_initialized = 0;
  generic_mourn_inferior ();
}

/* Move memory from child to/from gdb. */
int
child_xfer_memory (CORE_ADDR memaddr, char *our, int len, int write,
		   struct mem_attrib *attrib,
		   struct target_ops *target)
{
  if (len <= 0)
    return 0;

  if (write)
    res = remote_write_bytes (memaddr, our, len);
  else
    res = remote_read_bytes (memaddr, our, len);

  return res;
}

/* Terminate the process and wait for child to tell us it has completed. */
void
child_kill_inferior (void)
{
  CHECK (terminate_process (current_process_handle));

  for (;;)
    {
      if (!child_continue (DBG_CONTINUE, -1))
	break;
      if (!wait_for_debug_event (&current_event, INFINITE))
	break;
      if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
	break;
    }

  CHECK (close_handle (current_process_handle));
  close_handle (current_thread->h);
  target_mourn_inferior ();	/* or just child_mourn_inferior? */
}

/* Resume the child after an exception. */
void
child_resume (ptid_t ptid, int step, enum target_signal sig)
{
  thread_info *th;
  DWORD continue_status = last_sig > 0 && last_sig < NSIG ?
  DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE;
  int pid = PIDGET (ptid);

  DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
	       pid, step, sig));

  /* Get context for currently selected thread */
  th = thread_rec (current_event.dwThreadId, FALSE);

  if (th->context.ContextFlags)
    {
      CHECK (set_thread_context (th->h, &th->context));
      th->context.ContextFlags = 0;
    }

  /* Allow continuing with the same signal that interrupted us.
     Otherwise complain. */
  if (sig && sig != last_sig)
    fprintf_unfiltered (gdb_stderr, "Can't send signals to the child.  signal %d\n", sig);

  last_sig = 0;
  child_continue (continue_status, pid);
}

static void
child_prepare_to_store (void)
{
  /* Do nothing, since we can store individual regs */
}

static int
child_can_run (void)
{
  return 1;
}

static void
child_close (void)
{
  DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n",
                PIDGET (inferior_ptid)));
}

/* Explicitly upload file to remotedir */

static void
child_load (char *file, int from_tty)
{
  upload_to_device (file, file);
}

struct target_ops child_ops;

static void
init_child_ops (void)
{
  memset (&child_ops, 0, sizeof (child_ops));
  child_ops.to_shortname = (char *) "child";
  child_ops.to_longname = (char *) "Windows CE process";
  child_ops.to_doc = (char *) "Windows CE process (started by the \"run\" command).";
  child_ops.to_open = child_open;
  child_ops.to_close = child_close;
  child_ops.to_resume = child_resume;
  child_ops.to_wait = child_wait;
  child_ops.to_fetch_registers = child_fetch_inferior_registers;
  child_ops.to_store_registers = child_store_inferior_registers;
  child_ops.to_prepare_to_store = child_prepare_to_store;
  child_ops.to_xfer_memory = child_xfer_memory;
  child_ops.to_files_info = child_files_info;
  child_ops.to_insert_breakpoint = memory_insert_breakpoint;
  child_ops.to_remove_breakpoint = memory_remove_breakpoint;
  child_ops.to_terminal_init = terminal_init_inferior;
  child_ops.to_terminal_inferior = terminal_inferior;
  child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
  child_ops.to_terminal_ours = terminal_ours;
  child_ops.to_terminal_info = child_terminal_info;
  child_ops.to_kill = child_kill_inferior;
  child_ops.to_load = child_load;
  child_ops.to_create_inferior = child_create_inferior;
  child_ops.to_mourn_inferior = child_mourn_inferior;
  child_ops.to_can_run = child_can_run;
  child_ops.to_thread_alive = win32_child_thread_alive;
  child_ops.to_stratum = process_stratum;
  child_ops.to_has_all_memory = 1;
  child_ops.to_has_memory = 1;
  child_ops.to_has_stack = 1;
  child_ops.to_has_registers = 1;
  child_ops.to_has_execution = 1;
  child_ops.to_sections = 0;
  child_ops.to_sections_end = 0;
  child_ops.to_magic = OPS_MAGIC;
}


/* Handle 'set remoteupload' parameter. */

#define replace_upload(what) \
      upload_when = what; \
      remote_upload = xrealloc (remote_upload, strlen (upload_options[upload_when].name) + 1); \
      strcpy (remote_upload, upload_options[upload_when].name);

static void
set_upload_type (char *ignore, int from_tty)
{
  int i, len;
  char *bad_option;

  if (!remote_upload || !remote_upload[0])
    {
      replace_upload (UPLOAD_NEWER);
      if (from_tty)
	printf_unfiltered ("Upload upload_options are: always, newer, never.\n");
      return;
    }

  len = strlen (remote_upload);
  for (i = 0; i < (sizeof (upload_options) / sizeof (upload_options[0])); i++)
    if (len >= upload_options[i].abbrev &&
	strncasecmp (remote_upload, upload_options[i].name, len) == 0)
      {
	replace_upload (i);
	return;
      }

  bad_option = remote_upload;
  replace_upload (UPLOAD_NEWER);
  error ("Unknown upload type: %s.", bad_option);
}

void
_initialize_inftarg (void)
{
  struct cmd_list_element *set;
  init_child_ops ();

  add_show_from_set
    (add_set_cmd ((char *) "remotedirectory", no_class,
		  var_string_noescape, (char *) &remote_directory,
		  (char *) "Set directory for remote upload.\n",
		  &setlist),
     &showlist);
  remote_directory = xstrdup (remote_directory);

  set = add_set_cmd ((char *) "remoteupload", no_class,
		     var_string_noescape, (char *) &remote_upload,
	       (char *) "Set how to upload executables to remote device.\n",
		     &setlist);
  add_show_from_set (set, &showlist);
  set_cmd_cfunc (set, set_upload_type);
  set_upload_type (NULL, 0);

  add_show_from_set
    (add_set_cmd ((char *) "debugexec", class_support, var_boolean,
		  (char *) &debug_exec,
	      (char *) "Set whether to display execution in child process.",
		  &setlist),
     &showlist);

  add_show_from_set
    (add_set_cmd ((char *) "remoteaddhost", class_support, var_boolean,
		  (char *) &remote_add_host,
		  (char *) "Set whether to add this host to remote stub arguments for\n
debugging over a network.", &setlist),
     &showlist);

  add_show_from_set
    (add_set_cmd ((char *) "debugevents", class_support, var_boolean,
		  (char *) &debug_events,
	  (char *) "Set whether to display kernel events in child process.",
		  &setlist),
     &showlist);

  add_show_from_set
    (add_set_cmd ((char *) "debugmemory", class_support, var_boolean,
		  (char *) &debug_memory,
	(char *) "Set whether to display memory accesses in child process.",
		  &setlist),
     &showlist);

  add_show_from_set
    (add_set_cmd ((char *) "debugexceptions", class_support, var_boolean,
		  (char *) &debug_exceptions,
      (char *) "Set whether to display kernel exceptions in child process.",
		  &setlist),
     &showlist);

  add_target (&child_ops);
}

/* Determine if the thread referenced by "pid" is alive
   by "polling" it.  If WaitForSingleObject returns WAIT_OBJECT_0
   it means that the pid has died.  Otherwise it is assumed to be alive. */
static int
win32_child_thread_alive (ptid_t ptid)
{
  int pid = PIDGET (ptid);
  return thread_alive (thread_rec (pid, FALSE)->h);
}

/* Convert pid to printable format. */
char *
cygwin_pid_to_str (int pid)
{
  static char buf[80];
  if (pid == current_event.dwProcessId)
    sprintf (buf, "process %d", pid);
  else
    sprintf (buf, "thread %d.0x%x", (unsigned) current_event.dwProcessId, pid);
  return buf;
}
