Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [New WinCE support] [patch 1/4] : mv win32-i386-low.c win32-low.c
       [not found] <20070315235008.243411000@portugalmail.pt>
@ 2007-03-16  2:07 ` Pedro Alves
  2007-03-27 19:11   ` Daniel Jacobowitz
  2007-03-16  2:09 ` [New WinCE support] [patch 3/4] : bfd config Pedro Alves
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 19+ messages in thread
From: Pedro Alves @ 2007-03-16  2:07 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 288 bytes --]

This patch renames gdbserver/win32-i386-low.c to
gdbserver/win32-low.c.  Well, actually, it is mostly a
ChangeLog entry, as it is useless to post a patch for the file move.
Patch 4 will then move the i386 specifics into a new
win32-i386-low.c, and add a win32-arm-low.c with ARM stuff.



[-- Attachment #2: win32-i386-low_rename.diff --]
[-- Type: text/plain, Size: 1692 bytes --]

gdbserver/ChangeLog

	* win32-i386-low.c: Rename to ...
	* win32-low.c: ... this.
	* configure.srv: Replace win32-i386-low.o with win32-low.o.
	* Makefile.in: Likewise.

---
 gdb/gdbserver/Makefile.in   |    2 +-
 gdb/gdbserver/configure.srv |    4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

Index: src/gdb/gdbserver/configure.srv
===================================================================
--- src.orig/gdb/gdbserver/configure.srv	2007-03-15 00:27:36.000000000 +0000
+++ src/gdb/gdbserver/configure.srv	2007-03-15 02:25:20.000000000 +0000
@@ -44,7 +44,7 @@ case "${target}" in
 			srv_linux_thread_db=yes
 			;;
   i[34567]86-*-cygwin*)	srv_regobj=reg-i386.o
-			srv_tgtobj="win32-i386-low.o"
+			srv_tgtobj="win32-low.o"
 			;;
   i[34567]86-*-linux*)	srv_regobj=reg-i386-linux.o
 			srv_tgtobj="linux-low.o linux-i386-low.o i387-fp.o"
@@ -53,7 +53,7 @@ case "${target}" in
 			srv_linux_thread_db=yes
 			;;
   i[34567]86-*-mingw*)	srv_regobj=reg-i386.o
-			srv_tgtobj="win32-i386-low.o"
+			srv_tgtobj="win32-low.o"
 			srv_mingw=yes
 			;;
   ia64-*-linux*)	srv_regobj=reg-ia64.o
Index: src/gdb/gdbserver/Makefile.in
===================================================================
--- src.orig/gdb/gdbserver/Makefile.in	2007-03-15 00:27:38.000000000 +0000
+++ src/gdb/gdbserver/Makefile.in	2007-03-15 02:25:20.000000000 +0000
@@ -310,7 +310,7 @@ linux-sh-low.o: linux-sh-low.c $(linux_l
 linux-x86-64-low.o: linux-x86-64-low.c $(linux_low_h) $(server_h) \
 	$(gdb_proc_service_h)
 
-win32-i386-low.o: win32-i386-low.c $(server_h) $(regdef_h) $(regcache_h)
+win32-low.o: win32-low.c $(server_h) $(regdef_h) $(regcache_h)
 
 spu-low.o: spu-low.c $(server_h)
 





^ permalink raw reply	[flat|nested] 19+ messages in thread

* [New WinCE support] [patch 2/4] : s/thread_info/win32_thread_info/g
       [not found] <20070315235008.243411000@portugalmail.pt>
  2007-03-16  2:07 ` [New WinCE support] [patch 1/4] : mv win32-i386-low.c win32-low.c Pedro Alves
  2007-03-16  2:09 ` [New WinCE support] [patch 3/4] : bfd config Pedro Alves
@ 2007-03-16  2:09 ` Pedro Alves
  2007-03-27 19:12   ` Daniel Jacobowitz
  2007-03-16  2:10 ` [New WinCE support] [patch 4/4] The bulk of the code Pedro Alves
  3 siblings, 1 reply; 19+ messages in thread
From: Pedro Alves @ 2007-03-16  2:09 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 566 bytes --]

This is a pretty mechanical patch, that fixes one annoyance I had
when I started reading the gdbserver win32 support code.  There is an
opaque struct thread_info declared in server.h, and the win32-low.c
file implements a 'typedef struct win32_thread_info thread_info'.  I
find it confusing to have code like:

thread_rec (DWORD id, int get_context)
{
     struct thread_info *thread;
     thread_info *th;

I only noticed the types where unrelated after my first working
gdbserver/WinCE prototype was working :)

The attached patch should make the code clearer.




[-- Attachment #2: gdbserver_win32_thread_info.diff --]
[-- Type: text/plain, Size: 4911 bytes --]

gdbserver/ChangeLog

	* win32-low.c: Rename typedef thread_info to
	win32_thread_info throughout.

---

 gdb/gdbserver/win32-low.c |   36 ++++++++++++++++++------------------
 1 file changed, 18 insertions(+), 18 deletions(-)

Index: src/gdb/gdbserver/win32-low.c
===================================================================
--- src.orig/gdb/gdbserver/win32-low.c	2007-03-15 00:38:04.000000000 +0000
+++ src/gdb/gdbserver/win32-low.c	2007-03-15 02:25:20.000000000 +0000
@@ -68,13 +68,13 @@ typedef BOOL winapi_DebugSetProcessKillO
 
 /* Thread information structure used to track extra information about
    each thread.  */
-typedef struct thread_info_struct
+typedef struct win32_thread_info
 {
   DWORD tid;
   HANDLE h;
   int suspend_count;
   CONTEXT context;
-} thread_info;
+} win32_thread_info;
 static DWORD main_thread_id = 0;
 
 /* Get the thread ID from the current selected inferior (the current
@@ -82,17 +82,17 @@ static DWORD main_thread_id = 0;
 static DWORD
 current_inferior_tid (void)
 {
-  thread_info *th = inferior_target_data (current_inferior);
+  win32_thread_info *th = inferior_target_data (current_inferior);
   return th->tid;
 }
 
 /* Find a thread record given a thread id.  If GET_CONTEXT is set then
    also retrieve the context for this thread.  */
-static thread_info *
+static win32_thread_info *
 thread_rec (DWORD id, int get_context)
 {
   struct thread_info *thread;
-  thread_info *th;
+  win32_thread_info *th;
 
   thread = (struct thread_info *) find_inferior_id (&all_threads, id);
   if (thread == NULL)
@@ -126,15 +126,15 @@ thread_rec (DWORD id, int get_context)
 }
 
 /* Add a thread to the thread list.  */
