/* Target-vector operations for controlling Windows CE child processes, for GDB.
   Copyright 1999, 2000 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 "dcache.h"
#include <time.h>

/* The ui's event loop. */
extern int (*ui_loop_hook) PARAMS ((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. */

static DCACHE *remote_dcache;

/* 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 (int);
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, realloc will act as
     a malloc (under cygwin, at least).
   */
  outs[n] = (LPWSTR) realloc (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 ()
{
  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 (unsigned int 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 (unsigned int 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 (unsigned int 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 ()
{
  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);
      free (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);
      free (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 (inferior_pid, 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 (inferior_pid, 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 (PTR 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 = inferior_pid = current_event.dwThreadId;
      /* Add the main thread */
      th = child_add_thread (inferior_pid,
			     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 int
child_wait (int pid, struct target_waitstatus *ourstatus)
{
  DWORD event_code;
  int retval;

  /* 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 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 (ignore)
     struct target_ops *ignore;
{
  printf_unfiltered ("\tUsing the running image of child %s.\n",
		     target_pid_to_str (inferior_pid));
}

/* ARGSUSED */
static void
child_open (arg, from_tty)
     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 *) realloc (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 ()
{
  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_pid 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. */
  if (!remote_dcache)
    remote_dcache = dcache_init (remote_read_bytes, remote_write_bytes);
  else
    dcache_flush (remote_dcache);

  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));
  inferior_pid = current_event.dwThreadId = pi.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 (inferior_pid, &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) 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 target_ops *target)
{
  if (len <= 0)
    return 0;
  return dcache_xfer_memory (remote_dcache, memaddr, our, len, write);
}

/* 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 (int pid, int step, enum target_signal sig)
{
  thread_info *th;
  DWORD continue_status = last_sig > 0 && last_sig < NSIG ?
  DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE;

  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;
    }

  dcache_flush (remote_dcache);

  /* 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 ()
{
  /* Do nothing, since we can store individual regs */
}

static int
child_can_run ()
{
  return 1;
}

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

/* 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 = realloc (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 ()
{
  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->function.cfunc = set_upload_type;
  set_upload_type (NULL, 0);
  set_dcache_state (1);

  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 (int pid)
{
  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;
}
