From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29581 invoked by alias); 17 Apr 2010 23:18:12 -0000 Received: (qmail 29565 invoked by uid 22791); 17 Apr 2010 23:18:07 -0000 X-SWARE-Spam-Status: No, hits=-1.7 required=5.0 tests=BAYES_00,MSGID_MULTIPLE_AT,TW_AV,TW_EG,TW_GP X-Spam-Check-By: sourceware.org Received: from mailhost.u-strasbg.fr (HELO mailhost.u-strasbg.fr) (130.79.200.152) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 17 Apr 2010 23:17:58 +0000 Received: from baal.u-strasbg.fr (baal.u-strasbg.fr [IPv6:2001:660:2402::41]) by mailhost.u-strasbg.fr (8.14.3/jtpda-5.5pre1) with ESMTP id o3HNHnoh035879 ; Sun, 18 Apr 2010 01:17:49 +0200 (CEST) (envelope-from pierre.muller@ics-cnrs.unistra.fr) Received: from mailserver.u-strasbg.fr (ms3.u-strasbg.fr [IPv6:2001:660:2402:d::12]) by baal.u-strasbg.fr (8.14.0/jtpda-5.5pre1) with ESMTP id o3HNHnmc022630 ; Sun, 18 Apr 2010 01:17:49 +0200 (CEST) (envelope-from pierre.muller@ics-cnrs.unistra.fr) Received: from d620muller (lec67-4-82-230-53-140.fbx.proxad.net [82.230.53.140]) (user=mullerp mech=LOGIN) by mailserver.u-strasbg.fr (8.14.3/jtpda-5.5pre1) with ESMTP id o3HNHlJb000407 (version=TLSv1/SSLv3 cipher=RC4-MD5 bits=128 verify=NO) ; Sun, 18 Apr 2010 01:17:47 +0200 (CEST) (envelope-from pierre.muller@ics-cnrs.unistra.fr) From: "Pierre Muller" To: "'Pedro Alves'" Cc: References: <000d01cadd79$efa9e2b0$cefda810$@muller@ics-cnrs.unistra.fr> <201004161659.37990.pedro@codesourcery.com> <001f01caddf0$6d4246b0$47c6d410$@muller@ics-cnrs.unistra.fr> <201004171158.08327.pedro@codesourcery.com> In-Reply-To: <201004171158.08327.pedro@codesourcery.com> Subject: [RFC-v2] Mingw Windows 64-bit gdbserver Date: Sat, 17 Apr 2010 23:18:00 -0000 Message-ID: <003701cade84$38fbdd00$aaf39700$@muller@ics-cnrs.unistra.fr> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2010-04/txt/msg00537.txt.bz2 > -----Message d'origine----- > De=A0: gdb-patches-owner@sourceware.org [mailto:gdb-patches- > owner@sourceware.org] De la part de Pedro Alves > Envoy=E9=A0: Saturday, April 17, 2010 12:58 PM > =C0=A0: Pierre Muller > Cc=A0: gdb-patches@sourceware.org > Objet=A0: Re: [RFC] Mingw Windows 64-bit gdbserver >=20 > On Saturday 17 April 2010 06:40:02, Pierre Muller wrote: >=20 > > > How about instead merging the files, like > > > linux-x86-low.c handles both 64-bit and 32-bit? There's > > > a lot of common stuff between both archs support, it > > > seems. > > > > Of course, I agree with you that the two files > > share a very large common portion that is identical. > > There are only two places where they really differ: > > For the call to the init_registers_XXX > > and for the register mappings array. > > > > The main question is how should we split these parts > > off if we want to keep a common part: > > > > I would propose this: > > rename win32-i386-low.c to win-x86-low.c >=20 > Lets avoid someone reading this and getting religious > against "win", and go with windows-*-low.c, just > like gdb/windows-nat.c was renamed from win32-nat.c, and > gdb has i386-windows-nat.c and amd64-windows-nat.c. >=20 > > Create win32-i386-low.h and win64-amd64-low.h > > that would have the register mappings and > > a macro to define their local init_registers. >=20 > Yes, much better, if nothing else because that's how > gdb handles this as well. It's always good to have the > code bases solve the same problem in the same way, so > that we can more easily keep them in sync or merge them. >=20 > Take a look at gdb/amd64-windows-nat.c, it also does something > similar to handle the common stuff, though since we have > a win32_target_ops in gdbserver, we can put the register mappings > array pointer directly in win32_target_ops instead of making it > a global. >=20 > Let's avoid macros. Use for example the `arch_setup' callback > in the win32_target_ops vector for this, keeping the arrays > defined in the corresponding arch specific .c files. Here is a new version of the patch: I tried to minimize code duplication, but I still needed one macro to decide which file from win32-i386-low.c or win64-amd64-low.c=20 should be read. The macro is named COMPILE_WIN64 and set by configuration in config.h header. I also change the regular expression used for target matching to 'x86_64-*-mingw*' as is done in gdb directory. mappings is now a pointer, that is set to=20 windows_i386_mappings or windows_amd64_mappings. This should minimize problems if we later want to support debugging windows 32-bit programs with a 64-bit gdbserver. The ChangeLog is a bit messy because I renamed a file and reused the old name to create a new file... but I didn't find another name that would fit better... Unless I use windows- as a prefix everywhere... =20 Pierre 2010-04-18 Pierre Muller * configure.tgt (x86_64-*-mingw*): Mark building of gdbserver for this target. =09 gdbserver ChangeLog entry: 2010-04-18 Pierre Muller * configure.ac (COMPILE_WIN64): New macro for config.h defined if srv_mingw64 is set to `yes'. * config.in: Regenerate. * configure: Regenerate. * configure.srv: Adapt to win32-i386-low.c to windows-x86-low.c rename. (x86_64-*-mingw*): New server target. * win32-i386-low.c: Rename to ... * windows-x86-low.c: New file name, reads in `win32-i386-low.c' or `win64-amdd64-low.c'. (mappings): New static variable. (the_low_target): Change arch_setup field to init_windows_x86. * win32-i386-low.c: New file. (init_registers_i386): Declare external. (windows_i386_mappings): Array moved from old win32-i386-low.c. (init_windows_x86): New function. * win64-amd64-low.c: New file. (init_registers_amd64): Declare external. (windows_amd64_mappings): New array. (init_windows_x86): New function. * win32-low.c: Adapt to support also 64-bit architecture. (child_xfer_memory): Use uintptr_t type for local variable `addr'. (get_image_name): Use SIZE_T type for local variable `done'. (psapi_get_dll_name): Use uintptr_t type for parameter `BaseAddress'. (toolhelp_get_dll_name): Idem. (handle_load_dll): Use uintptr_t type for local variable `load_addr'. (handle_unload_dll): Use unitptr_t typecast to avoid warning. (handle_exception): Use phex_nz to avoid warning. (win32_wait): Remove unused local variable `process'. Index: configure.tgt =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvs/src/src/gdb/configure.tgt,v retrieving revision 1.230 diff -u -p -r1.230 configure.tgt --- configure.tgt 25 Feb 2010 20:30:58 -0000 1.230 +++ configure.tgt 17 Apr 2010 22:08:33 -0000 @@ -590,6 +590,7 @@ x86_64-*-mingw*) gdb_target_obs=3D"amd64-tdep.o amd64-windows-tdep.o \ i386-tdep.o i386-cygwin-tdep.o i387-tdep.o \ solib-target.o windows-tdep.o" + build_gdbserver=3Dyes ;; x86_64-*-netbsd* | x86_64-*-knetbsd*-gnu) # Target: NetBSD/amd64 Index: gdbserver/config.in =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvs/src/src/gdb/gdbserver/config.in,v retrieving revision 1.26 diff -u -p -r1.26 config.in --- gdbserver/config.in 21 Dec 2009 20:52:53 -0000 1.26 +++ gdbserver/config.in 17 Apr 2010 22:08:33 -0000 @@ -1,5 +1,8 @@ /* config.in. Generated from configure.ac by autoheader. */ =20 +/* Define if we compile a Windows-64 bit program. */ +#undef COMPILE_WIN64 + /* Define to 1 if you have the header file. */ #undef HAVE_ARPA_INET_H =20 @@ -33,6 +36,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H =20 +/* Define to 1 if you have the `dl' library (-ldl). */ +#undef HAVE_LIBDL + /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_ELF_H =20 Index: gdbserver/configure =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvs/src/src/gdb/gdbserver/configure,v retrieving revision 1.48 diff -u -p -r1.48 configure --- gdbserver/configure 17 Apr 2010 20:43:13 -0000 1.48 +++ gdbserver/configure 17 Apr 2010 22:08:35 -0000 @@ -4067,6 +4067,12 @@ $as_echo "#define USE_WIN32API 1" >>conf =20 fi =20 +if test "${srv_mingw64}" =3D "yes"; then + +$as_echo "#define COMPILE_WIN64 1" >>confdefs.h + +fi + if test "${srv_linux_usrregs}" =3D "yes"; then =20 $as_echo "#define HAVE_LINUX_USRREGS 1" >>confdefs.h Index: gdbserver/configure.ac =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvs/src/src/gdb/gdbserver/configure.ac,v retrieving revision 1.34 diff -u -p -r1.34 configure.ac --- gdbserver/configure.ac 17 Apr 2010 20:43:13 -0000 1.34 +++ gdbserver/configure.ac 17 Apr 2010 22:08:35 -0000 @@ -131,6 +131,11 @@ if test "${srv_mingw}" =3D "yes"; then for Cygwin.]) fi =20 +if test "${srv_mingw64}" =3D "yes"; then + AC_DEFINE(COMPILE_WIN64, 1, + [Define if we compile a Windows-64 bit program.]) +fi + if test "${srv_linux_usrregs}" =3D "yes"; then AC_DEFINE(HAVE_LINUX_USRREGS, 1, [Define if the target supports PTRACE_PEEKUSR for register ] Index: gdbserver/configure.srv =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvs/src/src/gdb/gdbserver/configure.srv,v retrieving revision 1.53 diff -u -p -r1.53 configure.srv --- gdbserver/configure.srv 8 Apr 2010 22:32:38 -0000 1.53 +++ gdbserver/configure.srv 17 Apr 2010 22:08:35 -0000 @@ -24,7 +24,7 @@ srv_hostio_err_objs=3D"hostio-errno.o" =20 srv_i386_regobj=3D"i386.o i386-avx.o i386-mmx.o" srv_i386_linux_regobj=3D"i386-linux.o i386-avx-linux.o i386-mmx-linux.o" -srv_amd64_regobj=3D"amd64.o x86-64-avx.o" +srv_amd64_regobj=3D"amd64.o amd64-avx.o" srv_amd64_linux_regobj=3D"amd64-linux.o amd64-avx-linux.o" =20 srv_i386_32bit_xmlfiles=3D"i386/32bit-core.xml i386/32bit-sse.xml i386/32bit-avx.xml" @@ -73,7 +73,7 @@ case "${target}" in srv_linux_thread_db=3Dyes ;; i[34567]86-*-cygwin*) srv_regobj=3D"$srv_i386_regobj" - srv_tgtobj=3D"i386-low.o win32-low.o win32-i386-low.o" + srv_tgtobj=3D"i386-low.o win32-low.o windows-x86-low.o" srv_xmlfiles=3D"$srv_i386_xmlfiles" ;; i[34567]86-*-linux*) srv_regobj=3D"$srv_i386_linux_regobj" @@ -89,7 +89,7 @@ case "${target}" in ;; i[34567]86-*-mingw32ce*) srv_regobj=3D"$srv_i386_regobj" - srv_tgtobj=3D"i386-low.o win32-low.o win32-i386-low.o" + srv_tgtobj=3D"i386-low.o win32-low.o windows-x86-low.o" srv_tgtobj=3D"${srv_tgtobj} wincecompat.o" srv_xmlfiles=3D"$srv_i386_xmlfiles" # hostio_last_error implementation is in win32-low.c @@ -98,7 +98,7 @@ case "${target}" in srv_mingwce=3Dyes ;; i[34567]86-*-mingw*) srv_regobj=3D"$srv_i386_regobj" - srv_tgtobj=3D"i386-low.o win32-low.o win32-i386-low.o" + srv_tgtobj=3D"i386-low.o win32-low.o windows-x86-low.o" srv_xmlfiles=3D"$srv_i386_xmlfiles" srv_mingw=3Dyes ;; @@ -231,6 +231,13 @@ case "${target}" in srv_linux_regsets=3Dyes srv_linux_thread_db=3Dyes ;; + x86_64-*-mingw*) srv_regobj=3D"$srv_amd64_regobj" + srv_tgtobj=3D"i386-low.o win32-low.o windows-x86-low.o" + srv_xmlfiles=3D"$srv_amd64_xmlfiles" + srv_mingw64=3Dyes + srv_mingw=3Dyes + ;; + xscale*-*-linux*) srv_regobj=3Dreg-arm.o srv_tgtobj=3D"linux-low.o linux-arm-low.o" srv_linux_usrregs=3Dyes Index: gdbserver/win32-i386-low.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvs/src/src/gdb/gdbserver/win32-i386-low.c,v retrieving revision 1.18 diff -u -p -r1.18 win32-i386-low.c --- gdbserver/win32-i386-low.c 20 Jan 2010 22:55:38 -0000 1.18 +++ gdbserver/win32-i386-low.c 17 Apr 2010 22:08:35 -0000 @@ -15,205 +15,9 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ =20 -#include "server.h" -#include "win32-low.h" -#include "i386-low.h" - -#define FCS_REGNUM 27 -#define FOP_REGNUM 31 - -#define FLAG_TRACE_BIT 0x100 - /* Defined in auto-generated file reg-i386.c. */ void init_registers_i386 (void); =20 -static struct i386_debug_reg_state debug_reg_state; - -static int debug_registers_changed =3D 0; -static int debug_registers_used =3D 0; - -/* Update the inferior's debug register REGNUM from STATE. */ - -void -i386_dr_low_set_addr (const struct i386_debug_reg_state *state, int regnum) -{ - if (! (regnum >=3D 0 && regnum <=3D DR_LASTADDR - DR_FIRSTADDR)) - fatal ("Invalid debug register %d", regnum); - - /* debug_reg_state.dr_mirror is already set. - Just notify i386_set_thread_context, i386_thread_added - that the registers need to be updated. */ - debug_registers_changed =3D 1; - debug_registers_used =3D 1; -} - -/* Update the inferior's DR7 debug control register from STATE. */ - -void -i386_dr_low_set_control (const struct i386_debug_reg_state *state) -{ - /* debug_reg_state.dr_control_mirror is already set. - Just notify i386_set_thread_context, i386_thread_added - that the registers need to be updated. */ - debug_registers_changed =3D 1; - debug_registers_used =3D 1; -} - -/* Get the value of the DR6 debug status register from the inferior - and record it in STATE. */ - -void -i386_dr_low_get_status (struct i386_debug_reg_state *state) -{ - /* We don't need to do anything here, the last call to thread_rec for - current_event.dwThreadId id has already set it. */ -} - -/* Watchpoint support. */ - -static int -i386_insert_point (char type, CORE_ADDR addr, int len) -{ - switch (type) - { - case '2': - case '3': - case '4': - return i386_low_insert_watchpoint (&debug_reg_state, - type, addr, len); - default: - /* Unsupported. */ - return 1; - } -} - -static int -i386_remove_point (char type, CORE_ADDR addr, int len) -{ - switch (type) - { - case '2': - case '3': - case '4': - return i386_low_remove_watchpoint (&debug_reg_state, - type, addr, len); - default: - /* Unsupported. */ - return 1; - } -} - -static int -i386_stopped_by_watchpoint (void) -{ - return i386_low_stopped_by_watchpoint (&debug_reg_state); -} - -static CORE_ADDR -i386_stopped_data_address (void) -{ - CORE_ADDR addr; - if (i386_low_stopped_data_address (&debug_reg_state, &addr)) - return addr; - return 0; -} - -static void -i386_initial_stuff (void) -{ - i386_low_init_dregs (&debug_reg_state); - debug_registers_changed =3D 0; - debug_registers_used =3D 0; -} - -static void -i386_get_thread_context (win32_thread_info *th, DEBUG_EVENT* current_event) -{ - /* Requesting the CONTEXT_EXTENDED_REGISTERS register set fails if - the system doesn't support extended registers. */ - static DWORD extended_registers =3D CONTEXT_EXTENDED_REGISTERS; - - again: - th->context.ContextFlags =3D (CONTEXT_FULL - | CONTEXT_FLOATING_POINT - | CONTEXT_DEBUG_REGISTERS - | extended_registers); - - if (!GetThreadContext (th->h, &th->context)) - { - DWORD e =3D GetLastError (); - - if (extended_registers && e =3D=3D ERROR_INVALID_PARAMETER) - { - extended_registers =3D 0; - goto again; - } - - error ("GetThreadContext failure %ld\n", (long) e); - } - - debug_registers_changed =3D 0; - - if (th->tid =3D=3D current_event->dwThreadId) - { - /* Copy dr values from the current thread. */ - struct i386_debug_reg_state *dr =3D &debug_reg_state; - dr->dr_mirror[0] =3D th->context.Dr0; - dr->dr_mirror[1] =3D th->context.Dr1; - dr->dr_mirror[2] =3D th->context.Dr2; - dr->dr_mirror[3] =3D th->context.Dr3; - dr->dr_status_mirror =3D th->context.Dr6; - dr->dr_control_mirror =3D th->context.Dr7; - } -} - -static void -i386_set_thread_context (win32_thread_info *th, DEBUG_EVENT* current_event) -{ - if (debug_registers_changed) - { - struct i386_debug_reg_state *dr =3D &debug_reg_state; - th->context.Dr0 =3D dr->dr_mirror[0]; - th->context.Dr1 =3D dr->dr_mirror[1]; - th->context.Dr2 =3D dr->dr_mirror[2]; - th->context.Dr3 =3D dr->dr_mirror[3]; - /* th->context.Dr6 =3D dr->dr_status_mirror; - FIXME: should we set dr6 also ?? */ - th->context.Dr7 =3D dr->dr_control_mirror; - } - - SetThreadContext (th->h, &th->context); -} - -static void -i386_thread_added (win32_thread_info *th) -{ - /* Set the debug registers for the new thread if they are used. */ - if (debug_registers_used) - { - struct i386_debug_reg_state *dr =3D &debug_reg_state; - th->context.ContextFlags =3D CONTEXT_DEBUG_REGISTERS; - GetThreadContext (th->h, &th->context); - - th->context.Dr0 =3D dr->dr_mirror[0]; - th->context.Dr1 =3D dr->dr_mirror[1]; - th->context.Dr2 =3D dr->dr_mirror[2]; - th->context.Dr3 =3D dr->dr_mirror[3]; - /* th->context.Dr6 =3D dr->dr_status_mirror; - FIXME: should we set dr6 also ?? */ - th->context.Dr7 =3D dr->dr_control_mirror; - - SetThreadContext (th->h, &th->context); - th->context.ContextFlags =3D 0; - } -} - -static void -i386_single_step (win32_thread_info *th) -{ - th->context.EFlags |=3D 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 @@ -222,7 +26,7 @@ i386_single_step (win32_thread_info *th) 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[] =3D { +static const int windows_i386_mappings[] =3D { context_offset (Eax), context_offset (Ecx), context_offset (Edx), @@ -269,54 +73,13 @@ static const int mappings[] =3D { }; #undef context_offset =20 -/* Fetch register from gdbserver regcache data. */ -static void -i386_fetch_inferior_register (struct regcache *regcache, - win32_thread_info *th, int r) -{ - char *context_offset =3D (char *) &th->context + mappings[r]; - - long l; - if (r =3D=3D FCS_REGNUM) - { - l =3D *((long *) context_offset) & 0xffff; - supply_register (regcache, r, (char *) &l); - } - else if (r =3D=3D FOP_REGNUM) - { - l =3D (*((long *) context_offset) >> 16) & ((1 << 11) - 1); - supply_register (regcache, r, (char *) &l); - } - else - supply_register (regcache, r, context_offset); -} - -/* Store a new register value into the thread context of TH. */ static void -i386_store_inferior_register (struct regcache *regcache, - win32_thread_info *th, int r) +init_windows_x86 () { - char *context_offset =3D (char *) &th->context + mappings[r]; - collect_register (regcache, r, context_offset); + init_registers_i386 (); + mappings =3D windows_i386_mappings; + the_low_target.num_regs =3D sizeof (windows_i386_mappings) + / sizeof (windows_i386_mappings[0]); } =20 -static const unsigned char i386_win32_breakpoint =3D 0xcc; -#define i386_win32_breakpoint_len 1 =20 -struct win32_target_ops the_low_target =3D { - init_registers_i386, - sizeof (mappings) / sizeof (mappings[0]), - i386_initial_stuff, - i386_get_thread_context, - i386_set_thread_context, - i386_thread_added, - i386_fetch_inferior_register, - i386_store_inferior_register, - i386_single_step, - &i386_win32_breakpoint, - i386_win32_breakpoint_len, - i386_insert_point, - i386_remove_point, - i386_stopped_by_watchpoint, - i386_stopped_data_address -}; Index: gdbserver/win32-low.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvs/src/src/gdb/gdbserver/win32-low.c,v retrieving revision 1.46 diff -u -p -r1.46 win32-low.c --- gdbserver/win32-low.c 16 Apr 2010 07:49:37 -0000 1.46 +++ gdbserver/win32-low.c 17 Apr 2010 22:08:36 -0000 @@ -280,7 +280,7 @@ child_xfer_memory (CORE_ADDR memaddr, ch int write, struct target_ops *target) { SIZE_T done; - long addr =3D (long) memaddr; + uintptr_t addr =3D (uintptr_t) memaddr; =20 if (write) { @@ -941,7 +941,7 @@ get_image_name (HANDLE h, void *address, char *address_ptr; int len =3D 0; char b[2]; - DWORD done; + SIZE_T done; =20 /* Attempt to read the name of the dll that was detected. This is documented to work only when actively debugging @@ -1019,7 +1019,7 @@ load_psapi (void) } =20 static int -psapi_get_dll_name (DWORD BaseAddress, char *dll_name_ret) +psapi_get_dll_name (uintptr_t BaseAddress, char *dll_name_ret) { DWORD len; MODULEINFO mi; @@ -1064,7 +1064,7 @@ psapi_get_dll_name (DWORD BaseAddress, c (int) err, strwinerror (err)); } =20 - if ((DWORD) (mi.lpBaseOfDll) =3D=3D BaseAddress) + if ((uintptr_t) (mi.lpBaseOfDll) =3D=3D BaseAddress) { len =3D (*win32_GetModuleFileNameExA) (current_process_handle, DllHandle[i], @@ -1134,7 +1134,7 @@ load_toolhelp (void) } =20 static int -toolhelp_get_dll_name (DWORD BaseAddress, char *dll_name_ret) +toolhelp_get_dll_name (uintptr_t BaseAddress, char *dll_name_ret) { HANDLE snapshot_module; MODULEENTRY32 modEntry =3D { sizeof (MODULEENTRY32) }; @@ -1151,7 +1151,7 @@ toolhelp_get_dll_name (DWORD BaseAddress /* Ignore the first module, which is the exe. */ if (win32_Module32First (snapshot_module, &modEntry)) while (win32_Module32Next (snapshot_module, &modEntry)) - if ((DWORD) modEntry.modBaseAddr =3D=3D BaseAddress) + if ((uintptr_t) modEntry.modBaseAddr =3D=3D BaseAddress) { #ifdef UNICODE wcstombs (dll_name_ret, modEntry.szExePath, MAX_PATH + 1); @@ -1176,21 +1176,21 @@ handle_load_dll (void) LOAD_DLL_DEBUG_INFO *event =3D ¤t_event.u.LoadDll; char dll_buf[MAX_PATH + 1]; char *dll_name =3D NULL; - DWORD load_addr; + uintptr_t load_addr; =20 dll_buf[0] =3D dll_buf[sizeof (dll_buf) - 1] =3D '\0'; =20 /* Windows does not report the image name of the dlls in the debug event on attaches. We resort to iterating over the list of loaded dlls looking for a match by image base. */ - if (!psapi_get_dll_name ((DWORD) event->lpBaseOfDll, dll_buf)) + if (!psapi_get_dll_name ((uintptr_t) event->lpBaseOfDll, dll_buf)) { if (!server_waiting) /* On some versions of Windows and Windows CE, we can't create toolhelp snapshots while the inferior is stopped in a LOAD_DLL_DEBUG_EVENT due to a dll load, but we can while Windows is reporting the already loaded dlls. */ - toolhelp_get_dll_name ((DWORD) event->lpBaseOfDll, dll_buf); + toolhelp_get_dll_name ((uintptr_t) event->lpBaseOfDll, dll_buf); } =20 dll_name =3D dll_buf; @@ -1205,7 +1205,7 @@ handle_load_dll (void) the offset from 0 of the first byte in an image - because of the file header and the section alignment. */ =20 - load_addr =3D (DWORD) event->lpBaseOfDll + 0x1000; + load_addr =3D (uintptr_t) event->lpBaseOfDll + 0x1000; win32_add_one_solib (dll_name, load_addr); } =20 @@ -1213,7 +1213,7 @@ static void handle_unload_dll (void) { CORE_ADDR load_addr =3D - (CORE_ADDR) (DWORD) current_event.u.UnloadDll.lpBaseOfDll; + (CORE_ADDR) (uintptr_t) current_event.u.UnloadDll.lpBaseOfDll; load_addr +=3D 0x1000; unloaded_dll (NULL, load_addr); } @@ -1314,10 +1314,10 @@ handle_exception (struct target_waitstat ourstatus->kind =3D TARGET_WAITKIND_SPURIOUS; return; } - OUTMSG2 (("gdbserver: unknown target exception 0x%08lx at 0x%08lx", + OUTMSG2 (("gdbserver: unknown target exception 0x%08lx at 0x%s", current_event.u.Exception.ExceptionRecord.ExceptionCode, - (DWORD) current_event.u.Exception.ExceptionRecord. - ExceptionAddress)); + phex_nz ((uintptr_t) current_event.u.Exception.ExceptionRecord. + ExceptionAddress, sizeof(uintptr_t)))); ourstatus->value.sig =3D TARGET_SIGNAL_UNKNOWN; break; } @@ -1577,7 +1577,6 @@ get_child_debug_event (struct target_wai static ptid_t win32_wait (ptid_t ptid, struct target_waitstatus *ourstatus, int options) { - struct process_info *process; struct regcache *regcache; =20 while (1) Index: gdbserver/win64-amd64-low.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: gdbserver/win64-amd64-low.c diff -N gdbserver/win64-amd64-low.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gdbserver/win64-amd64-low.c 17 Apr 2010 22:08:36 -0000 @@ -0,0 +1,98 @@ +/* Copyright (C) 2007, 2008, 2009, 2010 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 3 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, see . */ + +/* Defined in auto-generated file reg-amd64.c. */ +void init_registers_amd64 (void); + +#ifndef CONTEXT_EXTENDED_REGISTERS +#define CONTEXT_EXTENDED_REGISTERS 0 +#endif + +#define context_offset(x) (offsetof (CONTEXT, x)) +static const int windows_amd64_mappings[] =3D +{ + context_offset (Rax), + context_offset (Rbx), + context_offset (Rcx), + context_offset (Rdx), + context_offset (Rsi), + context_offset (Rdi), + context_offset (Rbp), + context_offset (Rsp), + context_offset (R8), + context_offset (R9), + context_offset (R10), + context_offset (R11), + context_offset (R12), + context_offset (R13), + context_offset (R14), + context_offset (R15), + context_offset (Rip), + context_offset (EFlags), + context_offset (SegCs), + context_offset (SegSs), + context_offset (SegDs), + context_offset (SegEs), + context_offset (SegFs), + context_offset (SegGs), + context_offset (FloatSave.FloatRegisters[0]), + context_offset (FloatSave.FloatRegisters[1]), + context_offset (FloatSave.FloatRegisters[2]), + context_offset (FloatSave.FloatRegisters[3]), + context_offset (FloatSave.FloatRegisters[4]), + context_offset (FloatSave.FloatRegisters[5]), + context_offset (FloatSave.FloatRegisters[6]), + context_offset (FloatSave.FloatRegisters[7]), + 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 (Xmm0), + context_offset (Xmm1), + context_offset (Xmm2), + context_offset (Xmm3), + context_offset (Xmm4), + context_offset (Xmm5), + context_offset (Xmm6), + context_offset (Xmm7), + context_offset (Xmm8), + context_offset (Xmm9), + context_offset (Xmm10), + context_offset (Xmm11), + context_offset (Xmm12), + context_offset (Xmm13), + context_offset (Xmm14), + context_offset (Xmm15), + /* MXCSR */ + context_offset (FloatSave.MxCsr) +}; +#undef context_offset + +static void +init_windows_x86 () +{ + init_registers_amd64 (); + mappings =3D windows_amd64_mappings; + the_low_target.num_regs =3D sizeof (windows_amd64_mappings) + / sizeof (windows_amd64_mappings[0]); +} + Index: gdbserver/windows-x86-low.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: gdbserver/windows-x86-low.c diff -N gdbserver/windows-x86-low.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gdbserver/windows-x86-low.c 17 Apr 2010 22:08:36 -0000 @@ -0,0 +1,272 @@ +/* Copyright (C) 2007, 2008, 2009, 2010 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 3 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, see . */ + +#include "server.h" +#include "win32-low.h" +#include "i386-low.h" + +static const int *mappings; + +#ifdef COMPILE_WIN64 +#include "win64-amd64-low.c" +#else +#include "win32-i386-low.c" +#endif + +#define FCS_REGNUM 27 +#define FOP_REGNUM 31 + +#define FLAG_TRACE_BIT 0x100 + +static struct i386_debug_reg_state debug_reg_state; + +static int debug_registers_changed =3D 0; +static int debug_registers_used =3D 0; + +/* Update the inferior's debug register REGNUM from STATE. */ + +void +i386_dr_low_set_addr (const struct i386_debug_reg_state *state, int regnum) +{ + if (! (regnum >=3D 0 && regnum <=3D DR_LASTADDR - DR_FIRSTADDR)) + fatal ("Invalid debug register %d", regnum); + + /* debug_reg_state.dr_mirror is already set. + Just notify i386_set_thread_context, i386_thread_added + that the registers need to be updated. */ + debug_registers_changed =3D 1; + debug_registers_used =3D 1; +} + +/* Update the inferior's DR7 debug control register from STATE. */ + +void +i386_dr_low_set_control (const struct i386_debug_reg_state *state) +{ + /* debug_reg_state.dr_control_mirror is already set. + Just notify i386_set_thread_context, i386_thread_added + that the registers need to be updated. */ + debug_registers_changed =3D 1; + debug_registers_used =3D 1; +} + +/* Get the value of the DR6 debug status register from the inferior + and record it in STATE. */ + +void +i386_dr_low_get_status (struct i386_debug_reg_state *state) +{ + /* We don't need to do anything here, the last call to thread_rec for + current_event.dwThreadId id has already set it. */ +} + +/* Watchpoint support. */ + +static int +i386_insert_point (char type, CORE_ADDR addr, int len) +{ + switch (type) + { + case '2': + case '3': + case '4': + return i386_low_insert_watchpoint (&debug_reg_state, + type, addr, len); + default: + /* Unsupported. */ + return 1; + } +} + +static int +i386_remove_point (char type, CORE_ADDR addr, int len) +{ + switch (type) + { + case '2': + case '3': + case '4': + return i386_low_remove_watchpoint (&debug_reg_state, + type, addr, len); + default: + /* Unsupported. */ + return 1; + } +} + +static int +i386_stopped_by_watchpoint (void) +{ + return i386_low_stopped_by_watchpoint (&debug_reg_state); +} + +static CORE_ADDR +i386_stopped_data_address (void) +{ + CORE_ADDR addr; + if (i386_low_stopped_data_address (&debug_reg_state, &addr)) + return addr; + return 0; +} + +static void +i386_initial_stuff (void) +{ + i386_low_init_dregs (&debug_reg_state); + debug_registers_changed =3D 0; + debug_registers_used =3D 0; +} + +static void +i386_get_thread_context (win32_thread_info *th, DEBUG_EVENT* current_event) +{ + /* Requesting the CONTEXT_EXTENDED_REGISTERS register set fails if + the system doesn't support extended registers. */ + static DWORD extended_registers =3D CONTEXT_EXTENDED_REGISTERS; + + again: + th->context.ContextFlags =3D (CONTEXT_FULL + | CONTEXT_FLOATING_POINT + | CONTEXT_DEBUG_REGISTERS + | extended_registers); + + if (!GetThreadContext (th->h, &th->context)) + { + DWORD e =3D GetLastError (); + + if (extended_registers && e =3D=3D ERROR_INVALID_PARAMETER) + { + extended_registers =3D 0; + goto again; + } + + error ("GetThreadContext failure %ld\n", (long) e); + } + + debug_registers_changed =3D 0; + + if (th->tid =3D=3D current_event->dwThreadId) + { + /* Copy dr values from the current thread. */ + struct i386_debug_reg_state *dr =3D &debug_reg_state; + dr->dr_mirror[0] =3D th->context.Dr0; + dr->dr_mirror[1] =3D th->context.Dr1; + dr->dr_mirror[2] =3D th->context.Dr2; + dr->dr_mirror[3] =3D th->context.Dr3; + dr->dr_status_mirror =3D th->context.Dr6; + dr->dr_control_mirror =3D th->context.Dr7; + } +} + +static void +i386_set_thread_context (win32_thread_info *th, DEBUG_EVENT* current_event) +{ + if (debug_registers_changed) + { + struct i386_debug_reg_state *dr =3D &debug_reg_state; + th->context.Dr0 =3D dr->dr_mirror[0]; + th->context.Dr1 =3D dr->dr_mirror[1]; + th->context.Dr2 =3D dr->dr_mirror[2]; + th->context.Dr3 =3D dr->dr_mirror[3]; + /* th->context.Dr6 =3D dr->dr_status_mirror; + FIXME: should we set dr6 also ?? */ + th->context.Dr7 =3D dr->dr_control_mirror; + } + + SetThreadContext (th->h, &th->context); +} + +static void +i386_thread_added (win32_thread_info *th) +{ + /* Set the debug registers for the new thread if they are used. */ + if (debug_registers_used) + { + struct i386_debug_reg_state *dr =3D &debug_reg_state; + th->context.ContextFlags =3D CONTEXT_DEBUG_REGISTERS; + GetThreadContext (th->h, &th->context); + + th->context.Dr0 =3D dr->dr_mirror[0]; + th->context.Dr1 =3D dr->dr_mirror[1]; + th->context.Dr2 =3D dr->dr_mirror[2]; + th->context.Dr3 =3D dr->dr_mirror[3]; + /* th->context.Dr6 =3D dr->dr_status_mirror; + FIXME: should we set dr6 also ?? */ + th->context.Dr7 =3D dr->dr_control_mirror; + + SetThreadContext (th->h, &th->context); + th->context.ContextFlags =3D 0; + } +} + +static void +i386_single_step (win32_thread_info *th) +{ + th->context.EFlags |=3D FLAG_TRACE_BIT; +} + +/* Fetch register from gdbserver regcache data. */ +static void +i386_fetch_inferior_register (struct regcache *regcache, + win32_thread_info *th, int r) +{ + char *context_offset =3D (char *) &th->context + mappings[r]; + + long l; + if (r =3D=3D FCS_REGNUM) + { + l =3D *((long *) context_offset) & 0xffff; + supply_register (regcache, r, (char *) &l); + } + else if (r =3D=3D FOP_REGNUM) + { + l =3D (*((long *) context_offset) >> 16) & ((1 << 11) - 1); + supply_register (regcache, r, (char *) &l); + } + else + supply_register (regcache, r, context_offset); +} + +/* Store a new register value into the thread context of TH. */ +static void +i386_store_inferior_register (struct regcache *regcache, + win32_thread_info *th, int r) +{ + char *context_offset =3D (char *) &th->context + mappings[r]; + collect_register (regcache, r, context_offset); +} + +static const unsigned char i386_win32_breakpoint =3D 0xcc; +#define i386_win32_breakpoint_len 1 + +struct win32_target_ops the_low_target =3D { + init_windows_x86, + 0, /* Filled in init_windows_x86 function. */=20 + i386_initial_stuff, + i386_get_thread_context, + i386_set_thread_context, + i386_thread_added, + i386_fetch_inferior_register, + i386_store_inferior_register, + i386_single_step, + &i386_win32_breakpoint, + i386_win32_breakpoint_len, + i386_insert_point, + i386_remove_point, + i386_stopped_by_watchpoint, + i386_stopped_data_address +};