-static thread_info *
+static win32_thread_info *
 child_add_thread (DWORD tid, HANDLE h)
 {
-  thread_info *th;
+  win32_thread_info *th;
 
   if ((th = thread_rec (tid, FALSE)))
     return th;
 
-  th = (thread_info *) malloc (sizeof (*th));
+  th = (win32_thread_info *) malloc (sizeof (*th));
   memset (th, 0, sizeof (*th));
   th->tid = tid;
   th->h = h;
@@ -170,7 +170,7 @@ child_add_thread (DWORD tid, HANDLE h)
 static void
 delete_thread_info (struct inferior_list_entry *thread)
 {
-  thread_info *th = inferior_target_data ((struct thread_info *) thread);
+  win32_thread_info *th = inferior_target_data ((struct thread_info *) thread);
 
   remove_thread ((struct thread_info *) thread);
   CloseHandle (th->h);
@@ -341,7 +341,7 @@ continue_one_thread (struct inferior_lis
 {
   struct thread_info *thread = (struct thread_info *) this_thread;
   int thread_id = * (int *) id_ptr;
-  thread_info *th = inferior_target_data (thread);
+  win32_thread_info *th = inferior_target_data (thread);
   int i;
 
   if ((thread_id == -1 || thread_id == th->tid)
@@ -386,7 +386,7 @@ child_continue (DWORD continue_status, i
 
 /* Fetch register(s) from gdbserver regcache data.  */
 static void
-do_child_fetch_inferior_registers (thread_info *th, int r)
+do_child_fetch_inferior_registers (win32_thread_info *th, int r)
 {
   char *context_offset = ((char *) &th->context) + mappings[r];
   long l;
@@ -409,7 +409,7 @@ static void
 child_fetch_inferior_registers (int r)
 {
   int regno;
-  thread_info *th = thread_rec (current_inferior_tid (), TRUE);
+  win32_thread_info *th = thread_rec (current_inferior_tid (), TRUE);
   if (r == -1 || r == 0 || r > NUM_REGS)
     child_fetch_inferior_registers (NUM_REGS);
   else
@@ -419,7 +419,7 @@ child_fetch_inferior_registers (int r)
 
 /* Get register from gdbserver regcache data.  */
 static void
-do_child_store_inferior_registers (thread_info *th, int r)
+do_child_store_inferior_registers (win32_thread_info *th, int r)
 {
   collect_register (r, ((char *) &th->context) + mappings[r]);
 }
@@ -430,7 +430,7 @@ static void
 child_store_inferior_registers (int r)
 {
   int regno;
-  thread_info *th = thread_rec (current_inferior_tid (), TRUE);
+  win32_thread_info *th = thread_rec (current_inferior_tid (), TRUE);
   if (r == -1 || r == 0 || r > NUM_REGS)
     child_store_inferior_registers (NUM_REGS);
   else
@@ -644,7 +644,7 @@ win32_resume (struct thread_resume *resu
   DWORD tid;
   enum target_signal sig;
   int step;
-  thread_info *th;
+  win32_thread_info *th;
   DWORD continue_status = DBG_CONTINUE;
 
   /* This handles the very limited set of resume packets that GDB can
@@ -722,7 +722,7 @@ win32_resume (struct thread_resume *resu
 static int
 handle_exception (struct target_waitstatus *ourstatus)
 {
-  thread_info *th;
+  win32_thread_info *th;
   DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
 
   ourstatus->kind = TARGET_WAITKIND_STOPPED;
@@ -830,8 +830,8 @@ get_child_debug_event (struct target_wai
 {
   BOOL debug_event;
   DWORD continue_status, event_code;
-  thread_info *th = NULL;
-  static thread_info dummy_thread_info;
+  win32_thread_info *th = NULL;
+  static win32_thread_info dummy_thread_info;
   int retval = 0;
 
 in:



^ permalink raw reply	[flat|nested] 19+ messages in thread

* [New WinCE support] [patch 3/4] : bfd config.
       [not found] <20070315235008.243411000@portugalmail.pt>
  2007-03-16  2:07 ` [New WinCE support] [patch 1/4] : mv win32-i386-low.c win32-low.c Pedro Alves
@ 2007-03-16  2:09 ` Pedro Alves
  2007-03-16  2:09 ` [New WinCE support] [patch 2/4] : s/thread_info/win32_thread_info/g Pedro Alves
  2007-03-16  2:10 ` [New WinCE support] [patch 4/4] The bulk of the code Pedro Alves
  3 siblings, 0 replies; 19+ messages in thread
From: Pedro Alves @ 2007-03-16  2:09 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 199 bytes --]

Not really a gdb patch, but posted here for completeness, in case
someone wants to build an arm-wince-mingw32ce-gdb.  I'll post it
at binutils once the patch I sent to config-patches is accepted.




[-- Attachment #2: wince_bfd.diff --]
[-- Type: text/plain, Size: 717 bytes --]

bfd/ChangeLog

	* config.bfd (arm*-*-mingw32ce*): Add.

---
 bfd/config.bfd |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: src/bfd/config.bfd
===================================================================
--- src.orig/bfd/config.bfd	2007-03-15 00:45:50.000000000 +0000
+++ src/bfd/config.bfd	2007-03-15 00:48:52.000000000 +0000
@@ -231,7 +231,7 @@ case "${targ}" in
     targ_underscore=no
     targ_cflags=-DARM_COFF_BUGFIX
     ;;
-  arm-wince-pe | arm-*-wince)
+  arm-wince-pe | arm-*-wince | arm*-*-mingw32ce*)
     targ_defvec=arm_wince_pe_little_vec
     targ_selvecs="arm_wince_pe_little_vec arm_wince_pe_big_vec arm_wince_pei_little_vec arm_wince_pei_big_vec"
     targ_underscore=no



^ permalink raw reply	[flat|nested] 19+ messages in thread

* [New WinCE support] [patch 4/4] The bulk of the code.
       [not found] <20070315235008.243411000@portugalmail.pt>
                   ` (2 preceding siblings ...)
  2007-03-16  2:09 ` [New WinCE support] [patch 2/4] : s/thread_info/win32_thread_info/g Pedro Alves
@ 2007-03-16  2:10 ` Pedro Alves
  2007-03-16 12:52   ` Eli Zaretskii
  3 siblings, 1 reply; 19+ messages in thread
From: Pedro Alves @ 2007-03-16  2:10 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 2284 bytes --]

This patch is the bulk of the new WinCE support.
It contains:

      - The new WinCE support on gdb/ side.
      - The gdbserver port.

WinCE has the following (and a few more) twists:
          - No errno/perror/strerror - The runtime only knows about
            GetLastError/SetLastError.
          - No signals support.
          - The initial breakpoint (the automatically inserted
            at the entry point breakpoint) must be inserted manually.
          - All programs link to coredll.dll instead of kernel32.dll.
          - CreateProcess has the same signature as the 9x/NT Windows,
            but a bunch of parameters are unsupported, and the
            image name (first param) must never be null.

There was a little bug in win32-low.c
(original win32-i386-low.c).  There was a call to
strerror (GetLastError ()), but strerror should take an errno
value, not a winerror, as the error codes are not compatible.
That was fixed by using a new strwinerror function, that is
used also as a replacement for strerror on WinCE.

The patch moves the gdbserver i386 specifics into a new
win32-i386-low.c, and the new arm stuff into
win32-arm-low.c.  The changes were modelled on the linux
support.  It was done this way to minimize the #ifdefery.

The arm/i386 differences are mostly:
     - the gdb/'win32 Context' register mappings
     - I need to store the ARM WinCE breakpoint opcode somewhere - it
       is used to insert the initial breakpoint.
     - The i386 debug registers handling (although watchpoint support isn't
       really implemented in win32-i386-low.c currently; gdb/i386-nat.c
       would have to be copied/used from gdbserver).

Note that i386/arm is orthogonal to 9x/NT/CE.  WinCE can also be i386.

I stashed the i386 debug registers copying into a
load/store interface, mainly because I needed to get them out
of the generic win32-low.c.  I'm open to better suggestions.
Note that although the debug registers handling code was copied from
gdb/win32-nat.c, watchpoints are not supported, making the
debug registers copying unneeded; they could be disabled until
proper watchpoint support is implemented.

With this patch, the old config/arm/tm-wince.h, wince.c,
wince-stub.h and wince-stub.c file can finally go away.

Cheers,
Pedro Alves






[-- Attachment #2: wince_gdbserver.diff --]
[-- Type: text/plain, Size: 54261 bytes --]

ChangeLog

	* arm-wince-tdep.c: New.
	* config/arm/wince.mt (DEPRECATED_TM_FILE): Use tm-arm.h.
	(MT_CFLAGS): Delete.
	(TM_CLIBS): Delete.
	(TDEPFILES): Add arm-wince-tdep.o, corelow.o, solib.o,
	solib-legacy.o, solib-svr4.o, and remove wince.o.
	* configure.tgt (arm*-*-mingw32ce*): Add.
	* signals/signals.c [HAVE_SIGNAL_H]: Check.
	(do_target_signal_to_host): Silence 'not used' warning.
	* config/arm/tm-wince.h: Remove.
	* wince.c: Remove.
	* wince-stub.h: Remove.
	* wince-stub.c: Remove.

doc/ChangeLog

	* gdb.texinfo (WinCE): Delete subsection.

gdbserver/ChangeLog

	* gdbserver/configure.ac: Add errno checking.
	(AC_CHECK_HEADERS): Add errno.h, fcntl.h, signal.h,
	sys/file.h, malloc.h and windows.h.
	(AC_CHECK_DECLS): Add perror.
	(srv_mingwce): Handle.
	* gdbserver/configure.srv (i[34567]86-*-cygwin*): Add
	win32-i386-low.o to srv_tgtobj.
	(i[34567]86-*-mingw*): Likewise.
	(arm*-*-mingw32ce*): Add case.
	* gdbreplay.c [HAVE_SYS_FILE_H, HAVE_SIGNAL_H,
	HAVE_FCNTL_H, HAVE_ERRNO_H, HAVE_MALLOC_H]: Check.
	(strwinerror): New function.
	(perror_with_name): Call strwinerr on Windows CE.
	(remote_open): Remove extra close call.
	* mem-break.c (delete_breakpoint_at): New function.
	* mem-break.h (delete_breakpoint_at): Declare.
	* remote-utils.c [HAVE_SYS_FILE_H, HAVE_SIGNAL_H,
	HAVE_FCNTL_H, HAVE_UNISTD_H, HAVE_ERRNO_H]: Check.
	[USE_WIN32API] (read, write): Add char* casts.
	* server.c [HAVE_UNISTD_H, HAVE_SIGNAL_H]: Check.
	* server.h [HAVE_ERRNO_H]: Check.
	(perror): Declare if not declared.
	(strwinerror): Declare.
	* utils.c: Add stdlib.h, errno.h, malloc.h and
	windows.h includes.
	(perror_with_name): Remove errno declaration.
	Call strwinerror on Windows CE.
	(strwinerror): New function.
	* wincecompat.c: New.
	* win32-low.h: New.
	* win32-arm-low.c: New.
	* win32-i386-low.c: New.
	(win32-low.c): Include mem-break.h and win32-low.h, and winnt.h.
	(OUTMSG2): Make it safe.
	(_T): Define.
	(NUM_REGS): Get it from the low target.
	(CONTEXT_EXTENDED_REGISTERS, CONTEXT_FLOATING_POINT,
	CONTEXT_DEBUG_REGISTERS): Add fallbacks to 0.
	(thread_rec): Let low target handle debug registers.
	(child_add_thread): Likewise.
	(child_init_thread_list): Likewise.
	(continue_one_thread): Likewise.
	(regptr): New.
	(do_child_fetch_inferior_registers): Move to ...
	* win32-i386-low.c: ... here, and rename to ...
	(do_fetch_inferior_registers): ... this.
	* win32-low.c (child_fetch_inferior_registers): 
	Go through the low target.
	(do_child_store_inferior_registers): Use regptr.
	(win32_create_inferior): Handle Windows CE.
	Use strwinerror instead of strerror on Windows error
	codes.  Add program to the error output.
	Don't close the main thread handle on Windows CE.
	(win32_attach): Use coredll.dll on Windows CE.
	(win32_kill): Close current process and current
	thread handles.
	(win32_detach): Use coredll.dll on Windows CE.
	(win32_resume): Let low target handle debug registers, and
	step request.
	(handle_exception): Add/Remove initial breakpoint.  Avoid
	non-existant WSTOPSIG on Windows CE.
	(win32_read_inferior_memory): Cast to remove warning.
	(win32_arch_string): Go through the low target.
	(initialize_low): Call set_breakpoint_data with the low
	target's breakpoint.
	* win32-low.c (dr, FLAG_TRACE_BIT, FCS_REGNUM,
	FOP_REGNUM, mappings): Move to ...
	* win32-i386-low.c: ... here.
	* win32-low.c (win32_thread_info): Move to ...
	* win32-low.h: ... here.
	* Makefile.in (SFILES): Add win32-low.c, win32-i386-low.c,
	win32-arm-low.c and wincecompat.c.
	(all:): Add $EXEEXT.
	(install-only:): Likewise.
	(gdbserver:): Likewise.
	(gdbreplay:): Likewise.
	* config.in: Regenerate.
	* configure: Regenerate.

---

 gdb/arm-wince-tdep.c           |   84 ++++++++++
 gdb/config/arm/wince.mt        |    9 -
 gdb/configure.tgt              |    5 
 gdb/doc/gdb.texinfo            |   40 -----
 gdb/gdbserver/Makefile.in      |   20 +-
 gdb/gdbserver/config.in        |   28 +++
 gdb/gdbserver/configure        |  203 +++++++++++++++++++++++++
 gdb/gdbserver/configure.ac     |   26 +++
 gdb/gdbserver/configure.srv    |   10 +
 gdb/gdbserver/gdbreplay.c      |   52 ++++++
 gdb/gdbserver/mem-break.c      |    8 +
 gdb/gdbserver/mem-break.h      |    5 
 gdb/gdbserver/remote-utils.c   |   14 +
 gdb/gdbserver/server.c         |    4 
 gdb/gdbserver/server.h         |    9 +
 gdb/gdbserver/utils.c          |   53 ++++++
 gdb/gdbserver/win32-arm-low.c  |   57 +++++++
 gdb/gdbserver/win32-i386-low.c |  133 ++++++++++++++++
 gdb/gdbserver/win32-low.c      |  323 ++++++++++++++++++++---------------------
 gdb/gdbserver/win32-low.h      |   76 +++++++++
 gdb/gdbserver/wincecompat.c    |   41 +++++
 gdb/signals/signals.c          |    5 
 22 files changed, 976 insertions(+), 229 deletions(-)

Index: src/gdb/arm-wince-tdep.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ src/gdb/arm-wince-tdep.c	2007-03-15 22:00:18.000000000 +0000
@@ -0,0 +1,84 @@
+/* Target-dependent code for Windows CE running on ARM processors,
+   for GDB.
+
+   Copyright (C) 2007 Free Software Foundation, Inc.
+
+   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., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+#include "defs.h"
+#include "osabi.h"
+#include "solib-svr4.h"
+#include "target.h"
+
+#include "gdb_string.h"
+
+#include "arm-tdep.h"
+
+static const char arm_wince_le_breakpoint[] = { 0x10, 0x00, 0x00, 0xe6 };
+
+/* Description of the longjmp buffer.  */
+#define ARM_WINCE_JB_ELEMENT_SIZE	INT_REGISTER_SIZE
+#define ARM_WINCE_JB_PC			21
+
+static void
+arm_wince_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  tdep->arm_breakpoint = arm_wince_le_breakpoint;
+  tdep->arm_breakpoint_size = sizeof (arm_wince_le_breakpoint);
+  tdep->struct_return = pcc_struct_return;
+
+  tdep->fp_model = ARM_FLOAT_SOFT_VFP;
+
+  tdep->jb_pc = ARM_WINCE_JB_PC;
+  tdep->jb_elt_size = ARM_WINCE_JB_ELEMENT_SIZE;
+
+  /* On ARM WinCE char defaults to signed.  */
+  set_gdbarch_char_signed (gdbarch, 1);
+
+  set_solib_svr4_fetch_link_map_offsets
+    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+
+  /* Shared library handling.  */
+  set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
+}
+
+static enum gdb_osabi
+arm_wince_osabi_sniffer (bfd *abfd)
+{
+  const char *target_name = bfd_get_target (abfd);
+
+  if (strcmp (target_name, "pei-arm-wince-little") == 0)
+    return GDB_OSABI_WINCE;
+
+  return GDB_OSABI_UNKNOWN;
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+void _initialize_arm_wince_tdep (void);
+
+void
+_initialize_arm_wince_tdep (void)
+{
+  gdbarch_register_osabi_sniffer (bfd_arch_arm, bfd_target_coff_flavour,
+                                  arm_wince_osabi_sniffer);
+
+  gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_WINCE,
+                          arm_wince_init_abi);
+}
Index: src/gdb/config/arm/wince.mt
===================================================================
--- src.orig/gdb/config/arm/wince.mt	2007-03-15 02:25:20.000000000 +0000
+++ src/gdb/config/arm/wince.mt	2007-03-15 22:00:18.000000000 +0000
@@ -1,5 +1,4 @@
-# Target: Acorn RISC machine (ARM) with simulator
-TDEPFILES= arm-tdep.o wince.o
-DEPRECATED_TM_FILE= tm-wince.h
-MT_CFLAGS=-DARM -U_X86_ -U_M_IX86 -U__i386__ -U__i486__ -U__i586__ -U__i686__ -DUNICODE -D_WIN32_WCE -DWINCE_STUB='"${target_alias}-stub.exe"'
-TM_CLIBS=-lrapi
+# Target: ARM based machine running Windows CE (win32)
+DEPRECATED_TM_FILE= tm-arm.h
+TDEPFILES= arm-tdep.o arm-wince-tdep.o corelow.o \
+  solib.o solib-legacy.o solib-svr4.o
Index: src/gdb/configure.tgt
===================================================================
--- src.orig/gdb/configure.tgt	2007-03-15 02:25:20.000000000 +0000
+++ src/gdb/configure.tgt	2007-03-15 22:00:18.000000000 +0000
@@ -54,7 +54,10 @@ alpha*-*-*)		gdb_target=alpha ;;
 # mn10300 / am33 liunux
 am33_2.0*-*-linux*)	gdb_target=linux ;;
 
-arm*-wince-pe)		gdb_target=wince ;;
+arm*-wince-pe | arm*-*-mingw32ce*)
+			gdb_target=wince
+			build_gdbserver=yes
+			;;
 arm*-*-linux*)		gdb_target=linux
 			build_gdbserver=yes
 			;;
Index: src/gdb/gdbserver/configure.ac
===================================================================
--- src.orig/gdb/gdbserver/configure.ac	2007-03-15 02:25:20.000000000 +0000
+++ src/gdb/gdbserver/configure.ac	2007-03-15 22:00:18.000000000 +0000
@@ -39,10 +39,27 @@ AC_HEADER_STDC
 AC_CHECK_HEADERS(sgtty.h termio.h termios.h sys/reg.h string.h dnl
 		 proc_service.h sys/procfs.h thread_db.h linux/elf.h dnl
 		 stdlib.h unistd.h dnl
+ 		 errno.h fcntl.h signal.h sys/file.h malloc.h windows.h dnl
 		 sys/ioctl.h netinet/in.h sys/socket.h netdb.h dnl
 		 netinet/tcp.h arpa/inet.h sys/wait.h)
 
-AC_CHECK_DECLS(strerror)
+have_errno=no
+AC_MSG_CHECKING(for errno)
+AC_TRY_LINK([
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif], [static int x; x = errno;],
+  [AC_MSG_RESULT(yes - in errno.h); AC_DEFINE(HAVE_ERRNO, 1, [Define if errno is available]) have_errno=yes])
+if test $have_errno = no; then
+AC_TRY_LINK([
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif], [extern int errno; static int x; x = errno;],
+  [AC_MSG_RESULT(yes - must define); AC_DEFINE(HAVE_ERRNO, 1, [Define if errno is available]) AC_DEFINE(MUST_DEFINE_ERRNO, 1, [Checking if errno must be defined])],
+  [AC_MSG_RESULT(no)])
+fi
+
+AC_CHECK_DECLS([strerror, perror])
 
 AC_CHECK_TYPES(socklen_t, [], [],
 [#include <sys/types.h>
@@ -68,8 +85,13 @@ esac
 
 . ${srcdir}/configure.srv
 
-if test "${srv_mingw}" = "yes"; then
+if test "${srv_mingwce}" = "yes"; then
+  LIBS="$LIBS -lws2"
+elif test "${srv_mingw}" = "yes"; then
   LIBS="$LIBS -lwsock32"
+fi
+
+if test "${srv_mingw}" = "yes"; then
   AC_DEFINE(USE_WIN32API, 1,
 	    [Define if we should use the Windows API, instead of the
 	     POSIX API.  On Windows, we use the Windows API when
Index: src/gdb/gdbserver/configure.srv
===================================================================
--- src.orig/gdb/gdbserver/configure.srv	2007-03-15 22:00:16.000000000 +0000
+++ src/gdb/gdbserver/configure.srv	2007-03-15 22:00:18.000000000 +0000
@@ -44,7 +44,7 @@ case "${target}" in
 			srv_linux_thread_db=yes
 			;;
   i[34567]86-*-cygwin*)	srv_regobj=reg-i386.o
-			srv_tgtobj="win32-low.o"
+			srv_tgtobj="win32-low.o win32-i386-low.o"
 			;;
   i[34567]86-*-linux*)	srv_regobj=reg-i386-linux.o
 			srv_tgtobj="linux-low.o linux-i386-low.o i387-fp.o"
@@ -52,8 +52,14 @@ case "${target}" in
 			srv_linux_regsets=yes
 			srv_linux_thread_db=yes
 			;;
+  arm*-*-mingw32ce*)	srv_regobj=reg-arm.o
+			srv_tgtobj="win32-low.o win32-arm-low.o"
+			srv_tgtobj="${srv_tgtobj} wincecompat.o"
+			srv_mingw=yes
+			srv_mingwce=yes
+			;;
   i[34567]86-*-mingw*)	srv_regobj=reg-i386.o
-			srv_tgtobj="win32-low.o"
+			srv_tgtobj="win32-low.o win32-i386-low.o"
 			srv_mingw=yes
 			;;
   ia64-*-linux*)	srv_regobj=reg-ia64.o
Index: src/gdb/gdbserver/gdbreplay.c
===================================================================
--- src.orig/gdb/gdbserver/gdbreplay.c	2007-03-15 02:25:20.000000000 +0000
+++ src/gdb/gdbserver/gdbreplay.c	2007-03-15 22:00:18.000000000 +0000
@@ -22,12 +22,19 @@
 
 #include "config.h"
 #include <stdio.h>
+#if HAVE_SYS_FILE_H
 #include <sys/file.h>
+#endif
+#if HAVE_SIGNAL_H
 #include <signal.h>
+#endif
 #include <ctype.h>
+#if HAVE_FCNTL_H
 #include <fcntl.h>
+#endif
+#if HAVE_ERRNO_H
 #include <errno.h>
-
+#endif
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>
 #endif
@@ -49,6 +56,9 @@
 #if HAVE_NETINET_TCP_H
 #include <netinet/tcp.h>
 #endif
+#if HAVE_MALLOC_H
+#include <malloc.h>
+#endif
 
 #if USE_WIN32API
 #include <winsock.h>
@@ -63,6 +73,40 @@ typedef int socklen_t;
 
 static int remote_desc;
 
+#ifdef __MINGW32CE__
+
+/* An strerror-like function that takes a Win32 error instead
+   of an errno error in ERROR.  */
+
+static char *
+strwinerror (DWORD error)
+{
+  static char buf[1024];
+  wchar_t msgbuf[1024];
+  DWORD chars = FormatMessageW (
+		FORMAT_MESSAGE_FROM_SYSTEM,
+                NULL,
+                error,
+                0, /* Default language */
+                (LPVOID)&msgbuf,
+                0,
+                NULL);
+  if (chars != 0)
+    {
+      /* If there is an \r\n appended, zap it.  */
+      if (chars >= 2
+	  && msgbuf[chars - 2] == '\r'
+	  && msgbuf[chars - 1] == '\n')
+	msgbuf[chars - 2] = 0;
+      wcstombs (buf, msgbuf, chars + 1);
+    }
+  else
+    sprintf (buf, "unknown win32 error (%ld)", error);
+  return buf;
+}
+
+#endif /* __MINGW32CE__ */
+
 /* Print the system error message for errno, and also mention STRING
    as the file name for which the error was encountered.
    Then return to command level.  */
@@ -76,7 +120,11 @@ perror_with_name (char *string)
   const char *err;
   char *combined;
 
+#ifdef __MINGW32CE__
+  err = strwinerror (GetLastError ());
+#else
   err = strerror (errno);
+#endif
   if (err == NULL)
     err = "unknown error";
 
@@ -178,8 +226,6 @@ remote_open (char *name)
       setsockopt (remote_desc, IPPROTO_TCP, TCP_NODELAY,
 		  (char *) &tmp, sizeof (tmp));
 
-      close (tmp_desc);		/* No longer need this */
-
 #ifndef USE_WIN32API
       close (tmp_desc);		/* No longer need this */
 
Index: src/gdb/gdbserver/mem-break.c
===================================================================
--- src.orig/gdb/gdbserver/mem-break.c	2007-03-15 02:25:20.000000000 +0000
+++ src/gdb/gdbserver/mem-break.c	2007-03-15 22:00:18.000000000 +0000
@@ -113,6 +113,14 @@ find_breakpoint_at (CORE_ADDR where)
   return NULL;
 }
 
+void
+delete_breakpoint_at (CORE_ADDR addr)
+{
+  struct breakpoint *bp = find_breakpoint_at (addr);
+  if (bp != NULL)
+    delete_breakpoint (bp);
+}
+
 static void
 reinsert_breakpoint_handler (CORE_ADDR stop_pc)
 {
Index: src/gdb/gdbserver/mem-break.h
===================================================================
--- src.orig/gdb/gdbserver/mem-break.h	2007-03-15 02:25:20.000000000 +0000
+++ src/gdb/gdbserver/mem-break.h	2007-03-15 22:00:18.000000000 +0000
@@ -31,6 +31,11 @@
 void set_breakpoint_at (CORE_ADDR where,
 			void (*handler) (CORE_ADDR));
 
+/* Delete a breakpoint previously inserted at ADDR with
+   set_breakpoint_at.  */
+
+void delete_breakpoint_at (CORE_ADDR addr);
+
 /* Create a reinsertion breakpoint at STOP_AT for the breakpoint
    currently at STOP_PC (and temporarily remove the breakpoint at
    STOP_PC).  */
Index: src/gdb/gdbserver/remote-utils.c
===================================================================
--- src.orig/gdb/gdbserver/remote-utils.c	2007-03-15 02:25:20.000000000 +0000
+++ src/gdb/gdbserver/remote-utils.c	2007-03-15 22:00:18.000000000 +0000
@@ -26,7 +26,9 @@
 #if HAVE_SYS_IOCTL_H
 #include <sys/ioctl.h>
 #endif
+#if HAVE_SYS_FILE_H
 #include <sys/file.h>
+#endif
 #if HAVE_NETINET_IN_H
 #include <netinet/in.h>
 #endif
@@ -42,15 +44,23 @@
 #if HAVE_SYS_IOCTL_H
 #include <sys/ioctl.h>
 #endif
+#if HAVE_SIGNAL_H
 #include <signal.h>
+#endif
+#if HAVE_FCNTL_H
 #include <fcntl.h>
+#endif
 #include <sys/time.h>
+#if HAVE_UNISTD_H
 #include <unistd.h>
+#endif
 #if HAVE_ARPA_INET_H
 #include <arpa/inet.h>
 #endif
 #include <sys/stat.h>
+#if HAVE_ERRNO_H
 #include <errno.h>
+#endif
 
 #if USE_WIN32API
 #include <winsock.h>
@@ -85,8 +95,8 @@ extern int using_threads;
 extern int debug_threads;
 
 #ifdef USE_WIN32API
-# define read(fd, buf, len) recv (fd, buf, len, 0)
-# define write(fd, buf, len) send (fd, buf, len, 0)
+# define read(fd, buf, len) recv (fd, (char *) buf, len, 0)
+# define write(fd, buf, len) send (fd, (char *) buf, len, 0)
 #endif
 
 /* Open a connection to a remote debugger.
Index: src/gdb/gdbserver/server.c
===================================================================
--- src.orig/gdb/gdbserver/server.c	2007-03-15 02:25:20.000000000 +0000
+++ src/gdb/gdbserver/server.c	2007-03-15 22:00:18.000000000 +0000
@@ -21,8 +21,12 @@
 
 #include "server.h"
 
+#if HAVE_UNISTD_H
 #include <unistd.h>
+#endif
+#if HAVE_SIGNAL_H
 #include <signal.h>
+#endif
 #if HAVE_SYS_WAIT_H
 #include <sys/wait.h>
 #endif
Index: src/gdb/gdbserver/server.h
===================================================================
--- src.orig/gdb/gdbserver/server.h	2007-03-15 02:25:20.000000000 +0000
+++ src/gdb/gdbserver/server.h	2007-03-15 22:00:18.000000000 +0000
@@ -27,7 +27,9 @@
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
+#ifdef HAVE_ERRNO_H
 #include <errno.h>
+#endif
 #include <setjmp.h>
 
 #ifdef HAVE_STRING_H
@@ -40,6 +42,12 @@ extern char *strerror (int);	/* X3.159-1
 #endif
 #endif
 
+#if !HAVE_DECL_PERROR
+#ifndef perror
+extern void perror (const char *);
+#endif
+#endif
+
 #ifndef ATTR_NORETURN
 #if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7))
 #define ATTR_NORETURN __attribute__ ((noreturn))
@@ -186,6 +194,7 @@ void perror_with_name (char *string);
 void error (const char *string,...) ATTR_NORETURN ATTR_FORMAT (printf, 1, 2);
 void fatal (const char *string,...) ATTR_NORETURN ATTR_FORMAT (printf, 1, 2);
 void warning (const char *string,...) ATTR_FORMAT (printf, 1, 2);
+char *strwinerror (unsigned long error);
 
 /* Functions from the register cache definition.  */
 
Index: src/gdb/gdbserver/utils.c
===================================================================
--- src.orig/gdb/gdbserver/utils.c	2007-03-15 02:25:20.000000000 +0000
+++ src/gdb/gdbserver/utils.c	2007-03-15 22:00:18.000000000 +0000
@@ -22,6 +22,16 @@
 #include "server.h"
 #include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#if HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+#if HAVE_WINDOWS_H
+#include <windows.h>
+#endif
 
 /* Generally useful subroutines used throughout the program.  */
 
@@ -32,13 +42,14 @@
 void
 perror_with_name (char *string)
 {
-#ifndef STDC_HEADERS
-  extern int errno;
-#endif
   const char *err;
   char *combined;
 
+#ifdef __MINGW32CE__
+  err = strwinerror (GetLastError ());
+#else
   err = strerror (errno);
+#endif
   if (err == NULL)
     err = "unknown error";
 
@@ -94,3 +105,39 @@ warning (const char *string,...)
   fprintf (stderr, "\n");
   va_end (args);
 }
+
+/* An strerror-like function that takes a Win32 error instead
+   of an errno error in ERROR.  */
+
+char *
+strwinerror (unsigned long error)
+{
+  static char buf[1024];
+#if HAVE_WINDOWS_H
+  TCHAR msgbuf[1024];
+  DWORD chars = FormatMessage (
+		FORMAT_MESSAGE_FROM_SYSTEM,
+                NULL,
+                error,
+                0, /* Default language */
+                (LPVOID)&msgbuf,
+                0,
+                NULL);
+  if (chars != 0)
+    {
+      /* If there is an \r\n appended, zap it.  */
+      if (chars >= 2
+	  && msgbuf[chars - 2] == '\r'
+	  && msgbuf[chars - 1] == '\n')
+	msgbuf[chars - 2] = 0;
+#ifdef UNICODE
+      wcstombs (buf, msgbuf, chars + 1);
+#else
+      strncpy (buf, msgbuf, chars + 1);
+#endif
+    }
+  else
+#endif /* HAVE_WINDOWS_H */
+    sprintf (buf, "unknown win32 error (%ld)", error);
+  return buf;
+}
Index: src/gdb/gdbserver/win32-low.c
===================================================================
--- src.orig/gdb/gdbserver/win32-low.c	2007-03-15 22:00:16.000000000 +0000
+++ src/gdb/gdbserver/win32-low.c	2007-03-15 22:00:18.000000000 +0000
@@ -23,8 +23,11 @@
 #include "server.h"
 #include "regcache.h"
 #include "gdb/signals.h"
+#include "mem-break.h"
+#include "win32-low.h"
 
 #include <windows.h>
+#include <winnt.h>
 #include <imagehlp.h>
 #include <psapi.h>
 #include <sys/param.h>
@@ -41,7 +44,11 @@
 #if LOG
 #define OUTMSG2(X) do { printf X; fflush (stdout); } while (0)
 #else
-#define OUTMSG2(X)
+#define OUTMSG2(X) do ; while (0)
+#endif
+
+#ifndef _T
+#define _T(x) TEXT (x)
 #endif
 
 int using_threads = 1;
@@ -56,25 +63,28 @@ static DEBUG_EVENT current_event;
 
 static int debug_registers_changed = 0;
 static int debug_registers_used = 0;
-static unsigned dr[8];
+
+#define NUM_REGS (the_low_target.num_regs)
 
 typedef BOOL winapi_DebugActiveProcessStop (DWORD dwProcessId);
 typedef BOOL winapi_DebugSetProcessKillOnExit (BOOL KillOnExit);
 
-#define FLAG_TRACE_BIT 0x100
+#ifndef CONTEXT_EXTENDED_REGISTERS
+#define CONTEXT_EXTENDED_REGISTERS 0
+#endif
+
+#ifndef CONTEXT_FLOATING_POINT
+#define CONTEXT_FLOATING_POINT 0
+#endif
+
+#ifndef CONTEXT_DEBUG_REGISTERS
+#define CONTEXT_DEBUG_REGISTERS 0
+#endif
+
 #define CONTEXT_DEBUGGER (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
 #define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS	\
   | CONTEXT_EXTENDED_REGISTERS
 
-/* Thread information structure used to track extra information about
-   each thread.  */
-typedef struct win32_thread_info
-{
-  DWORD tid;
-  HANDLE h;
-  int suspend_count;
-  CONTEXT context;
-} win32_thread_info;
 static DWORD main_thread_id = 0;
 
 /* Get the thread ID from the current selected inferior (the current
@@ -113,12 +123,8 @@ thread_rec (DWORD id, int get_context)
       if (id == current_event.dwThreadId)
 	{
 	  /* Copy dr values from that thread.  */
-	  dr[0] = th->context.Dr0;
-	  dr[1] = th->context.Dr1;
-	  dr[2] = th->context.Dr2;
-	  dr[3] = th->context.Dr3;
-	  dr[6] = th->context.Dr6;
-	  dr[7] = th->context.Dr7;
+	  if (the_low_target.store_debug_registers != NULL)
+	    (*the_low_target.store_debug_registers) (th);
 	}
     }
 
@@ -145,20 +151,16 @@ child_add_thread (DWORD tid, HANDLE h)
 			      new_register_cache ());
 
   /* Set the debug registers for the new thread if they are used.  */
-  if (debug_registers_used)
+  if (debug_registers_used
+      && the_low_target.load_debug_registers != NULL)
     {
       /* Only change the value of the debug registers.  */
       th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
 
       GetThreadContext (th->h, &th->context);
 
-      th->context.Dr0 = dr[0];
-      th->context.Dr1 = dr[1];
-      th->context.Dr2 = dr[2];
-      th->context.Dr3 = dr[3];
-      /* th->context.Dr6 = dr[6];
-         FIXME: should we set dr6 also ?? */
-      th->context.Dr7 = dr[7];
+      (*the_low_target.load_debug_registers) (th);
+
       SetThreadContext (th->h, &th->context);
       th->context.ContextFlags = 0;
     }
@@ -257,60 +259,26 @@ struct target_waitstatus
   value;
 };
 
