/* wince-stub.c -- debugging stub for a Windows CE device

   Copyright (C) 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 eve nthe 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., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
 */

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

#include <stdarg.h>
#include <windows.h>
#include <winsock.h>
#include "wince-stub.h"

#define MALLOC(n) (void *) LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, (UINT)(n))
#define REALLOC(s, n) (void *) LocalReAlloc ((HLOCAL)(s), (UINT)(n), LMEM_MOVEABLE)
#define FREE(s) LocalFree ((HLOCAL)(s))

static int skip_next_id = 0;	/* Don't read next API code from socket */

/* v-style interface for handling varying argument list error messages.
   Displays the error message in a dialog box and exits when user clicks
   on OK. */
static void
vstub_error (LPCWSTR fmt, va_list args)
{
  WCHAR buf[4096];
  wvsprintfW (buf, fmt, args);

  MessageBoxW (NULL, buf, L"GDB", MB_ICONERROR);
  WSACleanup ();
  ExitThread (1);
}

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

/* Allocate a limited pool of memory, reallocating over unused
   buffers.  This assumes that there will never be more than four
   "buffers" required which, so far, is a safe assumption. */
static LPVOID
mempool (unsigned int len)
{
  static int outn = -1;
  static LPWSTR outs[4] = {NULL, NULL, NULL, NULL};

  if (++outn >= (sizeof (outs) / sizeof (outs[0])))
    outn = 0;

  /* Allocate space for the converted string, reusing any previously allocated
     space, if applicable. */
  if (outs[outn])
    FREE (outs[outn]);
  outs[outn] = (LPWSTR) MALLOC (len);

  return outs[outn];
}

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

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

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

/* Get a an ID (possibly) and a DWORD from the host gdb.
   Don't bother with the id if the main loop has already
   read it. */
