From 0694bce61924ece755442f0871d5900728b2e88b Mon Sep 17 00:00:00 2001 From: Steve Chamberlain Date: Thu, 5 Oct 1995 20:57:30 +0000 Subject: Thu Oct 5 13:27:30 1995 steve chamberlain * win32.c: New file; support for debugging on windows NT. * configure.in: (i[345]86-*-win32): New target. * configure: Regnerated. * eval.c (evaluate_subexp_standard): Remove unused name. * serial.c (gdb_string.h): Include. * source.c (value.h): Include. * config/i386/i386win32.mh (XDEPFILES): Add win32.o * config/i386/i386win32.mt: New. * config/i386/tm-i386win32.h: New. --- gdb/.Sanitize | 1 + gdb/ChangeLog | 12 + gdb/config/i386/.Sanitize | 2 + gdb/config/i386/i386win32.mh | 3 +- gdb/config/i386/i386win32.mt | 5 + gdb/config/i386/tm-i386win32.h | 120 ++++++++ gdb/configure | 266 +++++++++++++---- gdb/configure.in | 1 + gdb/eval.c | 209 ++++++++++---- gdb/serial.c | 1 + gdb/win32.c | 643 +++++++++++++++++++++++++++++++++++++++++ 11 files changed, 1138 insertions(+), 125 deletions(-) create mode 100644 gdb/config/i386/i386win32.mt create mode 100644 gdb/config/i386/tm-i386win32.h create mode 100644 gdb/win32.c (limited to 'gdb') diff --git a/gdb/.Sanitize b/gdb/.Sanitize index 4dc85d7..219fac7 100644 --- a/gdb/.Sanitize +++ b/gdb/.Sanitize @@ -351,6 +351,7 @@ vax-tdep.c vx-share w65-tdep.c w89k-rom.c +win32.c xcoffread.c xcoffsolib.c xcoffsolib.h diff --git a/gdb/ChangeLog b/gdb/ChangeLog index eb0bfff..76ed885 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,15 @@ +Thu Oct 5 13:27:30 1995 steve chamberlain + + * win32.c: New file; support for debugging on windows NT. + * configure.in: (i[345]86-*-win32): New target. + * configure: Regnerated. + * eval.c (evaluate_subexp_standard): Remove unused name. + * serial.c (gdb_string.h): Include. + * source.c (value.h): Include. + * config/i386/i386win32.mh (XDEPFILES): Add win32.o + * config/i386/i386win32.mt: New. + * config/i386/tm-i386win32.h: New. + Wed Oct 4 18:41:34 1995 Per Bothner * expression.h (enum exp_code): Added OP_NAME. diff --git a/gdb/config/i386/.Sanitize b/gdb/config/i386/.Sanitize index 37dac98..232e03b 100644 --- a/gdb/config/i386/.Sanitize +++ b/gdb/config/i386/.Sanitize @@ -51,6 +51,7 @@ i386v32.mh i386v4.mh i386v4.mt i386win32.mh +i386win32.mt linux.mh linux.mt nbsd.mh @@ -89,6 +90,7 @@ tm-i386nw.h tm-i386os9k.h tm-i386v.h tm-i386v4.h +tm-i386win32.h tm-linux.h tm-nbsd.h tm-ptx.h diff --git a/gdb/config/i386/i386win32.mh b/gdb/config/i386/i386win32.mh index c6047cc..1b01fa9 100644 --- a/gdb/config/i386/i386win32.mh +++ b/gdb/config/i386/i386win32.mh @@ -1,6 +1,5 @@ MH_CFLAGS= -XDEPFILES= XM_FILE=xm-i386win32.h TERMCAP= - +XDEPFILES=win32.o diff --git a/gdb/config/i386/i386win32.mt b/gdb/config/i386/i386win32.mt new file mode 100644 index 0000000..b71b059 --- /dev/null +++ b/gdb/config/i386/i386win32.mt @@ -0,0 +1,5 @@ +# Target: Intel 386 run win32 +TDEPFILES= i386-tdep.o i387-tdep.o +TM_FILE= tm-i386win32.h + + diff --git a/gdb/config/i386/tm-i386win32.h b/gdb/config/i386/tm-i386win32.h new file mode 100644 index 0000000..fece826 --- /dev/null +++ b/gdb/config/i386/tm-i386win32.h @@ -0,0 +1,120 @@ +/* Macro definitions for i386 running under the win32 API Unix. + Copyright 1995 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + + +#include "i386/tm-i386v.h" + +#undef MAX_REGISTER_RAW_SIZE +#undef MAX_REGISTER_VIRTUAL_SIZE +#undef NUM_REGS +#undef REGISTER_BYTE +#undef REGISTER_BYTES +#undef REGISTER_CONVERTIBLE +#undef REGISTER_CONVERT_TO_RAW +#undef REGISTER_CONVERT_TO_VIRTUAL +#undef REGISTER_NAMES +#undef REGISTER_RAW_SIZE +#undef REGISTER_VIRTUAL_SIZE +#undef REGISTER_VIRTUAL_TYPE + +/* Number of machine registers */ + +#define NUM_REGS 24 + +/* Initializer for an array of names of registers. + There should be NUM_REGS strings in this initializer. */ + +/* the order of the first 8 registers must match the compiler's + * numbering scheme (which is the same as the 386 scheme) + * also, this table must match regmap in i386-pinsn.c. + */ + +#define REGISTER_NAMES { "eax", "ecx", "edx", "ebx", \ + "esp", "ebp", "esi", "edi", \ + "eip", "ps", "cs", "ss", \ + "ds", "es", "fs", "gs", \ + "st", "st(1)","st(2)","st(3)",\ + "st(4)","st(5)","st(6)","st(7)",} + +#define FP0_REGNUM 16 + +/* Total amount of space needed to store our copies of the machine's + register state, the array `registers'. */ + +#define REGISTER_BYTES (16 * 4 + 8 * 10) + +/* Index within `registers' of the first byte of the space for + register N. */ + +#define REGISTER_BYTE(N) (((N) < 16) ? (N) * 4 : (((N) - 16) * 10) + (16 * 4)) + +/* Number of bytes of storage in the actual machine representation + for register N. */ + +#define REGISTER_RAW_SIZE(N) (((N) < 16) ? 4 : 10) + +/* Number of bytes of storage in the program's representation + for register N. */ + +#define REGISTER_VIRTUAL_SIZE(N) (((N) < 16) ? 4 : 10) + +/* Largest value REGISTER_RAW_SIZE can have. */ + +#define MAX_REGISTER_RAW_SIZE 10 + +/* Largest value REGISTER_VIRTUAL_SIZE can have. */ + +#define MAX_REGISTER_VIRTUAL_SIZE 10 + +/* Nonzero if register N requires conversion + from raw format to virtual format. */ + +#define REGISTER_CONVERTIBLE(N) \ + ((N < FP0_REGNUM) ? 0 : 1) + +/* Convert data from raw format for register REGNUM in buffer FROM + to virtual format with type TYPE in buffer TO. */ +extern void +i387_to_double PARAMS ((char *, char *)); + + +#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \ +{ \ + double val; \ + i387_to_double ((FROM), (char *)&val); \ + store_floating ((TO), TYPE_LENGTH (TYPE), val); \ +} + +extern void +double_to_i387 PARAMS ((char *, char *)); + +#define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \ +{ \ + double val = extract_floating ((FROM), TYPE_LENGTH (TYPE)); \ + double_to_i387((char *)&val, (TO)); \ +} + +/* Return the GDB type object for the "standard" data type + of data in register N. */ + +#define REGISTER_VIRTUAL_TYPE(N) \ + ((N < FP0_REGNUM) ? builtin_type_int : \ + builtin_type_double) + +#define NAMES_HAVE_UNDERSCORE diff --git a/gdb/configure b/gdb/configure index 36e3ad8..8b04368 100755 --- a/gdb/configure +++ b/gdb/configure @@ -1,7 +1,7 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated automatically using autoconf version 2.4 +# Generated automatically using autoconf version 2.4.2 # Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation @@ -39,6 +39,18 @@ target=NONE verbose= x_includes=NONE x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' # Initialize some other variables. subdirs= @@ -63,9 +75,14 @@ do case "$ac_option" in - -build | --build | --buil | --bui | --bu | --b) + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) ac_prev=build ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=* | --b=*) + -build=* | --build=* | --buil=* | --bui=* | --bu=*) build="$ac_optarg" ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ @@ -75,6 +92,12 @@ do | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file="$ac_optarg" ;; + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + -disable-* | --disable-*) ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` # Reject names that are not valid shell variable names. @@ -125,12 +148,26 @@ Configuration: Directory and file names: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] - --exec-prefix=PREFIX install architecture-dependent files in PREFIX + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] --srcdir=DIR find the sources in DIR [configure dir or ..] --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names +EOF + cat << EOF Host type: --build=BUILD configure for building on BUILD [BUILD=HOST] --host=HOST configure for HOST [guessed] @@ -151,6 +188,44 @@ EOF -host=* | --host=* | --hos=* | --ho=*) host="$ac_optarg" ;; + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; @@ -163,6 +238,15 @@ EOF | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) @@ -203,6 +287,23 @@ EOF | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) @@ -213,6 +314,13 @@ EOF -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir="$ac_optarg" ;; + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) @@ -222,7 +330,7 @@ EOF verbose=yes ;; -version | --version | --versio | --versi | --vers) - echo "configure generated by autoconf version 2.4" + echo "configure generated by autoconf version 2.4.2" exit 0 ;; -with-* | --with-*) @@ -387,9 +495,12 @@ fi ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5 2>&5' -ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5 2>&5' +ac_cpp='echo $CPP $CPPFLAGS 1>&5; +$CPP $CPPFLAGS' +ac_compile='echo ${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5; +${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5 2>&5' +ac_link='echo ${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5; +${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5 2>&5' if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. @@ -450,6 +561,7 @@ else ac_cv_prog_gcc=no fi fi + echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes @@ -467,7 +579,8 @@ fi rm -f conftest* fi - echo "$ac_t""$ac_cv_prog_gcc_g" 1>&6 + +echo "$ac_t""$ac_cv_prog_gcc_g" 1>&6 if test $ac_cv_prog_gcc_g = yes; then CFLAGS="-g -O" else @@ -494,7 +607,7 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error @@ -508,7 +621,7 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error @@ -535,7 +648,7 @@ echo "$ac_t""$CPP" 1>&6 echo $ac_n "checking for AIX""... $ac_c" 1>&6 cat > conftest.$ac_ext <&6 else cat > conftest.$ac_ext < EOF @@ -680,10 +793,17 @@ else esac done IFS="$ac_save_ifs" - # As a last resort, use the slow shell script. - test -z "$ac_cv_path_install" && ac_cv_path_install="$ac_install_sh" + fi - INSTALL="$ac_cv_path_install" + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi fi echo "$ac_t""$INSTALL" 1>&6 @@ -854,7 +974,7 @@ else ac_cv_c_cross=yes else cat > conftest.$ac_ext <&6 +cross_compiling=$ac_cv_c_cross echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -897,7 +1018,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -915,7 +1036,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -936,7 +1057,7 @@ if test "$cross_compiling" = yes; then ac_cv_header_stdc=no else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -957,6 +1078,7 @@ fi rm -fr conftest* fi fi + echo "$ac_t""$ac_cv_header_stdc" 1>&6 if test $ac_cv_header_stdc = yes; then cat >> confdefs.h <<\EOF @@ -973,7 +1095,7 @@ if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF @@ -991,7 +1113,7 @@ rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 - ac_tr_hdr=HAVE_`echo $ac_hdr | tr '[a-z]./\055' '[A-Z]___'` + ac_tr_hdr=HAVE_`echo $ac_hdr | tr 'abcdedfghijklmnopqrstuvwxyz./\055' 'ABCDEDFGHIJKLMNOPQRSTUVWXYZ___'` cat >> confdefs.h <&6 else cat > conftest.$ac_ext < #include @@ -1047,6 +1169,7 @@ fi rm -f conftest* fi + echo "$ac_t""$ac_cv_header_stat_broken" 1>&6 if test $ac_cv_header_stat_broken = yes; then cat >> confdefs.h <<\EOF @@ -1064,7 +1187,7 @@ else ac_cv_func_mmap=no else cat > conftest.$ac_ext <&6 if test $ac_cv_func_mmap = yes; then cat >> confdefs.h <<\EOF @@ -1162,8 +1286,8 @@ ENABLE_CLIBS= ENABLE_OBS= # Check whether --enable-netrom or --disable-netrom was given. -enableval="$enable_netrom" -if test -n "$enableval"; then +if test "${enable_netrom+set}" = set; then + enableval="$enable_netrom" case "${enableval}" in yes) enable_netrom=yes ;; no) enable_netrom=no ;; @@ -1180,8 +1304,8 @@ fi ENABLE_GDBTK= # Check whether --enable-gdbtk or --disable-gdbtk was given. -enableval="$enable_gdbtk" -if test -n "$enableval"; then +if test "${enable_gdbtk+set}" = set; then + enableval="$enable_gdbtk" case "${enableval}" in yes) enable_gdbtk=yes ;; no) enable_gdbtk=no ;; @@ -1198,8 +1322,8 @@ if test "${enable_gdbtk}" = "yes"; then echo $ac_n "checking for X""... $ac_c" 1>&6 # Check whether --with-x or --without-x was given. -withval="$with_x" -if test -n "$withval"; then +if test "${with_x+set}" = set; then + withval="$with_x" : fi @@ -1252,7 +1376,7 @@ test -z "$x_direct_test_library" && x_direct_test_library=Xt test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h cat > conftest.$ac_ext < EOF @@ -1315,7 +1439,7 @@ rm -f conftest* ac_save_LIBS="$LIBS" LIBS="-l$x_direct_test_library $LIBS" cat > conftest.$ac_ext <&6 -if eval "test \"`echo '$''{'ac_cv_lib_ICE'+set}'`\" = set"; then +ac_lib_var=`echo ICE | tr './+' '__p'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lICE $LIBS" cat > conftest.$ac_ext <&6 X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE" else @@ -1470,13 +1595,14 @@ fi # libraries were built with DECnet support. And karl@cs.umb.edu says # the Alpha needs dnet_stub (dnet does not exist). echo $ac_n "checking for -ldnet""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_lib_dnet'+set}'`\" = set"; then +ac_lib_var=`echo dnet | tr './+' '__p'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ldnet $LIBS" cat > conftest.$ac_ext <&6 X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" else @@ -1504,13 +1630,14 @@ fi if test $ac_cv_lib_dnet = no; then echo $ac_n "checking for -ldnet_stub""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_lib_dnet_stub'+set}'`\" = set"; then +ac_lib_var=`echo dnet_stub | tr './+' '__p'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ldnet_stub $LIBS" cat > conftest.$ac_ext <&6 X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" else @@ -1543,13 +1670,14 @@ fi # Not sure which flavor of 386 UNIX this is, but it seems harmless to # check for it. echo $ac_n "checking for -lnsl""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_lib_nsl'+set}'`\" = set"; then +ac_lib_var=`echo nsl | tr './+' '__p'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <&6 X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" else @@ -1581,13 +1709,14 @@ fi # But -lsocket is broken on IRIX, according to simon@lia.di.epfl.ch. if test "`(uname) 2>/dev/null`" != IRIX; then echo $ac_n "checking for -lsocket""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_lib_socket'+set}'`\" = set"; then +ac_lib_var=`echo socket | tr './+' '__p'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&6 X_EXTRA_LIBS="$X_EXTRA_LIBS -lsocket" else @@ -1644,7 +1773,7 @@ if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF @@ -1746,7 +1875,7 @@ if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF @@ -2075,6 +2204,7 @@ i[345]86-*-mach*) gdb_target=i386mach ;; i[345]86-*-netware*) gdb_target=i386nw configdirs="${configdirs} nlm" ;; i[345]86-*-osf1mk*) gdb_target=i386mk ;; +i[345]86-*-win32) gdb_target=i386win32 ;; i960-*-bout*) gdb_target=vxworks960 ;; i960-*-coff*) gdb_target=nindy960 ;; @@ -2358,7 +2488,7 @@ do echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) - echo "$CONFIG_STATUS generated by autoconf version 2.4" + echo "$CONFIG_STATUS generated by autoconf version 2.4.2" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; @@ -2385,6 +2515,18 @@ s%@LIBS@%$LIBS%g s%@exec_prefix@%$exec_prefix%g s%@prefix@%$prefix%g s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g s%@CC@%$CC%g s%@CPP@%$CPP%g s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g diff --git a/gdb/configure.in b/gdb/configure.in index 5aa5d07..1f0ad09 100644 --- a/gdb/configure.in +++ b/gdb/configure.in @@ -317,6 +317,7 @@ i[345]86-*-mach*) gdb_target=i386mach ;; i[345]86-*-netware*) gdb_target=i386nw configdirs="${configdirs} nlm" ;; i[345]86-*-osf1mk*) gdb_target=i386mk ;; +i[345]86-*-win32) gdb_target=i386win32 ;; i960-*-bout*) gdb_target=vxworks960 ;; i960-*-coff*) gdb_target=nindy960 ;; diff --git a/gdb/eval.c b/gdb/eval.c index 9964c31..9bc898c 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -16,7 +16,7 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "defs.h" #include "gdb_string.h" @@ -141,75 +141,165 @@ evaluate_type (exp) return evaluate_subexp (NULL_TYPE, exp, &pc, EVAL_AVOID_SIDE_EFFECTS); } -/* Helper function called by evaluate_subexp to initialize a field - a structure from a tuple in Chill. This is recursive, to handle - more than one field name labels. +/* If the next expression is an OP_LABELED, skips past it, + returning the label. Otherwise, does nothing and returns NULL. */ - STRUCT_VAL is the structure value we are constructing. - (*FIELDNOP) is the field to set, if there is no label. - It is set to the field following this one. - EXP, POS, and NOSIDE are as for evaluate_subexp. - - This function does not handle variant records. FIXME */ - -static value_ptr -evaluate_labeled_field_init (struct_val, fieldnop, exp, pos, noside) - value_ptr struct_val; - int *fieldnop; +static char* +get_label (exp, pos) register struct expression *exp; - register int *pos; - enum noside noside; + int *pos; { - int fieldno = *fieldnop; - value_ptr val; - int bitpos, bitsize; - char *addr; - struct type *struct_type = VALUE_TYPE (struct_val); if (exp->elts[*pos].opcode == OP_LABELED) { int pc = (*pos)++; char *name = &exp->elts[pc + 2].string; int tem = longest_to_int (exp->elts[pc + 1].longconst); (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1); - for (fieldno = 0; ; fieldno++) - { - if (fieldno >= TYPE_NFIELDS (struct_type)) - error ("there is no field named %s", name); - if (STREQ (TYPE_FIELD_NAME (struct_type, fieldno), name)) - break; - } - *fieldnop = fieldno; - val = evaluate_labeled_field_init (struct_val, fieldnop, - exp, pos, noside); + return name; } else + return NULL; +} + +/* This function evaluates tupes (in Chill) or brace-initializers + (in C/C++) for structure types. */ + +static value_ptr +evaluate_struct_tuple (struct_val, exp, pos, noside, nargs) + value_ptr struct_val; + register struct expression *exp; + register int *pos; + enum noside noside; + int nargs; +{ + struct type *struct_type = VALUE_TYPE (struct_val); + struct type *substruct_type = struct_type; + struct type *field_type; + int fieldno = -1; + int variantno = -1; + int subfieldno = -1; + while (--nargs >= 0) { - fieldno = (*fieldnop)++; - if (fieldno >= TYPE_NFIELDS (struct_type)) - error ("too many initializers"); - val = evaluate_subexp (TYPE_FIELD_TYPE (struct_type, fieldno), - exp, pos, noside); - } + int pc = *pos; + value_ptr val = NULL; + int nlabels = 0; + int bitpos, bitsize; + char *addr; + + /* Skip past the labels, and count them. */ + while (get_label (exp, pos) != NULL) + nlabels++; - /* Assign val to field fieldno. */ - if (VALUE_TYPE (val) != TYPE_FIELD_TYPE (struct_type, fieldno)) - val = value_cast (TYPE_FIELD_TYPE (struct_type, fieldno), val); -#if 1 - bitsize = TYPE_FIELD_BITSIZE (struct_type, fieldno); - bitpos = TYPE_FIELD_BITPOS (struct_type, fieldno); - addr = VALUE_CONTENTS (struct_val); - addr += bitpos / 8; - if (bitsize) - modify_field (addr, value_as_long (val), - bitpos % 8, bitsize); - else - memcpy (addr, VALUE_CONTENTS (val), - TYPE_LENGTH (VALUE_TYPE (val))); -#else - value_assign (value_primitive_field (struct_val, 0, fieldno, struct_type), - val); -#endif - return val; + do + { + char *label = get_label (exp, &pc); + if (label) + { + for (fieldno = 0; fieldno < TYPE_NFIELDS (struct_type); + fieldno++) + { + char *field_name = TYPE_FIELD_NAME (struct_type, fieldno); + if (field_name != NULL && STREQ (field_name, label)) + { + variantno = -1; + subfieldno = fieldno; + substruct_type = struct_type; + goto found; + } + } + for (fieldno = 0; fieldno < TYPE_NFIELDS (struct_type); + fieldno++) + { + char *field_name = TYPE_FIELD_NAME (struct_type, fieldno); + field_type = TYPE_FIELD_TYPE (struct_type, fieldno); + if ((field_name == 0 || *field_name == '\0') + && TYPE_CODE (field_type) == TYPE_CODE_UNION) + { + variantno = 0; + for (; variantno < TYPE_NFIELDS (field_type); + variantno++) + { + substruct_type + = TYPE_FIELD_TYPE (field_type, variantno); + if (TYPE_CODE (substruct_type) == TYPE_CODE_STRUCT) + { + for (subfieldno = 0; + subfieldno < TYPE_NFIELDS (substruct_type); + subfieldno++) + { + if (STREQ (TYPE_FIELD_NAME (substruct_type, + subfieldno), + label)) + { + goto found; + } + } + } + } + } + } + error ("there is no field named %s", label); + found: + ; + } + else + { + /* Unlabelled tuple element - go to next field. */ + if (variantno >= 0) + { + subfieldno++; + if (subfieldno >= TYPE_NFIELDS (substruct_type)) + { + variantno = -1; + substruct_type = struct_type; + } + } + if (variantno < 0) + { + fieldno++; + subfieldno = fieldno; + if (fieldno >= TYPE_NFIELDS (struct_type)) + error ("too many initializers"); + field_type = TYPE_FIELD_TYPE (struct_type, fieldno); + if (TYPE_CODE (field_type) == TYPE_CODE_UNION + && TYPE_FIELD_NAME (struct_type, fieldno)[0] == '0') + error ("don't know which variant you want to set"); + } + } + + /* Here, struct_type is the type of the inner struct, + while substruct_type is the type of the inner struct. + These are the same for normal structures, but a variant struct + contains anonymous union fields that contain substruct fields. + The value fieldno is the index of the top-level (normal or + anonymous union) field in struct_field, while the value + subfieldno is the index of the actual real (named inner) field + in substruct_type. */ + + field_type = TYPE_FIELD_TYPE (substruct_type, subfieldno); + if (val == 0) + val = evaluate_subexp (substruct_type, exp, pos, noside); + + /* Now actually set the field in struct_val. */ + + /* Assign val to field fieldno. */ + if (VALUE_TYPE (val) != field_type) + val = value_cast (field_type, val); + + bitsize = TYPE_FIELD_BITSIZE (substruct_type, subfieldno); + bitpos = TYPE_FIELD_BITPOS (struct_type, fieldno); + if (variantno >= 0) + bitpos += TYPE_FIELD_BITPOS (substruct_type, subfieldno); + addr = VALUE_CONTENTS (struct_val) + bitpos / 8; + if (bitsize) + modify_field (addr, value_as_long (val), + bitpos % 8, bitsize); + else + memcpy (addr, VALUE_CONTENTS (val), + TYPE_LENGTH (VALUE_TYPE (val))); + } while (--nlabels > 0); + } + return struct_val; } value_ptr @@ -350,11 +440,8 @@ evaluate_subexp_standard (expect_type, exp, pos, noside) && TYPE_CODE (expect_type) == TYPE_CODE_STRUCT) { value_ptr rec = allocate_value (expect_type); - int fieldno = 0; memset (VALUE_CONTENTS_RAW (rec), '\0', TYPE_LENGTH (expect_type)); - for (tem = 0; tem < nargs; tem++) - evaluate_labeled_field_init (rec, &fieldno, exp, pos, noside); - return rec; + return evaluate_struct_tuple (rec, exp, pos, noside, nargs); } if (expect_type != NULL_TYPE && noside != EVAL_SKIP diff --git a/gdb/serial.c b/gdb/serial.c index 9aa49cb..8a3a21b 100644 --- a/gdb/serial.c +++ b/gdb/serial.c @@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "defs.h" #include "serial.h" +#include "gdb_string.h" /* Linked list of serial I/O handlers */ diff --git a/gdb/win32.c b/gdb/win32.c new file mode 100644 index 0000000..b7308c5 --- /dev/null +++ b/gdb/win32.c @@ -0,0 +1,643 @@ +/* Target-vector operations for controlling win32 child processes, for GDB. + Copyright 1996 + Free Software Foundation, Inc. + + Contributed by Cygnus Support. + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without eve nthe implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* by Steve Chamberlain, sac@cygnus.com */ + +#include "defs.h" +#include "frame.h" /* required by inferior.h */ +#include "inferior.h" +#include "target.h" +#include "wait.h" +#include "gdbcore.h" +#include "command.h" +#include +#include +#include +#include +#include "buildsym.h" +#include "gdb_string.h" +#include "thread.h" +#include "gdbcmd.h" + +#define CHECK(x) check (x, __FILE__,__LINE__) +#define DEBUG(x) if (remote_debug) printf x + + +/* Forward declaration */ +extern struct target_ops child_ops; + +/* The most recently read context. Inspect ContextFlags to see what + bits are valid. */ + +static CONTEXT context; + +/* The process and thread handles for the above context. */ + +static HANDLE current_process; +static HANDLE current_thread; +static int current_process_id; +static int current_thread_id; + +/* Counts of things. */ +static int exception_count = 0; +static int event_count = 0; + +/* User options. */ +static int new_console = 0; +static int new_group = 0; + +/* This vector maps GDB's idea of a register's number into an address + in the win32 exception context vector. + + It also contains the bit mask needed to load the register in question. + + One day we could read a reg, we could inspect the context we + already have loaded, if it doesn't have the bit set that we need, + we read that set of registers in using GetThreadContext. If the + context already contains what we need, we just unpack it. Then to + write a register, first we have to ensure that the context contains + the other regs of the group, and then we copy the info in and set + out bit. */ + +struct regmappings + { + char *incontext; + int mask; + }; + +static const struct regmappings + mappings[] = +{ + {(char *) &context.Eax, CONTEXT_INTEGER}, + {(char *) &context.Ecx, CONTEXT_INTEGER}, + {(char *) &context.Edx, CONTEXT_INTEGER}, + {(char *) &context.Ebx, CONTEXT_INTEGER}, + {(char *) &context.Esp, CONTEXT_CONTROL}, + {(char *) &context.Ebp, CONTEXT_CONTROL}, + {(char *) &context.Esi, CONTEXT_INTEGER}, + {(char *) &context.Edi, CONTEXT_INTEGER}, + {(char *) &context.Eip, CONTEXT_CONTROL}, + {(char *) &context.EFlags, CONTEXT_CONTROL}, + {(char *) &context.SegCs, CONTEXT_SEGMENTS}, + {(char *) &context.SegSs, CONTEXT_SEGMENTS}, + {(char *) &context.SegDs, CONTEXT_SEGMENTS}, + {(char *) &context.SegEs, CONTEXT_SEGMENTS}, + {(char *) &context.SegFs, CONTEXT_SEGMENTS}, + {(char *) &context.SegGs, CONTEXT_SEGMENTS}, + {&context.FloatSave.RegisterArea[0 * 10], CONTEXT_FLOATING_POINT}, + {&context.FloatSave.RegisterArea[1 * 10], CONTEXT_FLOATING_POINT}, + {&context.FloatSave.RegisterArea[2 * 10], CONTEXT_FLOATING_POINT}, + {&context.FloatSave.RegisterArea[3 * 10], CONTEXT_FLOATING_POINT}, + {&context.FloatSave.RegisterArea[4 * 10], CONTEXT_FLOATING_POINT}, + {&context.FloatSave.RegisterArea[5 * 10], CONTEXT_FLOATING_POINT}, + {&context.FloatSave.RegisterArea[6 * 10], CONTEXT_FLOATING_POINT}, + {&context.FloatSave.RegisterArea[7 * 10], CONTEXT_FLOATING_POINT}, +}; + + +/* This vector maps the target's idea of an exception (extracted + from the DEBUG_EVENT structure) to GDB's idea. */ + +struct xlate_exception + { + int them; + enum target_signal us; + }; + + +static const struct xlate_exception + xlate[] = +{ + {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV}, + {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP}, + {DBG_CONTROL_C, TARGET_SIGNAL_INT}, + {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP}, + {-1, -1}}; + + +static void +check (BOOL ok, const char *file, int line) +{ + if (!ok) + printf_filtered ("error return %s:%d was %d\n", file, line, GetLastError ()); +} + +static void +child_fetch_inferior_registers (int r) +{ + if (r < 0) + { + for (r = 0; r < NUM_REGS; r++) + child_fetch_inferior_registers (r); + } + else + { + supply_register (r, mappings[r].incontext); + } +} + +static void +child_store_inferior_registers (int r) +{ + if (r < 0) + { + for (r = 0; r < NUM_REGS; r++) + child_store_inferior_registers (r); + } + else + { + read_register_gen (r, mappings[r].incontext); + } +} + + +/* Wait for child to do something. Return pid of child, or -1 in case + of error; store status through argument pointer OURSTATUS. */ + + +static void +handle_load_dll (DEBUG_EVENT * event) +{ + DWORD dll_name_ptr; + DWORD done; + + ReadProcessMemory (current_process, + (DWORD) event->u.LoadDll.lpImageName, + (char *) &dll_name_ptr, + sizeof (dll_name_ptr), &done); + + /* See if we could read the address of a string, and that the + address isn't null. */ + + if (done == sizeof (dll_name_ptr) && dll_name_ptr) + { + char *dll_name; + int size = event->u.LoadDll.fUnicode ? sizeof (WCHAR) : sizeof (char); + int len = 0; + char b[2]; + do + { + ReadProcessMemory (current_process, + dll_name_ptr + len * size, + &b, + size, + &done); + len++; + } + while ((b[0] != 0 || b[size - 1] != 0) && done == size); + + + dll_name = alloca (len); + + if (event->u.LoadDll.fUnicode) + { + WCHAR *unicode_dll_name = (WCHAR *) alloca (len * sizeof (WCHAR)); + ReadProcessMemory (current_process, + dll_name_ptr, + unicode_dll_name, + len * sizeof (WCHAR), + &done); + + WideCharToMultiByte (CP_ACP, 0, + unicode_dll_name, len, + dll_name, len, 0, 0); + } + else + { + ReadProcessMemory (current_process, + dll_name_ptr, + dll_name, + len, + &done); + } + + /* FIXME!! It would be nice to define one symbol which pointed to the + front of the dll if we can't find any symbols. */ + + context.ContextFlags = CONTEXT_FULL; + GetThreadContext (current_thread, &context); + + symbol_file_add (dll_name, 0, (int) event->u.LoadDll.lpBaseOfDll, 0, 0, 0); + + /* We strip off the path of the dll for tidiness. */ + if (strrchr (dll_name, '\\')) + dll_name = strrchr (dll_name, '\\') + 1; + printf_unfiltered ("%x:%s\n", event->u.LoadDll.lpBaseOfDll, dll_name); + } +} + + +static void +handle_exception (DEBUG_EVENT * event, struct target_waitstatus *ourstatus) +{ + int i; + int done = 0; + ourstatus->kind = TARGET_WAITKIND_STOPPED; + + for (i = 0; !done && xlate[i].us > 0; i++) + { + if (xlate[i].them == event->u.Exception.ExceptionRecord.ExceptionCode) + { + ourstatus->value.sig = xlate[i].us; + done = 1; + break; + } + } + + if (!done) + { + printf_unfiltered ("Want to know about exception code %08x\n", + event->u.Exception.ExceptionRecord.ExceptionCode); + ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN; + } + context.ContextFlags = CONTEXT_FULL; + GetThreadContext (current_thread, &context); + exception_count++; +} + +static int +child_wait (int pid, struct target_waitstatus *ourstatus) +{ + /* We loop when we get a non-standard exception rather than return + with a SPURIOUS because resume can try and step or modify things, + which needs a current_thread. But some of these exceptions mark + the birth or death of threads, which mean that the current thread + isn't necessarily what you think it is. */ + + while (1) + { + DEBUG_EVENT event; + BOOL t = WaitForDebugEvent (&event, INFINITE); + + DEBUG (("%d = WaitForDebugEvent() code=%d pid=%d tid=%d)\n", + t, + event.dwDebugEventCode, + event.dwProcessId, + event.dwThreadId)); + + event_count++; + + current_thread_id = event.dwThreadId; + current_process_id = event.dwProcessId; + + switch (event.dwDebugEventCode) + { + case CREATE_THREAD_DEBUG_EVENT: + case EXIT_THREAD_DEBUG_EVENT: + case CREATE_PROCESS_DEBUG_EVENT: + break; + + case EXIT_PROCESS_DEBUG_EVENT: + ourstatus->kind = TARGET_WAITKIND_EXITED; + ourstatus->value.integer = event.u.ExitProcess.dwExitCode; + CloseHandle (current_process); + CloseHandle (current_thread); + return current_process_id; + break; + + case LOAD_DLL_DEBUG_EVENT: + handle_load_dll (&event); + break; + case EXCEPTION_DEBUG_EVENT: + handle_exception (&event, ourstatus); + return current_process_id; + default: + printf_unfiltered ("waitfor it %d %d %d %d\n", t, + event.dwDebugEventCode, + event.dwProcessId, + event.dwThreadId); + break; + } + CHECK (ContinueDebugEvent (current_process_id, + current_thread_id, + DBG_CONTINUE)); + } +} + + + + +/* Attach to process PID, then initialize for debugging it. */ + +static void +child_attach (args, from_tty) + char *args; + int from_tty; +{ + BOOL ok; + + if (!args) + error_no_arg ("process-id to attach"); + + current_process_id = strtoul (args, 0, 0); + + ok = DebugActiveProcess (current_process_id); + + if (!ok) + error ("Can't attach to process."); + + + exception_count = 0; + event_count = 0; + + if (from_tty) + { + char *exec_file = (char *) get_exec_file (0); + + if (exec_file) + printf_unfiltered ("Attaching to program `%s', %s\n", exec_file, + target_pid_to_str (current_process_id)); + else + printf_unfiltered ("Attaching to %s\n", + target_pid_to_str (current_process_id)); + + gdb_flush (gdb_stdout); + } + + inferior_pid = current_process_id; + push_target (&child_ops); +} + + +static void +child_detach (args, from_tty) + char *args; + int from_tty; +{ + if (from_tty) + { + char *exec_file = get_exec_file (0); + if (exec_file == 0) + exec_file = ""; + printf_unfiltered ("Detaching from program: %s %s\n", exec_file, + target_pid_to_str (inferior_pid)); + gdb_flush (gdb_stdout); + } + inferior_pid = 0; + unpush_target (&child_ops); +} + + +/* Print status information about what we're accessing. */ + +static void +child_files_info (ignore) + struct target_ops *ignore; +{ + printf_unfiltered ("\tUsing the running image of %s %s.\n", + attach_flag ? "attached" : "child", target_pid_to_str (inferior_pid)); +} + +/* ARGSUSED */ +static void +child_open (arg, from_tty) + char *arg; + int from_tty; +{ + error ("Use the \"run\" command to start a Unix child process."); +} + +/* Stub function which causes the inferior that runs it, to be ptrace-able + by its parent process. */ + + +/* Start an inferior Unix child process and sets inferior_pid to its pid. + EXEC_FILE is the file to run. + ALLARGS is a string containing the arguments to the program. + ENV is the environment vector to pass. Errors reported with error(). */ + + +static void +child_create_inferior (exec_file, allargs, env) + char *exec_file; + char *allargs; + char **env; +{ + char *real_path; + STARTUPINFO si; + PROCESS_INFORMATION pi; + struct target_waitstatus dummy; + BOOL ret; + DWORD flags; + + if (!exec_file) + { + error ("No executable specified, use `target exec'.\n"); + } + + memset (&si, 0, sizeof (si)); + si.cb = sizeof (si); + + /* A realpath is always the same size, or a bit shorter than a nice path. */ + real_path = alloca (strlen (exec_file) + 1); + path_to_real_path (exec_file, real_path); + + flags = DEBUG_ONLY_THIS_PROCESS | DEBUG_PROCESS; + + if (new_group) + flags |= CREATE_NEW_PROCESS_GROUP; + + if (new_console) + flags |= CREATE_NEW_CONSOLE; + + ret = CreateProcess (real_path, + allargs, + NULL, /* Security */ + NULL, /* thread */ + TRUE, /* inherit handles */ + flags, /* start flags */ + env, + NULL, /* current directory */ + &si, + &pi); + if (!ret) + error ("Error creating process %s\n", exec_file); + + exception_count = 0; + event_count = 0; + + inferior_pid = pi.dwProcessId; + current_process = pi.hProcess; + current_thread = pi.hThread; + current_process_id = pi.dwProcessId; + current_thread_id = pi.dwThreadId; + push_target (&child_ops); + init_thread_list (); + init_wait_for_inferior (); + clear_proceed_status (); + target_terminal_init (); + target_terminal_inferior (); + + /* Ignore the first trap */ + child_wait (inferior_pid, &dummy); + + proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0); +} + +static void +child_mourn_inferior () +{ + unpush_target (&child_ops); + generic_mourn_inferior (); +} + + +/* Send a SIGINT to the process group. This acts just like the user typed a + ^C on the controlling terminal. */ + +void +child_stop () +{ + CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, 0)); +} + +int +child_xfer_memory (CORE_ADDR memaddr, char *our, int len, int write, struct target_ops *target) +{ + DWORD done; + if (write) + { + WriteProcessMemory (current_process, memaddr, our, len, &done); + FlushInstructionCache (current_process, memaddr, len); + } + else + { + ReadProcessMemory (current_process, memaddr, our, len, &done); + } + return done; +} + +void +child_kill_inferior (void) +{ + CHECK (TerminateProcess (current_process, 0)); + CHECK (CloseHandle (current_process)); + CHECK (CloseHandle (current_thread)); +} + +void +child_resume (int pid, int step, enum target_signal signal) +{ + DEBUG (("child_resume (%d, %d, %d);\n", pid, step, signal)); + + if (step) + { + /* Single step by setting t bit */ + child_fetch_inferior_registers (PS_REGNUM); + context.EFlags |= FLAG_TRACE_BIT; + } + + if (context.ContextFlags) + { + CHECK (SetThreadContext (current_thread, &context)); + context.ContextFlags = 0; + } + + if (signal) + { + fprintf_unfiltered (gdb_stderr, "Can't send signals to the child.\n"); + } + + CHECK (ContinueDebugEvent (current_process_id, + current_thread_id, + DBG_CONTINUE)); +} + +static void +child_prepare_to_store () +{ + /* Do nothing, since we can store individual regs */ +} + +static int +child_can_run () +{ + return 1; +} + +static void +child_close () +{ + +} +struct target_ops child_ops = +{ + "child", /* to_shortname */ + "Win32 child process", /* to_longname */ + "Win32 child process (started by the \"run\" command).", /* to_doc */ + child_open, /* to_open */ + child_close, /* to_close */ + child_attach, /* to_attach */ + child_detach, /* to_detach */ + child_resume, /* to_resume */ + child_wait, /* to_wait */ + child_fetch_inferior_registers,/* to_fetch_registers */ + child_store_inferior_registers,/* to_store_registers */ + child_prepare_to_store, /* to_child_prepare_to_store */ + child_xfer_memory, /* to_xfer_memory */ + child_files_info, /* to_files_info */ + memory_insert_breakpoint, /* to_insert_breakpoint */ + memory_remove_breakpoint, /* to_remove_breakpoint */ + terminal_init_inferior, /* to_terminal_init */ + terminal_inferior, /* to_terminal_inferior */ + terminal_ours_for_output, /* to_terminal_ours_for_output */ + terminal_ours, /* to_terminal_ours */ + child_terminal_info, /* to_terminal_info */ + child_kill_inferior, /* to_kill */ + 0, /* to_load */ + 0, /* to_lookup_symbol */ + child_create_inferior, /* to_create_inferior */ + child_mourn_inferior, /* to_mourn_inferior */ + child_can_run, /* to_can_run */ + 0, /* to_notice_signals */ + 0, /* to_thread_alive */ + child_stop, /* to_stop */ + process_stratum, /* to_stratum */ + 0, /* to_next */ + 1, /* to_has_all_memory */ + 1, /* to_has_memory */ + 1, /* to_has_stack */ + 1, /* to_has_registers */ + 1, /* to_has_execution */ + 0, /* to_sections */ + 0, /* to_sections_end */ + OPS_MAGIC /* to_magic */ +}; + +void +_initialize_inftarg () +{ + add_show_from_set + (add_set_cmd ("new-console", class_support, var_boolean, + (char *) &new_console, + "Set creation of new console when creating child process.", + &setlist), + &showlist); + + add_show_from_set + (add_set_cmd ("new-group", class_support, var_boolean, + (char *) &new_group, + "Set creation of new group when creating child process.", + &setlist), + &showlist); + + add_target (&child_ops); +} -- cgit v1.1