-#define NUM_REGS 41
-#define FCS_REGNUM 27
-#define FOP_REGNUM 31
-
-#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
-static const int mappings[] = {
-  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]),
-  context_offset (FloatSave.ControlWord),
-  context_offset (FloatSave.StatusWord),
-  context_offset (FloatSave.TagWord),
-  context_offset (FloatSave.ErrorSelector),
-  context_offset (FloatSave.ErrorOffset),
-  context_offset (FloatSave.DataSelector),
-  context_offset (FloatSave.DataOffset),
-  context_offset (FloatSave.ErrorSelector),
-  /* XMM0-7 */
-  context_offset (ExtendedRegisters[10 * 16]),
-  context_offset (ExtendedRegisters[11 * 16]),
-  context_offset (ExtendedRegisters[12 * 16]),
-  context_offset (ExtendedRegisters[13 * 16]),
-  context_offset (ExtendedRegisters[14 * 16]),
-  context_offset (ExtendedRegisters[15 * 16]),
-  context_offset (ExtendedRegisters[16 * 16]),
-  context_offset (ExtendedRegisters[17 * 16]),
-  /* MXCSR */
-  context_offset (ExtendedRegisters[24])
-};
+/* Return a pointer into a CONTEXT field indexed by gdb register number.
+   Return a pointer to an dummy register holding zero if there is no
+   corresponding CONTEXT field for the given register number.  */
+char *
+regptr (CONTEXT* c, int r)
+{
+  if (the_low_target.regmap[r] < 0)
+  {
+    static ULONG zero;
+    /* Always force value to zero, in case the user tried to write
+       to this register before.  */
+    zero = 0;
+    return (char *) &zero;
+  }
+  else
+    return (char *) c + the_low_target.regmap[r];
+}
 
-#undef context_offset
 
-/* Clear out any old thread list and reintialize it to a pristine
+/* Clear out any old thread list and reinitialize it to a pristine
    state. */
 static void
 child_init_thread_list (void)
@@ -321,17 +289,17 @@ child_init_thread_list (void)
 static void
 do_initial_child_stuff (DWORD pid)
 {
-  int i;
-
   last_sig = TARGET_SIGNAL_0;
 
   debug_registers_changed = 0;
   debug_registers_used = 0;
-  for (i = 0; i < sizeof (dr) / sizeof (dr[0]); i++)
-    dr[i] = 0;
+
   memset (&current_event, 0, sizeof (current_event));
 
   child_init_thread_list ();
+
+  if (the_low_target.initial_stuff != NULL)
+    (*the_low_target.initial_stuff) ();
 }
 
 /* Resume all artificially suspended threads if we are continuing
@@ -354,13 +322,10 @@ continue_one_thread (struct inferior_lis
 	{
 	  /* Only change the value of the debug registers.  */
 	  th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
-	  th->context.Dr0 = dr[0];
-	  th->context.Dr1 = dr[1];
-	  th->context.Dr2 = dr[2];
-	  th->context.Dr3 = dr[3];
-	  /* th->context.Dr6 = dr[6];
-	     FIXME: should we set dr6 also ?? */
-	  th->context.Dr7 = dr[7];
+
+	  if (the_low_target.load_debug_registers != NULL)
+	    the_low_target.load_debug_registers (th);
+
 	  SetThreadContext (th->h, &th->context);
 	  th->context.ContextFlags = 0;
 	}
@@ -384,26 +349,6 @@ child_continue (DWORD continue_status, i
   return res;
 }
 
-/* Fetch register(s) from gdbserver regcache data.  */
-static void
-do_child_fetch_inferior_registers (win32_thread_info *th, int r)
-{
-  char *context_offset = ((char *) &th->context) + mappings[r];
-  long l;
-  if (r == FCS_REGNUM)
-    {
-      l = *((long *) context_offset) & 0xffff;
-      supply_register (r, (char *) &l);
-    }
-  else if (r == FOP_REGNUM)
-    {
-      l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
-      supply_register (r, (char *) &l);
-    }
-  else
-    supply_register (r, context_offset);
-}
-
 /* Fetch register(s) from the current thread context.  */
 static void
 child_fetch_inferior_registers (int r)
@@ -414,14 +359,14 @@ child_fetch_inferior_registers (int r)
     child_fetch_inferior_registers (NUM_REGS);
   else
     for (regno = 0; regno < r; regno++)
-      do_child_fetch_inferior_registers (th, regno);
+      (*the_low_target.fetch_inferior_registers) (th, regno);
 }
 
 /* Get register from gdbserver regcache data.  */
 static void
 do_child_store_inferior_registers (win32_thread_info *th, int r)
 {
-  collect_register (r, ((char *) &th->context) + mappings[r]);
+  collect_register (r, regptr (&th->context, r));
 }
 
 /* Store a new register value into the current thread context.  We don't
@@ -451,21 +396,22 @@ win32_create_inferior (char *program, ch
   char real_path[MAXPATHLEN];
   char *orig_path, *new_path, *path_ptr;
 #endif
-  char *winenv = NULL;
-  STARTUPINFO si;
-  PROCESS_INFORMATION pi;
   BOOL ret;
   DWORD flags;
   char *args;
   int argslen;
   int argc;
+  PROCESS_INFORMATION pi;
+#ifndef __MINGW32CE__
+  STARTUPINFO si = { sizeof (STARTUPINFO) };
+  char *winenv = NULL;
+#else
+  wchar_t *wargs, *wprogram;
+#endif
 
   if (!program)
     error ("No executable specified, specify executable to debug.\n");
 
-  memset (&si, 0, sizeof (si));
-  si.cb = sizeof (si);
-
   flags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS;
 
 #ifndef USE_WIN32API
@@ -483,11 +429,11 @@ win32_create_inferior (char *program, ch
   program = real_path;
 #endif
 
-  argslen = strlen (program) + 1;
+  argslen = 1;
   for (argc = 1; program_args[argc]; argc++)
     argslen += strlen (program_args[argc]) + 1;
   args = alloca (argslen);
-  strcpy (args, program);
+  args[0] = '\0';
   for (argc = 1; program_args[argc]; argc++)
     {
       /* FIXME: Can we do better about quoting?  How does Cygwin
@@ -495,17 +441,40 @@ win32_create_inferior (char *program, ch
       strcat (args, " ");
       strcat (args, program_args[argc]);
     }
-  OUTMSG2 (("Command line is %s\n", args));
+  OUTMSG2 (("Command line is \"%s\"\n", args));
 
+#ifdef CREATE_NEW_PROCESS_GROUP
   flags |= CREATE_NEW_PROCESS_GROUP;
+#endif
 
-  ret = CreateProcess (0, args,	/* command line */
-		       NULL,	/* Security */
+#ifdef __MINGW32CE__
+  to_back_slashes (program);
+  wargs = alloca (argslen * sizeof (wchar_t));
+  mbstowcs (wargs, args, argslen);
+  wprogram = alloca ((strlen (program) + 1) * sizeof (wchar_t));
+  mbstowcs (wprogram, program, strlen (program) + 1);
+  ret = CreateProcessW (wprogram, /* image name */
+                        wargs,    /* command line */
+                        NULL,     /* security, not supported */
+                        NULL,     /* thread, not supported */
+                        FALSE,    /* inherit handles, not supported */
+                        flags,    /* start flags */
+                        NULL,     /* environment, not supported */
+                        NULL,     /* current directory, not supported */
+                        NULL,     /* start info, not supported */
+                        &pi);     /* proc info */
+#else
+  ret = CreateProcess (program, /* image name */
+		       args,	/* command line */
+		       NULL,	/* security */
 		       NULL,	/* thread */
 		       TRUE,	/* inherit handles */
 		       flags,	/* start flags */
-		       winenv, NULL,	/* current directory */
-		       &si, &pi);
+		       winenv,  /* environment */
+		       NULL,	/* current directory */
+		       &si,     /* start info */
+		       &pi);    /* proc info */
+#endif
 
 #ifndef USE_WIN32API
   if (orig_path)
@@ -514,15 +483,21 @@ win32_create_inferior (char *program, ch
 
   if (!ret)
     {
-      error ("Error creating process %s, (error %d): %s\n", args,
-	     (int) GetLastError (), strerror (GetLastError ()));
+      error ("Error creating process \"%s%s\", (error %d): %s\n",
+	     program, args,
+	     (int) GetLastError (), strwinerror (GetLastError ()));
     }
   else
     {
       OUTMSG2 (("Process created: %s\n", (char *) args));
     }
 
+#ifndef _WIN32_WCE
+  /* On Windows CE this handle can't be closed.  The OS reuses
+     it in the debug events, while the 9x/NT versions of Windows
+     probably use a DuplicateHandle'd one.  */
   CloseHandle (pi.hThread);
+#endif
 
   current_process_handle = pi.hProcess;
   current_process_id = pi.dwProcessId;
@@ -539,16 +514,18 @@ static int
 win32_attach (unsigned long pid)
 {
   int res = 0;
-  HMODULE kernel32 = LoadLibrary ("KERNEL32.DLL");
   winapi_DebugActiveProcessStop *DebugActiveProcessStop = NULL;
-  winapi_DebugSetProcessKillOnExit *DebugSetProcessKillOnExit = NULL;
 
-  DebugActiveProcessStop =
-    (winapi_DebugActiveProcessStop *) GetProcAddress (kernel32,
-						      "DebugActiveProcessStop");
-  DebugSetProcessKillOnExit =
-    (winapi_DebugSetProcessKillOnExit *) GetProcAddress (kernel32,
-							 "DebugSetProcessKillOnExit");
+  winapi_DebugSetProcessKillOnExit *DebugSetProcessKillOnExit = NULL;
+#ifdef _WIN32_WCE
+  HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
+#else
+  HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
+#endif
+  DebugActiveProcessStop = (winapi_DebugActiveProcessStop *)
+    GetProcAddress (dll, _T("DebugActiveProcessStop"));
+  DebugSetProcessKillOnExit = (winapi_DebugSetProcessKillOnExit *)
+    GetProcAddress (dll, _T("DebugSetProcessKillOnExit"));
 
   res = DebugActiveProcess (pid) ? 1 : 0;
 
@@ -571,8 +548,6 @@ win32_attach (unsigned long pid)
   if (res)
     do_initial_child_stuff (pid);
 
-  FreeLibrary (kernel32);
-
   return res;
 }
 
@@ -580,6 +555,8 @@ win32_attach (unsigned long pid)
 static void
 win32_kill (void)
 {
+  win32_thread_info *current_thread;
+
   if (current_process_handle == NULL)
     return;
 
@@ -593,22 +570,32 @@ win32_kill (void)
       if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
 	break;
     }
+
+  CloseHandle (current_process_handle);
+
+  current_thread = inferior_target_data (current_inferior);
+  if (current_thread && current_thread->h)
+    {
+      /* This may fail in an attached process, so don't check.  */
+      (void) CloseHandle (current_thread->h);
+    }
 }
 
 /* Detach from all inferiors.  */
 static void
 win32_detach (void)
 {
-  HMODULE kernel32 = LoadLibrary ("KERNEL32.DLL");
   winapi_DebugActiveProcessStop *DebugActiveProcessStop = NULL;
   winapi_DebugSetProcessKillOnExit *DebugSetProcessKillOnExit = NULL;
-
-  DebugActiveProcessStop =
-    (winapi_DebugActiveProcessStop *) GetProcAddress (kernel32,
-						      "DebugActiveProcessStop");
-  DebugSetProcessKillOnExit =
-    (winapi_DebugSetProcessKillOnExit *) GetProcAddress (kernel32,
-							 "DebugSetProcessKillOnExit");
+#ifdef _WIN32_WCE
+  HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
+#else
+  HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
+#endif
+  DebugActiveProcessStop = (winapi_DebugActiveProcessStop *)
+    GetProcAddress (dll, _T("DebugActiveProcessStop"));
+  DebugSetProcessKillOnExit = (winapi_DebugSetProcessKillOnExit *)
+    GetProcAddress (dll, _T("DebugSetProcessKillOnExit"));
 
   if (DebugSetProcessKillOnExit != NULL)
     DebugSetProcessKillOnExit (FALSE);
@@ -617,8 +604,6 @@ win32_detach (void)
     DebugActiveProcessStop (current_process_id);
   else
     win32_kill ();
-
-  FreeLibrary (kernel32);
 }
 
 /* Return 1 iff the thread with thread ID TID is alive.  */
@@ -691,23 +676,21 @@ win32_resume (struct thread_resume *resu
       if (th->context.ContextFlags)
 	{
 	  if (debug_registers_changed)
-	    {
-	      th->context.Dr0 = dr[0];
-	      th->context.Dr1 = dr[1];
-	      th->context.Dr2 = dr[2];
-	      th->context.Dr3 = dr[3];
-	      /* th->context.Dr6 = dr[6];
-	         FIXME: should we set dr6 also ?? */
-	      th->context.Dr7 = dr[7];
-	    }
+	    if (the_low_target.load_debug_registers != NULL)
+	      (*the_low_target.load_debug_registers) (th);
 
 	  /* Move register values from the inferior into the thread
 	     context structure.  */
 	  regcache_invalidate ();
 
 	  if (step)
-	    th->context.EFlags |= FLAG_TRACE_BIT;
-
+	    {
+	      if (the_low_target.single_step != NULL)
+		(*the_low_target.single_step) (th);
+	      else
+		error ("Software single stepping is not supported "
+		       "in this configuration.\n");
+	    }
 	  SetThreadContext (th->h, &th->context);
 	  th->context.ContextFlags = 0;
 	}
@@ -783,6 +766,11 @@ handle_exception (struct target_waitstat
     case EXCEPTION_BREAKPOINT:
       OUTMSG2 (("EXCEPTION_BREAKPOINT"));
       ourstatus->value.sig = TARGET_SIGNAL_TRAP;
+#ifdef _WIN32_WCE
+      /* Remove the initial breakpoint.  */
+      check_breakpoints ((CORE_ADDR) (long) current_event
+                         .u.Exception.ExceptionRecord.ExceptionAddress);
+#endif
       break;
     case DBG_CONTROL_C:
       OUTMSG2 (("DBG_CONTROL_C"));
@@ -892,6 +880,14 @@ in:
 			  current_event.u.CreateProcessInfo.hThread);
 
       retval = ourstatus->value.related_pid = current_event.dwThreadId;
+#ifdef _WIN32_WCE
+      /* Windows CE doesn't set the initial breakpoint automatically
+	 like the desktop versions of Windows do.  We add it explicitly
+	 here.  It will be removed as soon as it is hit.  */
+      set_breakpoint_at ((CORE_ADDR) (long) current_event.u
+			 .CreateProcessInfo.lpStartAddress,
+			 delete_breakpoint_at);
+#endif
       break;
 
     case EXIT_PROCESS_DEBUG_EVENT:
@@ -994,8 +990,13 @@ win32_wait (char *status)
 	}
       else if (our_status.kind == TARGET_WAITKIND_STOPPED)
 	{
+#ifndef __MINGW32CE__
 	  OUTMSG2 (("Child Stopped with signal = %x \n",
 		    WSTOPSIG (our_status.value.sig)));
+#else
+	  OUTMSG2 (("Child Stopped with signal = %x \n",
+		    our_status.value.sig));
+#endif
 
 	  *status = 'T';
 
@@ -1039,7 +1040,7 @@ win32_store_inferior_registers (int regn
 static int
 win32_read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
 {
-  return child_xfer_memory (memaddr, myaddr, len, 0, 0) != len;
+  return child_xfer_memory (memaddr, (char *) myaddr, len, 0, 0) != len;
 }
 
 /* Write memory to the inferior process.  This should generally be
@@ -1056,7 +1057,7 @@ win32_write_inferior_memory (CORE_ADDR m
 static const char *
 win32_arch_string (void)
 {
-  return "i386";
+  return the_low_target.arch_string;
 }
 
 static struct target_ops win32_target_ops = {
@@ -1088,6 +1089,8 @@ void
 initialize_low (void)
 {
   set_target_ops (&win32_target_ops);
-
+  if (the_low_target.breakpoint != NULL)
+    set_breakpoint_data (the_low_target.breakpoint,
+			 the_low_target.breakpoint_len);
   init_registers ();
 }
Index: src/gdb/signals/signals.c
===================================================================
--- src.orig/gdb/signals/signals.c	2007-03-15 02:25:20.000000000 +0000
+++ src/gdb/signals/signals.c	2007-03-15 22:00:18.000000000 +0000
@@ -28,7 +28,9 @@
 #include "gdb_string.h"
 #endif
 
+#ifdef HAVE_SIGNAL_H
 #include <signal.h>
+#endif
 
 /* Always use __SIGRTMIN if it's available.  SIGRTMIN is the lowest
    _available_ realtime signal, not the lowest supported; glibc takes
@@ -519,6 +521,9 @@ do_target_signal_to_host (enum target_si
 			  int *oursig_ok)
 {
   int retsig;
+  /* Silence the 'not used' warning, for targets that
+     do not support signals.  */
+  (void) retsig;
 
   *oursig_ok = 1;
   switch (oursig)
Index: src/gdb/gdbserver/Makefile.in
===================================================================
--- src.orig/gdb/gdbserver/Makefile.in	2007-03-15 22:00:16.000000000 +0000
+++ src/gdb/gdbserver/Makefile.in	2007-03-15 22:00:18.000000000 +0000
@@ -128,7 +128,9 @@ SFILES=	$(srcdir)/gdbreplay.c $(srcdir)/
 	$(srcdir)/linux-m68k-low.c $(srcdir)/linux-mips-low.c \
 	$(srcdir)/linux-ppc-low.c $(srcdir)/linux-ppc64-low.c \
 	$(srcdir)/linux-s390-low.c \
-	$(srcdir)/linux-sh-low.c $(srcdir)/linux-x86-64-low.c
+	$(srcdir)/linux-sh-low.c $(srcdir)/linux-x86-64-low.c \
+	$(srcdir)/win32-arm-low.c $(srcdir)/win32-i386-low.c \
+	$(srcdir)/win32-low.c $(srcdir)/wincecompat.c
 
 DEPFILES = @GDBSERVER_DEPFILES@
 
@@ -154,7 +156,7 @@ XML_BUILTIN = @srv_xmlbuiltin@
 .c.o:
 	${CC} -c ${INTERNAL_CFLAGS} $<
 
-all: gdbserver gdbreplay
+all: gdbserver$(EXEEXT) gdbreplay$(EXEEXT)
 
 # Traditionally "install" depends on "all".  But it may be useful
 # not to; for example, if the user has made some trivial change to a 
@@ -166,7 +168,7 @@ install-only: 
 	n=`echo gdbserver | sed '$(program_transform_name)'`; \
 	if [ x$$n = x ]; then n=gdbserver; else true; fi; \
 	$(SHELL) $(srcdir)/../../mkinstalldirs $(DESTDIR)$(bindir); \
-	$(INSTALL_PROGRAM) gdbserver $(DESTDIR)$(bindir)/$$n; \
+	$(INSTALL_PROGRAM) gdbserver$(EXEEXT) $(DESTDIR)$(bindir)/$$n$(EXEEXT); \
 	$(SHELL) $(srcdir)/../../mkinstalldirs $(DESTDIR)$(man1dir); \
 	$(INSTALL_DATA) $(srcdir)/gdbserver.1 $(DESTDIR)$(man1dir)/$$n.1
 
@@ -183,14 +185,14 @@ html:
 install-html:
 clean-info:
 
-gdbserver: $(OBS) ${ADD_DEPS} ${CDEPS}
-	rm -f gdbserver
-	${CC-LD} $(INTERNAL_CFLAGS) $(INTERNAL_LDFLAGS) -o gdbserver $(OBS) \
+gdbserver$(EXEEXT): $(OBS) ${ADD_DEPS} ${CDEPS}
+	rm -f gdbserver$(EXEEXT)
+	${CC-LD} $(INTERNAL_CFLAGS) $(INTERNAL_LDFLAGS) -o gdbserver$(EXEEXT) $(OBS) \
 	  $(GDBSERVER_LIBS) $(XM_CLIBS)
 
-gdbreplay: gdbreplay.o
-	rm -f gdbreplay
-	${CC-LD} $(INTERNAL_CFLAGS) $(INTERNAL_LDFLAGS) -o gdbreplay gdbreplay.o \
+gdbreplay$(EXEEXT): gdbreplay.o
+	rm -f gdbreplay$(EXEEXT)
+	${CC-LD} $(INTERNAL_CFLAGS) $(INTERNAL_LDFLAGS) -o gdbreplay$(EXEEXT) gdbreplay.o \
 	  $(XM_CLIBS)
 
 # Put the proper machine-specific files first, so M-. on a machine
Index: src/gdb/gdbserver/wincecompat.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ src/gdb/gdbserver/wincecompat.c	2007-03-15 22:00:18.000000000 +0000
@@ -0,0 +1,41 @@
+/* Compatibility routines for Windows CE.
+   Copyright (C) 2007 Free Software Foundation, Inc.
+
+   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., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+#include "server.h"
+
+#include <stdio.h>
+#include <windows.h>
+
+void
+perror (const char *s)
+{
+  if (s && *s)
+    fprintf (stderr, "%s: %s\n", s, strwinerror (GetLastError ()));
+  else
+    fprintf (stderr, "%s\n", strwinerror (GetLastError ()));
+}
+
+void
+to_back_slashes (char *path)
+{
+  for (; *path; ++path)
+    if ('/' == *path)
+      *path = '\\';
+}
Index: src/gdb/gdbserver/win32-arm-low.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ src/gdb/gdbserver/win32-arm-low.c	2007-03-15 23:49:34.000000000 +0000
@@ -0,0 +1,76 @@
+/* Copyright (C) 2007 Free Software Foundation, Inc.
+
+   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., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+#include "server.h"
+#include "win32-low.h"
+
+/* Fetch register(s) from gdbserver regcache data.  */
+static void
+do_fetch_inferior_registers (win32_thread_info *th, int r)
+{
+  char *context_offset = regptr (&th->context, r);
+  supply_register (r, context_offset);
+}
+
+#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
+static const int mappings[] = {
+  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, /* f0 */
+  -1, /* f1 */
+  -1, /* f2 */
+  -1, /* f3 */
+  -1, /* f4 */
+  -1, /* f5 */
+  -1, /* f6 */
+  -1, /* f7 */
+  -1, /* fps */
+  context_offset (Psr),
+};
+#undef context_offset
+
+static const unsigned char arm_wince_le_breakpoint[] =
+  { 0x10, 0x00, 0x00, 0xe6 };
+
+struct win32_target_ops the_low_target = {
+  mappings,
+  sizeof (mappings) / sizeof (mappings[0]),
+  NULL, /* initial_stuff */
+  NULL, /* store_debug_registers */
+  NULL, /* load_debug_registers */
+  do_fetch_inferior_registers,
+  NULL, /* single_step */
+  arm_wince_le_breakpoint,
+  sizeof (arm_wince_le_breakpoint) / sizeof (arm_wince_le_breakpoint[0]),
+  "arm" /* arch_string */
+};
Index: src/gdb/gdbserver/win32-i386-low.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ src/gdb/gdbserver/win32-i386-low.c	2007-03-15 23:49:42.000000000 +0000
@@ -0,0 +1,152 @@
+/* Copyright (C) 2007 Free Software Foundation, Inc.
+
+   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., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+#include "server.h"
+#include "win32-low.h"
+
+#define FCS_REGNUM 27
+#define FOP_REGNUM 31
+
+#define FLAG_TRACE_BIT 0x100
+
+static unsigned dr[8];
+
+static void
+initial_stuff (void)
+{
+  memset (&dr, 0, sizeof (dr));
+}
+
+static void
+store_debug_registers (win32_thread_info *th)
+{
+  dr[0] = th->context.Dr0;
+  dr[1] = th->context.Dr1;
+  dr[2] = th->context.Dr2;
+  dr[3] = th->context.Dr3;
+  dr[6] = th->context.Dr6;
+  dr[7] = th->context.Dr7;
+}
+
+static void
+load_debug_registers (win32_thread_info *th)
+{
+  th->context.Dr0 = dr[0];
+  th->context.Dr1 = dr[1];
+  th->context.Dr2 = dr[2];
+  th->context.Dr3 = dr[3];
+  /* th->context.Dr6 = dr[6];
+     FIXME: should we set dr6 also ?? */
+  th->context.Dr7 = dr[7];
+}
+
+/* Fetch register(s) from gdbserver regcache data.  */
+static void
+do_fetch_inferior_registers (win32_thread_info *th, int r)
+{
+  char *context_offset = regptr (&th->context, r);
+
+  long l;
+  if (r == FCS_REGNUM)
+    {
+      l = *((long *) context_offset) & 0xffff;
+      supply_register (r, (char *) &l);
+    }
+  else if (r == FOP_REGNUM)
+    {
+      l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
+      supply_register (r, (char *) &l);
+    }
+  else
+    supply_register (r, context_offset);
+}
+
+static void
+single_step (win32_thread_info *th)
+{
+  th->context.EFlags |= FLAG_TRACE_BIT;
+}
+
+/* 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.  In this case regptr will return
+   a pointer into a dummy register.  */
+#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
+static const int mappings[] = {
+  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]),
+  context_offset (FloatSave.ControlWord),
+  context_offset (FloatSave.StatusWord),
+  context_offset (FloatSave.TagWord),
+  context_offset (FloatSave.ErrorSelector),
+  context_offset (FloatSave.ErrorOffset),
+  context_offset (FloatSave.DataSelector),
+  context_offset (FloatSave.DataOffset),
+  context_offset (FloatSave.ErrorSelector),
+  /* XMM0-7 */
+  context_offset (ExtendedRegisters[10 * 16]),
+  context_offset (ExtendedRegisters[11 * 16]),
+  context_offset (ExtendedRegisters[12 * 16]),
+  context_offset (ExtendedRegisters[13 * 16]),
+  context_offset (ExtendedRegisters[14 * 16]),
+  context_offset (ExtendedRegisters[15 * 16]),
+  context_offset (ExtendedRegisters[16 * 16]),
+  context_offset (ExtendedRegisters[17 * 16]),
+  /* MXCSR */
+  context_offset (ExtendedRegisters[24])
+};
+#undef context_offset
+
+struct win32_target_ops the_low_target = {
+  mappings,
+  sizeof (mappings) / sizeof (mappings[0]),
+  initial_stuff,
+  store_debug_registers,
+  load_debug_registers,
+  do_fetch_inferior_registers,
+  single_step,
+  (const char*)NULL, /* breakpoint */
+  0, /* breakpoint_len */
+  "i386" /* arch_string */
+};
Index: src/gdb/gdbserver/win32-low.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ src/gdb/gdbserver/win32-low.h	2007-03-15 22:00:18.000000000 +0000
@@ -0,0 +1,76 @@
+/* Internal interfaces for the Win32 specific target code for gdbserver.
+   Copyright (C) 2007 Free Software Foundation, Inc.
+
+   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., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+#include <windows.h>
+
+/* Thread information structure used to track extra information about
+   each thread.  */
+typedef struct win32_thread_info
+{
+  DWORD tid;
+  HANDLE h;
+  int suspend_count;
+  CONTEXT context;
+} win32_thread_info;
+
+struct win32_target_ops
+{
+  /* 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.  In this case regptr will return
+     a pointer into a dummy register.  */
+  const int *regmap;
+
+  /* The number of elements of regmap.  */
+  int num_regs;
+
+  void (*initial_stuff) (void);
+
+  void (*store_debug_registers) (win32_thread_info *);
+  void (*load_debug_registers) (win32_thread_info *);
+
+  /* Fetch register(s) from gdbserver regcache data.  */
+  void (*fetch_inferior_registers) (win32_thread_info *th, int r);
+
+  void (*single_step) (win32_thread_info *th);
+
+  const unsigned char *breakpoint;
+  int breakpoint_len;
+
+  /* What string to report to GDB when it asks for the architecture,
+     or NULL not to answer.  */
+  const char *arch_string;
+};
+
+extern struct win32_target_ops the_low_target;
+
+/* in win32-low.c */
+
+/* Return a pointer into a CONTEXT field indexed by gdb register number.
+   Return a pointer to an dummy register holding zero if there is no
+   corresponding CONTEXT field for the given register number.  */
+extern char * regptr (CONTEXT* c, int r);
+
+/* in wincecompat.c */
+
+extern void to_back_slashes (char *);
Index: src/gdb/doc/gdb.texinfo
===================================================================
--- src.orig/gdb/doc/gdb.texinfo	2007-03-03 18:47:52.000000000 +0000
+++ src/gdb/doc/gdb.texinfo	2007-03-15 22:51:00.000000000 +0000
@@ -14312,7 +14312,6 @@ acceptable commands.
 * AVR::                         Atmel AVR
 * CRIS::                        CRIS
 * Super-H::                     Renesas Super-H