static DWORD
getdword (LPCWSTR huh, int s, gdb_wince_id what_this)
{
  DWORD n;
  gdb_wince_id what;

  if (skip_next_id)
    skip_next_id = 0;
  else
    do
      if (sockread (huh, s, &what, sizeof (what)) != sizeof (what))
	stub_error (L"error getting record type from host - %s.", huh);
    while (what_this != what);

  if (sockread (huh, s, &n, sizeof (n)) != sizeof (n))
    stub_error (L"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 (LPCWSTR huh, int s, gdb_wince_id what_this)
{
  WORD n;
  gdb_wince_id what;

  if (skip_next_id)
    skip_next_id = 0;
  else
    do
      if (sockread (huh, s, &what, sizeof (what)) != sizeof (what))
	stub_error (L"error getting record type from host - %s.", huh);
    while (what_this != what);

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

  return n;
}

/* Handy defines for getting various types of values. */
#define gethandle(huh, s, what) (HANDLE) getdword ((huh), (s), (what))
#define getpvoid(huh, s, what) (LPVOID) getdword ((huh), (s), (what))
#define getlen(huh, s, what) (gdb_wince_len) getword ((huh), (s), (what))

/* Get an arbitrary block of memory from the gdb host.  This comes in
   two chunks an id/dword representing the length and the stream of memory
   itself. Returns a pointer, allocated via mempool, to a memory buffer. */
static LPWSTR
getmemory (LPCWSTR huh, int s, gdb_wince_id what, gdb_wince_len *inlen)
{
  LPVOID p;
  gdb_wince_len dummy;

  if (!inlen)
    inlen = &dummy;

  *inlen = getlen (huh, s, what);

  p = mempool ((unsigned int) *inlen);	/* FIXME: check for error */

  if ((gdb_wince_len) sockread (huh, s, p, *inlen) != *inlen)
    stub_error (L"error getting string from host.");

  return p;
}

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

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

/* Convenience define for outputting a "gdb_wince_len" type. */
#define putlen(huh, s, what, n) putword ((huh), (s), (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 (LPCWSTR huh, int s, gdb_wince_id what, const void *mem, gdb_wince_len len)
{
  putlen (huh, s, what, len);
  if (((short) len > 0) && (gdb_wince_len) sockwrite (huh, s, mem, len) != len)
    stub_error (L"error writing memory to host.");
}

/* 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 void
putresult (LPCWSTR huh, gdb_wince_result res, int s, gdb_wince_id what, const void *mem, gdb_wince_len len)
{
  if (!res)
    len = -(int) GetLastError ();
  putmemory (huh, s, what, mem, len);
}

static HANDLE curproc;		/* Currently unused, but nice for debugging */

/* Emulate CreateProcess.  Returns &pi if no error. */
static void
create_process (int s)
{
  LPWSTR exec_file = getmemory (L"CreateProcess exec_file", s, GDB_CREATEPROCESS, NULL);
  LPWSTR args = getmemory (L"CreateProcess args", s, GDB_CREATEPROCESS, NULL);
  DWORD flags = getdword (L"CreateProcess flags", s, GDB_CREATEPROCESS);
  PROCESS_INFORMATION pi;
  gdb_wince_result res;

  res = CreateProcessW (exec_file,
			args,	/* command line */
			NULL,	/* Security */
			NULL,	/* thread */
			FALSE,	/* inherit handles */
			flags,	/* start flags */
			NULL,
			NULL,	/* current directory */
			NULL,
			&pi);
  putresult (L"CreateProcess", res, s, GDB_CREATEPROCESS, &pi, sizeof (pi));
  curproc = pi.hProcess;
}

/* Emulate TerminateProcess.  Returns return value of TerminateProcess if
   no error.
   *** NOTE:  For some unknown reason, TerminateProcess seems to always return
   an ACCESS_DENIED (on Windows CE???) error.  So, force a TRUE value for now. */
static void
terminate_process (int s)
{
  gdb_wince_result res;
  HANDLE h = gethandle (L"TerminateProcess handle", s, GDB_TERMINATEPROCESS);

  res = TerminateProcess (h, 0) || 1;	/* Doesn't seem to work on SH so default to TRUE */
  putresult (L"Terminate process result", res, s, GDB_TERMINATEPROCESS,
	     &res, sizeof (res));
}

static int stepped = 0;
/* Handle single step instruction.  FIXME: unneded? */
static void
flag_single_step (int s)
{
  stepped = 1;
  skip_next_id = 0;
}

struct skipper
{
  wchar_t *s;
  int nskip;
} skippy[] =
{
  {L"Undefined Instruction:", 1},
  {L"Data Abort:", 2},
  {NULL, 0}
};

static int
skip_message (DEBUG_EVENT *ev)
{
  char s[80];
  DWORD nread;
  struct skipper *skp;
  int nbytes = ev->u.DebugString.nDebugStringLength;

  if (nbytes > sizeof(s))
    nbytes = sizeof(s);

  memset (s, 0, sizeof (s));
  if (!ReadProcessMemory (curproc, ev->u.DebugString.lpDebugStringData,
			  s, nbytes, &nread))
    return 0;

  for (skp = skippy; skp->s != NULL; skp++)
    if (wcsncmp ((wchar_t *) s, skp->s, wcslen (skp->s)) == 0)
      return skp->nskip;

  return 0;
}

/* Emulate WaitForDebugEvent.  Returns the debug event on success. */
static void
wait_for_debug_event (int s)
{
  DWORD ms = getdword (L"WaitForDebugEvent ms", s, GDB_WAITFORDEBUGEVENT);
  gdb_wince_result res;
  DEBUG_EVENT ev;
  static int skip_next = 0;

  for (;;)
    {
      res = WaitForDebugEvent (&ev, ms);

      if (ev.dwDebugEventCode == OUTPUT_DEBUG_STRING_EVENT)
	{
	  if (skip_next)
	    {
	      skip_next--;
	      goto ignore;
	    }
	  if (skip_next = skip_message (&ev))
	    goto ignore;
	}

      putresult (L"WaitForDebugEvent event", res, s, GDB_WAITFORDEBUGEVENT,
		 &ev, sizeof (ev));
      break;

    ignore:
      ContinueDebugEvent (ev.dwProcessId, ev.dwThreadId, DBG_CONTINUE);
    }

  return;
}

/* Emulate GetThreadContext.  Returns CONTEXT structure on success. */
static void
get_thread_context (int s)
{
  CONTEXT c;
  HANDLE h = gethandle (L"GetThreadContext handle", s, GDB_GETTHREADCONTEXT);
  gdb_wince_result res;

  memset (&c, 0, sizeof (c));
  c.ContextFlags = getdword (L"GetThreadContext flags", s, GDB_GETTHREADCONTEXT);

  res = (gdb_wince_result) GetThreadContext (h, &c);
  putresult (L"GetThreadContext data", res, s, GDB_GETTHREADCONTEXT,
	     &c, sizeof (c));
}

/* Emulate GetThreadContext.  Returns success of SetThreadContext. */
static void
set_thread_context (int s)
{
  gdb_wince_result res;
  HANDLE h = gethandle (L"SetThreadContext handle", s, GDB_SETTHREADCONTEXT);
  LPCONTEXT pc = (LPCONTEXT) getmemory (L"SetThreadContext context", s,
					GDB_SETTHREADCONTEXT, NULL);

  res = SetThreadContext (h, pc);
  putresult (L"SetThreadContext result", res, s, GDB_SETTHREADCONTEXT,
	     &res, sizeof (res));
}

/* Emulate ReadProcessMemory.  Returns memory read on success. */
static void
read_process_memory (int s)
{
  HANDLE h = gethandle (L"ReadProcessMemory handle", s, GDB_READPROCESSMEMORY);
  LPVOID p = getpvoid (L"ReadProcessMemory base", s, GDB_READPROCESSMEMORY);
  gdb_wince_len len = getlen (L"ReadProcessMemory size", s, GDB_READPROCESSMEMORY);
  LPVOID buf = mempool ((unsigned int) len);
  DWORD outlen;
  gdb_wince_result res;

  outlen = 0;
  res = (gdb_wince_result) ReadProcessMemory (h, p, buf, len, &outlen);
  putresult (L"ReadProcessMemory data", res, s, GDB_READPROCESSMEMORY,
	     buf, (gdb_wince_len) outlen);
}

/* Emulate WriteProcessMemory.  Returns WriteProcessMemory success. */
static void
write_process_memory (int s)
{
  HANDLE h = gethandle (L"WriteProcessMemory handle", s, GDB_WRITEPROCESSMEMORY);
  LPVOID p = getpvoid (L"WriteProcessMemory base", s, GDB_WRITEPROCESSMEMORY);
  gdb_wince_len len;
  LPVOID buf = getmemory (L"WriteProcessMemory buf", s, GDB_WRITEPROCESSMEMORY, &len);
  DWORD outlen;
  gdb_wince_result res;

  outlen = 0;
  res = WriteProcessMemory (h, p, buf, (DWORD) len, &outlen);
  putresult (L"WriteProcessMemory data", res, s, GDB_WRITEPROCESSMEMORY,
	     (gdb_wince_len *) & outlen, sizeof (gdb_wince_len));
}

/* Return non-zero to gdb host if given thread is alive. */
static void
thread_alive (int s)
{
  HANDLE h = gethandle (L"ThreadAlive handle", s, GDB_THREADALIVE);
  gdb_wince_result res;

  res = WaitForSingleObject (h, 0) == WAIT_OBJECT_0 ? 1 : 0;
  putresult (L"WriteProcessMemory data", res, s, GDB_THREADALIVE,
	     &res, sizeof (res));
}

/* Emulate SuspendThread.  Returns value returned from SuspendThread. */
static void
suspend_thread (int s)
{
  DWORD res;
  HANDLE h = gethandle (L"SuspendThread handle", s, GDB_SUSPENDTHREAD);
  res = SuspendThread (h);
  putdword (L"SuspendThread result", s, GDB_SUSPENDTHREAD, res);
}

/* Emulate ResumeThread.  Returns value returned from ResumeThread. */
static void
resume_thread (int s)
{
  DWORD res;
  HANDLE h = gethandle (L"ResumeThread handle", s, GDB_RESUMETHREAD);
  res = ResumeThread (h);
  putdword (L"ResumeThread result", s, GDB_RESUMETHREAD, res);
}

/* Emulate ContinueDebugEvent.  Returns ContinueDebugEvent success. */
static void
continue_debug_event (int s)
{
  gdb_wince_result res;
  DWORD pid = getdword (L"ContinueDebugEvent pid", s, GDB_CONTINUEDEBUGEVENT);
  DWORD tid = getdword (L"ContinueDebugEvent tid", s, GDB_CONTINUEDEBUGEVENT);
  DWORD status = getdword (L"ContinueDebugEvent status", s, GDB_CONTINUEDEBUGEVENT);
  res = (gdb_wince_result) ContinueDebugEvent (pid, tid, status);
  putresult (L"ContinueDebugEvent result", res, s, GDB_CONTINUEDEBUGEVENT, &res, sizeof (res));
}

/* Emulate CloseHandle.  Returns CloseHandle success. */
static void
close_handle (int s)
{
  gdb_wince_result res;
  HANDLE h = gethandle (L"CloseHandle handle", s, GDB_CLOSEHANDLE);
  res = (gdb_wince_result) CloseHandle (h);
  putresult (L"CloseHandle result", res, s, GDB_CLOSEHANDLE, &res, sizeof (res));
}

/* Main loop for reading requests from gdb host on the socket. */
static void
dispatch (int s)
{
  gdb_wince_id id;

  /* Continue reading from socket until receive a GDB_STOPSUB. */
  while (sockread (L"Dispatch", s, &id, sizeof (id)) > 0)
    {
      skip_next_id = 1;
      switch (id)
	{
	case GDB_CREATEPROCESS:
	  create_process (s);
	  break;
	case GDB_TERMINATEPROCESS:
	  terminate_process (s);
	  break;
	case GDB_WAITFORDEBUGEVENT:
	  wait_for_debug_event (s);
	  break;
	case GDB_GETTHREADCONTEXT:
	  get_thread_context (s);
	  break;
	case GDB_SETTHREADCONTEXT:
	  set_thread_context (s);
	  break;
	case GDB_READPROCESSMEMORY:
	  read_process_memory (s);
	  break;
	case GDB_WRITEPROCESSMEMORY:
	  write_process_memory (s);
	  break;
	case GDB_THREADALIVE:
	  thread_alive (s);
	  break;
	case GDB_SUSPENDTHREAD:
	  suspend_thread (s);
	  break;
	case GDB_RESUMETHREAD:
	  resume_thread (s);
	  break;
	case GDB_CONTINUEDEBUGEVENT:
	  continue_debug_event (s);
	  break;
	case GDB_CLOSEHANDLE:
	  close_handle (s);
	  break;
	case GDB_STOPSTUB:
	  terminate_process (s);
	  return;
	case GDB_SINGLESTEP:
	  flag_single_step (s);
	  break;
	default:
	  {
	    WCHAR buf[80];
	    wsprintfW (buf, L"Invalid command id received: %d", id);
	    MessageBoxW (NULL, buf, L"GDB", MB_ICONERROR);
	    skip_next_id = 0;
	  }
	}
    }
}

/* The Windows Main entry point */
int WINAPI
WinMain (HINSTANCE hi, HINSTANCE hp, LPWSTR cmd, int show)
{
  struct hostent *h;
  int s;
  struct WSAData wd;
  struct sockaddr_in sin;
  int tmp;
  LPWSTR whost;
  char host[80];

  whost = wcschr (cmd, L' ');	/* Look for argument. */

  /* If no host is specified, just use default */
  if (whost)
    {
      /* Eat any spaces. */
      while (*whost == L' ' || *whost == L'\t')
	whost++;

      wcstombs (host, whost, 80);	/* Convert from UNICODE to ascii */
    }

  /* Winsock initialization. */
  if (WSAStartup (MAKEWORD (1, 1), &wd))
    stub_error (L"Couldn't initialize WINSOCK.");

  /* If whost was specified, first try it.  If it was not specified or the
     host lookup failed, try the Windows CE magic ppp_peer lookup.  ppp_peer
     is supposed to be the Windows host sitting on the other end of the
     serial cable. */
  if (whost && *whost && (h = gethostbyname (host)) != NULL)
    /* nothing to do */ ;
  else if ((h = gethostbyname ("ppp_peer")) == NULL)
    stub_error (L"Couldn't get IP address of host system.  Error %d", WSAGetLastError ());

  /* Get a socket. */
  if ((s = socket (AF_INET, SOCK_STREAM, 0)) < 0)
    stub_error (L"Couldn't connect to host system. Error %d", WSAGetLastError ());

  /* Allow rapid reuse of the port. */
  tmp = 1;
  setsockopt (s, 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 = h->h_addrtype;
  memcpy (&sin.sin_addr, h->h_addr, h->h_length);
  sin.sin_port = htons (7000);	/* FIXME: This should be configurable */

  /* Connect to host */
  if (connect (s, (struct sockaddr *) &sin, sizeof (sin)) < 0)
    stub_error (L"Couldn't connect to host gdb.");

  /* Read from socket until told to exit. */
  dispatch (s);
  WSACleanup ();
  return 0;
}
