aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/.Sanitize1
-rw-r--r--gdb/ChangeLog12
-rw-r--r--gdb/config/i386/.Sanitize2
-rw-r--r--gdb/config/i386/i386win32.mh3
-rw-r--r--gdb/config/i386/i386win32.mt5
-rw-r--r--gdb/config/i386/tm-i386win32.h120
-rwxr-xr-xgdb/configure266
-rw-r--r--gdb/configure.in1
-rw-r--r--gdb/eval.c209
-rw-r--r--gdb/serial.c1
-rw-r--r--gdb/win32.c643
11 files changed, 1138 insertions, 125 deletions
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 <sac@slash.cygnus.com>
+
+ * 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 <bothner@kalessin.cygnus.com>
* 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 <<EOF
-#line 498 "configure"
+#line 611 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
@@ -508,7 +621,7 @@ else
rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF
-#line 512 "configure"
+#line 625 "configure"
#include "confdefs.h"
#include <assert.h>
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 <<EOF
-#line 539 "configure"
+#line 652 "configure"
#include "confdefs.h"
#ifdef _AIX
yes
@@ -562,7 +675,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
-#line 566 "configure"
+#line 679 "configure"
#include "confdefs.h"
#include <minix/config.h>
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 <<EOF
-#line 858 "configure"
+#line 978 "configure"
#include "confdefs.h"
main(){return(0);}
EOF
@@ -867,15 +987,16 @@ fi
fi
rm -fr conftest*
fi
-cross_compiling=$ac_cv_c_cross
+
echo "$ac_t""$ac_cv_c_cross" 1>&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 <<EOF
-#line 879 "configure"
+#line 1000 "configure"
#include "confdefs.h"
#include <stdlib.h>
#include <stdarg.h>
@@ -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
-#line 901 "configure"
+#line 1022 "configure"
#include "confdefs.h"
#include <string.h>
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
-#line 919 "configure"
+#line 1040 "configure"
#include "confdefs.h"
#include <stdlib.h>
EOF
@@ -936,7 +1057,7 @@ if test "$cross_compiling" = yes; then
ac_cv_header_stdc=no
else
cat > conftest.$ac_ext <<EOF
-#line 940 "configure"
+#line 1061 "configure"
#include "confdefs.h"
#include <ctype.h>
#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
-#line 977 "configure"
+#line 1099 "configure"
#include "confdefs.h"
#include <$ac_hdr>
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 <<EOF
#define $ac_tr_hdr 1
EOF
@@ -1006,7 +1128,7 @@ if eval "test \"`echo '$''{'ac_cv_header_stat_broken'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1010 "configure"
+#line 1132 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/stat.h>
@@ -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 <<EOF
-#line 1068 "configure"
+#line 1191 "configure"
#include "confdefs.h"
/* Thanks to Mike Haertel and Jim Avera for this test. */
@@ -1148,6 +1271,7 @@ fi
fi
rm -fr conftest*
fi
+
echo "$ac_t""$ac_cv_func_mmap" 1>&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
-#line 1256 "configure"
+#line 1380 "configure"
#include "confdefs.h"
#include <$x_direct_test_include>
EOF
@@ -1315,7 +1439,7 @@ rm -f conftest*
ac_save_LIBS="$LIBS"
LIBS="-l$x_direct_test_library $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1319 "configure"
+#line 1443 "configure"
#include "confdefs.h"
int main() { return 0; }
@@ -1427,13 +1551,14 @@ else
# libraries we check for below, so use a different variable.
# --interran@uluru.Stanford.EDU, kb@cs.umb.edu.
echo $ac_n "checking for -lICE""... $ac_c" 1>&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 <<EOF
-#line 1437 "configure"
+#line 1562 "configure"
#include "confdefs.h"
int main() { return 0; }
@@ -1443,16 +1568,16 @@ IceConnectionNumber()
EOF
if eval $ac_link; then
rm -rf conftest*
- eval "ac_cv_lib_ICE=yes"
+ eval "ac_cv_lib_$ac_lib_var=yes"
else
rm -rf conftest*
- eval "ac_cv_lib_ICE=no"
+ eval "ac_cv_lib_$ac_lib_var=no"
fi
rm -f conftest*
LIBS="$ac_save_LIBS"
fi
-if eval "test \"`echo '$ac_cv_lib_'ICE`\" = yes"; then
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
echo "$ac_t""yes" 1>&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 <<EOF
-#line 1480 "configure"
+#line 1606 "configure"
#include "confdefs.h"
int main() { return 0; }
@@ -1486,16 +1612,16 @@ dnet_ntoa()
EOF
if eval $ac_link; then
rm -rf conftest*
- eval "ac_cv_lib_dnet=yes"
+ eval "ac_cv_lib_$ac_lib_var=yes"
else
rm -rf conftest*
- eval "ac_cv_lib_dnet=no"
+ eval "ac_cv_lib_$ac_lib_var=no"
fi
rm -f conftest*
LIBS="$ac_save_LIBS"
fi
-if eval "test \"`echo '$ac_cv_lib_'dnet`\" = yes"; then
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
echo "$ac_t""yes" 1>&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 <<EOF
-#line 1514 "configure"
+#line 1641 "configure"
#include "confdefs.h"
int main() { return 0; }
@@ -1520,16 +1647,16 @@ dnet_ntoa()
EOF
if eval $ac_link; then
rm -rf conftest*
- eval "ac_cv_lib_dnet_stub=yes"
+ eval "ac_cv_lib_$ac_lib_var=yes"
else
rm -rf conftest*
- eval "ac_cv_lib_dnet_stub=no"
+ eval "ac_cv_lib_$ac_lib_var=no"
fi
rm -f conftest*
LIBS="$ac_save_LIBS"
fi
-if eval "test \"`echo '$ac_cv_lib_'dnet_stub`\" = yes"; then
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
echo "$ac_t""yes" 1>&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 <<EOF
-#line 1553 "configure"
+#line 1681 "configure"
#include "confdefs.h"
int main() { return 0; }
@@ -1559,16 +1687,16 @@ t_accept()
EOF
if eval $ac_link; then
rm -rf conftest*
- eval "ac_cv_lib_nsl=yes"
+ eval "ac_cv_lib_$ac_lib_var=yes"
else
rm -rf conftest*
- eval "ac_cv_lib_nsl=no"
+ eval "ac_cv_lib_$ac_lib_var=no"
fi
rm -f conftest*
LIBS="$ac_save_LIBS"
fi
-if eval "test \"`echo '$ac_cv_lib_'nsl`\" = yes"; then
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
echo "$ac_t""yes" 1>&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 <<EOF
-#line 1591 "configure"
+#line 1720 "configure"
#include "confdefs.h"
int main() { return 0; }
@@ -1597,16 +1726,16 @@ socket()
EOF
if eval $ac_link; then
rm -rf conftest*
- eval "ac_cv_lib_socket=yes"
+ eval "ac_cv_lib_$ac_lib_var=yes"
else
rm -rf conftest*
- eval "ac_cv_lib_socket=no"
+ eval "ac_cv_lib_$ac_lib_var=no"
fi
rm -f conftest*
LIBS="$ac_save_LIBS"
fi
-if eval "test \"`echo '$ac_cv_lib_'socket`\" = yes"; then
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
echo "$ac_t""yes" 1>&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
-#line 1648 "configure"
+#line 1777 "configure"
#include "confdefs.h"
#include <tk.h>
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
-#line 1750 "configure"
+#line 1879 "configure"
#include "confdefs.h"
#include <tclInt.h>
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 <signal.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <windows.h>
+#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);
+}