-* WinCE::                       Windows CE child processes
 @end menu
 
 @node ARM
@@ -15501,45 +15500,6 @@ commands:
 Show the values of all Super-H registers.
 @end table
 
-@node WinCE
-@subsection Windows CE
-@cindex Windows CE
-
-The following commands are available for Windows CE:
-
-@table @code
-@item set remotedirectory @var{dir}
-@kindex set remotedirectory
-Tell @value{GDBN} to upload files from the named directory @var{dir}.
-The default is @file{/gdb}, i.e.@: the root directory on the current
-drive.
-
-@item show remotedirectory
-@kindex show remotedirectory
-Show the current value of the upload directory.
-
-@item set remoteupload @var{method}
-@kindex set remoteupload
-Set the method used to upload files to remote device.  Valid values
-for @var{method} are @samp{always}, @samp{newer}, and @samp{never}.
-The default is @samp{newer}.
-
-@item show remoteupload
-@kindex show remoteupload
-Show the current setting of the upload method.
-
-@item set remoteaddhost
-@kindex set remoteaddhost
-Tell @value{GDBN} whether to add this host to the remote stub's
-arguments when you debug over a network.
-
-@item show remoteaddhost
-@kindex show remoteaddhost
-Show whether to add this host to remote stub's arguments when
-debugging over a network.
-@end table
-
-
 @node Architectures
 @section Architectures
 





^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [New WinCE support] [patch 4/4] The bulk of the code.
  2007-03-16  2:10 ` [New WinCE support] [patch 4/4] The bulk of the code Pedro Alves
@ 2007-03-16 12:52   ` Eli Zaretskii
  2007-03-16 15:03     ` pedro alves
  0 siblings, 1 reply; 19+ messages in thread
From: Eli Zaretskii @ 2007-03-16 12:52 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

> Date: Fri, 16 Mar 2007 02:08:51 +0000
> From: Pedro Alves <pedro_alves@portugalmail.pt>
> 
> This patch is the bulk of the new WinCE support.

Thanks.

I have a few comments.

> +static char *
> +strwinerror (DWORD error)
> +{
> +  static char buf[1024];
> +  wchar_t msgbuf[1024];
> +  DWORD chars = FormatMessageW (
> +		FORMAT_MESSAGE_FROM_SYSTEM,
> +                NULL,
> +                error,
> +                0, /* Default language */
> +                (LPVOID)&msgbuf,
> +                0,
> +                NULL);

Instead of using an arbitrary size 1024 (btw, you don't check whether
FormatMessageW indicated that it needed more than 1024), isn't it
better to use FORMAT_MESSAGE_ALLOCATE_BUFFER?  As a bonus, it would
avoid overwriting the static buffer on each call, which is not a nice
API, IMHO.

> +#ifdef __MINGW32CE__
> +  err = strwinerror (GetLastError ());
> +#else
>    err = strerror (errno);
> +#endif

Why not call strwinerror strerror and avoid the ifdef?

> doc/ChangeLog
> 
> 	* gdb.texinfo (WinCE): Delete subsection.

Why?  Is that subsection incorrect in some ways?


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [New WinCE support] [patch 4/4] The bulk of the code.
  2007-03-16 12:52   ` Eli Zaretskii
@ 2007-03-16 15:03     ` pedro alves
  2007-03-17 11:18       ` Eli Zaretskii
  0 siblings, 1 reply; 19+ messages in thread
From: pedro alves @ 2007-03-16 15:03 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches

Hi Eli,
thanks for taking a look.

Eli Zaretskii wrote:
> > Date: Fri, 16 Mar 2007 02:08:51 +0000
> > From: Pedro Alves <pedro_alves@portugalmail.pt>
> >
> > This patch is the bulk of the new WinCE support.
>
> Thanks.
>
> I have a few comments.
>
> > +static char *
> > +strwinerror (DWORD error)
> > +{
> > +  static char buf[1024];
> > +  wchar_t msgbuf[1024];
> > +  DWORD chars = FormatMessageW (
> > +             FORMAT_MESSAGE_FROM_SYSTEM,
> > +                NULL,
> > +                error,
> > +                0, /* Default language */
> > +                (LPVOID)&msgbuf,
> > +                0,
> > +                NULL);
>
> Instead of using an arbitrary size 1024 (btw, you don't check whether
> FormatMessageW indicated that it needed more than 1024), isn't it
> better to use FORMAT_MESSAGE_ALLOCATE_BUFFER?  As a bonus, it would
> avoid overwriting the static buffer on each call, which is not a nice
> API, IMHO.
>

I'm using the same api as strerror, which returns a pointer into a
static buffer.
If I return an allocated buffer, either the client must release it
(but that would change
the contract), or the previous allocated one must be released on every
strwinerror invocation.  Hummm, I don't know how is it that I
specified a buffer of size
0, and Windows (at least CE) still fills the buffer.  Do you feel
strongly about using
FORMAT_MESSAGE_ALLOCATE_BUFFER, or would just passing the buffer limit
(nSize) to FormatMessage be OK?

> > +#ifdef __MINGW32CE__
> > +  err = strwinerror (GetLastError ());
> > +#else
> >    err = strerror (errno);
> > +#endif

>
> Why not call strwinerror strerror and avoid the ifdef?
>

Because then I would have to:

#ifdef __MINGW32CE__
#define errno (GetLastError ())
#endif

  err = strerror (errno);

That means I still must have an #ifdef somewhere.  Since there is only
one instance
of it (the #ifdef) in gdbserver, I thought it is better to have
strwinerror explicit.  I try to
avoid doing that #define errno (...) whenever possible.  When someone later uses
errno as an lvalue, it breaks WinCE again.  Since the errno <->
GetLastError mapping
is not 100% correct, it always feels dirty.  As you can imagine, this
is a recurring
problem while doing WinCE ports - see here for some options, but none
is perfect:
http://sourceforge.net/mailarchive/forum.php?thread_id=31663083&forum_id=49151

The other place I used strwinerror is in:

  if (!ret)
    {
-      error ("Error creating process %s, (error %d): %s\n", args,
-            (int) GetLastError (), strerror (GetLastError ()));
+      error ("Error creating process \"%s%s\", (error %d): %s\n",
+            program, args,
+            (int) GetLastError (), strwinerror (GetLastError ()));
    }

On Window 9x/NT it is wrong to do:
strerror (GetLastError ())

The errno values and the windows error codes are not the same.
I was going to post a patch to fix this using FormatMessage directly, but
since I needed a strerror for WinCE, I ended up using strwinerror here too.

Would you prefer to have that? That is, rewrite this last hunk to use
FormatMessage
directly, and rename strwinerror to strerror, put it wincecompat.c, and have a:

#ifdef __MINGW32CE__
#define errno (GetLastError ())
#endif

> > doc/ChangeLog
> >
> >       * gdb.texinfo (WinCE): Delete subsection.
>
> Why?  Is that subsection incorrect in some ways?
>

It is correct for the current WinCE support, using gdb/wince.c and
gdb/wince-stub.c,
which implements a custom remote protocol.  This patch removes those
files, removing
the functionality that subsection is documenting.

Cheers,
Pedro Alves


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [New WinCE support] [patch 4/4] The bulk of the code.
  2007-03-16 15:03     ` pedro alves
@ 2007-03-17 11:18       ` Eli Zaretskii
  2007-03-17 11:35         ` Andreas Schwab
  2007-03-19  1:53         ` Pedro Alves
  0 siblings, 2 replies; 19+ messages in thread
From: Eli Zaretskii @ 2007-03-17 11:18 UTC (permalink / raw)
  To: pedro alves; +Cc: gdb-patches

> Date: Fri, 16 Mar 2007 15:03:21 +0000
> From: "pedro alves" <alves.ped@gmail.com>
> Cc: gdb-patches@sourceware.org
> 
> > Instead of using an arbitrary size 1024 (btw, you don't check whether
> > FormatMessageW indicated that it needed more than 1024), isn't it
> > better to use FORMAT_MESSAGE_ALLOCATE_BUFFER?  As a bonus, it would
> > avoid overwriting the static buffer on each call, which is not a nice
> > API, IMHO.
> 
> I'm using the same api as strerror, which returns a pointer into a
> static buffer.

In that case, I guess it's okay to use a static buffer.  But please at
least check inside the function that the buffer size was enough, by
comparing the value returned by FormatMessageW with the size of the
buffer you passed to it.

> Hummm, I don't know how is it that I specified a buffer of size 0,
> and Windows (at least CE) still fills the buffer.

I think it fills the buffer because the buffer is larger than 0.  The
return value tells you how many characters it _really_ needed to
format the message.  By comparing that value with the size of the
buffer, you can find out whether the buffer was large enough.

> > > +#ifdef __MINGW32CE__
> > > +  err = strwinerror (GetLastError ());
> > > +#else
> > >    err = strerror (errno);
> > > +#endif
> 
> > Why not call strwinerror strerror and avoid the ifdef?
> 
> Because then I would have to:
> 
> #ifdef __MINGW32CE__
> #define errno (GetLastError ())
> #endif
> 
>   err = strerror (errno);
> 
> That means I still must have an #ifdef somewhere.

But that ifdef would be in only one place, while with a different
function you need an ifdef each time you use the function.

> Since there is only one instance of it (the #ifdef) in gdbserver, I
> thought it is better to have strwinerror explicit.

There's only one instance _today_.  Tomorrow we could have more of
them.

Btw, I see in your patch two instances of strwinerror and two places
that call it: one in gdbreplay.c, the other in utils.c.  Why did you
need two almost identical functions?

> When someone later uses errno as an lvalue, it breaks WinCE again.

I think such usage of errno is a bad idea anyway, since on many
platforms errno is a function already (to support multi-threading).

> The other place I used strwinerror is in:
> 
>   if (!ret)
>     {
> -      error ("Error creating process %s, (error %d): %s\n", args,
> -            (int) GetLastError (), strerror (GetLastError ()));
> +      error ("Error creating process \"%s%s\", (error %d): %s\n",
> +            program, args,
> +            (int) GetLastError (), strwinerror (GetLastError ()));
>     }
> 
> On Window 9x/NT it is wrong to do:
> strerror (GetLastError ())
> 
> The errno values and the windows error codes are not the same.

This is not a problem: errno should not be used with any literal
values anyway, only with symbolical constants.

> Would you prefer to have that? That is, rewrite this last hunk to use
> FormatMessage
> directly, and rename strwinerror to strerror, put it wincecompat.c, and have a:
> 
> #ifdef __MINGW32CE__
> #define errno (GetLastError ())
> #endif

Yes, I'd prefer that solution.  gdbserver/win32-low.c is already
Windows specific, so it's okay to use FormatMessage there.

> > > doc/ChangeLog
> > >
> > >       * gdb.texinfo (WinCE): Delete subsection.
> >
> > Why?  Is that subsection incorrect in some ways?
> >
> 
> It is correct for the current WinCE support, using gdb/wince.c and
> gdb/wince-stub.c, which implements a custom remote protocol.  This
> patch removes those files, removing the functionality that
> subsection is documenting.

Are there any WinCE-specific commands or features left after your
patch?  If there are, please describe them in this section.  If not,
then it's okay to delete the section.

Thanks.


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [New WinCE support] [patch 4/4] The bulk of the code.
  2007-03-17 11:18       ` Eli Zaretskii
@ 2007-03-17 11:35         ` Andreas Schwab
  2007-03-19  1:53         ` Pedro Alves
  1 sibling, 0 replies; 19+ messages in thread
From: Andreas Schwab @ 2007-03-17 11:35 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: pedro alves, gdb-patches

Eli Zaretskii <eliz@gnu.org> writes:

>> Date: Fri, 16 Mar 2007 15:03:21 +0000
>> From: "pedro alves" <alves.ped@gmail.com>
>> Cc: gdb-patches@sourceware.org
>> 
>> When someone later uses errno as an lvalue, it breaks WinCE again.
>
> I think such usage of errno is a bad idea anyway, since on many
> platforms errno is a function already (to support multi-threading).

Even then errno continues to be an lvalue, as required by POSIX.

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [New WinCE support] [patch 4/4] The bulk of the code.
  2007-03-17 11:18       ` Eli Zaretskii
  2007-03-17 11:35         ` Andreas Schwab
@ 2007-03-19  1:53         ` Pedro Alves
  2007-03-19  4:21           ` Eli Zaretskii
  2007-03-27 19:20           ` Daniel Jacobowitz
  1 sibling, 2 replies; 19+ messages in thread
From: Pedro Alves @ 2007-03-19  1:53 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 4698 bytes --]

Eli Zaretskii wrote:
>> Date: Fri, 16 Mar 2007 15:03:21 +0000
>> From: "pedro alves" <alves.ped@gmail.com>
>> Cc: gdb-patches@sourceware.org
>>
>>     
>> I'm using the same api as strerror, which returns a pointer into a
>> static buffer.
>>     
>
> In that case, I guess it's okay to use a static buffer.  But please at
> least check inside the function that the buffer size was enough, by
> comparing the value returned by FormatMessageW with the size of the
> buffer you passed to it.
>   

I had thought that the message would be truncated, so I didn't
care about that check, but that's not what happens.  If the buffer
isn't enough, 0 is returned.  Ended up switching to
FORMAT_MESSAGE_ALLOCATE_BUFFER.

>   
>> Hummm, I don't know how is it that I specified a buffer of size 0,
>> and Windows (at least CE) still fills the buffer.
>>     
>
> I think it fills the buffer because the buffer is larger than 0.  The
> return value tells you how many characters it _really_ needed to
> format the message.  By comparing that value with the size of the
> buffer, you can find out whether the buffer was large enough.
>
>   

I have no idea how I missed it, but it doesn't fill the buffer
after all.


>>>> +#ifdef __MINGW32CE__
>>>> +  err = strwinerror (GetLastError ());
>>>> +#else
>>>>    err = strerror (errno);
>>>> +#endif
>>>>         
>>> Why not call strwinerror strerror and avoid the ifdef?
>>>       
>> Because then I would have to:
>>
>> #ifdef __MINGW32CE__
>> #define errno (GetLastError ())
>> #endif
>>
>>   err = strerror (errno);
>>
>> That means I still must have an #ifdef somewhere.
>>     
>
> But that ifdef would be in only one place, while with a different
> function you need an ifdef each time you use the function.
>
>   
>> Since there is only one instance of it (the #ifdef) in gdbserver, I
>> thought it is better to have strwinerror explicit.
>>     
>
> There's only one instance _today_.  Tomorrow we could have more of
> them.
>
>   

OK.  Moved strwinerror to win32-low.c, and defined strerror to
strwinerror in wincecompat.h, which is then included in server.h.

> Btw, I see in your patch two instances of strwinerror and two places
> that call it: one in gdbreplay.c, the other in utils.c.  Why did you
> need two almost identical functions?
>
>   

Well, gdbreplay (a separate application) has some other functionality
that is copied from gdbserver instead of sharing objects,
eg: perror_with_name.  I didn't think it was worth it to change
how it is built for just one function.
They are not identical, because the gdbserver version only
cares about UNICODE (Win32 API on Windows CE is only wide).


>> When someone later uses errno as an lvalue, it breaks WinCE again.
>>     
>
> I think such usage of errno is a bad idea anyway, since on many
> platforms errno is a function already (to support multi-threading).
>
>   

As Andreas said, it must still be an lvalue.  The usual way to get
around it is to use something like __set_errno(VALUE) instead of
errno = VALUE, and define __set_errno to SetLastError on WinCE.

>> The other place I used strwinerror is in:
>>
>>   if (!ret)
>>     {
>> -      error ("Error creating process %s, (error %d): %s\n", args,
>> -            (int) GetLastError (), strerror (GetLastError ()));
>> +      error ("Error creating process \"%s%s\", (error %d): %s\n",
>> +            program, args,
>> +            (int) GetLastError (), strwinerror (GetLastError ()));
>>     }
>>
>> On Window 9x/NT it is wrong to do:
>> strerror (GetLastError ())
>>
>> The errno values and the windows error codes are not the same.
>>     
>
> This is not a problem: errno should not be used with any literal
> values anyway, only with symbolical constants.
>
>   

I don't understand what you mean here.

On MinGW, this:

printf ("%s\n", strerror (ERROR_TOO_MANY_OPEN_FILES));

prints:
"Interrupted function call"

Clearly not what was intended.  This happens because:

errno.h
#define EINTR           4       /* Interrupted function call */

winerror.h
#define ERROR_TOO_MANY_OPEN_FILES 4L



>> Would you prefer to have that? That is, rewrite this last hunk to use
>> FormatMessage
>> directly, and rename strwinerror to strerror, put it wincecompat.c, and have a:
>>
>> #ifdef __MINGW32CE__
>> #define errno (GetLastError ())
>> #endif
>>     
>
> Yes, I'd prefer that solution.  gdbserver/win32-low.c is already
> Windows specific, so it's okay to use FormatMessage there.
>   

Done.  See new attached patch.

> Are there any WinCE-specific commands or features left after your
> patch?  If there are, please describe them in this section.  If not,
> then it's okay to delete the section.
>
>   

There aren't any left.






[-- Attachment #2: wince_gdbserver.diff --]
[-- Type: text/plain, Size: 56141 bytes --]

ChangeLog

	* arm-wince-tdep.c: New.
	* config/arm/wince.mt (DEPRECATED_TM_FILE): Use tm-arm.h.
	(MT_CFLAGS): Delete.
	(TM_CLIBS): Delete.
	(TDEPFILES): Add arm-wince-tdep.o, corelow.o, solib.o,
	solib-legacy.o, solib-svr4.o, and remove wince.o.
	* configure.tgt (arm*-*-mingw32ce*): Add.
	* signals/signals.c [HAVE_SIGNAL_H]: Check.
	(do_target_signal_to_host): Silence 'not used' warning.
	* config/arm/tm-wince.h: Remove.
	* wince.c: Remove.
	* wince-stub.h: Remove.
	* wince-stub.c: Remove.

doc/ChangeLog

	* gdb.texinfo (WinCE): Delete subsection.

gdbserver/ChangeLog

	* gdbserver/configure.ac: Add errno checking.
	(AC_CHECK_HEADERS): Add errno.h, fcntl.h, signal.h,
	sys/file.h and malloc.h.
	(AC_CHECK_DECLS): Add perror.
	(srv_mingwce): Handle.
	* gdbserver/configure.srv (i[34567]86-*-cygwin*): Add
	win32-i386-low.o to srv_tgtobj.
	(i[34567]86-*-mingw*): Likewise.
	(arm*-*-mingw32ce*): Add case.
	* gdbreplay.c [HAVE_SYS_FILE_H, HAVE_SIGNAL_H,
	HAVE_FCNTL_H, HAVE_ERRNO_H, HAVE_MALLOC_H]: Check.
	[__MINGW32CE__] (strerror): New function.
	[__MINGW32CE__] (errno): Define to GetLastError.
	[__MINGW32CE__] (COUNTOF): New macro.
	(remote_open): Remove extra close call.
	* mem-break.c (delete_breakpoint_at): New function.
	* mem-break.h (delete_breakpoint_at): Declare.
	* remote-utils.c [HAVE_SYS_FILE_H, HAVE_SIGNAL_H,
	HAVE_FCNTL_H, HAVE_UNISTD_H, HAVE_ERRNO_H]: Check.
	[USE_WIN32API] (read, write): Add char* casts.
	* server.c [HAVE_UNISTD_H, HAVE_SIGNAL_H]: Check.
	* server.h: Include wincecompat.h on Windows CE.
	[HAVE_ERRNO_H]: Check.
	(perror): Declare if not declared.
	* utils.c: Add stdlib.h, errno.h and malloc.h includes.
	(perror_with_name): Remove errno declaration.
	* wincecompat.h: New.
	* wincecompat.c: New.
	* win32-low.h: New.
	* win32-arm-low.c: New.
	* win32-i386-low.c: New.
	(win32-low.c): Include mem-break.h and win32-low.h, and winnt.h.
	(OUTMSG2): Make it safe.
	(_T): New macro.
	(COUNTOF): New macro.
	(NUM_REGS): Get it from the low target.
	(CONTEXT_EXTENDED_REGISTERS, CONTEXT_FLOATING_POINT,
	CONTEXT_DEBUG_REGISTERS): Add fallbacks to 0.
	(thread_rec): Let low target handle debug registers.
	(child_add_thread): Likewise.
	(child_init_thread_list): Likewise.
	(continue_one_thread): Likewise.
	(regptr): New.
	(do_child_fetch_inferior_registers): Move to ...
	* win32-i386-low.c: ... here, and rename to ...
	(do_fetch_inferior_registers): ... this.
	* win32-low.c (child_fetch_inferior_registers): 
	Go through the low target.
	(do_child_store_inferior_registers): Use regptr.
	(strwinerror): New function.
	(win32_create_inferior): Handle Windows CE.
	Use strwinerror instead of strerror on Windows error
	codes.  Add program to the error output.
	Don't close the main thread handle on Windows CE.
	(win32_attach): Use coredll.dll on Windows CE.
	(win32_kill): Close current process and current
	thread handles.
	(win32_detach): Use coredll.dll on Windows CE.
	(win32_resume): Let low target handle debug registers, and
	step request.
	(handle_exception): Add/Remove initial breakpoint.  Avoid
	non-existant WSTOPSIG on Windows CE.
	(win32_read_inferior_memory): Cast to remove warning.
	(win32_arch_string): Go through the low target.
	(initialize_low): Call set_breakpoint_data with the low
	target's breakpoint.
	* win32-low.c (dr, FLAG_TRACE_BIT, FCS_REGNUM,
	FOP_REGNUM, mappings): Move to ...
	* win32-i386-low.c: ... here.
	* win32-low.c (win32_thread_info): Move to ...
	* win32-low.h: ... here.
	* Makefile.in (SFILES): Add win32-low.c, win32-i386-low.c,
	win32-arm-low.c and wincecompat.c.
	(all:): Add $EXEEXT.
	(install-only:): Likewise.
	(gdbserver:): Likewise.
	(gdbreplay:): Likewise.
	* config.in: Regenerate.
	* configure: Regenerate.

---

 gdb/arm-wince-tdep.c           |   84 +++++++++
 gdb/config/arm/wince.mt        |    9 
 gdb/configure.tgt              |    5 
 gdb/doc/gdb.texinfo            |   40 ----
 gdb/gdbserver/Makefile.in      |   20 +-
 gdb/gdbserver/configure.ac     |   26 ++
 gdb/gdbserver/configure.srv    |   10 -
 gdb/gdbserver/gdbreplay.c      |   65 ++++++
 gdb/gdbserver/mem-break.c      |    8 
 gdb/gdbserver/mem-break.h      |    5 
 gdb/gdbserver/remote-utils.c   |   14 +
 gdb/gdbserver/server.c         |    4 
 gdb/gdbserver/server.h         |   12 +
 gdb/gdbserver/utils.c          |   10 -
 gdb/gdbserver/win32-arm-low.c  |   76 ++++++++
 gdb/gdbserver/win32-i386-low.c |  152 ++++++++++++++++
 gdb/gdbserver/win32-low.c      |  382 +++++++++++++++++++++++------------------
 gdb/gdbserver/win32-low.h      |   87 +++++++++
 gdb/gdbserver/wincecompat.c    |   41 ++++
 gdb/gdbserver/wincecompat.h    |   32 +++
 gdb/signals/signals.c          |    5 
 21 files changed, 860 insertions(+), 227 deletions(-)

Index: src/gdb/arm-wince-tdep.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ src/gdb/arm-wince-tdep.c	2007-03-15 22:00:18.000000000 +0000
@@ -0,0 +1,84 @@
+/* Target-dependent code for Windows CE running on ARM processors,
+   for GDB.
+
+   Copyright (C) 2007 Free Software Foundation, Inc.
+
+   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., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+#include "defs.h"
+#include "osabi.h"
+#include "solib-svr4.h"
+#include "target.h"
+
+#include "gdb_string.h"
+
+#include "arm-tdep.h"
+
+static const char arm_wince_le_breakpoint[] = { 0x10, 0x00, 0x00, 0xe6 };
+
+/* Description of the longjmp buffer.  */
+#define ARM_WINCE_JB_ELEMENT_SIZE	INT_REGISTER_SIZE
+#define ARM_WINCE_JB_PC			21
+
+static void
+arm_wince_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  tdep->arm_breakpoint = arm_wince_le_breakpoint;
+  tdep->arm_breakpoint_size = sizeof (arm_wince_le_breakpoint);
+  tdep->struct_return = pcc_struct_return;
+
+  tdep->fp_model = ARM_FLOAT_SOFT_VFP;
+
+  tdep->jb_pc = ARM_WINCE_JB_PC;
+  tdep->jb_elt_size = ARM_WINCE_JB_ELEMENT_SIZE;
+
+  /* On ARM WinCE char defaults to signed.  */
+  set_gdbarch_char_signed (gdbarch, 1);
+
+  set_solib_svr4_fetch_link_map_offsets
+    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+
+  /* Shared library handling.  */
+  set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
+}
+
+static enum gdb_osabi
+arm_wince_osabi_sniffer (bfd *abfd)
+{
+  const char *target_name = bfd_get_target (abfd);
+
+  if (strcmp (target_name, "pei-arm-wince-little") == 0)
+    return GDB_OSABI_WINCE;
+
+  return GDB_OSABI_UNKNOWN;
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+void _initialize_arm_wince_tdep (void);
+
+void
+_initialize_arm_wince_tdep (void)
+{
+  gdbarch_register_osabi_sniffer (bfd_arch_arm, bfd_target_coff_flavour,
+                                  arm_wince_osabi_sniffer);
+
+  gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_WINCE,
+                          arm_wince_init_abi);
+}
Index: src/gdb/config/arm/wince.mt
===================================================================
--- src.orig/gdb/config/arm/wince.mt	2007-03-15 02:25:20.000000000 +0000
+++ src/gdb/config/arm/wince.mt	2007-03-15 22:00:18.000000000 +0000
@@ -1,5 +1,4 @@
-# Target: Acorn RISC machine (ARM) with simulator
-TDEPFILES= arm-tdep.o wince.o
-DEPRECATED_TM_FILE= tm-wince.h
-MT_CFLAGS=-DARM -U_X86_ -U_M_IX86 -U__i386__ -U__i486__ -U__i586__ -U__i686__ -DUNICODE -D_WIN32_WCE -DWINCE_STUB='"${target_alias}-stub.exe"'
-TM_CLIBS=-lrapi
+# Target: ARM based machine running Windows CE (win32)
+DEPRECATED_TM_FILE= tm-arm.h
+TDEPFILES= arm-tdep.o arm-wince-tdep.o corelow.o \
+  solib.o solib-legacy.o solib-svr4.o
Index: src/gdb/configure.tgt
===================================================================
--- src.orig/gdb/configure.tgt	2007-03-15 02:25:20.000000000 +0000
+++ src/gdb/configure.tgt	2007-03-15 22:00:18.000000000 +0000
@@ -54,7 +54,10 @@ alpha*-*-*)		gdb_target=alpha ;;
 # mn10300 / am33 liunux
 am33_2.0*-*-linux*)	gdb_target=linux ;;
 
-arm*-wince-pe)		gdb_target=wince ;;
+arm*-wince-pe | arm*-*-mingw32ce*)
+			gdb_target=wince
+			build_gdbserver=yes
+			;;
 arm*-*-linux*)		gdb_target=linux
 			build_gdbserver=yes
 			;;
Index: src/gdb/gdbserver/configure.ac
===================================================================
--- src.orig/gdb/gdbserver/configure.ac	2007-03-15 02:25:20.000000000 +0000
+++ src/gdb/gdbserver/configure.ac	2007-03-18 23:26:40.000000000 +0000
@@ -39,10 +39,27 @@ AC_HEADER_STDC
 AC_CHECK_HEADERS(sgtty.h termio.h termios.h sys/reg.h string.h dnl
 		 proc_service.h sys/procfs.h thread_db.h linux/elf.h dnl
 		 stdlib.h unistd.h dnl
+ 		 errno.h fcntl.h signal.h sys/file.h malloc.h dnl
 		 sys/ioctl.h netinet/in.h sys/socket.h netdb.h dnl
 		 netinet/tcp.h arpa/inet.h sys/wait.h)
 
-AC_CHECK_DECLS(strerror)
+have_errno=no
+AC_MSG_CHECKING(for errno)
+AC_TRY_LINK([
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif], [static int x; x = errno;],
+  [AC_MSG_RESULT(yes - in errno.h); AC_DEFINE(HAVE_ERRNO, 1, [Define if errno is available]) have_errno=yes])
+if test $have_errno = no; then
+AC_TRY_LINK([
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif], [extern int errno; static int x; x = errno;],
+  [AC_MSG_RESULT(yes - must define); AC_DEFINE(HAVE_ERRNO, 1, [Define if errno is available]) AC_DEFINE(MUST_DEFINE_ERRNO, 1, [Checking if errno must be defined])],
+  [AC_MSG_RESULT(no)])
+fi
+
+AC_CHECK_DECLS([strerror, perror])
 
 AC_CHECK_TYPES(socklen_t, [], [],
 [#include <sys/types.h>
@@ -68,8 +85,13 @@ esac
 
 . ${srcdir}/configure.srv
 
-if test "${srv_mingw}" = "yes"; then
+if test "${srv_mingwce}" = "yes"; then
+  LIBS="$LIBS -lws2"
+elif test "${srv_mingw}" = "yes"; then
   LIBS="$LIBS -lwsock32"
+fi
+
+if test "${srv_mingw}" = "yes"; then
   AC_DEFINE(USE_WIN32API, 1,
 	    [Define if we should use the Windows API, instead of the
 	     POSIX API.  On Windows, we use the Windows API when
Index: src/gdb/gdbserver/configure.srv
===================================================================
--- src.orig/gdb/gdbserver/configure.srv	2007-03-15 22:00:16.000000000 +0000
+++ src/gdb/gdbserver/configure.srv	2007-03-15 22:00:18.000000000 +0000
@@ -44,7 +44,7 @@ case "${target}" in
 			srv_linux_thread_db=yes
 			;;
   i[34567]86-*-cygwin*)	srv_regobj=reg-i386.o
-			srv_tgtobj="win32-low.o"
+			srv_tgtobj="win32-low.o win32-i386-low.o"
 			;;
   i[34567]86-*-linux*)	srv_regobj=reg-i386-linux.o
 			srv_tgtobj="linux-low.o linux-i386-low.o i387-fp.o"
@@ -52,8 +52,14 @@ case "${target}" in
 			srv_linux_regsets=yes
 			srv_linux_thread_db=yes
 			;;
+  arm*-*-mingw32ce*)	srv_regobj=reg-arm.o
+			srv_tgtobj="win32-low.o win32-arm-low.o"
+			srv_tgtobj="${srv_tgtobj} wincecompat.o"
+			srv_mingw=yes
+			srv_mingwce=yes
+			;;
   i[34567]86-*-mingw*)	srv_regobj=reg-i386.o
-			srv_tgtobj="win32-low.o"
+			srv_tgtobj="win32-low.o win32-i386-low.o"
 			srv_mingw=yes
 			;;
   ia64-*-linux*)	srv_regobj=reg-ia64.o
Index: src/gdb/gdbserver/gdbreplay.c
===================================================================
--- src.orig/gdb/gdbserver/gdbreplay.c	2007-03-15 02:25:20.000000000 +0000
+++ src/gdb/gdbserver/gdbreplay.c	2007-03-19 00:07:26.000000000 +0000
@@ -22,12 +22,19 @@
 
 #include "config.h"
 #include <stdio.h>
+#if HAVE_SYS_FILE_H
 #include <sys/file.h>
+#endif
+#if HAVE_SIGNAL_H
 #include <signal.h>
+#endif
 #include <ctype.h>
+#if HAVE_FCNTL_H
 #include <fcntl.h>
+#endif
+#if HAVE_ERRNO_H
 #include <errno.h>
-
+#endif
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>
 #endif
@@ -49,6 +56,9 @@
 #if HAVE_NETINET_TCP_H
 #include <netinet/tcp.h>
 #endif
+#if HAVE_MALLOC_H
+#include <malloc.h>
+#endif
 
 #if USE_WIN32API
 #include <winsock.h>
@@ -63,6 +73,57 @@ typedef int socklen_t;
 
 static int remote_desc;
 
+#ifdef __MINGW32CE__
+
+#ifndef COUNTOF
+#define COUNTOF(STR) (sizeof (STR) / sizeof ((STR)[0]))
+#endif
+
+#define errno (GetLastError ())
+
+char *
+strerror (DWORD error)
+{
+  static char buf[1024];
+  WCHAR *msgbuf;
+  DWORD lasterr = GetLastError ();
+  DWORD chars = FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM
+				| FORMAT_MESSAGE_ALLOCATE_BUFFER,
+				NULL,
+				error,
+				0, /* Default language */
+				(LPVOID)&msgbuf,
+				0,
+				NULL);
+  if (chars != 0)
+    {
+      /* If there is an \r\n appended, zap it.  */
+      if (chars >= 2
+	  && msgbuf[chars - 2] == '\r'
+	  && msgbuf[chars - 1] == '\n')
+	{
+	  chars -= 2;
+	  msgbuf[chars] = 0;
+	}
+
+      if (chars > ((COUNTOF (buf)) - 1))
+	{
+	  chars = COUNTOF (buf) - 1;
+	  msgbuf [chars] = 0;
+	}
+
+      wcstombs (buf, msgbuf, chars + 1);
+      LocalFree (msgbuf);
+    }
+  else
+    sprintf (buf, "unknown win32 error (%ld)", error);
+
+  SetLastError (lasterr);
+  return buf;
+}
+
+#endif /* __MINGW32CE__ */
+
 /* Print the system error message for errno, and also mention STRING
    as the file name for which the error was encountered.
    Then return to command level.  */
@@ -178,8 +239,6 @@ remote_open (char *name)
       setsockopt (remote_desc, IPPROTO_TCP, TCP_NODELAY,
 		  (char *) &tmp, sizeof (tmp));
 
-      close (tmp_desc);		/* No longer need this */
-
 #ifndef USE_WIN32API
       close (tmp_desc);		/* No longer need this */
 
Index: src/gdb/gdbserver/mem-break.c
===================================================================
--- src.orig/gdb/gdbserver/mem-break.c	2007-03-15 02:25:20.000000000 +0000
+++ src/gdb/gdbserver/mem-break.c	2007-03-15 22:00:18.000000000 +0000
@@ -113,6 +113,14 @@ find_breakpoint_at (CORE_ADDR where)
   return NULL;
 }
 
+void
+delete_breakpoint_at (CORE_ADDR addr)
+{
+  struct breakpoint *bp = find_breakpoint_at (addr);
+  if (bp != NULL)
+    delete_breakpoint (bp);
+}
+
 static void
 reinsert_breakpoint_handler (CORE_ADDR stop_pc)
 {
Index: src/gdb/gdbserver/mem-break.h
===================================================================
--- src.orig/gdb/gdbserver/mem-break.h	2007-03-15 02:25:20.000000000 +0000
+++ src/gdb/gdbserver/mem-break.h	2007-03-15 22:00:18.000000000 +0000
@@ -31,6 +31,11 @@
 void set_breakpoint_at (CORE_ADDR where,
 			void (*handler) (CORE_ADDR));
 
+/* Delete a breakpoint previously inserted at ADDR with
+   set_breakpoint_at.  */
+
+void delete_breakpoint_at (CORE_ADDR addr);
+
 /* Create a reinsertion breakpoint at STOP_AT for the breakpoint
    currently at STOP_PC (and temporarily remove the breakpoint at
    STOP_PC).  */
Index: src/gdb/gdbserver/remote-utils.c
===================================================================
--- src.orig/gdb/gdbserver/remote-utils.c	2007-03-15 02:25:20.000000000 +0000
+++ src/gdb/gdbserver/remote-utils.c	2007-03-15 22:00:18.000000000 +0000
@@ -26,7 +26,9 @@
 #if HAVE_SYS_IOCTL_H
 #include <sys/ioctl.h>
 #endif
+#if HAVE_SYS_FILE_H
 #include <sys/file.h>
+#endif
 #if HAVE_NETINET_IN_H
 #include <netinet/in.h>
 #endif
@@ -42,15 +44,23 @@
 #if HAVE_SYS_IOCTL_H
 #include <sys/ioctl.h>
 #endif
+#if HAVE_SIGNAL_H
 #include <signal.h>
+#endif
+#if HAVE_FCNTL_H
 #include <fcntl.h>
+#endif
 #include <sys/time.h>
+#if HAVE_UNISTD_H
 #include <unistd.h>
+#endif
 #if HAVE_ARPA_INET_H
 #include <arpa/inet.h>
 #endif
 #include <sys/stat.h>
+#if HAVE_ERRNO_H
 #include <errno.h>
+#endif
 
 #if USE_WIN32API
 #include <winsock.h>
@@ -85,8 +95,8 @@ extern int using_threads;
 extern int debug_threads;
 
 #ifdef USE_WIN32API
-# define read(fd, buf, len) recv (fd, buf, len, 0)
-# define write(fd, buf, len) send (fd, buf, len, 0)
+# define read(fd, buf, len) recv (fd, (char *) buf, len, 0)
+# define write(fd, buf, len) send (fd, (char *) buf, len, 0)
 #endif
 
 /* Open a connection to a remote debugger.
Index: src/gdb/gdbserver/server.c
===================================================================
--- src.orig/gdb/gdbserver/server.c	2007-03-15 02:25:20.000000000 +0000
+++ src/gdb/gdbserver/server.c	2007-03-15 22:00:18.000000000 +0000
@@ -21,8 +21,12 @@
 
 #include "server.h"
 
+#if HAVE_UNISTD_H
 #include <unistd.h>
+#endif
+#if HAVE_SIGNAL_H
 #include <signal.h>
+#endif
 #if HAVE_SYS_WAIT_H
 #include <sys/wait.h>
 #endif
Index: src/gdb/gdbserver/server.h
===================================================================
--- src.orig/gdb/gdbserver/server.h	2007-03-15 02:25:20.000000000 +0000
+++ src/gdb/gdbserver/server.h	2007-03-18 22:52:44.000000000 +0000
@@ -24,10 +24,16 @@
 
 #include "config.h"
 
+#ifdef __MINGW32CE__
+#include "wincecompat.h"
+#endif
+
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
+#ifdef HAVE_ERRNO_H
 #include <errno.h>
+#endif
 #include <setjmp.h>
 
 #ifdef HAVE_STRING_H
@@ -40,6 +46,12 @@ extern char *strerror (int);	/* X3.159-1
 #endif
 #endif
 
+#if !HAVE_DECL_PERROR
+#ifndef perror
+extern void perror (const char *);
+#endif
+#endif
+
 #ifndef ATTR_NORETURN
 #if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7))
 #define ATTR_NORETURN __attribute__ ((noreturn))
Index: src/gdb/gdbserver/utils.c
===================================================================
--- src.orig/gdb/gdbserver/utils.c	2007-03-15 02:25:20.000000000 +0000
+++ src/gdb/gdbserver/utils.c	2007-03-18 23:38:00.000000000 +0000
@@ -22,6 +22,13 @@
 #include "server.h"
 #include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#if HAVE_MALLOC_H
+#include <malloc.h>
+#endif
 
 /* Generally useful subroutines used throughout the program.  */
 
@@ -32,9 +39,6 @@
 void
 perror_with_name (char *string)
 {
-#ifndef STDC_HEADERS
-  extern int errno;
-#endif
   const char *err;
   char *combined;
 
Index: src/gdb/gdbserver/win32-low.c
===================================================================
--- src.orig/gdb/gdbserver/win32-low.c	2007-03-15 22:00:16.000000000 +0000
+++ src/gdb/gdbserver/win32-low.c	2007-03-19 00:06:14.000000000 +0000
@@ -23,8 +23,11 @@
 #include "server.h"
 #include "regcache.h"
 #include "gdb/signals.h"
+#include "mem-break.h"
+#include "win32-low.h"
 
 #include <windows.h>
+#include <winnt.h>
 #include <imagehlp.h>
 #include <psapi.h>
 #include <sys/param.h>
@@ -41,7 +44,15 @@
 #if LOG
 #define OUTMSG2(X) do { printf X; fflush (stdout); } while (0)
 #else
-#define OUTMSG2(X)
+#define OUTMSG2(X) do ; while (0)
+#endif
+
+#ifndef _T
+#define _T(x) TEXT (x)
+#endif
+
+#ifndef COUNTOF
+#define COUNTOF(STR) (sizeof (STR) / sizeof ((STR)[0]))
 #endif
 
 int using_threads = 1;
@@ -56,25 +67,28 @@ static DEBUG_EVENT current_event;
 
 static int debug_registers_changed = 0;
 static int debug_registers_used = 0;
-static unsigned dr[8];
+
+#define NUM_REGS (the_low_target.num_regs)
 
 typedef BOOL winapi_DebugActiveProcessStop (DWORD dwProcessId);
 typedef BOOL winapi_DebugSetProcessKillOnExit (BOOL KillOnExit);
 
-#define FLAG_TRACE_BIT 0x100
+#ifndef CONTEXT_EXTENDED_REGISTERS
+#define CONTEXT_EXTENDED_REGISTERS 0
+#endif
+
+#ifndef CONTEXT_FLOATING_POINT
+#define CONTEXT_FLOATING_POINT 0
+#endif
+
+#ifndef CONTEXT_DEBUG_REGISTERS
+#define CONTEXT_DEBUG_REGISTERS 0
+#endif
+
 #define CONTEXT_DEBUGGER (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
 #define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS	\
   | CONTEXT_EXTENDED_REGISTERS
 
-/* Thread information structure used to track extra information about
-   each thread.  */
-typedef struct win32_thread_info
-{
-  DWORD tid;
-  HANDLE h;
-  int suspend_count;
-  CONTEXT context;
-} win32_thread_info;
 static DWORD main_thread_id = 0;
 
 /* Get the thread ID from the current selected inferior (the current
@@ -113,12 +127,8 @@ thread_rec (DWORD id, int get_context)
       if (id == current_event.dwThreadId)
 	{
 	  /* Copy dr values from that thread.  */
-	  dr[0] = th->context.Dr0;
-	  dr[1] = th->context.Dr1;
-	  dr[2] = th->context.Dr2;
-	  dr[3] = th->context.Dr3;
-	  dr[6] = th->context.Dr6;
-	  dr[7] = th->context.Dr7;
+	  if (the_low_target.store_debug_registers != NULL)
+	    (*the_low_target.store_debug_registers) (th);
 	}
     }
 
@@ -145,20 +155,16 @@ child_add_thread (DWORD tid, HANDLE h)
 			      new_register_cache ());
 
   /* Set the debug registers for the new thread if they are used.  */
-  if (debug_registers_used)
+  if (debug_registers_used
+      && the_low_target.load_debug_registers != NULL)
     {
       /* Only change the value of the debug registers.  */
       th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
 
       GetThreadContext (th->h, &th->context);
 
-      th->context.Dr0 = dr[0];
-      th->context.Dr1 = dr[1];
-      th->context.Dr2 = dr[2];
-      th->context.Dr3 = dr[3];
-      /* th->context.Dr6 = dr[6];
-         FIXME: should we set dr6 also ?? */
-      th->context.Dr7 = dr[7];
+      (*the_low_target.load_debug_registers) (th);
+
       SetThreadContext (th->h, &th->context);
       th->context.ContextFlags = 0;
     }
@@ -257,60 +263,26 @@ struct target_waitstatus
   value;
 };
 
-#define NUM_REGS 41
-#define FCS_REGNUM 27
-#define FOP_REGNUM 31
-
-#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
-static const int mappings[] = {
-  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]),
-  context_offset (FloatSave.ControlWord),
-  context_offset (FloatSave.StatusWord),
-  context_offset (FloatSave.TagWord),
-  context_offset (FloatSave.ErrorSelector),
-  context_offset (FloatSave.ErrorOffset),
-  context_offset (FloatSave.DataSelector),
-  context_offset (FloatSave.DataOffset),
-  context_offset (FloatSave.ErrorSelector),
-  /* XMM0-7 */
-  context_offset (ExtendedRegisters[10 * 16]),
-  context_offset (ExtendedRegisters[11 * 16]),
-  context_offset (ExtendedRegisters[12 * 16]),
-  context_offset (ExtendedRegisters[13 * 16]),
-  context_offset (ExtendedRegisters[14 * 16]),
-  context_offset (ExtendedRegisters[15 * 16]),
-  context_offset (ExtendedRegisters[16 * 16]),
-  context_offset (ExtendedRegisters[17 * 16]),
-  /* MXCSR */
-  context_offset (ExtendedRegisters[24])
-};
+/* Return a pointer into a CONTEXT field indexed by gdb register number.
+   Return a pointer to an dummy register holding zero if there is no
+   corresponding CONTEXT field for the given register number.  */
+char *
+regptr (CONTEXT* c, int r)
+{
+  if (the_low_target.regmap[r] < 0)
+  {
+    static ULONG zero;
+    /* Always force value to zero, in case the user tried to write
+       to this register before.  */
+    zero = 0;
+    return (char *) &zero;
+  }
+  else
+    return (char *) c + the_low_target.regmap[r];
+}
 
-#undef context_offset
 
-/* Clear out any old thread list and reintialize it to a pristine
+/* Clear out any old thread list and reinitialize it to a pristine
    state. */
 static void
 child_init_thread_list (void)
@@ -321,17 +293,17 @@ child_init_thread_list (void)
 static void
 do_initial_child_stuff (DWORD pid)
 {
-  int i;
-
   last_sig = TARGET_SIGNAL_0;
 
   debug_registers_changed = 0;
   debug_registers_used = 0;
-  for (i = 0; i < sizeof (dr) / sizeof (dr[0]); i++)
-    dr[i] = 0;
+
   memset (&current_event, 0, sizeof (current_event));
 
   child_init_thread_list ();
+
+  if (the_low_target.initial_stuff != NULL)
+    (*the_low_target.initial_stuff) ();
 }
 
 /* Resume all artificially suspended threads if we are continuing
@@ -354,13 +326,10 @@ continue_one_thread (struct inferior_lis
 	{
 	  /* Only change the value of the debug registers.  */
 	  th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
-	  th->context.Dr0 = dr[0];
-	  th->context.Dr1 = dr[1];
-	  th->context.Dr2 = dr[2];
-	  th->context.Dr3 = dr[3];
-	  /* th->context.Dr6 = dr[6];
-	     FIXME: should we set dr6 also ?? */
-	  th->context.Dr7 = dr[7];
+
+	  if (the_low_target.load_debug_registers != NULL)
+	    the_low_target.load_debug_registers (th);
+
 	  SetThreadContext (th->h, &th->context);
 	  th->context.ContextFlags = 0;
 	}
@@ -384,26 +353,6 @@ child_continue (DWORD continue_status, i
   return res;
 }
 
-/* Fetch register(s) from gdbserver regcache data.  */
-static void
-do_child_fetch_inferior_registers (win32_thread_info *th, int r)
-{
-  char *context_offset = ((char *) &th->context) + mappings[r];
-  long l;
-  if (r == FCS_REGNUM)
-    {
-      l = *((long *) context_offset) & 0xffff;
-      supply_register (r, (char *) &l);
-    }
-  else if (r == FOP_REGNUM)
-    {
-      l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
-      supply_register (r, (char *) &l);
-    }
-  else
-    supply_register (r, context_offset);
-}
-
 /* Fetch register(s) from the current thread context.  */
 static void
 child_fetch_inferior_registers (int r)
@@ -414,14 +363,14 @@ child_fetch_inferior_registers (int r)
     child_fetch_inferior_registers (NUM_REGS);
   else
     for (regno = 0; regno < r; regno++)
-      do_child_fetch_inferior_registers (th, regno);
+      (*the_low_target.fetch_inferior_registers) (th, regno);
 }
 
 /* Get register from gdbserver regcache data.  */
 static void
 do_child_store_inferior_registers (win32_thread_info *th, int r)
 {
-  collect_register (r, ((char *) &th->context) + mappings[r]);
+  collect_register (r, regptr (&th->context, r));
 }
 
 /* Store a new register value into the current thread context.  We don't
@@ -438,6 +387,61 @@ child_store_inferior_registers (int r)
       do_child_store_inferior_registers (th, regno);
 }
 
+/* Map the Windows error number in ERROR to a locale-dependent error
+   message string and return a pointer to it.  Typically, the values
+   for ERROR come from GetLastError.
+
+   The string pointed to shall not be modified by the application,
+   but may be overwritten by a subsequent call to strwinerror
+
+   The strwinerror function does not change the current setting
+   of GetLastError.  */
+
+char *
+strwinerror (DWORD error)
+{
+  static char buf[1024];
+  TCHAR *msgbuf;
+  DWORD lasterr = GetLastError ();
+  DWORD chars = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
+			       | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+			       NULL,
+			       error,
+			       0, /* Default language */
+			       (LPVOID)&msgbuf,
+			       0,
+			       NULL);
+  if (chars != 0)
+    {
+      /* If there is an \r\n appended, zap it.  */
+      if (chars >= 2
+	  && msgbuf[chars - 2] == '\r'
+	  && msgbuf[chars - 1] == '\n')
+	{
+	  chars -= 2;
+	  msgbuf[chars] = 0;
+	}
+
+      if (chars > ((COUNTOF (buf)) - 1))
+	{
+	  chars = COUNTOF (buf) - 1;
+	  msgbuf [chars] = 0;
+	}
+
+#ifdef UNICODE
+      wcstombs (buf, msgbuf, chars + 1);
+#else
+      strncpy (buf, msgbuf, chars + 1);
+#endif
+      LocalFree (msgbuf);
+    }
+  else
+    sprintf (buf, "unknown win32 error (%ld)", error);
+
+  SetLastError (lasterr);
+  return buf;
+}
+
 /* Start a new process.
    PROGRAM is a path to the program to execute.
    ARGS is a standard NULL-terminated array of arguments,
@@ -451,21 +455,22 @@ win32_create_inferior (char *program, ch
   char real_path[MAXPATHLEN];
   char *orig_path, *new_path, *path_ptr;
 #endif
-  char *winenv = NULL;
-  STARTUPINFO si;
-  PROCESS_INFORMATION pi;
   BOOL ret;
   DWORD flags;
   char *args;
   int argslen;
   int argc;
+  PROCESS_INFORMATION pi;
+#ifndef __MINGW32CE__
+  STARTUPINFO si = { sizeof (STARTUPINFO) };
+  char *winenv = NULL;
+#else
+  wchar_t *wargs, *wprogram;
+#endif
 
   if (!program)
     error ("No executable specified, specify executable to debug.\n");
 
-  memset (&si, 0, sizeof (si));
-  si.cb = sizeof (si);
-
   flags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS;
 
 #ifndef USE_WIN32API
@@ -483,11 +488,11 @@ win32_create_inferior (char *program, ch
   program = real_path;
 #endif
 
-  argslen = strlen (program) + 1;
+  argslen = 1;
   for (argc = 1; program_args[argc]; argc++)
     argslen += strlen (program_args[argc]) + 1;
   args = alloca (argslen);
-  strcpy (args, program);
+  args[0] = '\0';
   for (argc = 1; program_args[argc]; argc++)
     {
       /* FIXME: Can we do better about quoting?  How does Cygwin
@@ -495,17 +500,40 @@ win32_create_inferior (char *program, ch
       strcat (args, " ");
       strcat (args, program_args[argc]);
     }
-  OUTMSG2 (("Command line is %s\n", args));
+  OUTMSG2 (("Command line is \"%s\"\n", args));
 
+#ifdef CREATE_NEW_PROCESS_GROUP
   flags |= CREATE_NEW_PROCESS_GROUP;
+#endif
 
-  ret = CreateProcess (0, args,	/* command line */
-		       NULL,	/* Security */
+#ifdef __MINGW32CE__
+  to_back_slashes (program);
+  wargs = alloca (argslen * sizeof (wchar_t));
+  mbstowcs (wargs, args, argslen);
+  wprogram = alloca ((strlen (program) + 1) * sizeof (wchar_t));
+  mbstowcs (wprogram, program, strlen (program) + 1);
+  ret = CreateProcessW (wprogram, /* image name */
+                        wargs,    /* command line */
+                        NULL,     /* security, not supported */
+                        NULL,     /* thread, not supported */
+                        FALSE,    /* inherit handles, not supported */
+                        flags,    /* start flags */
+                        NULL,     /* environment, not supported */
+                        NULL,     /* current directory, not supported */
+                        NULL,     /* start info, not supported */
+                        &pi);     /* proc info */
+#else
+  ret = CreateProcess (program, /* image name */
+		       args,	/* command line */
+		       NULL,	/* security */
 		       NULL,	/* thread */
 		       TRUE,	/* inherit handles */
 		       flags,	/* start flags */
-		       winenv, NULL,	/* current directory */
-		       &si, &pi);
+		       winenv,  /* environment */
+		       NULL,	/* current directory */
+		       &si,     /* start info */
+		       &pi);    /* proc info */
+#endif
 
 #ifndef USE_WIN32API
   if (orig_path)
@@ -514,15 +542,21 @@ win32_create_inferior (char *program, ch
 
   if (!ret)
     {
-      error ("Error creating process %s, (error %d): %s\n", args,
-	     (int) GetLastError (), strerror (GetLastError ()));
+      DWORD err = GetLastError ();
+      error ("Error creating process \"%s%s\", (error %d): %s\n",
+	     program, args, (int) err, strwinerror (err));
     }
   else
     {
       OUTMSG2 (("Process created: %s\n", (char *) args));
     }
 
+#ifndef _WIN32_WCE
+  /* On Windows CE this handle can't be closed.  The OS reuses
+     it in the debug events, while the 9x/NT versions of Windows
+     probably use a DuplicateHandle'd one.  */
   CloseHandle (pi.hThread);
+#endif
 
   current_process_handle = pi.hProcess;
   current_process_id = pi.dwProcessId;
@@ -539,16 +573,18 @@ static int
 win32_attach (unsigned long pid)
 {
   int res = 0;
-  HMODULE kernel32 = LoadLibrary ("KERNEL32.DLL");
   winapi_DebugActiveProcessStop *DebugActiveProcessStop = NULL;
-  winapi_DebugSetProcessKillOnExit *DebugSetProcessKillOnExit = NULL;
 
-  DebugActiveProcessStop =
-    (winapi_DebugActiveProcessStop *) GetProcAddress (kernel32,
-						      "DebugActiveProcessStop");
-  DebugSetProcessKillOnExit =
-    (winapi_DebugSetProcessKillOnExit *) GetProcAddress (kernel32,
-							 "DebugSetProcessKillOnExit");
+  winapi_DebugSetProcessKillOnExit *DebugSetProcessKillOnExit = NULL;
+#ifdef _WIN32_WCE
+  HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
+#else
+  HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
+#endif
+  DebugActiveProcessStop = (winapi_DebugActiveProcessStop *)
+    GetProcAddress (dll, _T("DebugActiveProcessStop"));
+  DebugSetProcessKillOnExit = (winapi_DebugSetProcessKillOnExit *)
+    GetProcAddress (dll, _T("DebugSetProcessKillOnExit"));
 
   res = DebugActiveProcess (pid) ? 1 : 0;
 
@@ -571,8 +607,6 @@ win32_attach (unsigned long pid)
   if (res)
     do_initial_child_stuff (pid);
 
-  FreeLibrary (kernel32);
-
   return res;
 }
 
@@ -580,6 +614,8 @@ win32_attach (unsigned long pid)
 static void
 win32_kill (void)
 {
+  win32_thread_info *current_thread;
+
   if (current_process_handle == NULL)
     return;
 
@@ -593,22 +629,32 @@ win32_kill (void)
       if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
 	break;
     }
+
+  CloseHandle (current_process_handle);
+
+  current_thread = inferior_target_data (current_inferior);
+  if (current_thread && current_thread->h)
+    {
+      /* This may fail in an attached process, so don't check.  */
+      (void) CloseHandle (current_thread->h);
+    }
 }
 
 /* Detach from all inferiors.  */
 static void
 win32_detach (void)
 {
-  HMODULE kernel32 = LoadLibrary ("KERNEL32.DLL");
   winapi_DebugActiveProcessStop *DebugActiveProcessStop = NULL;
   winapi_DebugSetProcessKillOnExit *DebugSetProcessKillOnExit = NULL;
-
-  DebugActiveProcessStop =
-    (winapi_DebugActiveProcessStop *) GetProcAddress (kernel32,
-						      "DebugActiveProcessStop");
-  DebugSetProcessKillOnExit =
-    (winapi_DebugSetProcessKillOnExit *) GetProcAddress (kernel32,
-							 "DebugSetProcessKillOnExit");
+#ifdef _WIN32_WCE
+  HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
+#else
+  HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
+#endif
+  DebugActiveProcessStop = (winapi_DebugActiveProcessStop *)
+    GetProcAddress (dll, _T("DebugActiveProcessStop"));
+  DebugSetProcessKillOnExit = (winapi_DebugSetProcessKillOnExit *)
+    GetProcAddress (dll, _T("DebugSetProcessKillOnExit"));
 
   if (DebugSetProcessKillOnExit != NULL)
     DebugSetProcessKillOnExit (FALSE);
@@ -617,8 +663,6 @@ win32_detach (void)
     DebugActiveProcessStop (current_process_id);
   else
     win32_kill ();
-
-  FreeLibrary (kernel32);
 }
 
 /* Return 1 iff the thread with thread ID TID is alive.  */
@@ -691,23 +735,21 @@ win32_resume (struct thread_resume *resu
       if (th->context.ContextFlags)
 	{
 	  if (debug_registers_changed)
-	    {
-	      th->context.Dr0 = dr[0];
-	      th->context.Dr1 = dr[1];
-	      th->context.Dr2 = dr[2];
-	      th->context.Dr3 = dr[3];
-	      /* th->context.Dr6 = dr[6];
-	         FIXME: should we set dr6 also ?? */
-	      th->context.Dr7 = dr[7];
-	    }
+	    if (the_low_target.load_debug_registers != NULL)
+	      (*the_low_target.load_debug_registers) (th);
 
 	  /* Move register values from the inferior into the thread
 	     context structure.  */
 	  regcache_invalidate ();
 
 	  if (step)
-	    th->context.EFlags |= FLAG_TRACE_BIT;
-
+	    {
+	      if (the_low_target.single_step != NULL)
+		(*the_low_target.single_step) (th);
+	      else
+		error ("Single stepping is not supported "
+		       "in this configuration.\n");
+	    }
 	  SetThreadContext (th->h, &th->context);
 	  th->context.ContextFlags = 0;
 	}
@@ -783,6 +825,11 @@ handle_exception (struct target_waitstat
     case EXCEPTION_BREAKPOINT:
       OUTMSG2 (("EXCEPTION_BREAKPOINT"));
       ourstatus->value.sig = TARGET_SIGNAL_TRAP;
+#ifdef _WIN32_WCE
+      /* Remove the initial breakpoint.  */
+      check_breakpoints ((CORE_ADDR) (long) current_event
+                         .u.Exception.ExceptionRecord.ExceptionAddress);
+#endif
       break;
     case DBG_CONTROL_C:
       OUTMSG2 (("DBG_CONTROL_C"));
@@ -892,6 +939,14 @@ in:
 			  current_event.u.CreateProcessInfo.hThread);
 
       retval = ourstatus->value.related_pid = current_event.dwThreadId;
+#ifdef _WIN32_WCE
+      /* Windows CE doesn't set the initial breakpoint automatically
+	 like the desktop versions of Windows do.  We add it explicitly
+	 here.  It will be removed as soon as it is hit.  */
+      set_breakpoint_at ((CORE_ADDR) (long) current_event.u
+			 .CreateProcessInfo.lpStartAddress,
+			 delete_breakpoint_at);
+#endif
       break;
 
     case EXIT_PROCESS_DEBUG_EVENT:
@@ -994,8 +1049,13 @@ win32_wait (char *status)
 	}
       else if (our_status.kind == TARGET_WAITKIND_STOPPED)
 	{
+#ifndef __MINGW32CE__
 	  OUTMSG2 (("Child Stopped with signal = %x \n",
 		    WSTOPSIG (our_status.value.sig)));
+#else
+	  OUTMSG2 (("Child Stopped with signal = %x \n",
+		    our_status.value.sig));
+#endif
 
 	  *status = 'T';
 
@@ -1039,7 +1099,7 @@ win32_store_inferior_registers (int regn
 static int
 win32_read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
 {
-  return child_xfer_memory (memaddr, myaddr, len, 0, 0) != len;
+  return child_xfer_memory (memaddr, (char *) myaddr, len, 0, 0) != len;
 }
 
 /* Write memory to the inferior process.  This should generally be
@@ -1056,7 +1116,7 @@ win32_write_inferior_memory (CORE_ADDR m
 static const char *
 win32_arch_string (void)
 {
-  return "i386";
+  return the_low_target.arch_string;
 }
 
 static struct target_ops win32_target_ops = {
@@ -1088,6 +1148,8 @@ void
 initialize_low (void)
 {
   set_target_ops (&win32_target_ops);
-
+  if (the_low_target.breakpoint != NULL)
+    set_breakpoint_data (the_low_target.breakpoint,
+			 the_low_target.breakpoint_len);
   init_registers ();
 }
Index: src/gdb/signals/signals.c
===================================================================
--- src.orig/gdb/signals/signals.c	2007-03-15 02:25:20.000000000 +0000
+++ src/gdb/signals/signals.c	2007-03-15 22:00:18.000000000 +0000
@@ -28,7 +28,9 @@
 #include "gdb_string.h"
 #endif
 
+#ifdef HAVE_SIGNAL_H
 #include <signal.h>
+#endif
 
 /* Always use __SIGRTMIN if it's available.  SIGRTMIN is the lowest
    _available_ realtime signal, not the lowest supported; glibc takes
@@ -519,6 +521,9 @@ do_target_signal_to_host (enum target_si
 			  int *oursig_ok)
 {
   int retsig;
+  /* Silence the 'not used' warning, for targets that
+     do not support signals.  */
+  (void) retsig;
 
   *oursig_ok = 1;
   switch (oursig)
Index: src/gdb/gdbserver/Makefile.in
===================================================================
--- src.orig/gdb/gdbserver/Makefile.in	2007-03-15 22:00:16.000000000 +0000
+++ src/gdb/gdbserver/Makefile.in	2007-03-15 22:00:18.000000000 +0000
@@ -128,7 +128,9 @@ SFILES=	$(srcdir)/gdbreplay.c $(srcdir)/
 	$(srcdir)/linux-m68k-low.c $(srcdir)/linux-mips-low.c \
 	$(srcdir)/linux-ppc-low.c $(srcdir)/linux-ppc64-low.c \
 	$(srcdir)/linux-s390-low.c \
-	$(srcdir)/linux-sh-low.c $(srcdir)/linux-x86-64-low.c
+	$(srcdir)/linux-sh-low.c $(srcdir)/linux-x86-64-low.c \
+	$(srcdir)/win32-arm-low.c $(srcdir)/win32-i386-low.c \
+	$(srcdir)/win32-low.c $(srcdir)/wincecompat.c
 
 DEPFILES = @GDBSERVER_DEPFILES@
 
@@ -154,7 +156,7 @@ XML_BUILTIN = @srv_xmlbuiltin@
 .c.o:
 	${CC} -c ${INTERNAL_CFLAGS} $<
 
-all: gdbserver gdbreplay
+all: gdbserver$(EXEEXT) gdbreplay$(EXEEXT)
 
 # Traditionally "install" depends on "all".  But it may be useful
 # not to; for example, if the user has made some trivial change to a 
@@ -166,7 +168,7 @@ install-only: 
 	n=`echo gdbserver | sed '$(program_transform_name)'`; \
 	if [ x$$n = x ]; then n=gdbserver; else true; fi; \
 	$(SHELL) $(srcdir)/../../mkinstalldirs $(DESTDIR)$(bindir); \
-	$(INSTALL_PROGRAM) gdbserver $(DESTDIR)$(bindir)/$$n; \
+	$(INSTALL_PROGRAM) gdbserver$(EXEEXT) $(DESTDIR)$(bindir)/$$n$(EXEEXT); \
 	$(SHELL) $(srcdir)/../../mkinstalldirs $(DESTDIR)$(man1dir); \
 	$(INSTALL_DATA) $(srcdir)/gdbserver.1 $(DESTDIR)$(man1dir)/$$n.1
 
@@ -183,14 +185,14 @@ html:
 install-html:
 clean-info:
 
-gdbserver: $(OBS) ${ADD_DEPS} ${CDEPS}
-	rm -f gdbserver
-	${CC-LD} $(INTERNAL_CFLAGS) $(INTERNAL_LDFLAGS) -o gdbserver $(OBS) \
+gdbserver$(EXEEXT): $(OBS) ${ADD_DEPS} ${CDEPS}
+	rm -f gdbserver$(EXEEXT)
+	${CC-LD} $(INTERNAL_CFLAGS) $(INTERNAL_LDFLAGS) -o gdbserver$(EXEEXT) $(OBS) \
 	  $(GDBSERVER_LIBS) $(XM_CLIBS)
 
-gdbreplay: gdbreplay.o
-	rm -f gdbreplay
-	${CC-LD} $(INTERNAL_CFLAGS) $(INTERNAL_LDFLAGS) -o gdbreplay gdbreplay.o \
+gdbreplay$(EXEEXT): gdbreplay.o
+	rm -f gdbreplay$(EXEEXT)
+	${CC-LD} $(INTERNAL_CFLAGS) $(INTERNAL_LDFLAGS) -o gdbreplay$(EXEEXT) gdbreplay.o \
 	  $(XM_CLIBS)
 
 # Put the proper machine-specific files first, so M-. on a machine
Index: src/gdb/gdbserver/wincecompat.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ src/gdb/gdbserver/wincecompat.c	2007-03-15 22:00:18.000000000 +0000
@@ -0,0 +1,41 @@
+/* Compatibility routines for Windows CE.
+   Copyright (C) 2007 Free Software Foundation, Inc.
+
+   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., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+#include "server.h"
+
+#include <stdio.h>
+#include <windows.h>
+
+void
+perror (const char *s)
+{
+  if (s && *s)
+    fprintf (stderr, "%s: %s\n", s, strwinerror (GetLastError ()));
+  else
+    fprintf (stderr, "%s\n", strwinerror (GetLastError ()));
+}
+
+void
+to_back_slashes (char *path)
+{
+  for (; *path; ++path)
+    if ('/' == *path)
+      *path = '\\';
+}
Index: src/gdb/gdbserver/win32-arm-low.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ src/gdb/gdbserver/win32-arm-low.c	2007-03-15 23:49:34.000000000 +0000
@@ -0,0 +1,76 @@
+/* Copyright (C) 2007 Free Software Foundation, Inc.
+
+   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., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+#include "server.h"
+#include "win32-low.h"
+
+/* Fetch register(s) from gdbserver regcache data.  */
+static void
+do_fetch_inferior_registers (win32_thread_info *th, int r)
+{
+  char *context_offset = regptr (&th->context, r);
+  supply_register (r, context_offset);
+}
+
+#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
+static const int mappings[] = {
+  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, /* f0 */
+  -1, /* f1 */
+  -1, /* f2 */
+  -1, /* f3 */
+  -1, /* f4 */
+  -1, /* f5 */
+  -1, /* f6 */
+  -1, /* f7 */
+  -1, /* fps */
+  context_offset (Psr),
+};
+#undef context_offset
+
+static const unsigned char arm_wince_le_breakpoint[] =
+  { 0x10, 0x00, 0x00, 0xe6 };
+
+struct win32_target_ops the_low_target = {
+  mappings,
+  sizeof (mappings) / sizeof (mappings[0]),
+  NULL, /* initial_stuff */
+  NULL, /* store_debug_registers */
+  NULL, /* load_debug_registers */
+  do_fetch_inferior_registers,
+  NULL, /* single_step */
+  arm_wince_le_breakpoint,
+  sizeof (arm_wince_le_breakpoint) / sizeof (arm_wince_le_breakpoint[0]),
+  "arm" /* arch_string */
+};
Index: src/gdb/gdbserver/win32-i386-low.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ src/gdb/gdbserver/win32-i386-low.c	2007-03-15 23:49:42.000000000 +0000
@@ -0,0 +1,152 @@
+/* Copyright (C) 2007 Free Software Foundation, Inc.
+
+   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., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+#include "server.h"
+#include "win32-low.h"
+
+#define FCS_REGNUM 27
+#define FOP_REGNUM 31
+
+#define FLAG_TRACE_BIT 0x100
+
+static unsigned dr[8];
+
+static void
+initial_stuff (void)
+{
+  memset (&dr, 0, sizeof (dr));
+}
+
+static void
+store_debug_registers (win32_thread_info *th)
+{
+  dr[0] = th->context.Dr0;
+  dr[1] = th->context.Dr1;
+  dr[2] = th->context.Dr2;
+  dr[3] = th->context.Dr3;
+  dr[6] = th->context.Dr6;
+  dr[7] = th->context.Dr7;
+}
+
+static void
+load_debug_registers (win32_thread_info *th)
+{
+  th->context.Dr0 = dr[0];
+  th->context.Dr1 = dr[1];
+  th->context.Dr2 = dr[2];
+  th->context.Dr3 = dr[3];
+  /* th->context.Dr6 = dr[6];
+     FIXME: should we set dr6 also ?? */
+  th->context.Dr7 = dr[7];
+}
+
+/* Fetch register(s) from gdbserver regcache data.  */
+static void
+do_fetch_inferior_registers (win32_thread_info *th, int r)
+{
+  char *context_offset = regptr (&th->context, r);
+
+  long l;
+  if (r == FCS_REGNUM)
+    {
+      l = *((long *) context_offset) & 0xffff;
+      supply_register (r, (char *) &l);
+    }
+  else if (r == FOP_REGNUM)
+    {
+      l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
+      supply_register (r, (char *) &l);
+    }
+  else
+    supply_register (r, context_offset);
+}
+
+static void
+single_step (win32_thread_info *th)
+{
+  th->context.EFlags |= FLAG_TRACE_BIT;
+}
+
+/* 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.  In this case regptr will return
+   a pointer into a dummy register.  */
+#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
+static const int mappings[] = {
+  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]),
+  context_offset (FloatSave.ControlWord),
+  context_offset (FloatSave.StatusWord),
+  context_offset (FloatSave.TagWord),
+  context_offset (FloatSave.ErrorSelector),
+  context_offset (FloatSave.ErrorOffset),
+  context_offset (FloatSave.DataSelector),
+  context_offset (FloatSave.DataOffset),
+  context_offset (FloatSave.ErrorSelector),
+  /* XMM0-7 */
+  context_offset (ExtendedRegisters[10 * 16]),
+  context_offset (ExtendedRegisters[11 * 16]),
+  context_offset (ExtendedRegisters[12 * 16]),
+  context_offset (ExtendedRegisters[13 * 16]),
+  context_offset (ExtendedRegisters[14 * 16]),
+  context_offset (ExtendedRegisters[15 * 16]),
+  context_offset (ExtendedRegisters[16 * 16]),
+  context_offset (ExtendedRegisters[17 * 16]),
+  /* MXCSR */
+  context_offset (ExtendedRegisters[24])
+};
+#undef context_offset
+
+struct win32_target_ops the_low_target = {
+  mappings,
+  sizeof (mappings) / sizeof (mappings[0]),
+  initial_stuff,
+  store_debug_registers,
+  load_debug_registers,
+  do_fetch_inferior_registers,
+  single_step,
+  (const char*)NULL, /* breakpoint */
+  0, /* breakpoint_len */
+  "i386" /* arch_string */
+};
Index: src/gdb/gdbserver/win32-low.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ src/gdb/gdbserver/win32-low.h	2007-03-18 22:49:38.000000000 +0000
@@ -0,0 +1,87 @@
+/* Internal interfaces for the Win32 specific target code for gdbserver.
+   Copyright (C) 2007 Free Software Foundation, Inc.
+
+   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., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+#include <windows.h>
+
+/* Thread information structure used to track extra information about
+   each thread.  */
+typedef struct win32_thread_info
+{
+  DWORD tid;
+  HANDLE h;
+  int suspend_count;
+  CONTEXT context;
+} win32_thread_info;
+
+struct win32_target_ops
+{
+  /* 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.  In this case regptr will return
+     a pointer into a dummy register.  */
+  const int *regmap;
+
+  /* The number of elements of regmap.  */
+  int num_regs;
+
+  void (*initial_stuff) (void);
+
+  void (*store_debug_registers) (win32_thread_info *);
+  void (*load_debug_registers) (win32_thread_info *);
+
+  /* Fetch register(s) from gdbserver regcache data.  */
+  void (*fetch_inferior_registers) (win32_thread_info *th, int r);
+
+  void (*single_step) (win32_thread_info *th);
+
+  const unsigned char *breakpoint;
+  int breakpoint_len;
+
+  /* What string to report to GDB when it asks for the architecture,
+     or NULL not to answer.  */
+  const char *arch_string;
+};
+
+extern struct win32_target_ops the_low_target;
+
+/* in win32-low.c */
+
+/* Return a pointer into a CONTEXT field indexed by gdb register number.
+   Return a pointer to an dummy register holding zero if there is no
+   corresponding CONTEXT field for the given register number.  */
+extern char * regptr (CONTEXT* c, int r);
+
+/* Map the Windows error number in ERROR to a locale-dependent error
+   message string and return a pointer to it.  Typically, the values
+   for ERROR come from GetLastError.
+
+   The string pointed to shall not be modified by the application,
+   but may be overwritten by a subsequent call to strwinerror
+
+   The strwinerror function does not change the current setting
+   of GetLastError.  */
+extern char * strwinerror (DWORD error);
+
+/* in wincecompat.c */
+
+extern void to_back_slashes (char *);
Index: src/gdb/doc/gdb.texinfo
===================================================================
--- src.orig/gdb/doc/gdb.texinfo	2007-03-03 18:47:52.000000000 +0000
+++ src/gdb/doc/gdb.texinfo	2007-03-15 22:51:00.000000000 +0000
@@ -14312,7 +14312,6 @@ acceptable commands.
 * AVR::                         Atmel AVR
 * CRIS::                        CRIS
 * Super-H::                     Renesas Super-H
-* WinCE::                       Windows CE child processes
 @end menu
 
 @node ARM
@@ -15501,45 +15500,6 @@ commands:
 Show the values of all Super-H registers.
 @end table
 
-@node WinCE
-@subsection Windows CE
-@cindex Windows CE
-
-The following commands are available for Windows CE:
-
-@table @code
-@item set remotedirectory @var{dir}
-@kindex set remotedirectory
-Tell @value{GDBN} to upload files from the named directory @var{dir}.
-The default is @file{/gdb}, i.e.@: the root directory on the current
-drive.
-
-@item show remotedirectory
-@kindex show remotedirectory
-Show the current value of the upload directory.
-
-@item set remoteupload @var{method}
-@kindex set remoteupload
-Set the method used to upload files to remote device.  Valid values
-for @var{method} are @samp{always}, @samp{newer}, and @samp{never}.
-The default is @samp{newer}.
-
-@item show remoteupload
-@kindex show remoteupload
-Show the current setting of the upload method.
-
-@item set remoteaddhost
-@kindex set remoteaddhost
-Tell @value{GDBN} whether to add this host to the remote stub's
-arguments when you debug over a network.
-
-@item show remoteaddhost
-@kindex show remoteaddhost
-Show whether to add this host to remote stub's arguments when
-debugging over a network.
-@end table
-
-
 @node Architectures
 @section Architectures
 
Index: src/gdb/gdbserver/wincecompat.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ src/gdb/gdbserver/wincecompat.h	2007-03-18 23:24:16.000000000 +0000
@@ -0,0 +1,32 @@
+/* Compatibility routines for Windows CE.
+   Copyright (C) 2007 Free Software Foundation, Inc.
+
+   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., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+#ifndef WINCECOMPAT_H
+#define WINCECOMPAT_H
+
+#include <windows.h>
+
+#define errno (GetLastError ())
+
+/* in win32-low.c */
+extern char * strwinerror (DWORD error);
+#define strerror strwinerror
+
+#endif




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [New WinCE support] [patch 4/4] The bulk of the code.
  2007-03-19  1:53         ` Pedro Alves
@ 2007-03-19  4:21           ` Eli Zaretskii
  2007-03-19 12:34             ` Daniel Jacobowitz
  2007-03-27 19:20           ` Daniel Jacobowitz
  1 sibling, 1 reply; 19+ messages in thread
From: Eli Zaretskii @ 2007-03-19  4:21 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

> Date: Mon, 19 Mar 2007 01:16:15 +0000
> From: Pedro Alves <pedro_alves@portugalmail.pt>
> CC:  gdb-patches@sourceware.org
> 
> > Btw, I see in your patch two instances of strwinerror and two places
> > that call it: one in gdbreplay.c, the other in utils.c.  Why did you
> > need two almost identical functions?
> 
> Well, gdbreplay (a separate application) has some other functionality
> that is copied from gdbserver instead of sharing objects,
> eg: perror_with_name.  I didn't think it was worth it to change
> how it is built for just one function.

Sounds rather unclean to me, but if no one else cares, I won't insist.

> They are not identical, because the gdbserver version only
> cares about UNICODE (Win32 API on Windows CE is only wide).

I saw that (that's why I said ``almost identical''), but the
difference is still very minor, so that a version that suits both
types of usage could be easily written.

> >> The errno values and the windows error codes are not the same.
> >
> > This is not a problem: errno should not be used with any literal
> > values anyway, only with symbolical constants.
> 
> I don't understand what you mean here.

I mean that, since WinCE doesn't have errno.h, you could define error
symbols such as EINTR and EMFILE as appropriate for values returned by
GetLastError.

Thanks for the new patch, I'm happy now.


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [New WinCE support] [patch 4/4] The bulk of the code.
  2007-03-19  4:21           ` Eli Zaretskii
@ 2007-03-19 12:34             ` Daniel Jacobowitz
  0 siblings, 0 replies; 19+ messages in thread
From: Daniel Jacobowitz @ 2007-03-19 12:34 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Pedro Alves, gdb-patches

On Mon, Mar 19, 2007 at 06:21:17AM +0200, Eli Zaretskii wrote:
> Sounds rather unclean to me, but if no one else cares, I won't insist.

Yes, this should be cleaned up some day - but no need to do it today.
gdbreplay is not much used at all.

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [New WinCE support] [patch 1/4] : mv win32-i386-low.c  win32-low.c
  2007-03-16  2:07 ` [New WinCE support] [patch 1/4] : mv win32-i386-low.c win32-low.c Pedro Alves
@ 2007-03-27 19:11   ` Daniel Jacobowitz
  0 siblings, 0 replies; 19+ messages in thread
From: Daniel Jacobowitz @ 2007-03-27 19:11 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On Fri, Mar 16, 2007 at 02:07:35AM +0000, Pedro Alves wrote:
> This patch renames gdbserver/win32-i386-low.c to
> gdbserver/win32-low.c.  Well, actually, it is mostly a
> ChangeLog entry, as it is useless to post a patch for the file move.
> Patch 4 will then move the i386 specifics into a new
> win32-i386-low.c, and add a win32-arm-low.c with ARM stuff.



> gdbserver/ChangeLog
> 
> 	* win32-i386-low.c: Rename to ...
> 	* win32-low.c: ... this.
> 	* configure.srv: Replace win32-i386-low.o with win32-low.o.
> 	* Makefile.in: Likewise.

OK.

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [New WinCE support] [patch 2/4] :  s/thread_info/win32_thread_info/g
  2007-03-16  2:09 ` [New WinCE support] [patch 2/4] : s/thread_info/win32_thread_info/g Pedro Alves
@ 2007-03-27 19:12   ` Daniel Jacobowitz
  0 siblings, 0 replies; 19+ messages in thread
From: Daniel Jacobowitz @ 2007-03-27 19:12 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On Fri, Mar 16, 2007 at 02:07:46AM +0000, Pedro Alves wrote:
> gdbserver/ChangeLog
> 
> 	* win32-low.c: Rename typedef thread_info to
> 	win32_thread_info throughout.

OK (thanks!)

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [New WinCE support] [patch 4/4] The bulk of the code.
  2007-03-19  1:53         ` Pedro Alves
  2007-03-19  4:21           ` Eli Zaretskii
@ 2007-03-27 19:20           ` Daniel Jacobowitz
  2007-03-29  3:18             ` Pedro Alves
  2007-03-29  3:51             ` Pedro Alves
  1 sibling, 2 replies; 19+ messages in thread
From: Daniel Jacobowitz @ 2007-03-27 19:20 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Eli Zaretskii, gdb-patches

On Mon, Mar 19, 2007 at 01:16:15AM +0000, Pedro Alves wrote:
> ChangeLog
> 
> 	* arm-wince-tdep.c: New.
> 	* config/arm/wince.mt (DEPRECATED_TM_FILE): Use tm-arm.h.
> 	(MT_CFLAGS): Delete.
> 	(TM_CLIBS): Delete.
> 	(TDEPFILES): Add arm-wince-tdep.o, corelow.o, solib.o,
> 	solib-legacy.o, solib-svr4.o, and remove wince.o.
> 	* configure.tgt (arm*-*-mingw32ce*): Add.
> 	* signals/signals.c [HAVE_SIGNAL_H]: Check.
> 	(do_target_signal_to_host): Silence 'not used' warning.
> 	* config/arm/tm-wince.h: Remove.
> 	* wince.c: Remove.
> 	* wince-stub.h: Remove.
> 	* wince-stub.c: Remove.
> 
> doc/ChangeLog
> 
> 	* gdb.texinfo (WinCE): Delete subsection.
> 
> gdbserver/ChangeLog
> 
> 	* gdbserver/configure.ac: Add errno checking.
> 	(AC_CHECK_HEADERS): Add errno.h, fcntl.h, signal.h,
> 	sys/file.h and malloc.h.
> 	(AC_CHECK_DECLS): Add perror.
> 	(srv_mingwce): Handle.
> 	* gdbserver/configure.srv (i[34567]86-*-cygwin*): Add
> 	win32-i386-low.o to srv_tgtobj.
> 	(i[34567]86-*-mingw*): Likewise.
> 	(arm*-*-mingw32ce*): Add case.
> 	* gdbreplay.c [HAVE_SYS_FILE_H, HAVE_SIGNAL_H,
> 	HAVE_FCNTL_H, HAVE_ERRNO_H, HAVE_MALLOC_H]: Check.
> 	[__MINGW32CE__] (strerror): New function.
> 	[__MINGW32CE__] (errno): Define to GetLastError.
> 	[__MINGW32CE__] (COUNTOF): New macro.
> 	(remote_open): Remove extra close call.
> 	* mem-break.c (delete_breakpoint_at): New function.
> 	* mem-break.h (delete_breakpoint_at): Declare.
> 	* remote-utils.c [HAVE_SYS_FILE_H, HAVE_SIGNAL_H,
> 	HAVE_FCNTL_H, HAVE_UNISTD_H, HAVE_ERRNO_H]: Check.
> 	[USE_WIN32API] (read, write): Add char* casts.
> 	* server.c [HAVE_UNISTD_H, HAVE_SIGNAL_H]: Check.
> 	* server.h: Include wincecompat.h on Windows CE.
> 	[HAVE_ERRNO_H]: Check.
> 	(perror): Declare if not declared.
> 	* utils.c: Add stdlib.h, errno.h and malloc.h includes.
> 	(perror_with_name): Remove errno declaration.
> 	* wincecompat.h: New.
> 	* wincecompat.c: New.
> 	* win32-low.h: New.
> 	* win32-arm-low.c: New.
> 	* win32-i386-low.c: New.
> 	(win32-low.c): Include mem-break.h and win32-low.h, and winnt.h.
> 	(OUTMSG2): Make it safe.
> 	(_T): New macro.
> 	(COUNTOF): New macro.
> 	(NUM_REGS): Get it from the low target.
> 	(CONTEXT_EXTENDED_REGISTERS, CONTEXT_FLOATING_POINT,
> 	CONTEXT_DEBUG_REGISTERS): Add fallbacks to 0.
> 	(thread_rec): Let low target handle debug registers.
> 	(child_add_thread): Likewise.
> 	(child_init_thread_list): Likewise.
> 	(continue_one_thread): Likewise.
> 	(regptr): New.
> 	(do_child_fetch_inferior_registers): Move to ...
> 	* win32-i386-low.c: ... here, and rename to ...
> 	(do_fetch_inferior_registers): ... this.
> 	* win32-low.c (child_fetch_inferior_registers): 
> 	Go through the low target.
> 	(do_child_store_inferior_registers): Use regptr.
> 	(strwinerror): New function.
> 	(win32_create_inferior): Handle Windows CE.
> 	Use strwinerror instead of strerror on Windows error
> 	codes.  Add program to the error output.
> 	Don't close the main thread handle on Windows CE.
> 	(win32_attach): Use coredll.dll on Windows CE.
> 	(win32_kill): Close current process and current
> 	thread handles.
> 	(win32_detach): Use coredll.dll on Windows CE.
> 	(win32_resume): Let low target handle debug registers, and
> 	step request.
> 	(handle_exception): Add/Remove initial breakpoint.  Avoid
> 	non-existant WSTOPSIG on Windows CE.
> 	(win32_read_inferior_memory): Cast to remove warning.
> 	(win32_arch_string): Go through the low target.
> 	(initialize_low): Call set_breakpoint_data with the low
> 	target's breakpoint.
> 	* win32-low.c (dr, FLAG_TRACE_BIT, FCS_REGNUM,
> 	FOP_REGNUM, mappings): Move to ...
> 	* win32-i386-low.c: ... here.
> 	* win32-low.c (win32_thread_info): Move to ...
> 	* win32-low.h: ... here.
> 	* Makefile.in (SFILES): Add win32-low.c, win32-i386-low.c,
> 	win32-arm-low.c and wincecompat.c.
> 	(all:): Add $EXEEXT.
> 	(install-only:): Likewise.
> 	(gdbserver:): Likewise.
> 	(gdbreplay:): Likewise.
> 	* config.in: Regenerate.
> 	* configure: Regenerate.

This is OK.  Doesn't it deserve a NEWS entry?

I didn't go over the Windows-specific changes too closely; I trust you
:-)  I'll try not to break it too badly when working on the Linux ports.

> @@ -52,8 +52,14 @@ case "${target}" in
>  			srv_linux_regsets=yes
>  			srv_linux_thread_db=yes
>  			;;
> +  arm*-*-mingw32ce*)	srv_regobj=reg-arm.o
> +			srv_tgtobj="win32-low.o win32-arm-low.o"
> +			srv_tgtobj="${srv_tgtobj} wincecompat.o"
> +			srv_mingw=yes
> +			srv_mingwce=yes
> +			;;
>    i[34567]86-*-mingw*)	srv_regobj=reg-i386.o
> -			srv_tgtobj="win32-low.o"
> +			srv_tgtobj="win32-low.o win32-i386-low.o"
>  			srv_mingw=yes
>  			;;
>    ia64-*-linux*)	srv_regobj=reg-ia64.o

Please put arm*-*-mingw32ce* up higher, near other ARM targets - the
case statement is pretty much sorted.

Should you check arm-wince-pe here too, since you did in the directory
above?  Not that I expect a lot of native arm-wince-pe gdb :-)

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [New WinCE support] [patch 4/4] The bulk of the code.
  2007-03-27 19:20           ` Daniel Jacobowitz
@ 2007-03-29  3:18             ` Pedro Alves
  2007-03-29  3:51             ` Pedro Alves
  1 sibling, 0 replies; 19+ messages in thread
From: Pedro Alves @ 2007-03-29  3:18 UTC (permalink / raw)
  To: Eli Zaretskii, gdb-patches

Daniel Jacobowitz wrote:
> On Mon, Mar 19, 2007 at 01:16:15AM +0000, Pedro Alves wrote:
>   
>> ChangeLog

>> 	* wince.c: Remove.
>> 	* wince-stub.h: Remove.
>> 	* wince-stub.c: Remove.

Humm, these files are still used by the current sh and mips WinCE 
ports.  As I
understand it, those ports are scheduled for removal.  I'll post a separate
patch to remove them all.

> This is OK.  Doesn't it deserve a NEWS entry?
>   

Thanks a bunch!

I'll prepare a NEWS entry separately.

> I didn't go over the Windows-specific changes too closely; I trust you
> :-)  I'll try not to break it too badly when working on the Linux ports.
>
>   

Thanks for the trust :)
I've tried to make sure I didn't break Cygwin gdbserver in the process.

>> @@ -52,8 +52,14 @@ case "${target}" in
>>  			srv_linux_regsets=yes
>>  			srv_linux_thread_db=yes
>>  			;;
>> +  arm*-*-mingw32ce*)	srv_regobj=reg-arm.o
>> +			srv_tgtobj="win32-low.o win32-arm-low.o"
>> +			srv_tgtobj="${srv_tgtobj} wincecompat.o"
>> +			srv_mingw=yes
>> +			srv_mingwce=yes
>> +			;;
>>    i[34567]86-*-mingw*)	srv_regobj=reg-i386.o
>> -			srv_tgtobj="win32-low.o"
>> +			srv_tgtobj="win32-low.o win32-i386-low.o"
>>  			srv_mingw=yes
>>  			;;
>>    ia64-*-linux*)	srv_regobj=reg-ia64.o
>>     
>
> Please put arm*-*-mingw32ce* up higher, near other ARM targets - the
> case statement is pretty much sorted.
>
>   

Ok, I'll do that.


> Should you check arm-wince-pe here too, since you did in the directory
> above?  Not that I expect a lot of native arm-wince-pe gdb :-)

I don't think so.  arm-wince-pe is supposed (at least that is what I get 
from the binutils archives
from the time Nick made the original binutils/gcc wince support, and 
from current FSF
arm-wince-pe-gcc) to use MSFT's headers and libs, and as such will not 
be able to build
gdbserver OOTB.  Nevertheless, it should be possible to have an 
arm-wince-pe-gdb
connect to a arm-wince-mingw32ce-gdbserver.

Cheers,
Pedro Alves



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [New WinCE support] [patch 4/4] The bulk of the code.
  2007-03-27 19:20           ` Daniel Jacobowitz
  2007-03-29  3:18             ` Pedro Alves
@ 2007-03-29  3:51             ` Pedro Alves
  2007-03-30 11:56               ` Pierre Muller
  1 sibling, 1 reply; 19+ messages in thread
From: Pedro Alves @ 2007-03-29  3:51 UTC (permalink / raw)
  To: Eli Zaretskii, gdb-patches

[-- Attachment #1: Type: text/plain, Size: 266 bytes --]

Daniel Jacobowitz wrote:
> Please put arm*-*-mingw32ce* up higher, near other ARM targets - the
> case statement is pretty much sorted.
>   

Ooops, ended up committing without this change.  Sorry for that.
Committed the attached as obvious.

Cheers,
Pedro Alves




[-- Attachment #2: fixconf.diff --]
[-- Type: text/plain, Size: 1666 bytes --]

Index: ChangeLog
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/ChangeLog,v
retrieving revision 1.117
diff -u -p -r1.117 ChangeLog
--- ChangeLog	29 Mar 2007 01:10:37 -0000	1.117
+++ ChangeLog	29 Mar 2007 01:44:25 -0000
@@ -1,5 +1,10 @@
 2007-03-29  Pedro Alves  <pedro_alves@portugalmail.pt>
 
+	* configure.srv (arm*-*-mingw32ce*): Move near the other
+	arm targets.
+
+2007-03-29  Pedro Alves  <pedro_alves@portugalmail.pt>
+
 	* configure.ac: Add errno checking.
 	(AC_CHECK_HEADERS): Add errno.h, fcntl.h, signal.h,
 	sys/file.h and malloc.h.
Index: configure.srv
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/configure.srv,v
retrieving revision 1.22
diff -u -p -r1.22 configure.srv
--- configure.srv	29 Mar 2007 01:06:47 -0000	1.22
+++ configure.srv	29 Mar 2007 01:44:25 -0000
@@ -33,6 +33,12 @@ case "${target}" in
 			  srv_regobj=reg-arm.o
 			fi
 			;;
+  arm*-*-mingw32ce*)	srv_regobj=reg-arm.o
+			srv_tgtobj="win32-low.o win32-arm-low.o"
+			srv_tgtobj="${srv_tgtobj} wincecompat.o"
+			srv_mingw=yes
+			srv_mingwce=yes
+			;;
   crisv32-*-linux*)	srv_regobj=reg-crisv32.o
 			srv_tgtobj="linux-low.o linux-crisv32-low.o"
 			srv_linux_regsets=yes
@@ -52,12 +58,6 @@ case "${target}" in
 			srv_linux_regsets=yes
 			srv_linux_thread_db=yes
 			;;
-  arm*-*-mingw32ce*)	srv_regobj=reg-arm.o
-			srv_tgtobj="win32-low.o win32-arm-low.o"
-			srv_tgtobj="${srv_tgtobj} wincecompat.o"
-			srv_mingw=yes
-			srv_mingwce=yes
-			;;
   i[34567]86-*-mingw*)	srv_regobj=reg-i386.o
 			srv_tgtobj="win32-low.o win32-i386-low.o"
 			srv_mingw=yes

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: [New WinCE support] [patch 4/4] The bulk of the code.
  2007-03-29  3:51             ` Pedro Alves
@ 2007-03-30 11:56               ` Pierre Muller
  2007-03-30 12:23                 ` pedro alves
  0 siblings, 1 reply; 19+ messages in thread
From: Pierre Muller @ 2007-03-30 11:56 UTC (permalink / raw)
  To: 'Pedro Alves', 'Eli Zaretskii', gdb-patches

 I get an error when I try to compile
gdbserver on cygwin.

gcc -Wall -g -O2    -I. -I../../../src/gdb/gdbserver
-I../../../src/gdb/gdbserve
r/../regformats -I../../../src/gdb/gdbserver/../../include -I../../bfd
-I../../.
./src/gdb/gdbserver/../../bfd   -o gdbserver.exe inferiors.o regcache.o
remote-u
tils.o server.o signals.o target.o utils.o version.o mem-break.o  reg-i386.o
win
32-low.o win32-i386-low.o  \

win32-i386-low.o: In function `do_fetch_inferior_registers':
/usr/local/src/cvs/build/gdb/gdbserver/../../../src/gdb/gdbserver/win32-i386
-low
.c:63: undefined reference to `_regptr'
collect2: ld returned 1 exit status
make[3]: *** [gdbserver.exe] Error 1

It seems like you forgot to 
commit some change in win32-low.c
because
at  /usr/local/src/cvs/src/gdb/gdbserver
$ grep regptr *
ChangeLog:      (regptr): New.
ChangeLog:      (do_child_store_inferior_registers): Use regptr.
win32-arm-low.c:  char *context_offset = regptr (&th->context, r);
win32-i386-low.c:  char *context_offset = regptr (&th->context, r);
win32-i386-low.c:   register in it's CONTEXT structure.  In this case regptr
wil
l return
win32-low.h:     register in it's CONTEXT structure.  In this case regptr
will r
eturn
win32-low.h:extern char * regptr (CONTEXT* c, int r);


So I suppose that you have a local modification of win32-low.c
that implements regptr function,
unless I am missing something else.

Could you please try to fix that problem?

Thanks in advance,


Pierre Muller
Chargé de recherches
Institut Charles Sadron
6, rue Boussingault
F 67083 Strasbourg Cedex
Tél. : +(33)3-88-41-40-07






^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [New WinCE support] [patch 4/4] The bulk of the code.
  2007-03-30 11:56               ` Pierre Muller
@ 2007-03-30 12:23                 ` pedro alves
  2007-03-30 20:35                   ` pedro alves
  0 siblings, 1 reply; 19+ messages in thread
From: pedro alves @ 2007-03-30 12:23 UTC (permalink / raw)
  To: Pierre Muller; +Cc: Eli Zaretskii, gdb-patches

On 3/30/07, Pierre Muller <muller@ics.u-strasbg.fr> wrote:
>  I get an error when I try to compile
> gdbserver on cygwin.
>
> gcc -Wall -g -O2    -I. -I../../../src/gdb/gdbserver
> -I../../../src/gdb/gdbserve
> r/../regformats -I../../../src/gdb/gdbserver/../../include -I../../bfd
> -I../../.
> ./src/gdb/gdbserver/../../bfd   -o gdbserver.exe inferiors.o regcache.o
> remote-u
> tils.o server.o signals.o target.o utils.o version.o mem-break.o  reg-i386.o
> win
> 32-low.o win32-i386-low.o  \
>
> win32-i386-low.o: In function `do_fetch_inferior_registers':
> /usr/local/src/cvs/build/gdb/gdbserver/../../../src/gdb/gdbserver/win32-i386
> -low
> .c:63: undefined reference to `_regptr'
> collect2: ld returned 1 exit status
> make[3]: *** [gdbserver.exe] Error 1
>
> It seems like you forgot to
> commit some change in win32-low.c
> because

I guess you are right.  Looking at CVSweb I see that I didn't commit the changes
to win32-low.c.  I will only have access to cvs later when I get home
(no less than
8 hours), and I'll fix it then, unless someone takes that hunk from the patch,
and commits it before me.

Sorry for all the breakage...

Cheers,
Pedro Alves


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [New WinCE support] [patch 4/4] The bulk of the code.
  2007-03-30 12:23                 ` pedro alves
@ 2007-03-30 20:35                   ` pedro alves
  0 siblings, 0 replies; 19+ messages in thread
From: pedro alves @ 2007-03-30 20:35 UTC (permalink / raw)
  To: Pierre Muller; +Cc: gdb-patches

Pedro Alves wrote:
>
> I guess you are right.  Looking at CVSweb I see that I didn't commit
> the changes
> to win32-low.c.  I will only have access to cvs later when I get home
> (no less than 8 hours), and I'll fix it then, unless someone takes
> that hunk from the patch,
> and commits it before me.

Well, at least I got the timings right :)

Just committed the missing changes, with the following log
entry, so people checking out by date based on the ChangeLog
dates don't get (too) surprised.

2007-03-30  Pedro Alves  <pedro_alves@portugalmail.pt>

       * win32-low.c: Commit leftover changes from 2007-03-29.

Sorry again.

Cheers,
Pedro Alves


^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2007-03-30 20:35 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20070315235008.243411000@portugalmail.pt>
2007-03-16  2:07 ` [New WinCE support] [patch 1/4] : mv win32-i386-low.c win32-low.c Pedro Alves
2007-03-27 19:11   ` Daniel Jacobowitz
2007-03-16  2:09 ` [New WinCE support] [patch 3/4] : bfd config Pedro Alves
2007-03-16  2:09 ` [New WinCE support] [patch 2/4] : s/thread_info/win32_thread_info/g Pedro Alves
2007-03-27 19:12   ` Daniel Jacobowitz
2007-03-16  2:10 ` [New WinCE support] [patch 4/4] The bulk of the code Pedro Alves
2007-03-16 12:52   ` Eli Zaretskii
2007-03-16 15:03     ` pedro alves
2007-03-17 11:18       ` Eli Zaretskii
2007-03-17 11:35         ` Andreas Schwab
2007-03-19  1:53         ` Pedro Alves
2007-03-19  4:21           ` Eli Zaretskii
2007-03-19 12:34             ` Daniel Jacobowitz
2007-03-27 19:20           ` Daniel Jacobowitz
2007-03-29  3:18             ` Pedro Alves
2007-03-29  3:51             ` Pedro Alves
2007-03-30 11:56               ` Pierre Muller
2007-03-30 12:23                 ` pedro alves
2007-03-30 20:35                   ` pedro alves

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox